add assigned-asset, add more hosting-asset test-data and introduce HsBookingDebitor+hs_booking_debitor_rv #58
@ -18,7 +18,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
// a partial HsOfficeDebitorEntity to reduce the number of SQL queries to load the entity
|
||||
@Entity
|
||||
@Table(name = "hs_office_debitor_rv") // TODO.impl: create a readonly view for this, which also joins the partner-number?
|
||||
@Table(name = "hs_booking_debitor_rv")
|
||||
@Getter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@ -37,8 +37,8 @@ public class HsBookingDebitorEntity implements Stringifyable {
|
||||
@Id
|
||||
private UUID uuid;
|
||||
|
||||
@Column(name = "debitornumbersuffix", length = 2)
|
||||
private String debitorNumberSuffix;
|
||||
@Column(name = "debitornumber")
|
||||
private Integer debitorNumber;
|
||||
|
||||
@Column(name = "defaultprefix", columnDefinition = "char(3) not null")
|
||||
private String defaultPrefix;
|
||||
@ -50,6 +50,6 @@ public class HsBookingDebitorEntity implements Stringifyable {
|
||||
|
||||
@Override
|
||||
public String toShortString() {
|
||||
return DEBITOR_NUMBER_TAG + defaultPrefix;
|
||||
return DEBITOR_NUMBER_TAG + debitorNumber;
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,5 @@ public interface HsBookingDebitorRepository extends Repository<HsBookingDebitorE
|
||||
|
||||
Optional<HsBookingDebitorEntity> findByUuid(UUID id);
|
||||
|
||||
List<HsBookingDebitorEntity> findByDefaultPrefix(String defaultPrefix);
|
||||
|
||||
long count();
|
||||
List<HsBookingDebitorEntity> findByDefaultPrefix(String defaultPrefix); // FIXME: change to findByDebitorNumber
|
||||
}
|
@ -202,6 +202,6 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject, Validatab
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
rbac().generateWithBaseFileName("6-hs-booking/620-booking-item/6203-hs-booking-item-rbac");
|
||||
rbac().generateWithBaseFileName("6-hs-booking/630-booking-item/6303-hs-booking-item-rbac");
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.project;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository;
|
||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingProjectsApi;
|
||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectInsertResource;
|
||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectPatchResource;
|
||||
@ -12,8 +13,10 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
||||
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@RestController
|
||||
public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||
@ -27,6 +30,9 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||
@Autowired
|
||||
private HsBookingProjectRepository bookingProjectRepo;
|
||||
|
||||
@Autowired
|
||||
private HsBookingDebitorRepository debitorRepo;
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsBookingProjectResource>> listBookingProjectsByDebitorUuid(
|
||||
@ -50,7 +56,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
|
||||
final var entityToSave = mapper.map(body, HsBookingProjectEntity.class);
|
||||
final var entityToSave = mapper.map(body, HsBookingProjectEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
|
||||
final var saved = bookingProjectRepo.save(entityToSave);
|
||||
|
||||
@ -111,4 +117,12 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||
final var mapped = mapper.map(saved, HsBookingProjectResource.class);
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
||||
final BiConsumer<HsBookingProjectInsertResource, HsBookingProjectEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||
if (resource.getDebitorUuid() != null) {
|
||||
entity.setDebitor(debitorRepo.findByUuid(resource.getDebitorUuid())
|
||||
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] debitorUuid %s not found".formatted(
|
||||
resource.getDebitorUuid()))));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -109,6 +109,6 @@ public class HsBookingProjectEntity implements Stringifyable, RbacObject {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
rbac().generateWithBaseFileName("6-hs-booking/610-booking-project/6103-hs-booking-project-rbac");
|
||||
rbac().generateWithBaseFileName("6-hs-booking/620-booking-project/6203-hs-booking-project-rbac");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-booking-debitor-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create view hs_booking_debitor_rv as
|
||||
select debitor.uuid,
|
||||
debitor.version,
|
||||
(partner.partnerNumber::varchar || debitor.debitorNumberSuffix)::numeric as debitorNumber,
|
||||
debitor.defaultPrefix
|
||||
from hs_office_debitor_rv debitor
|
||||
-- RBAC for debitor is sufficient, for faster access we are bypassing RBAC for the join tables
|
||||
join hs_office_relation debitorRel on debitor.debitorReluUid=debitorRel.uuid
|
||||
join hs_office_relation partnerRel on partnerRel.holderUuid=debitorRel.anchorUuid
|
||||
join hs_office_partner partner on partner.partnerReluUid=partnerRel.uuid;
|
||||
--//
|
@ -130,17 +130,19 @@ databaseChangeLog:
|
||||
- include:
|
||||
file: db/changelog/5-hs-office/512-coopassets/5128-hs-office-coopassets-test-data.sql
|
||||
- include:
|
||||
file: db/changelog/6-hs-booking/610-booking-project/6100-hs-booking-project.sql
|
||||
file: db/changelog/6-hs-booking/610-booking-debitor/6100-hs-booking-debitor.sql
|
||||
- include:
|
||||
file: db/changelog/6-hs-booking/610-booking-project/6103-hs-booking-project-rbac.sql
|
||||
file: db/changelog/6-hs-booking/620-booking-project/6200-hs-booking-project.sql
|
||||
- include:
|
||||
file: db/changelog/6-hs-booking/610-booking-project/6108-hs-booking-project-test-data.sql
|
||||
file: db/changelog/6-hs-booking/620-booking-project/6203-hs-booking-project-rbac.sql
|
||||
- include:
|
||||
file: db/changelog/6-hs-booking/620-booking-item/6200-hs-booking-item.sql
|
||||
file: db/changelog/6-hs-booking/620-booking-project/6208-hs-booking-project-test-data.sql
|
||||
- include:
|
||||
file: db/changelog/6-hs-booking/620-booking-item/6203-hs-booking-item-rbac.sql
|
||||
file: db/changelog/6-hs-booking/630-booking-item/6200-hs-booking-item.sql
|
||||
- include:
|
||||
file: db/changelog/6-hs-booking/620-booking-item/6208-hs-booking-item-test-data.sql
|
||||
file: db/changelog/6-hs-booking/630-booking-item/6203-hs-booking-item-rbac.sql
|
||||
- include:
|
||||
file: db/changelog/6-hs-booking/630-booking-item/6208-hs-booking-item-test-data.sql
|
||||
- include:
|
||||
file: db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql
|
||||
- include:
|
||||
|
@ -9,25 +9,25 @@ class HsBookingDebitorEntityTest {
|
||||
@Test
|
||||
void toStringContainsDebitorNumberAndDefaultPrefix() {
|
||||
final var given = HsBookingDebitorEntity.builder()
|
||||
.debitorNumberSuffix("67")
|
||||
.debitorNumber(1234567)
|
||||
.defaultPrefix("som")
|
||||
.build();
|
||||
|
||||
final var result = given.toString();
|
||||
|
||||
assertThat(result).isEqualTo("booking-debitor(D-som: som)"); // FIXME: I want "booking-debitor(D-1000167: som)"
|
||||
assertThat(result).isEqualTo("booking-debitor(D-1234567: som)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toShortStringContainsDefaultPrefix() {
|
||||
final var given = HsBookingDebitorEntity.builder()
|
||||
.debitorNumberSuffix("67")
|
||||
.debitorNumber(1234567)
|
||||
.defaultPrefix("som")
|
||||
.build();
|
||||
|
||||
final var result = given.toShortString();
|
||||
|
||||
assertThat(result).isEqualTo("D-som"); // FIXME: I want "booking-debitor(D-1000167: som)"
|
||||
assertThat(result).isEqualTo("D-1234567");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,10 +6,8 @@ import lombok.experimental.UtilityClass;
|
||||
@UtilityClass
|
||||
public class TestHsBookingDebitor {
|
||||
|
||||
public String DEFAULT_DEBITOR_SUFFIX = "00";
|
||||
|
||||
public static final HsBookingDebitorEntity TEST_BOOKING_DEBITOR = HsBookingDebitorEntity.builder()
|
||||
.debitorNumberSuffix(DEFAULT_DEBITOR_SUFFIX)
|
||||
.debitorNumber(1234500)
|
||||
.defaultPrefix("abc")
|
||||
.build();
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
assertThat(bookingItemRepo.findByUuid(givenBookingItem.getUuid())).isPresent().get()
|
||||
.matches(mandate -> {
|
||||
assertThat(mandate.getProject().getDebitor().toString()).isEqualTo("booking-debitor(D-fir: fir)");
|
||||
assertThat(mandate.getProject().getDebitor().toString()).isEqualTo("booking-debitor(D-1000111: fir)");
|
||||
assertThat(mandate.getValidFrom()).isEqualTo("2022-11-01");
|
||||
assertThat(mandate.getValidTo()).isEqualTo("2022-12-31");
|
||||
return true;
|
||||
|
@ -29,14 +29,14 @@ class HsBookingItemEntityUnitTest {
|
||||
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
|
||||
final var result = givenBookingItem.toString();
|
||||
|
||||
assertThat(result).isEqualTo("HsBookingItemEntity(D-abc:test project, CLOUD_SERVER, [2020-01-01,2031-01-01), some caption, { CPUs: 2, HDD-storage: 2048, SSD-storage: 512 })");
|
||||
assertThat(result).isEqualTo("HsBookingItemEntity(D-1234500:test project, CLOUD_SERVER, [2020-01-01,2031-01-01), some caption, { CPUs: 2, HDD-storage: 2048, SSD-storage: 512 })");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toShortStringContainsOnlyMemberNumberAndCaption() {
|
||||
final var result = givenBookingItem.toShortString();
|
||||
|
||||
assertThat(result).isEqualTo("D-abc:test project:some caption");
|
||||
assertThat(result).isEqualTo("D-1234500:test project:some caption");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -174,9 +174,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
// then
|
||||
allTheseBookingItemsAreReturned(
|
||||
result,
|
||||
"HsBookingItemEntity(D-sec:D-1000212 default project, MANAGED_WEBSPACE, [2022-10-01,), some ManagedWebspace, { Daemons: 2, Multi: 4, SDD: 512, Traffic: 12 })",
|
||||
"HsBookingItemEntity(D-sec:D-1000212 default project, MANAGED_SERVER, [2022-10-01,), separate ManagedServer, { CPUs: 2, RAM: 8, SDD: 512, Traffic: 42 })",
|
||||
"HsBookingItemEntity(D-sec:D-1000212 default project, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10240, SDD: 10240, Traffic: 42 })");
|
||||
"HsBookingItemEntity(D-1000212:D-1000212 default project, MANAGED_WEBSPACE, [2022-10-01,), some ManagedWebspace, { Daemons: 2, Multi: 4, SDD: 512, Traffic: 12 })",
|
||||
"HsBookingItemEntity(D-1000212:D-1000212 default project, MANAGED_SERVER, [2022-10-01,), separate ManagedServer, { CPUs: 2, RAM: 8, SDD: 512, Traffic: 42 })",
|
||||
"HsBookingItemEntity(D-1000212:D-1000212 default project, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10240, SDD: 10240, Traffic: 42 })");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -194,9 +194,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
// then:
|
||||
exactlyTheseBookingItemsAreReturned(
|
||||
result,
|
||||
"HsBookingItemEntity(D-fir:D-1000111 default project, MANAGED_SERVER, [2022-10-01,), separate ManagedServer, { CPUs: 2, RAM: 8, SDD: 512, Traffic: 42 })",
|
||||
"HsBookingItemEntity(D-fir:D-1000111 default project, MANAGED_WEBSPACE, [2022-10-01,), some ManagedWebspace, { Daemons: 2, Multi: 4, SDD: 512, Traffic: 12 })",
|
||||
"HsBookingItemEntity(D-fir:D-1000111 default project, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10240, SDD: 10240, Traffic: 42 })");
|
||||
"HsBookingItemEntity(D-1000111:D-1000111 default project, MANAGED_SERVER, [2022-10-01,), separate ManagedServer, { CPUs: 2, RAM: 8, SDD: 512, Traffic: 42 })",
|
||||
"HsBookingItemEntity(D-1000111:D-1000111 default project, MANAGED_WEBSPACE, [2022-10-01,), some ManagedWebspace, { Daemons: 2, Multi: 4, SDD: 512, Traffic: 12 })",
|
||||
"HsBookingItemEntity(D-1000111:D-1000111 default project, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10240, SDD: 10240, Traffic: 42 })");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,7 +220,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent().get()
|
||||
.matches(mandate -> {
|
||||
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(D-1000111: rel(anchor='LP First GmbH', type='DEBITOR', holder='LP First GmbH'), fir)");
|
||||
assertThat(mandate.getDebitor().toString()).isEqualTo("booking-debitor(D-1000111: fir)");
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -15,13 +15,13 @@ class HsBookingProjectEntityUnitTest {
|
||||
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
|
||||
final var result = givenBookingProject.toString();
|
||||
|
||||
assertThat(result).isEqualTo("HsBookingProjectEntity(D-1000100, some caption)");
|
||||
assertThat(result).isEqualTo("HsBookingProjectEntity(D-1234500, some caption)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toShortStringContainsOnlyMemberNumberAndCaption() {
|
||||
final var result = givenBookingProject.toShortString();
|
||||
|
||||
assertThat(result).isEqualTo("D-1000100:some caption");
|
||||
assertThat(result).isEqualTo("D-1234500:some caption");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user