OfficeScenarioTests CoopShares+Assets #121

Merged
hsh-michaelhoennig merged 39 commits from feature/use-case-acceptance-tests-4 into master 2024-11-15 11:54:19 +01:00
14 changed files with 67 additions and 66 deletions
Showing only changes of commit faf654e499 - Show all commits

View File

@ -129,7 +129,7 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
final BiConsumer<HsOfficeCoopAssetsTransactionInsertResource, HsOfficeCoopAssetsTransactionEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
if ( resource.getReverseEntryUuid() != null ) {
entity.setAdjustedAssetTx(coopAssetsTransactionRepo.findByUuid(resource.getReverseEntryUuid())
entity.setRevertedAssetTx(coopAssetsTransactionRepo.findByUuid(resource.getReverseEntryUuid())
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] reverseEntityUuid %s not found".formatted(resource.getReverseEntryUuid()))));
}
};

View File

@ -50,8 +50,8 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
.withProp(HsOfficeCoopAssetsTransactionEntity::getAssetValue)
.withProp(HsOfficeCoopAssetsTransactionEntity::getReference)
.withProp(HsOfficeCoopAssetsTransactionEntity::getComment)
.withProp(at -> ofNullable(at.getAdjustedAssetTx()).map(HsOfficeCoopAssetsTransactionEntity::toShortString).orElse(null))
.withProp(at -> ofNullable(at.getAdjustmentAssetTx()).map(HsOfficeCoopAssetsTransactionEntity::toShortString).orElse(null))
.withProp(at -> ofNullable(at.getRevertedAssetTx()).map(HsOfficeCoopAssetsTransactionEntity::toShortString).orElse(null))
.withProp(at -> ofNullable(at.getReversalAssetTx()).map(HsOfficeCoopAssetsTransactionEntity::toShortString).orElse(null))
.quotedValues(false);
@Id
@ -77,7 +77,7 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
* The signed value which directly affects the booking balance.
*
* <p>This means, that a DEPOSIT is always positive, a DISBURSAL is always negative,
* but an ADJUSTMENT can bei either positive or negative.
* but an REVERSAL can bei either positive or negative.
* See {@link HsOfficeCoopAssetsTransactionType} for</p> more information.
*/
@Column(name = "assetvalue")
@ -96,14 +96,14 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
private String comment;
/**
* Optionally, the UUID of the corresponding transaction for an adjustment transaction.
* Optionally, the UUID of the corresponding transaction for an reversal transaction.
*/
@OneToOne
@JoinColumn(name = "adjustedassettxuuid")
private HsOfficeCoopAssetsTransactionEntity adjustedAssetTx;
@JoinColumn(name = "revertedassettxuuid")
private HsOfficeCoopAssetsTransactionEntity revertedAssetTx;
@OneToOne(mappedBy = "adjustedAssetTx")
private HsOfficeCoopAssetsTransactionEntity adjustmentAssetTx;
@OneToOne(mappedBy = "revertedAssetTx")
private HsOfficeCoopAssetsTransactionEntity reversalAssetTx;
@Override
public HsOfficeCoopAssetsTransactionEntity load() {

View File

@ -4,7 +4,7 @@ public enum HsOfficeCoopAssetsTransactionType {
/**
* correction of wrong bookings, value can be positive or negative
*/
ADJUSTMENT,
REVERSAL,
/**
* payment received from member after signing shares, value >0

View File

@ -38,12 +38,6 @@ public interface HsOfficeMembershipRepository extends Repository<HsOfficeMembers
final var partnerNumber = memberNumber / 100;
final String suffix = String.format("%02d", memberNumber % 100);
final var result = findMembershipByPartnerNumberAndSuffix(partnerNumber, suffix);
// FIXME: remove
if (result == null) {
final var all = findAll();
all.size();
}
return result;
}

View File

@ -6,7 +6,7 @@ components:
HsOfficeCoopAssetsTransactionType:
type: string
enum:
- ADJUSTMENT # FIXME: rename to REVERSAL
- REVERSAL
- DEPOSIT
- DISBURSAL
- TRANSFER
@ -32,15 +32,15 @@ components:
type: string
comment:
type: string
adjustedAssetTx: # FIXME: rename to revertedAssetTx
revertedAssetTx:
$ref: '#/components/schemas/HsOfficeReferencedCoopAssetsTransaction'
adjustmentAssetTx: # FIXME: rename to reversalAssetTx
reversalAssetTx:
$ref: '#/components/schemas/HsOfficeReferencedCoopAssetsTransaction'
HsOfficeReferencedCoopAssetsTransaction:
description:
Similar to `HsOfficeCoopAssetsTransaction` but without the self-referencing properties
(`adjustedAssetTx` and `adjustmentAssetTx`), to avoid recursive JSON.
(`revertedAssetTx` and `reversalAssetTx`), to avoid recursive JSON.
type: object
properties:
uuid:

View File

@ -4,7 +4,7 @@
--changeset michael.hoennig:hs-office-coopassets-MAIN-TABLE endDelimiter:--//
-- ----------------------------------------------------------------------------
CREATE TYPE hs_office.CoopAssetsTransactionType AS ENUM ('ADJUSTMENT',
CREATE TYPE hs_office.CoopAssetsTransactionType AS ENUM ('REVERSAL',
'DEPOSIT',
'DISBURSAL',
'TRANSFER',
@ -24,7 +24,7 @@ create table if not exists hs_office.coopassettx
valueDate date not null,
assetValue money not null,
reference varchar(48) not null,
adjustedAssetTxUuid uuid unique REFERENCES hs_office.coopassettx(uuid) DEFERRABLE INITIALLY DEFERRED,
revertedAssetTxUuid uuid unique REFERENCES hs_office.coopassettx(uuid) DEFERRABLE INITIALLY DEFERRED,
comment varchar(512)
);
--//
@ -36,8 +36,8 @@ create table if not exists hs_office.coopassettx
alter table hs_office.coopassettx
add constraint reverse_entry_missing
check ( transactionType = 'ADJUSTMENT' and adjustedAssetTxUuid is not null
or transactionType <> 'ADJUSTMENT' and adjustedAssetTxUuid is null);
check ( transactionType = 'REVERSAL' and revertedAssetTxUuid is not null
or transactionType <> 'REVERSAL' and revertedAssetTxUuid is null);
--//
-- ============================================================================

View File

@ -27,12 +27,12 @@ begin
raise notice 'creating test coopAssetsTransaction: %', givenPartnerNumber || givenMemberNumberSuffix;
lossEntryUuid := uuid_generate_v4();
insert
into hs_office.coopassettx(uuid, membershipuuid, transactiontype, valuedate, assetvalue, reference, comment, adjustedAssetTxUuid)
into hs_office.coopassettx(uuid, membershipuuid, transactiontype, valuedate, assetvalue, reference, comment, revertedAssetTxUuid)
values
(uuid_generate_v4(), membership.uuid, 'DEPOSIT', '2010-03-15', 320.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-1', 'initial deposit', null),
(uuid_generate_v4(), membership.uuid, 'DISBURSAL', '2021-09-01', -128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-2', 'partial disbursal', null),
(lossEntryUuid, membership.uuid, 'DEPOSIT', '2022-10-20', 128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-3', 'some loss', null),
(uuid_generate_v4(), membership.uuid, 'ADJUSTMENT', '2022-10-21', -128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-3', 'some adjustment', lossEntryUuid);
(uuid_generate_v4(), membership.uuid, 'REVERSAL', '2022-10-21', -128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-3', 'some reversal', lossEntryUuid);
end; $$;
--//

View File

@ -442,7 +442,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
34002=CoopAssetsTransaction(M-1002000: 2016-12-31, DISBURSAL, -100.00, 1002000, for cancellation D),
34003=CoopAssetsTransaction(M-1002000: 2016-12-31, LOSS, -20.00, 1002000, for cancellation D),
35001=CoopAssetsTransaction(M-1909000: 2024-01-15, DEPOSIT, 128.00, 1909000, for subscription E),
35002=CoopAssetsTransaction(M-1909000: 2024-01-20, ADJUSTMENT, -128.00, 1909000, chargeback for subscription E, M-1909000:DEP:+128.00),
35002=CoopAssetsTransaction(M-1909000: 2024-01-20, REVERSAL, -128.00, 1909000, chargeback for subscription E, M-1909000:DEP:+128.00),
358=CoopAssetsTransaction(M-1000300: 2000-12-06, DEPOSIT, 5120, 1000300, for subscription A),
442=CoopAssetsTransaction(M-1015200: 2003-07-07, DEPOSIT, 64, 1015200),
577=CoopAssetsTransaction(M-1000300: 2011-12-12, DEPOSIT, 1024, 1000300),
@ -810,7 +810,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
a.getShareCount() == negativeValue)
.findAny()
.orElseThrow(() -> new IllegalStateException(
"cannot determine share reverse entry for adjustment " + shareTransaction));
"cannot determine share reverse entry for reversal " + shareTransaction));
shareTransaction.setRevertedShareTx(revertedShareTx);
}
coopShares.put(rec.getInteger("member_share_id"), shareTransaction);
@ -837,7 +837,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
final var assetTypeMapping = new HashMap<String, HsOfficeCoopAssetsTransactionType>() {
{
put("ADJUSTMENT", HsOfficeCoopAssetsTransactionType.ADJUSTMENT);
put("REVERSAL", HsOfficeCoopAssetsTransactionType.REVERSAL);
put("HANDOVER", HsOfficeCoopAssetsTransactionType.TRANSFER);
put("ADOPTION", HsOfficeCoopAssetsTransactionType.ADOPTION);
put("LOSS", HsOfficeCoopAssetsTransactionType.LOSS);
@ -865,16 +865,16 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
.reference(member.getMemberNumber().toString())
.build();
if (assetTransaction.getTransactionType() == HsOfficeCoopAssetsTransactionType.ADJUSTMENT) {
if (assetTransaction.getTransactionType() == HsOfficeCoopAssetsTransactionType.REVERSAL) {
final var negativeValue = assetTransaction.getAssetValue().negate();
final var adjustedAssetTx = coopAssets.values().stream().filter(a ->
a.getTransactionType() != HsOfficeCoopAssetsTransactionType.ADJUSTMENT &&
final var revertedAssetTx = coopAssets.values().stream().filter(a ->
a.getTransactionType() != HsOfficeCoopAssetsTransactionType.REVERSAL &&
a.getMembership() == assetTransaction.getMembership() &&
a.getAssetValue().equals(negativeValue))
.findAny()
.orElseThrow(() -> new IllegalStateException(
"cannot determine asset reverse entry for adjustment " + assetTransaction));
assetTransaction.setAdjustedAssetTx(adjustedAssetTx);
"cannot determine asset reverse entry for reversal " + assetTransaction));
assetTransaction.setRevertedAssetTx(revertedAssetTx);
}
coopAssets.put(rec.getInteger("member_asset_id"), assetTransaction);

View File

@ -109,21 +109,21 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
"valueDate": "2022-10-20",
"reference": "ref 1000202-3",
"comment": "some loss",
"adjustmentAssetTx": {
"transactionType": "ADJUSTMENT",
"reversalAssetTx": {
"transactionType": "REVERSAL",
"assetValue": -128.00,
"valueDate": "2022-10-21",
"reference": "ref 1000202-3",
"comment": "some adjustment"
"comment": "some reversal"
}
},
{
"transactionType": "ADJUSTMENT",
"transactionType": "REVERSAL",
"assetValue": -128.00,
"valueDate": "2022-10-21",
"reference": "ref 1000202-3",
"comment": "some adjustment",
"adjustedAssetTx": {
"comment": "some reversal",
"revertedAssetTx": {
"transactionType": "DEPOSIT",
"assetValue": 128.00,
"valueDate": "2022-10-20",
@ -214,7 +214,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
}
@Test
void globalAdmin_canAddCoopAssetsAdjustmentTransaction() {
void globalAdmin_canAddCoopAssetsReversalTransaction() {
context.define("superuser-alex@hostsharing.net");
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101);
@ -238,11 +238,11 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
.body("""
{
"membership.uuid": "%s",
"transactionType": "ADJUSTMENT",
"transactionType": "REVERSAL",
"assetValue": %s,
"valueDate": "2022-10-30",
"reference": "test ref adjustment",
"comment": "some coop assets adjustment transaction",
"reference": "test ref reversal",
"comment": "some coop assets reversal transaction",
"reverseEntry.uuid": "%s"
}
""".formatted(
@ -258,12 +258,12 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
.body("uuid", isUuidValid())
.body("", lenientlyEquals("""
{
"transactionType": "ADJUSTMENT",
"transactionType": "REVERSAL",
"assetValue": -256.00,
"valueDate": "2022-10-30",
"reference": "test ref adjustment",
"comment": "some coop assets adjustment transaction",
"adjustedAssetTx": {
"reference": "test ref reversal",
"comment": "some coop assets reversal transaction",
"revertedAssetTx": {
"transactionType": "DEPOSIT",
"assetValue": 256.00,
"valueDate": "2022-10-20",

View File

@ -77,7 +77,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
ASSETS_VALUE_MUST_NOT_BE_NULL(
requestBody -> requestBody
.with("transactionType", "ADJUSTMENT")
.with("transactionType", "REVERSAL")
.with("assetValue", 0.00),
"[assetValue must not be 0 but is \"0.00\"]"),

View File

@ -21,14 +21,14 @@ class HsOfficeCoopAssetsTransactionEntityUnitTest {
.build();
final HsOfficeCoopAssetsTransactionEntity givenCoopAssetAdjustmentTransaction = HsOfficeCoopAssetsTransactionEntity.builder()
final HsOfficeCoopAssetsTransactionEntity givenCoopAssetReversalTransaction = HsOfficeCoopAssetsTransactionEntity.builder()
.membership(TEST_MEMBERSHIP)
.reference("some-ref")
.valueDate(LocalDate.parse("2020-01-15"))
.transactionType(HsOfficeCoopAssetsTransactionType.ADJUSTMENT)
.transactionType(HsOfficeCoopAssetsTransactionType.REVERSAL)
.assetValue(new BigDecimal("-128.00"))
.comment("some comment")
.adjustedAssetTx(givenCoopAssetTransaction)
.revertedAssetTx(givenCoopAssetTransaction)
.build();
final HsOfficeCoopAssetsTransactionEntity givenEmptyCoopAssetsTransaction = HsOfficeCoopAssetsTransactionEntity.builder().build();
@ -42,11 +42,11 @@ class HsOfficeCoopAssetsTransactionEntityUnitTest {
@Test
void toStringWithReverseEntryContainsReverseEntry() {
givenCoopAssetTransaction.setAdjustedAssetTx(givenCoopAssetAdjustmentTransaction);
givenCoopAssetTransaction.setRevertedAssetTx(givenCoopAssetReversalTransaction);
final var result = givenCoopAssetTransaction.toString();
assertThat(result).isEqualTo("CoopAssetsTransaction(M-1000101: 2020-01-01, DEPOSIT, 128.00, some-ref, some comment, M-1000101:ADJ:-128.00)");
assertThat(result).isEqualTo("CoopAssetsTransaction(M-1000101: 2020-01-01, DEPOSIT, 128.00, some-ref, some comment, M-1000101:REV:-128.00)");
}
@Test

View File

@ -142,18 +142,18 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
result,
"CoopAssetsTransaction(M-1000101: 2010-03-15, DEPOSIT, 320.00, ref 1000101-1, initial deposit)",
"CoopAssetsTransaction(M-1000101: 2021-09-01, DISBURSAL, -128.00, ref 1000101-2, partial disbursal)",
"CoopAssetsTransaction(M-1000101: 2022-10-20, DEPOSIT, 128.00, ref 1000101-3, some loss, M-1000101:ADJ:-128.00)",
"CoopAssetsTransaction(M-1000101: 2022-10-21, ADJUSTMENT, -128.00, ref 1000101-3, some adjustment, M-1000101:DEP:+128.00)",
"CoopAssetsTransaction(M-1000101: 2022-10-20, DEPOSIT, 128.00, ref 1000101-3, some loss, M-1000101:REV:-128.00)",
"CoopAssetsTransaction(M-1000101: 2022-10-21, REVERSAL, -128.00, ref 1000101-3, some reversal, M-1000101:DEP:+128.00)",
"CoopAssetsTransaction(M-1000202: 2010-03-15, DEPOSIT, 320.00, ref 1000202-1, initial deposit)",
"CoopAssetsTransaction(M-1000202: 2021-09-01, DISBURSAL, -128.00, ref 1000202-2, partial disbursal)",
"CoopAssetsTransaction(M-1000202: 2022-10-20, DEPOSIT, 128.00, ref 1000202-3, some loss, M-1000202:ADJ:-128.00)",
"CoopAssetsTransaction(M-1000202: 2022-10-21, ADJUSTMENT, -128.00, ref 1000202-3, some adjustment, M-1000202:DEP:+128.00)",
"CoopAssetsTransaction(M-1000202: 2022-10-20, DEPOSIT, 128.00, ref 1000202-3, some loss, M-1000202:REV:-128.00)",
"CoopAssetsTransaction(M-1000202: 2022-10-21, REVERSAL, -128.00, ref 1000202-3, some reversal, M-1000202:DEP:+128.00)",
"CoopAssetsTransaction(M-1000303: 2010-03-15, DEPOSIT, 320.00, ref 1000303-1, initial deposit)",
"CoopAssetsTransaction(M-1000303: 2021-09-01, DISBURSAL, -128.00, ref 1000303-2, partial disbursal)",
"CoopAssetsTransaction(M-1000303: 2022-10-20, DEPOSIT, 128.00, ref 1000303-3, some loss, M-1000303:ADJ:-128.00)",
"CoopAssetsTransaction(M-1000303: 2022-10-21, ADJUSTMENT, -128.00, ref 1000303-3, some adjustment, M-1000303:DEP:+128.00)");
"CoopAssetsTransaction(M-1000303: 2022-10-20, DEPOSIT, 128.00, ref 1000303-3, some loss, M-1000303:REV:-128.00)",
"CoopAssetsTransaction(M-1000303: 2022-10-21, REVERSAL, -128.00, ref 1000303-3, some reversal, M-1000303:DEP:+128.00)");
}
@Test
@ -173,8 +173,8 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
result,
"CoopAssetsTransaction(M-1000202: 2010-03-15, DEPOSIT, 320.00, ref 1000202-1, initial deposit)",
"CoopAssetsTransaction(M-1000202: 2021-09-01, DISBURSAL, -128.00, ref 1000202-2, partial disbursal)",
"CoopAssetsTransaction(M-1000202: 2022-10-20, DEPOSIT, 128.00, ref 1000202-3, some loss, M-1000202:ADJ:-128.00)",
"CoopAssetsTransaction(M-1000202: 2022-10-21, ADJUSTMENT, -128.00, ref 1000202-3, some adjustment, M-1000202:DEP:+128.00)");
"CoopAssetsTransaction(M-1000202: 2022-10-20, DEPOSIT, 128.00, ref 1000202-3, some loss, M-1000202:REV:-128.00)",
"CoopAssetsTransaction(M-1000202: 2022-10-21, REVERSAL, -128.00, ref 1000202-3, some reversal, M-1000202:DEP:+128.00)");
}
@Test
@ -211,8 +211,8 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
result,
"CoopAssetsTransaction(M-1000101: 2010-03-15, DEPOSIT, 320.00, ref 1000101-1, initial deposit)",
"CoopAssetsTransaction(M-1000101: 2021-09-01, DISBURSAL, -128.00, ref 1000101-2, partial disbursal)",
"CoopAssetsTransaction(M-1000101: 2022-10-20, DEPOSIT, 128.00, ref 1000101-3, some loss, M-1000101:ADJ:-128.00)",
"CoopAssetsTransaction(M-1000101: 2022-10-21, ADJUSTMENT, -128.00, ref 1000101-3, some adjustment, M-1000101:DEP:+128.00)");
"CoopAssetsTransaction(M-1000101: 2022-10-20, DEPOSIT, 128.00, ref 1000101-3, some loss, M-1000101:REV:-128.00)",
"CoopAssetsTransaction(M-1000101: 2022-10-21, REVERSAL, -128.00, ref 1000101-3, some reversal, M-1000101:DEP:+128.00)");
}
}

View File

@ -279,7 +279,7 @@ public abstract class UseCase<T extends UseCase<?>> {
public HttpResponse keepAs(final String alias) {
ScenarioTest.putAlias(
alias == null ? "unknown alias" : alias, // FIXME
nonNullAlias(alias),
new ScenarioTest.Alias<>(UseCase.this.getClass(), locationUuid));
return this;
}
@ -348,6 +348,13 @@ public abstract class UseCase<T extends UseCase<?>> {
testReport.printLine("```");
testReport.printLine("");
}
private String nonNullAlias(final String alias) {
// This marker tag should not appear in the source-code, as here is nothing to fix.
// But if it appears in generated Markdown files, it should show up when that marker tag is searched.
final var onlyVisibleInGeneratedMarkdownNotInSource = new String(new char[]{'F', 'I', 'X', 'M', 'E'});
return alias == null ? "unknown alias -- " + onlyVisibleInGeneratedMarkdownNotInSource : alias;
}
}
protected T self() {

View File

@ -16,4 +16,4 @@ member_asset_id; bp_id; date; action; amount; comment
34002; 120; 2016-12-31; PAYBACK; -100.00; for cancellation D
34003; 120; 2016-12-31; LOSS; -20.00; for cancellation D
35001; 190; 2024-01-15; PAYMENT; 128.00; for subscription E
35002; 190; 2024-01-20; ADJUSTMENT;-128.00; chargeback for subscription E
35002; 190; 2024-01-20; REVERSAL;-128.00; chargeback for subscription E
hsh-michaelhoennig marked this conversation as resolved Outdated

ADJUSTMENT

ADJUSTMENT

1 member_asset_id bp_id date action amount comment
16 34002 120 2016-12-31 PAYBACK -100.00 for cancellation D
17 34003 120 2016-12-31 LOSS -20.00 for cancellation D
18 35001 190 2024-01-15 PAYMENT 128.00 for subscription E
19 35002 190 2024-01-20 ADJUSTMENT REVERSAL -128.00 chargeback for subscription E