23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ |
24 */ |
25 |
25 |
26 package de.uapcore.lightpit.entities |
26 package de.uapcore.lightpit.entities |
27 |
27 |
|
28 import de.uapcore.lightpit.types.IssueCategory |
|
29 import de.uapcore.lightpit.types.IssueStatus |
|
30 import de.uapcore.lightpit.types.IssueStatusPhase |
28 import java.sql.Date |
31 import java.sql.Date |
29 import java.sql.Timestamp |
32 import java.sql.Timestamp |
30 import java.time.Instant |
33 import java.time.Instant |
31 import kotlin.math.roundToInt |
|
32 |
34 |
33 data class IssueStatusPhase(val number: Int) { |
35 data class Issue(override var id: Int, var project: Project, var component: Component? = null) : Entity { |
34 companion object { |
|
35 val Open = IssueStatusPhase(0) |
|
36 val WorkInProgress = IssueStatusPhase(1) |
|
37 val Done = IssueStatusPhase(2) |
|
38 } |
|
39 } |
|
40 |
|
41 enum class IssueStatus(val phase: IssueStatusPhase) { |
|
42 InSpecification(IssueStatusPhase.Open), |
|
43 ToDo(IssueStatusPhase.Open), |
|
44 Scheduled(IssueStatusPhase.Open), |
|
45 InProgress(IssueStatusPhase.WorkInProgress), |
|
46 InReview(IssueStatusPhase.WorkInProgress), |
|
47 Done(IssueStatusPhase.Done), |
|
48 Rejected(IssueStatusPhase.Done), |
|
49 Withdrawn(IssueStatusPhase.Done), |
|
50 Duplicate(IssueStatusPhase.Done); |
|
51 } |
|
52 |
|
53 enum class IssueCategory { |
|
54 Feature, Improvement, Bug, Task, Test |
|
55 } |
|
56 |
|
57 data class Issue(var id: Int) { |
|
58 |
|
59 var project: Project? = null |
|
60 var component: Component? = null |
|
61 |
36 |
62 var status = IssueStatus.InSpecification |
37 var status = IssueStatus.InSpecification |
63 var category = IssueCategory.Feature |
38 var category = IssueCategory.Feature |
64 |
39 |
65 var subject: String? = null |
40 var subject: String = "" |
66 var description: String? = null |
41 var description: String? = null |
67 var assignee: User? = null |
42 var assignee: User? = null |
68 |
|
69 var affectedVersions = emptyList<Version>() |
|
70 var resolvedVersions = emptyList<Version>() |
|
71 |
43 |
72 var created: Timestamp = Timestamp.from(Instant.now()) |
44 var created: Timestamp = Timestamp.from(Instant.now()) |
73 var updated: Timestamp = Timestamp.from(Instant.now()) |
45 var updated: Timestamp = Timestamp.from(Instant.now()) |
74 var eta: Date? = null |
46 var eta: Date? = null |
|
47 |
|
48 var affectedVersions = emptyList<Version>() |
|
49 var resolvedVersions = emptyList<Version>() |
75 |
50 |
76 /** |
51 /** |
77 * An issue is overdue, if it is not done and the ETA is before the current time. |
52 * An issue is overdue, if it is not done and the ETA is before the current time. |
78 */ |
53 */ |
79 val overdue get() = status.phase != IssueStatusPhase.Done && eta?.before(Date(System.currentTimeMillis())) ?: false |
54 val overdue get() = status.phase != IssueStatusPhase.Done && eta?.before(Date(System.currentTimeMillis())) ?: false |
80 } |
55 } |
81 |
56 |
82 class IssueSummary { |
|
83 var open = 0 |
|
84 var active = 0 |
|
85 var done = 0 |
|
86 |
|
87 val total get() = open + active + done |
|
88 |
|
89 val openPercent get() = 100 - activePercent - donePercent |
|
90 val activePercent get() = if (total > 0) (100f * active / total).roundToInt() else 0 |
|
91 val donePercent get() = if (total > 0) (100f * done / total).roundToInt() else 100 |
|
92 |
|
93 /** |
|
94 * Adds the specified issue to the summary by incrementing the respective counter. |
|
95 * @param issue the issue |
|
96 */ |
|
97 fun add(issue: Issue) { |
|
98 when (issue.status.phase) { |
|
99 IssueStatusPhase.Open -> open++ |
|
100 IssueStatusPhase.WorkInProgress -> active++ |
|
101 IssueStatusPhase.Done -> done++ |
|
102 } |
|
103 } |
|
104 } |
|
105 |
|