Repository: adessose/budgeteer
Issue: Aggregation period sorting defective

The Aggregation Period column of the Budget Bured table in all Week Reports on Budget is sorted lexically.

It must be sorted by date. For projects that do not exceed a year, this is equivalent to sort by week number. However, I recommend to fix the general case, i.e., week 28 of 2020 should have sorting key "2020-28".

Changed files:
budgeteer-web-interface/src/main/java/org/wickedsource/budgeteer/service/record/RecordJoiner.java
budgeteer-web-interface/src/test/java/org/wickedsource/budgeteer/service/record/RecordJoinerTest.java
budgeteer-web-interface/src/main/java/org/wickedsource/budgeteer/service/record/AggregatedRecord.java

diff --git a/budgeteer-web-interface/src/main/java/org/wickedsource/budgeteer/service/record/AggregatedRecord.java b/budgeteer-web-interface/src/main/java/org/wickedsource/budgeteer/service/record/AggregatedRecord.java
index c03fe2a5..8c094c30 100644
--- a/budgeteer-web-interface/src/main/java/org/wickedsource/budgeteer/service/record/AggregatedRecord.java
+++ b/budgeteer-web-interface/src/main/java/org/wickedsource/budgeteer/service/record/AggregatedRecord.java
@@ -33,12 +33,12 @@ public class AggregatedRecord {
             aggregationPeriodStart = c.getTime();
             c.add(Calendar.MONTH, 1);
             c.add(Calendar.DAY_OF_YEAR, -1);
-            aggregationPeriodTitle = String.format("%d/%02d", planAndWorkRecord.getYear(), planAndWorkRecord.getMonth() + 1);
+            aggregationPeriodTitle = String.format("Month %d-%02d", planAndWorkRecord.getYear(), planAndWorkRecord.getMonth() + 1);
         } else {
             c.set(Calendar.WEEK_OF_YEAR, planAndWorkRecord.getWeek());
             aggregationPeriodStart = c.getTime();
             c.add(Calendar.DAY_OF_YEAR, 6);
-            aggregationPeriodTitle = String.format("Week #%d", planAndWorkRecord.getWeek());
+            aggregationPeriodTitle = String.format("Week %d-%d", planAndWorkRecord.getYear(), planAndWorkRecord.getWeek());
         }
 
         aggregationPeriodEnd = c.getTime();
diff --git a/budgeteer-web-interface/src/main/java/org/wickedsource/budgeteer/service/record/RecordJoiner.java b/budgeteer-web-interface/src/main/java/org/wickedsource/budgeteer/service/record/RecordJoiner.java
index fbbb9a13..23bdc48d 100644
--- a/budgeteer-web-interface/src/main/java/org/wickedsource/budgeteer/service/record/RecordJoiner.java
+++ b/budgeteer-web-interface/src/main/java/org/wickedsource/budgeteer/service/record/RecordJoiner.java
@@ -140,7 +140,7 @@ public class RecordJoiner {
                 record.setAggregationPeriodStart(c.getTime());
                 c.add(Calendar.DAY_OF_YEAR, 6);
                 record.setAggregationPeriodEnd(c.getTime());
-                record.setAggregationPeriodTitle(String.format("Week #%d", recordBean.getWeek()));
+                record.setAggregationPeriodTitle(String.format("Week %d-%d", recordBean.getYear(), recordBean.getWeek()));
                 put(getKey(recordBean), record);
             }
             return record;
@@ -158,7 +158,7 @@ public class RecordJoiner {
                 c.add(Calendar.MONTH, 1);
                 c.add(Calendar.DAY_OF_YEAR, -1);
                 record.setAggregationPeriodEnd(c.getTime());
-                record.setAggregationPeriodTitle(String.format("%d/%02d", recordBean.getYear(), recordBean.getMonth() + 1));
+                record.setAggregationPeriodTitle(String.format("Month %d-%02d", recordBean.getYear(), recordBean.getMonth() + 1));
                 put(getKey(recordBean), record);
             }
             return record;
