|
|
|
@@ -24,6 +24,8 @@ class TripFinanceQueryServiceTest {
|
|
|
|
|
void bill(long source,int version) {
|
|
|
|
|
jdbc.update("INSERT INTO fin_bill VALUES(1,1,'BILL-A','CNY','ISSUED')");
|
|
|
|
|
jdbc.update("INSERT INTO fin_bill_line VALUES(1,1,?,?,'CNY')",source,version);
|
|
|
|
|
// Fixture models the real ISSUE source state; this does not call the write service.
|
|
|
|
|
jdbc.update("UPDATE fin_fee_source SET status='BILLED' WHERE id=? AND status='AVAILABLE'",source);
|
|
|
|
|
}
|
|
|
|
|
void receipt(String amount) {
|
|
|
|
|
jdbc.update("INSERT INTO fin_receipt VALUES(1,1,'CONFIRMED','CNY')");
|
|
|
|
@@ -35,6 +37,33 @@ class TripFinanceQueryServiceTest {
|
|
|
|
|
assertThat(result.totals().get(0).receivableAmount()).isEqualByComparingTo("20");
|
|
|
|
|
assertThat(result.documents().get(0).allocationStatus()).isEqualTo("ATTRIBUTED");
|
|
|
|
|
}
|
|
|
|
|
@Test void legalSourceAndBillStatesKeepReceivableAndRecordedReceiptAcrossLifecycle() {
|
|
|
|
|
for(String sourceStatus:List.of("AVAILABLE","BILLED","SETTLED"))for(String billStatus:List.of("ISSUED","PARTIALLY_PAID","PAID")) {
|
|
|
|
|
setup();fee(1,1,"DL-A",1,"CNY","20",sourceStatus);bill(1,1);
|
|
|
|
|
jdbc.update("UPDATE fin_fee_source SET status=?",sourceStatus);
|
|
|
|
|
jdbc.update("UPDATE fin_bill SET status=?",billStatus);
|
|
|
|
|
if(!"ISSUED".equals(billStatus))receipt("PAID".equals(billStatus)?"20":"3.5");
|
|
|
|
|
var result=service.query(request(true));
|
|
|
|
|
assertThat(result.sources()).as(sourceStatus+"/"+billStatus).hasSize(1);
|
|
|
|
|
assertThat(result.sources().get(0).status()).isEqualTo(sourceStatus);
|
|
|
|
|
assertThat(result.totals().get(0).receivableAmount()).isEqualByComparingTo("20");
|
|
|
|
|
assertThat(result.documents()).hasSize(1);
|
|
|
|
|
if("ISSUED".equals(billStatus)) {
|
|
|
|
|
assertThat(result.totals().get(0).receivedAmount()).isNull();
|
|
|
|
|
assertThat(result.documents().get(0).allocationStatus()).isEqualTo("PENDING_ALLOCATION");
|
|
|
|
|
} else {
|
|
|
|
|
assertThat(result.totals().get(0).receivedAmount()).isEqualByComparingTo("PAID".equals(billStatus)?"20":"3.5");
|
|
|
|
|
assertThat(result.documents().get(0).allocationStatus()).isEqualTo("ATTRIBUTED");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@Test void lockedVoidedAndSupersededSourcesRemainExcluded() {
|
|
|
|
|
for(String status:List.of("LOCKED","VOIDED","SUPERSEDED")) {
|
|
|
|
|
setup();fee(1,1,"DL-A",1,"CNY","20",status);bill(1,1);receipt("20");
|
|
|
|
|
var result=service.query(request(true));assertThat(result.sources()).as(status).isEmpty();
|
|
|
|
|
assertThat(result.totals()).isEmpty();assertThat(result.documents()).isEmpty();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@Test void issuedPartialAndPaidBillsKeepTheirConfirmedAllocation() {
|
|
|
|
|
for(String status:List.of("ISSUED","PARTIALLY_PAID","PAID")) {
|
|
|
|
|
setup();fee(1,1,"DL-A",1,"CNY","20","AVAILABLE");bill(1,1);
|
|
|
|
@@ -78,8 +107,8 @@ class TripFinanceQueryServiceTest {
|
|
|
|
|
assertThat(service.query(request(true)).totals().get(0).receivableAmount()).isEqualByComparingTo("0");
|
|
|
|
|
}
|
|
|
|
|
@Test void latestVoidedDoesNotFallBackAndOtherCustomerExcluded() {
|
|
|
|
|
fee(1,1,"DL-A",1,"CNY","20","AVAILABLE");fee(2,1,"DL-A",2,"CNY","20","VOIDED");
|
|
|
|
|
fee(3,2,"DL-A",1,"CNY","999","AVAILABLE");
|
|
|
|
|
fee(1,1,"DL-A",1,"CNY","20","BILLED");fee(2,1,"DL-A",2,"CNY","20","VOIDED");
|
|
|
|
|
fee(3,2,"DL-A",1,"CNY","999","BILLED");
|
|
|
|
|
var result=service.query(request(true));assertThat(result.sources()).isEmpty();assertThat(result.status()).isEqualTo("PENDING_ALLOCATION");
|
|
|
|
|
}
|
|
|
|
|
@Test void currenciesSeparateAndNoReceiptPermissionMasksDocuments() {
|
|
|
|
|