ApercuTache.kt
54 lignes · 2339 octets
package fr.ebii.card2vcf.planning import fr.ebii.card2vcf.data.TacheEntity import fr.ebii.card2vcf.sync.SousTacheDto import fr.ebii.card2vcf.sync.syncJson import java.time.LocalDate /** * Ce qu'une carte kanban affiche d'une tâche planifiée. Extrait du Compose pour * être testable, sur le modèle de `KanbanFilter`. * * Toutes les entrées viennent du serveur et peuvent être malformées après une * synchronisation partielle : chaque fonction rend `null` plutôt que de lever. */ object ApercuTache { /** « 09/01 → 13/01 » selon le rythme du projet ; `null` si la tâche n'est pas datée. */ fun periode(tache: TacheEntity, joursOuvres: Int): String? { val debut = dateOuNull(tache.debut) ?: return null return CalendrierOuvre(joursOuvres).periodeAffichee(debut, tache.dureeJours ?: 1) } /** `(faites, total)` des sous-tâches ; `null` s'il n'y en a aucune. */ fun avancement(tache: TacheEntity): Pair<Int, Int>? { val toutes = etats(tache) if (toutes.isEmpty()) return null return toutes.count { it } to toutes.size } /** La tâche finit-elle après l'échéance du projet ? */ fun enRetard(tache: TacheEntity, joursOuvres: Int, echeance: String?): Boolean { val cible = dateOuNull(echeance) ?: return false val debut = dateOuNull(tache.debut) ?: return false return CalendrierOuvre(joursOuvres).fin(debut, tache.dureeJours ?: 1).isAfter(cible) } /** Sous-tâches décodées, dans l'ordre ; liste vide si absentes ou illisibles. */ fun sousTaches(tache: TacheEntity?): List<SousTacheDto> = runCatching { syncJson.decodeFromString<List<SousTacheDto>>(tache?.sousTachesJson ?: "[]") }.getOrDefault(emptyList()) /** Teinte de l'étiquette, identique à celle du web. */ fun couleur(tache: TacheEntity): String? = CouleurEtiquette.pour(tache.etiquette) /** * États `fait` des sous-tâches ; liste vide si illisible. * * Décodé par kotlinx-serialization, pas par `org.json` : ce dernier n'est * qu'un stub dans les tests unitaires JVM. */ private fun etats(tache: TacheEntity): List<Boolean> = sousTaches(tache).map { it.fait } private fun dateOuNull(iso: String?): LocalDate? = iso?.let { runCatching { LocalDate.parse(it) }.getOrNull() } }
GitRust