diff --git a/budgeteer-web-interface/src/test/java/org/wickedsource/budgeteer/service/record/RecordJoinerTest.java b/budgeteer-web-interface/src/test/java/org/wickedsource/budgeteer/service/record/RecordJoinerTest.java
index 0254eddb..5a49feee 100644
--- a/budgeteer-web-interface/src/test/java/org/wickedsource/budgeteer/service/record/RecordJoinerTest.java
+++ b/budgeteer-web-interface/src/test/java/org/wickedsource/budgeteer/service/record/RecordJoinerTest.java
@@ -28,21 +28,21 @@ class RecordJoinerTest extends ServiceTestTemplate {
 
         Assertions.assertEquals(format.parse("03.03.2014"), records.get(0).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("09.03.2014"), records.get(0).getAggregationPeriodEnd());
-        Assertions.assertEquals("Week #10", records.get(0).getAggregationPeriodTitle());
+        Assertions.assertEquals("Week 2014-10", records.get(0).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(50000), records.get(0).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(12300), records.get(0).getBudgetPlanned_net());
         Assertions.assertEquals(5d, records.get(0).getHours(), 0.1d);
 
         Assertions.assertEquals(format.parse("06.04.2015"), records.get(1).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("12.04.2015"), records.get(1).getAggregationPeriodEnd());
-        Assertions.assertEquals("Week #15", records.get(1).getAggregationPeriodTitle());
+        Assertions.assertEquals("Week 2015-15", records.get(1).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(50000), records.get(1).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(12300), records.get(1).getBudgetPlanned_net());
         Assertions.assertEquals(5d, records.get(1).getHours(), 0.1d);
 
         Assertions.assertEquals(format.parse("13.04.2015"), records.get(2).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("19.04.2015"), records.get(2).getAggregationPeriodEnd());
-        Assertions.assertEquals("Week #16", records.get(2).getAggregationPeriodTitle());
+        Assertions.assertEquals("Week 2015-16", records.get(2).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(60000), records.get(2).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(32100), records.get(2).getBudgetPlanned_net());
         Assertions.assertEquals(6d, records.get(2).getHours(), 0.1d);
@@ -55,7 +55,7 @@ class RecordJoinerTest extends ServiceTestTemplate {
 
         Assertions.assertEquals(format.parse("26.03.2018"), recordsWithTax.get(0).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("1.04.2018"), recordsWithTax.get(0).getAggregationPeriodEnd());
-        Assertions.assertEquals("Week #13", recordsWithTax.get(0).getAggregationPeriodTitle());
+        Assertions.assertEquals("Week 2018-13", recordsWithTax.get(0).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(16250), recordsWithTax.get(0).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(18750), recordsWithTax.get(0).getBudgetPlanned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(17625), recordsWithTax.get(0).getBudgetBurned_gross());
@@ -64,7 +64,7 @@ class RecordJoinerTest extends ServiceTestTemplate {
 
         Assertions.assertEquals(format.parse("02.04.2018"), recordsWithTax.get(1).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("08.04.2018"), recordsWithTax.get(1).getAggregationPeriodEnd());
-        Assertions.assertEquals("Week #14", recordsWithTax.get(1).getAggregationPeriodTitle());
+        Assertions.assertEquals("Week 2018-14", recordsWithTax.get(1).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(3750), recordsWithTax.get(1).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(5000), recordsWithTax.get(1).getBudgetPlanned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(4125), recordsWithTax.get(1).getBudgetBurned_gross());
@@ -79,21 +79,21 @@ class RecordJoinerTest extends ServiceTestTemplate {
 
         Assertions.assertEquals(format.parse("01.01.2014"), records.get(0).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("31.01.2014"), records.get(0).getAggregationPeriodEnd());
-        Assertions.assertEquals("2014/01", records.get(0).getAggregationPeriodTitle());
+        Assertions.assertEquals("Month 2014-01", records.get(0).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(50000), records.get(0).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(12300), records.get(0).getBudgetPlanned_net());
         Assertions.assertEquals(5d, records.get(0).getHours(), 0.1d);
 
         Assertions.assertEquals(format.parse("01.06.2015"), records.get(1).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("30.06.2015"), records.get(1).getAggregationPeriodEnd());
-        Assertions.assertEquals("2015/06", records.get(1).getAggregationPeriodTitle());
+        Assertions.assertEquals("Month 2015-06", records.get(1).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(50000), records.get(1).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(12300), records.get(1).getBudgetPlanned_net());
         Assertions.assertEquals(5d, records.get(1).getHours(), 0.1d);
 
         Assertions.assertEquals(format.parse("01.07.2015"), records.get(2).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("31.07.2015"), records.get(2).getAggregationPeriodEnd());
-        Assertions.assertEquals("2015/07", records.get(2).getAggregationPeriodTitle());
+        Assertions.assertEquals("Month 2015-07", records.get(2).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(60000), records.get(2).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(32100), records.get(2).getBudgetPlanned_net());
         Assertions.assertEquals(6d, records.get(2).getHours(), 0.1d);
@@ -107,7 +107,7 @@ class RecordJoinerTest extends ServiceTestTemplate {
 
         Assertions.assertEquals(format.parse("01.01.2014"), records.get(0).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("31.01.2014"), records.get(0).getAggregationPeriodEnd());
-        Assertions.assertEquals("2014/01", records.get(0).getAggregationPeriodTitle());
+        Assertions.assertEquals("Month 2014-01", records.get(0).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(100000), records.get(0).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(12300), records.get(0).getBudgetPlanned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(107500), records.get(0).getBudgetBurned_gross());
@@ -116,7 +116,7 @@ class RecordJoinerTest extends ServiceTestTemplate {
 
         Assertions.assertEquals(format.parse("01.06.2015"), records.get(1).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("30.06.2015"), records.get(1).getAggregationPeriodEnd());
-        Assertions.assertEquals("2015/06", records.get(1).getAggregationPeriodTitle());
+        Assertions.assertEquals("Month 2015-06", records.get(1).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(50000), records.get(1).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(12300), records.get(1).getBudgetPlanned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(55000), records.get(1).getBudgetBurned_gross());
@@ -125,7 +125,7 @@ class RecordJoinerTest extends ServiceTestTemplate {
 
         Assertions.assertEquals(format.parse("01.07.2015"), records.get(2).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("31.07.2015"), records.get(2).getAggregationPeriodEnd());
-        Assertions.assertEquals("2015/07", records.get(2).getAggregationPeriodTitle());
+        Assertions.assertEquals("Month 2015-07", records.get(2).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(60000), records.get(2).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(20000), records.get(2).getBudgetPlanned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(66000), records.get(2).getBudgetBurned_gross());
@@ -134,7 +134,7 @@ class RecordJoinerTest extends ServiceTestTemplate {
 
         Assertions.assertEquals(format.parse("01.01.2016"), records.get(3).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("31.01.2016"), records.get(3).getAggregationPeriodEnd());
-        Assertions.assertEquals("2016/01", records.get(3).getAggregationPeriodTitle());
+        Assertions.assertEquals("Month 2016-01", records.get(3).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(143750), records.get(3).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(156250), records.get(3).getBudgetPlanned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(152219), records.get(3).getBudgetBurned_gross());
@@ -143,7 +143,7 @@ class RecordJoinerTest extends ServiceTestTemplate {
 
         Assertions.assertEquals(format.parse("01.06.2016"), records.get(4).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("30.06.2016"), records.get(4).getAggregationPeriodEnd());
-        Assertions.assertEquals("2016/06", records.get(4).getAggregationPeriodTitle());
+        Assertions.assertEquals("Month 2016-06", records.get(4).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(201250), records.get(4).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(208125), records.get(4).getBudgetPlanned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(221375), records.get(4).getBudgetBurned_gross());
@@ -152,7 +152,7 @@ class RecordJoinerTest extends ServiceTestTemplate {
 
         Assertions.assertEquals(format.parse("01.07.2016"), records.get(5).getAggregationPeriodStart());
         Assertions.assertEquals(format.parse("31.07.2016"), records.get(5).getAggregationPeriodEnd());
-        Assertions.assertEquals("2016/07", records.get(5).getAggregationPeriodTitle());
+        Assertions.assertEquals("Month 2016-07", records.get(5).getAggregationPeriodTitle());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(200000), records.get(5).getBudgetBurned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(208125), records.get(5).getBudgetPlanned_net());
         Assertions.assertEquals(MoneyUtil.createMoneyFromCents(220000), records.get(5).getBudgetBurned_gross());