From 0b0f57c17613a21e6ad9b499375f49150dcf38c4 Mon Sep 17 00:00:00 2001
From: Michael Hoennig <michael@hoennig.de>
Date: Sat, 22 Oct 2022 12:38:36 +0200
Subject: [PATCH] map HsOfficeMembershipInsertResource via ModelMapper and
 Entity.setValidTo/From

---
 .../HsOfficeMembershipController.java         | 17 +--------
 .../membership/HsOfficeMembershipEntity.java  | 10 +++--
 .../hostsharing/hsadminng/mapper/Mapper.java  |  2 +-
 .../hsadminng/mapper/PostgresDateRange.java   | 10 +++--
 .../mapper/PostgresDateRangeUnitTest.java     | 37 +++++++++++++++++++
 5 files changed, 53 insertions(+), 23 deletions(-)
 create mode 100644 src/test/java/net/hostsharing/hsadminng/mapper/PostgresDateRangeUnitTest.java

diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java
index 827d6222..c5ad8a94 100644
--- a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java
+++ b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java
@@ -1,12 +1,10 @@
 package net.hostsharing.hsadminng.hs.office.membership;
 
 import net.hostsharing.hsadminng.context.Context;
-import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
 import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeMembershipsApi;
 import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipInsertResource;
 import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
 import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipResource;
-import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.transaction.annotation.Transactional;
@@ -21,7 +19,6 @@ import java.util.function.BiConsumer;
 
 import static net.hostsharing.hsadminng.mapper.Mapper.map;
 import static net.hostsharing.hsadminng.mapper.Mapper.mapList;
-import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
 
 @RestController
 
@@ -62,7 +59,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
 
         context.define(currentUser, assumedRoles);
 
-        final var entityToSave = mapX(body, HsOfficeMembershipEntity.class);
+        final var entityToSave = map(body, HsOfficeMembershipEntity.class);
         entityToSave.setUuid(UUID.randomUUID());
 
         final var saved = membershipRepo.save(entityToSave);
@@ -135,16 +132,4 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
             resource.setValidTo(entity.getValidity().upper().minusDays(1));
         }
     };
-
-    private HsOfficeMembershipEntity mapX(
-            final HsOfficeMembershipInsertResource resource,
-            final Class<HsOfficeMembershipEntity> entityClass) {
-        final var entity = new HsOfficeMembershipEntity();
-        entity.setPartner(em.getReference(HsOfficePartnerEntity.class, resource.getPartnerUuid()));
-        entity.setMainDebitor(em.getReference(HsOfficeDebitorEntity.class, resource.getMainDebitorUuid()));
-        entity.setMemberNumber(resource.getMemberNumber());
-        entity.setValidity(toPostgresDateRange(resource.getValidFrom(), resource.getValidTo()));
-        entity.setReasonForTermination(map(resource.getReasonForTermination(), HsOfficeReasonForTermination.class));
-        return entity;
-    }
 }
diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java
index 0cee1196..7e54291c 100644
--- a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java
+++ b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java
@@ -4,11 +4,11 @@ import com.vladmihalcea.hibernate.type.basic.PostgreSQLEnumType;
 import com.vladmihalcea.hibernate.type.range.PostgreSQLRangeType;
 import com.vladmihalcea.hibernate.type.range.Range;
 import lombok.*;
-import net.hostsharing.hsadminng.stringify.Stringify;
-import net.hostsharing.hsadminng.stringify.Stringifyable;
 import net.hostsharing.hsadminng.errors.DisplayName;
 import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
 import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
+import net.hostsharing.hsadminng.stringify.Stringify;
+import net.hostsharing.hsadminng.stringify.Stringifyable;
 import org.hibernate.annotations.Fetch;
 import org.hibernate.annotations.FetchMode;
 import org.hibernate.annotations.Type;
