src/main/kotlin/de/uapcore/lightpit/entities/Issue.kt

changeset 150
822b7e3d064d
child 167
3f30adba1c63
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/kotlin/de/uapcore/lightpit/entities/Issue.kt	Fri Oct 23 20:34:57 2020 +0200
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2020 Mike Becker. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package de.uapcore.lightpit.entities
+
+import java.sql.Date
+import java.sql.Timestamp
+import java.time.Instant
+import kotlin.math.roundToInt
+
+data class IssueStatusPhase(val number: Int) {
+    companion object {
+        val Open = IssueStatusPhase(0)
+        val WorkInProgress = IssueStatusPhase(1)
+        val Done = IssueStatusPhase(2)
+    }
+}
+
+enum class IssueStatus(val phase: IssueStatusPhase) {
+    InSpecification(IssueStatusPhase.Open),
+    ToDo(IssueStatusPhase.Open),
+    Scheduled(IssueStatusPhase.Open),
+    InProgress(IssueStatusPhase.WorkInProgress),
+    InReview(IssueStatusPhase.WorkInProgress),
+    Done(IssueStatusPhase.Done),
+    Rejected(IssueStatusPhase.Done),
+    Withdrawn(IssueStatusPhase.Done),
+    Duplicate(IssueStatusPhase.Done);
+}
+
+enum class IssueCategory {
+    Feature, Improvement, Bug, Task, Test
+}
+
+data class Issue(var id: Int) {
+
+    var project: Project? = null
+    var component: Component? = null
+
+    var status = IssueStatus.InSpecification
+    var category = IssueCategory.Feature
+
+    var subject: String? = null
+    var description: String? = null
+    var assignee: User? = null
+
+    var affectedVersions = emptyList<Version>()
+    var resolvedVersions = emptyList<Version>()
+
+    var created: Timestamp = Timestamp.from(Instant.now())
+    var updated: Timestamp = Timestamp.from(Instant.now())
+    var eta: Date? = null
+
+    /**
+     * An issue is overdue, if it is not done and the ETA is before the current time.
+     */
+    val overdue get() = status.phase != IssueStatusPhase.Done && eta?.before(Date(System.currentTimeMillis())) ?: false
+}
+
+class IssueSummary {
+    var open = 0
+    var active = 0
+    var done = 0
+
+    val total get() = open + active + done
+
+    val openPercent get() = 100 - activePercent - donePercent
+    val activePercent get() = if (total > 0) (100f * active / total).roundToInt() else 0
+    val donePercent get() = if (total > 0) (100f * done / total).roundToInt() else 100
+
+    /**
+     * Adds the specified issue to the summary by incrementing the respective counter.
+     * @param issue the issue
+     */
+    fun add(issue: Issue) {
+        when (issue.status.phase) {
+            IssueStatusPhase.Open -> open++
+            IssueStatusPhase.WorkInProgress -> active++
+            IssueStatusPhase.Done -> done++
+        }
+    }
+}
+

mercurial