ApercuTache.swift
46 lignes · 2030 octets
import Foundation /// Ce qu'une carte kanban affiche d'une tâche planifiée. Extrait de la vue 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 `nil` plutôt que de lever. /// /// Port de `planning/ApercuTache.kt`. enum ApercuTache { /// « 09/01 → 13/01 » selon le rythme du projet ; `nil` si la tâche n'est pas datée. static func periode(_ tache: TacheEntity, joursOuvres: Int) -> String? { guard let debut = dateOuNil(tache.debut) else { return nil } return CalendrierOuvre(joursOuvres: joursOuvres) .periodeAffichee(debut, tache.dureeJours ?? 1) } /// `(faites, total)` des sous-tâches ; `nil` s'il n'y en a aucune. static func avancement(_ tache: TacheEntity) -> (faites: Int, total: Int)? { let toutes = sousTaches(tache) if toutes.isEmpty { return nil } return (toutes.filter(\.fait).count, toutes.count) } /// La tâche finit-elle après l'échéance du projet ? static func enRetard(_ tache: TacheEntity, joursOuvres: Int, echeance: String?) -> Bool { guard let cible = dateOuNil(echeance), let debut = dateOuNil(tache.debut) else { return false } return CalendrierOuvre(joursOuvres: joursOuvres).fin(debut, tache.dureeJours ?? 1) > cible } /// Sous-tâches décodées, dans l'ordre ; liste vide si absentes ou illisibles. static func sousTaches(_ tache: TacheEntity?) -> [SousTacheDto] { let json = tache?.sousTachesJson ?? "[]" return (try? SyncJson.decode([SousTacheDto].self, from: json)) ?? [] } /// Teinte de l'étiquette, identique à celle du web. static func couleur(_ tache: TacheEntity) -> String? { CouleurEtiquette.pour(tache.etiquette) } private static func dateOuNil(_ iso: String?) -> DateCivile? { guard let iso else { return nil } return DateCivile(iso: iso) } }
GitRust