@@ -63,13 +63,17 @@ public class HsOfficeMembershipEntity implements Stringifyable {
     private int memberNumber;
 
     @Column(name = "validity", columnDefinition = "daterange")
-    private Range<LocalDate> validity;
+    private Range<LocalDate> validity = Range.infinite(LocalDate.class);
 
     @Column(name = "reasonfortermination")
     @Enumerated(EnumType.STRING)
     @Type(type = "pgsql_enum")
     private HsOfficeReasonForTermination reasonForTermination;
 
+    public void setValidFrom(final LocalDate validFrom) {
+        validity = toPostgresDateRange(validFrom, getValidity().upper());
+    }
+
     public void setValidTo(final LocalDate validTo) {
         validity = toPostgresDateRange(getValidity().lower(), validTo);
     }
diff --git a/src/main/java/net/hostsharing/hsadminng/mapper/Mapper.java b/src/main/java/net/hostsharing/hsadminng/mapper/Mapper.java
index 05e1b44d..1263e2e1 100644
--- a/src/main/java/net/hostsharing/hsadminng/mapper/Mapper.java
+++ b/src/main/java/net/hostsharing/hsadminng/mapper/Mapper.java
@@ -35,7 +35,7 @@ public abstract class Mapper {
     }
 
     public static <S, T> T map(final S source, final Class<T> targetClass, final BiConsumer<S, T> postMapper) {
-        if (source == null ) {
+        if (source == null) {
             return null;
         }
         final var target = modelMapper.map(source, targetClass);
diff --git a/src/main/java/net/hostsharing/hsadminng/mapper/PostgresDateRange.java b/src/main/java/net/hostsharing/hsadminng/mapper/PostgresDateRange.java
index 30b4fab7..fd70ed04 100644
--- a/src/main/java/net/hostsharing/hsadminng/mapper/PostgresDateRange.java
+++ b/src/main/java/net/hostsharing/hsadminng/mapper/PostgresDateRange.java
@@ -11,8 +11,12 @@ public class PostgresDateRange {
     public static Range<LocalDate> toPostgresDateRange(
             final LocalDate validFrom,
             final LocalDate validTo) {
-        return validTo != null
-                ? Range.closedOpen(validFrom, validTo.plusDays(1))
-                : Range.closedInfinite(validFrom);
+        return validFrom != null
+                ? validTo != null
+                    ? Range.closedOpen(validFrom, validTo.plusDays(1))
+                    : Range.closedInfinite(validFrom)
+                : validTo != null
+                    ? Range.infiniteOpen(validTo.plusDays(1))
+                    : Range.infinite(LocalDate.class);
     }
 }
diff --git a/src/test/java/net/hostsharing/hsadminng/mapper/PostgresDateRangeUnitTest.java b/src/test/java/net/hostsharing/hsadminng/mapper/PostgresDateRangeUnitTest.java
new file mode 100644
index 00000000..b0433824
--- /dev/null
+++ b/src/test/java/net/hostsharing/hsadminng/mapper/PostgresDateRangeUnitTest.java
@@ -0,0 +1,37 @@
+package net.hostsharing.hsadminng.mapper;
+
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDate;
+
+import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
+import static org.assertj.core.api.Assertions.assertThat;
+
+class PostgresDateRangeUnitTest {
+
+    @Test
+    void createsInfiniteRange() {
+        final var actual = toPostgresDateRange(null, null);
+        assertThat(actual.toString()).isEqualTo("Range{lower=null, upper=null, mask=116, clazz=class java.time.LocalDate}");
+    }
+
+    @Test
+    void createsClosedInfiniteRange() {
+        final var actual = toPostgresDateRange(LocalDate.parse("2020-10-31"), null);
+        assertThat(actual.toString()).isEqualTo("Range{lower=2020-10-31, upper=null, mask=82, clazz=class java.time.LocalDate}");
+    }
+
+    @Test
+    void createsInfiniteOpenRange() {
+        final var actual = toPostgresDateRange(null, LocalDate.parse("2020-10-31"));
+        assertThat(actual.toString()).isEqualTo("Range{lower=null, upper=2020-11-01, mask=52, clazz=class java.time.LocalDate}");
+    }
+
+    @Test
+    void createsClosedOpenRange() {
+        final var actual = toPostgresDateRange(LocalDate.parse("2020-10-31"), LocalDate.parse("2020-12-31"));
+        assertThat(actual.toString()).isEqualTo(
+                "Range{lower=2020-10-31, upper=2021-01-01, mask=18, clazz=class java.time.LocalDate}");
+    }
+
+}