fix StrictMapper related issues and introduce UuidResolver.resolve

This commit is contained in:
Michael Hoennig 2025-01-13 11:13:49 +01:00
parent abd6a48b5e
commit 4d5cb239f3
5 changed files with 56 additions and 21 deletions

View File

@ -29,6 +29,7 @@ import java.util.UUID;
import java.util.function.BiConsumer;
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
import static net.hostsharing.hsadminng.hs.validation.UuidResolver.resolve;
import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
@RestController
@ -75,9 +76,9 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
final var entities = partnerNumber != null
? debitorRepo.findDebitorsByPartnerNumber(cropTag("P-", partnerNumber))
: partnerUuid != null
? debitorRepo.findDebitorsByPartnerUuid(partnerUuid)
: debitorRepo.findDebitorsByOptionalNameLike(name);
: partnerUuid != null
? debitorRepo.findDebitorsByPartnerUuid(partnerUuid)
: debitorRepo.findDebitorsByOptionalNameLike(name);
final var resources = mapper.mapList(entities, HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
return ResponseEntity.ok(resources);
@ -93,11 +94,14 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
context.define(currentSubject, assumedRoles);
Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRelUuid() == null,
Validate.isTrue(
body.getDebitorRel() == null || body.getDebitorRelUuid() == null,
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found both");
Validate.isTrue(body.getDebitorRel() != null || body.getDebitorRelUuid() != null,
Validate.isTrue(
body.getDebitorRel() != null || body.getDebitorRelUuid() != null,
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found none");
Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRel().getMark() == null,
Validate.isTrue(
body.getDebitorRel() == null || body.getDebitorRel().getMark() == null,
"ERROR: [400] debitorRel.mark must be null");
final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@ -206,21 +210,24 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
final BiConsumer<HsOfficeDebitorInsertResource, HsOfficeDebitorEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
if (resource.getDebitorRel() != null) {
final var debitorRel = realRelRepo.save(HsOfficeRelationRealEntity.builder()
.type(DEBITOR)
.anchor(realPersonRepo.findByUuid(resource.getDebitorRel().getAnchorUuid()).orElseThrow() ) // FIXME
.holder(realPersonRepo.findByUuid(resource.getDebitorRel().getHolderUuid()).orElseThrow() ) // FIXME
.contact(realContactRepo.findByUuid(resource.getDebitorRel().getContactUuid()).orElseThrow() ) // FIXME
.build());
.type(DEBITOR)
.anchor(resolve(
"debitorRel.anchor.uuid", resource.getDebitorRel().getAnchorUuid(), realPersonRepo::findByUuid))
.holder(resolve(
"debitorRel.holder.uuid", resource.getDebitorRel().getHolderUuid(), realPersonRepo::findByUuid))
.contact(resolve(
"debitorRel.contact.uuid", resource.getDebitorRel().getContactUuid(), realContactRepo::findByUuid))
.build());
entity.setDebitorRel(debitorRel);
}
if (resource.getRefundBankAccountUuid() != null) {
final var bankAccountEntity = bankAccountRepo.findByUuid(resource.getRefundBankAccountUuid())
.orElseThrow(() -> new ValidationException()); // FIXME
entity.setRefundBankAccount(bankAccountEntity);
entity.setRefundBankAccount(resolve(
"refundBankAccount.uuid", resource.getRefundBankAccountUuid(), bankAccountRepo::findByUuid));
}
};
final BiConsumer<HsOfficeDebitorEntity, HsOfficeDebitorResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
resource.setDebitorNumber(entity.getTaggedDebitorNumber());
resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber());
};
}

View File

@ -26,6 +26,7 @@ import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.List;
import java.util.UUID;
import java.util.function.BiConsumer;
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.EX_PARTNER;
import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
@ -60,7 +61,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
final var entities = partnerRepo.findPartnerByOptionalNameLike(name);
final var resources = mapper.mapList(entities, HsOfficePartnerResource.class);
final var resources = mapper.mapList(entities, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
return ResponseEntity.ok(resources);
}
@ -83,7 +84,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
.path("/api/hs/office/partners/{id}")
.buildAndExpand(saved.getUuid())
.toUri();
final var mapped = mapper.map(saved, HsOfficePartnerResource.class);
final var mapped = mapper.map(saved, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
return ResponseEntity.created(uri).body(mapped);
}
@ -101,7 +102,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
if (result.isEmpty()) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(mapper.map(result.get(), HsOfficePartnerResource.class));
final var mapped = mapper.map(result.get(), HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
return ResponseEntity.ok(mapped);
}
@Override
@ -118,7 +120,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
if (result.isEmpty()) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(mapper.map(result.get(), HsOfficePartnerResource.class));
final var mapped = mapper.map(result.get(), HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
return ResponseEntity.ok(mapped);
}
@Override
@ -161,7 +164,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
final var saved = partnerRepo.save(current);
optionallyCreateExPartnerRelation(saved, previousPartnerRel);
final var mapped = mapper.map(saved, HsOfficePartnerResource.class);
final var mapped = mapper.map(saved, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
return ResponseEntity.ok(mapped);
}
@ -197,4 +200,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
throw new ReferenceNotFoundException(entityClass, uuid, exc);
}
}
final BiConsumer<HsOfficePartnerEntity, HsOfficePartnerResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
resource.setPartnerNumber(entity.getTaggedPartnerNumber());
};
}

View File

@ -0,0 +1,17 @@
package net.hostsharing.hsadminng.hs.validation;
import lombok.experimental.UtilityClass;
import jakarta.validation.ValidationException;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Function;
@UtilityClass
public class UuidResolver {
public static <T> T resolve(final String jsonPath, final UUID uuid, final Function<UUID, Optional<T>> findByUuid) {
return findByUuid.apply(uuid)
.orElseThrow(() -> new ValidationException("Unable to find " + jsonPath + ": " + uuid));
}
}

View File

@ -467,7 +467,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
.post("http://localhost/api/hs/office/debitors")
.then().log().all().assertThat()
.statusCode(400)
.body("message", is("ERROR: [400] Unable to find RealContact by debitorRel.contactUuid: 00000000-0000-0000-0000-000000000000"));
.body("message", is("ERROR: [400] Unable to find debitorRel.contact.uuid: 00000000-0000-0000-0000-000000000000"));
// @formatter:on
}

View File

@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.membership;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
import net.hostsharing.hsadminng.mapper.StrictMapper;
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
@ -75,6 +76,9 @@ public class HsOfficeMembershipControllerRestTest {
@MockBean
HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo;
@MockBean
HsOfficePartnerRepository partnerRepo;
@MockBean
HsOfficeMembershipRepository membershipRepo;
@ -275,7 +279,7 @@ public class HsOfficeMembershipControllerRestTest {
.andExpect(jsonPath("statusPhrase", is("Bad Request")))
.andExpect(jsonPath(
"message",
is("ERROR: [400] Unable to find Partner by partner.uuid: " + givenPartnerUuid)));
is("ERROR: [400] partnerUuid " + givenPartnerUuid + " not found")));
}
@ParameterizedTest