Skip to content

Commit

Permalink
#998: add new maven project quarter_lib
Browse files Browse the repository at this point in the history
  • Loading branch information
clean-coder committed Sep 19, 2024
1 parent 9355edf commit 27e8799
Show file tree
Hide file tree
Showing 10 changed files with 564 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ frontend/node_modules
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/backend/target/
/quarter_lib/target/
/.idea/
parent.iml
backend/backend.iml
Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
</parent>

<modules>
<module>quarter_lib</module>
<module>backend</module>
</modules>

Expand Down
52 changes: 52 additions & 0 deletions quarter_lib/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>ch.puzzle.okr</groupId>
<artifactId>quarter_lib</artifactId>
<version>2.0.136-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.jupiter.version>5.10.2</junit.jupiter.version>
</properties>

<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package ch.puzzle.quarter.generate;

import java.time.LocalDate;

/**
* Quarter data for H2 database.</br>
* </br>
* This class is used for testing purposes only. Do NOT use this class in production mode.
*/
public record QuarterData(String label, LocalDate startDate, LocalDate endDate) {

public String startDateAsIsoString() {
return isoFormat(startDate);
}

public String endDateAsIsoString() {
return isoFormat(endDate);
}

private String isoFormat(LocalDate date) {
int year = date.getYear();
String month = String.format("%02d", date.getMonthValue());
String day = String.format("%02d", date.getDayOfMonth());
return year + "-" + month + "-" + day;
}

@Override
public String toString() {
return "(" + "'" + label() + "', " + //
"'" + startDateAsIsoString() + "', " + //
"'" + endDateAsIsoString() + "'" + //
")";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package ch.puzzle.quarter.generate;

import java.time.LocalDate;

/**
* Quarter label for H2 database.</br>
* </br>
* This class is used for testing purposes only. Do NOT use this class in production mode.
*/
public class QuarterLabel {
private final LocalDate date;

public QuarterLabel(LocalDate date) {
this.date = date;
}

public String label() {
return "GJ " + //
formatYearAs2Digits(firstYearOfGeschaeftsJahr()) + "/" + //
formatYearAs2Digits(secondYearOfGeschaeftsJahr()) + "-Q" + //
getQuarterDigit();
}

private int getQuarterDigit() {
int month = date.getMonthValue();
if (month < 4)
return 3;
if (month < 7)
return 4;
if (month < 10)
return 1;
return 2;
}

private int firstYearOfGeschaeftsJahr() {
if (isNowInNewGeschaeftsJahr()) {
return date.getYear();
}
return date.getYear() - 1;
}

private boolean isNowInNewGeschaeftsJahr() {
LocalDate startNewGJ = startOfNewGeschaeftsJahr();
return date.equals(startNewGJ) || date.isAfter(startNewGJ);
}

private int secondYearOfGeschaeftsJahr() {
return firstYearOfGeschaeftsJahr() + 1;
}

private int formatYearAs2Digits(int year) {
return year % 1000;
}

private LocalDate startOfNewGeschaeftsJahr() {
return LocalDate.of(date.getYear(), 7, 1);
}
}
64 changes: 64 additions & 0 deletions quarter_lib/src/main/java/ch/puzzle/quarter/generate/Quarters.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package ch.puzzle.quarter.generate;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

/**
* Static initialize quarters for H2 database.</br>
* </br>
* This class is used for testing purposes only. Do NOT use this class in production mode.
*/
public class Quarters {
private record QuarterDateRange(LocalDate startDate, LocalDate endDate) {
}

private static final String Q1_START = "07-01";
private static final String Q1_END = "09-30";
private static final String Q2_START = "10-01";
private static final String Q2_END = "12-31";
private static final String Q3_START = "01-01";
private static final String Q3_END = "03-31";
private static final String Q4_START = "04-01";
private static final String Q4_END = "06-30";

private final List<QuarterDateRange> quarters = new ArrayList<>();

public Quarters(int year) {
createQuarters(year);
}

private void createQuarters(int year) {
quarters.add(createQuarter(year, Q1_START, Q1_END));
quarters.add(createQuarter(year, Q2_START, Q2_END));
quarters.add(createQuarter(year, Q3_START, Q3_END));
quarters.add(createQuarter(year, Q4_START, Q4_END));
}

private QuarterDateRange createQuarter(int year, String startMonthDay, String endMonthDay) {
LocalDate startDate = toDate(year, startMonthDay);
LocalDate endDate = toDate(year, endMonthDay);
return new QuarterDateRange(startDate, endDate);
}

private LocalDate toDate(int year, String monthDay) {
return LocalDate.parse(year + "-" + monthDay);
}

public QuarterData currentQuarter(LocalDate date) {
for (QuarterDateRange quarter : quarters) {
if (isDateInQuarter(date, quarter.startDate(), quarter.endDate())) {
String label = new QuarterLabel(date).label();
return new QuarterData(label, quarter.startDate(), quarter.endDate());
}
}
throw new RuntimeException("No current quarter found for " + date);
}

private boolean isDateInQuarter(LocalDate date, LocalDate start, LocalDate end) {
boolean isAfterStart = date.equals(start) || date.isAfter(start);
boolean isBeforeEnd = date.isBefore(end) || date.equals(end);
return isAfterStart && isBeforeEnd;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package ch.puzzle.quarter.generate.h2;

import ch.puzzle.quarter.generate.QuarterData;
import ch.puzzle.quarter.generate.Quarters;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;

/**
* Quarter functions for H2 database.</br>
* </br>
* This class is used for testing purposes only. Do NOT use this class in production mode.
*/
public class QuarterFunction {
public static final int CURRENT_QUARTER_DB_ID = 2;
public static final int NEXT_QUARTER_DB_ID = 3;

private static final Map<Integer, QuarterData> QUARTERS = new HashMap<>();

public static void initQuarterData() {
LocalDate now = LocalDate.now();
registerCurrentQuarterForDate(now, CURRENT_QUARTER_DB_ID);

LocalDate in3Months = now.plusMonths(3);
registerCurrentQuarterForDate(in3Months, NEXT_QUARTER_DB_ID);
}

private static void registerCurrentQuarterForDate(LocalDate date, int dbId) {
Quarters quarters = new Quarters(date.getYear());
QuarterData currentQuarter = quarters.currentQuarter(date);
QUARTERS.put(dbId, currentQuarter);
}

public static String currentQuarterLabel() {
return QUARTERS.get(CURRENT_QUARTER_DB_ID).label();
}

public static String currentQuarterStartDate() {
return QUARTERS.get(CURRENT_QUARTER_DB_ID).startDateAsIsoString();
}

public static String currentQuarterEndDate() {
return QUARTERS.get(CURRENT_QUARTER_DB_ID).endDateAsIsoString();
}

public static String nextQuarterLabel() {
return QUARTERS.get(NEXT_QUARTER_DB_ID).label();
}

public static String nextQuarterStartDate() {
return QUARTERS.get(NEXT_QUARTER_DB_ID).startDateAsIsoString();
}

public static String nextQuarterEndDate() {
return QUARTERS.get(NEXT_QUARTER_DB_ID).endDateAsIsoString();
}

}
55 changes: 55 additions & 0 deletions quarter_lib/src/test/java/generate/QuarterLabelTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package generate;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import ch.puzzle.quarter.generate.QuarterLabel;

import java.time.LocalDate;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.*;

public class QuarterLabelTest {

@DisplayName("label() should return label with year and quarter info")
@ParameterizedTest
@MethodSource("datesAndLabels")
void labelShouldReturnLabelWithYearAndQuarterInfo(LocalDate date, String expectedLabel) {
QuarterLabel quarterLabel = new QuarterLabel(date);
assertEquals(expectedLabel, quarterLabel.label());
}

private static Stream<Arguments> datesAndLabels() {
return Stream.of( //
Arguments.of(LocalDate.of(2024, 7, 1), "GJ 24/25-Q1"),
Arguments.of(LocalDate.of(2024, 7, 2), "GJ 24/25-Q1"),
Arguments.of(LocalDate.of(2024, 7, 15), "GJ 24/25-Q1"),
Arguments.of(LocalDate.of(2024, 9, 15), "GJ 24/25-Q1"),
Arguments.of(LocalDate.of(2024, 9, 29), "GJ 24/25-Q1"),
Arguments.of(LocalDate.of(2024, 9, 30), "GJ 24/25-Q1"),

Arguments.of(LocalDate.of(2024, 10, 1), "GJ 24/25-Q2"),
Arguments.of(LocalDate.of(2024, 10, 2), "GJ 24/25-Q2"),
Arguments.of(LocalDate.of(2024, 10, 15), "GJ 24/25-Q2"),
Arguments.of(LocalDate.of(2024, 12, 15), "GJ 24/25-Q2"),
Arguments.of(LocalDate.of(2024, 12, 30), "GJ 24/25-Q2"),
Arguments.of(LocalDate.of(2024, 12, 31), "GJ 24/25-Q2"),

Arguments.of(LocalDate.of(2024, 1, 1), "GJ 23/24-Q3"),
Arguments.of(LocalDate.of(2024, 1, 2), "GJ 23/24-Q3"),
Arguments.of(LocalDate.of(2024, 1, 15), "GJ 23/24-Q3"),
Arguments.of(LocalDate.of(2024, 3, 15), "GJ 23/24-Q3"),
Arguments.of(LocalDate.of(2024, 3, 30), "GJ 23/24-Q3"),
Arguments.of(LocalDate.of(2024, 3, 31), "GJ 23/24-Q3"),

Arguments.of(LocalDate.of(2024, 4, 1), "GJ 23/24-Q4"),
Arguments.of(LocalDate.of(2024, 4, 2), "GJ 23/24-Q4"),
Arguments.of(LocalDate.of(2024, 4, 15), "GJ 23/24-Q4"),
Arguments.of(LocalDate.of(2024, 6, 15), "GJ 23/24-Q4"),
Arguments.of(LocalDate.of(2024, 6, 29), "GJ 23/24-Q4"),
Arguments.of(LocalDate.of(2024, 6, 30), "GJ 23/24-Q4"));
}

}
Loading

0 comments on commit 27e8799

Please sign in to comment.