getListOfDebitors with partnerNumber and getSingleDebitorByDebitorNumber
This commit is contained in:
parent
cc72a5fb94
commit
dc6da887a0
@ -57,11 +57,11 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final String name,
|
||||
final String debitorNumber) {
|
||||
final String partnerNumber) {
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = debitorNumber != null
|
||||
? debitorRepo.findDebitorByDebitorNumber(cropTag("D-", debitorNumber))
|
||||
final var entities = partnerNumber != null
|
||||
? debitorRepo.findDebitorByPartnerNumber(cropTag("P-", partnerNumber))
|
||||
: debitorRepo.findDebitorByOptionalNameLike(name);
|
||||
|
||||
final var resources = mapper.mapList(entities, HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
@ -133,6 +133,23 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
return ResponseEntity.ok(mapper.map(result.get(), HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
@Timed("app.office.debitors.api.getSingleDebitorByDebitorNumber")
|
||||
public ResponseEntity<HsOfficeDebitorResource> getSingleDebitorByDebitorNumber(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final Integer debitorNumber) {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = debitorRepo.findDebitorByDebitorNumber(debitorNumber);
|
||||
if (result.isEmpty()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
return ResponseEntity.ok(mapper.map(result.get(), HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Timed("app.office.debitors.api.deleteDebitorByUuid")
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.hostsharing.hsadminng.hs.office.debitor;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import net.hostsharing.hsadminng.lambda.Reducer;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
@ -19,15 +20,20 @@ public interface HsOfficeDebitorRepository extends Repository<HsOfficeDebitorEnt
|
||||
ON partner.partnerRel.holder = debitor.debitorRel.anchor
|
||||
AND partner.partnerRel.type = 'PARTNER' AND debitor.debitorRel.type = 'DEBITOR'
|
||||
WHERE partner.partnerNumber = :partnerNumber
|
||||
AND debitor.debitorNumberSuffix = :debitorNumberSuffix
|
||||
AND (:debitorNumberSuffix IS NULL OR debitor.debitorNumberSuffix = :debitorNumberSuffix)
|
||||
""")
|
||||
@Timed("app.office.debitors.repo.findDebitorByPartnerNumberAndDebitorNumberSuffix")
|
||||
List<HsOfficeDebitorEntity> findDebitorByPartnerNumberAndDebitorNumberSuffix(int partnerNumber, String debitorNumberSuffix);
|
||||
List<HsOfficeDebitorEntity> findDebitorByPartnerNumberAndOptionalDebitorNumberSuffix(int partnerNumber, String debitorNumberSuffix);
|
||||
|
||||
default List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumber) {
|
||||
default Optional<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumber) {
|
||||
final var partnerNumber = debitorNumber / 100;
|
||||
final String suffix = String.format("%02d", debitorNumber % 100);
|
||||
final var result = findDebitorByPartnerNumberAndDebitorNumberSuffix(partnerNumber, suffix);
|
||||
final var result = findDebitorByPartnerNumberAndOptionalDebitorNumberSuffix(partnerNumber, suffix);
|
||||
return result.stream().reduce(Reducer::toSingleElement);
|
||||
}
|
||||
|
||||
default List<HsOfficeDebitorEntity> findDebitorByPartnerNumber(int partnerNumber) {
|
||||
final var result = findDebitorByPartnerNumberAndOptionalDebitorNumberSuffix(partnerNumber, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ map:
|
||||
- type: string:uuid => java.util.UUID
|
||||
- type: string:format => java.lang.String
|
||||
- type: number:currency => java.math.BigDecimal
|
||||
- type: number:integer => java.lang.Integer
|
||||
|
||||
paths:
|
||||
/api/hs/office/partners/{partnerUUID}:
|
||||
|
@ -0,0 +1,29 @@
|
||||
get:
|
||||
tags:
|
||||
- hs-office-debitors
|
||||
description: 'Fetch a single debitor by its debitorNumber, if visible for the current subject.'
|
||||
operationId: getSingleDebitorByDebitorNumber
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: debitorNumber
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: number
|
||||
format: integer
|
||||
minimum: 1000000
|
||||
maximum: 9999999
|
||||
description: debitor-number of the debitor to fetch.
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
'application/json':
|
||||
schema:
|
||||
$ref: 'hs-office-debitor-schemas.yaml#/components/schemas/HsOfficeDebitor'
|
||||
|
||||
"401":
|
||||
$ref: 'error-responses.yaml#/components/responses/Unauthorized'
|
||||
"403":
|
||||
$ref: 'error-responses.yaml#/components/responses/Forbidden'
|
@ -13,15 +13,15 @@ get:
|
||||
schema:
|
||||
type: string
|
||||
description: Prefix of name properties from person or contact to filter the results.
|
||||
- name: debitorNumber
|
||||
- name: partnerNumber
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
minLength: 9
|
||||
maxLength: 9
|
||||
pattern: 'D-[0-9]{7}'
|
||||
description: Debitor number of the requested debitor.
|
||||
pattern: 'P-[0-9]{5}'
|
||||
description: Partner number of the requested debitor.
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
|
@ -61,6 +61,9 @@ paths:
|
||||
/api/hs/office/debitors:
|
||||
$ref: "hs-office-debitors.yaml"
|
||||
|
||||
/api/hs/office/debitors/D-{debitorNumber}:
|
||||
$ref: "hs-office-debitors-with-debitorNumber.yaml"
|
||||
|
||||
/api/hs/office/debitors/{debitorUUID}:
|
||||
$ref: "hs-office-debitors-with-uuid.yaml"
|
||||
|
||||
|
@ -233,7 +233,56 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
}
|
||||
|
||||
@Test
|
||||
void globalAdmin_withoutAssumedRoles_canFindDebitorDebitorByDebitorNumber() {
|
||||
void globalAdmin_withoutAssumedRoles_canGetDebitorByDebitorNumber() {
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/hs/office/debitors/P-10002")
|
||||
.then().log().all().assertThat()
|
||||
.statusCode(200)
|
||||
.contentType("application/json")
|
||||
.body("", lenientlyEquals("""
|
||||
[
|
||||
{
|
||||
"debitorNumber": "D-1000211",
|
||||
"partner": { "partnerNumber": "P-10002" },
|
||||
"debitorRel": {
|
||||
"contact": { "caption": "second contact" }
|
||||
},
|
||||
"vatId": null,
|
||||
"vatCountryCode": null,
|
||||
"vatBusiness": true
|
||||
},
|
||||
{
|
||||
"debitorNumber": "D-1000212",
|
||||
"partner": { "partnerNumber": "P-10002" },
|
||||
"debitorRel": {
|
||||
"contact": { "caption": "second contact" }
|
||||
},
|
||||
"vatId": null,
|
||||
"vatCountryCode": null,
|
||||
"vatBusiness": true
|
||||
},
|
||||
{
|
||||
"debitorNumber": "D-1000213",
|
||||
"partner": { "partnerNumber": "P-10002" },
|
||||
"debitorRel": {
|
||||
"contact": { "caption": "second contact" }
|
||||
},
|
||||
"vatId": null,
|
||||
"vatCountryCode": null,
|
||||
"vatBusiness": true
|
||||
}
|
||||
]
|
||||
"""));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void globalAdmin_withoutAssumedRoles_canFindDebitorsByPartnerNumber() {
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
@ -258,7 +307,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
}
|
||||
]
|
||||
"""));
|
||||
// @formatter:on
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
HsOfficePartnerRepository partnerRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficeContactRealRepository contactrealRepo;
|
||||
HsOfficeContactRealRepository contactRealRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficePersonRealRepository personRepo;
|
||||
@ -85,7 +85,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
final var count = debitorRepo.count();
|
||||
final var givenPartner = partnerRepo.findPartnerByPartnerNumber(10001).orElseThrow();
|
||||
final var givenPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First GmbH"));
|
||||
final var givenContact = one(contactrealRepo.findContactByOptionalCaptionLike("first contact"));
|
||||
final var givenContact = one(contactRealRepo.findContactByOptionalCaptionLike("first contact"));
|
||||
|
||||
// when
|
||||
final var result = attempt(em, () -> {
|
||||
@ -119,7 +119,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
// given
|
||||
context("superuser-alex@hostsharing.net");
|
||||
final var givenPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First GmbH"));
|
||||
final var givenContact = one(contactrealRepo.findContactByOptionalCaptionLike("first contact"));
|
||||
final var givenContact = one(contactRealRepo.findContactByOptionalCaptionLike("first contact"));
|
||||
|
||||
// when
|
||||
final var result = attempt(em, () -> {
|
||||
@ -158,7 +158,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
attempt(em, () -> {
|
||||
final var givenPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First GmbH"));
|
||||
final var givenDebitorPerson = one(personRepo.findPersonByOptionalNameLike("Fourth eG"));
|
||||
final var givenContact = one(contactrealRepo.findContactByOptionalCaptionLike("fourth contact"));
|
||||
final var givenContact = one(contactRealRepo.findContactByOptionalCaptionLike("fourth contact"));
|
||||
final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||
.debitorNumberSuffix("22")
|
||||
.debitorRel(HsOfficeRelationRealEntity.builder()
|
||||
@ -278,7 +278,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
}
|
||||
|
||||
@Nested
|
||||
class FindByDebitorNumberLike {
|
||||
class FindByDebitorNumber {
|
||||
|
||||
@Test
|
||||
public void globalAdmin_canViewAllDebitors() {
|
||||
@ -288,6 +288,23 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
// when
|
||||
final var result = debitorRepo.findDebitorByDebitorNumber(1000313);
|
||||
|
||||
// then
|
||||
assertThat(result).map(Object::toString).contains(
|
||||
"debitor(D-1000313: rel(anchor='IF Third OHG', type='DEBITOR', holder='IF Third OHG'), thi)");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class FindByPartnerNumber {
|
||||
|
||||
@Test
|
||||
public void globalAdmin_canViewAllDebitors() {
|
||||
// given
|
||||
context("superuser-alex@hostsharing.net");
|
||||
|
||||
// when
|
||||
final var result = debitorRepo.findDebitorByPartnerNumber(10003);
|
||||
|
||||
// then
|
||||
exactlyTheseDebitorsAreReturned(result,
|
||||
"debitor(D-1000313: rel(anchor='IF Third OHG', type='DEBITOR', holder='IF Third OHG'), thi)");
|
||||
@ -324,7 +341,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
"hs_office.relation#FourtheG-with-DEBITOR-FourtheG:ADMIN", true);
|
||||
final var givenNewPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First"));
|
||||
final var givenNewBillingPerson = one(personRepo.findPersonByOptionalNameLike("Firby"));
|
||||
final var givenNewContact = one(contactrealRepo.findContactByOptionalCaptionLike("sixth contact"));
|
||||
final var givenNewContact = one(contactRealRepo.findContactByOptionalCaptionLike("sixth contact"));
|
||||
final var givenNewBankAccount = one(bankAccountRepo.findByOptionalHolderLike("first"));
|
||||
final String givenNewVatId = "NEW-VAT-ID";
|
||||
final String givenNewVatCountryCode = "NC";
|
||||
@ -613,7 +630,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
context("superuser-alex@hostsharing.net");
|
||||
final var givenPartner = one(partnerRepo.findPartnerByOptionalNameLike(partnerName));
|
||||
final var givenPartnerPerson = givenPartner.getPartnerRel().getHolder();
|
||||
final var givenContact = one(contactrealRepo.findContactByOptionalCaptionLike(contactCaption));
|
||||
final var givenContact = one(contactRealRepo.findContactByOptionalCaptionLike(contactCaption));
|
||||
final var givenBankAccount =
|
||||
bankAccountHolder != null ? one(bankAccountRepo.findByOptionalHolderLike(bankAccountHolder)) : null;
|
||||
final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||
|
@ -524,7 +524,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
||||
private HsOfficeSepaMandateEntity givenSomeTemporarySepaMandateForDebitorNumber(final int debitorNumber) {
|
||||
return jpaAttempt.transacted(() -> {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(debitorNumber).get(0);
|
||||
final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(debitorNumber).orElseThrow();
|
||||
final var bankAccountHolder = ofNullable(givenDebitor.getPartner().getPartnerRel().getHolder().getTradeName())
|
||||
.orElse(givenDebitor.getPartner().getPartnerRel().getHolder().getFamilyName());
|
||||
final var givenBankAccount = bankAccountRepo.findByOptionalHolderLike(bankAccountHolder).get(0);
|
||||
|
Loading…
Reference in New Issue
Block a user