调整手工开票Rate校验和夜数派生

This commit is contained in:
andy
2026-07-22 22:59:28 +07:00
parent 5712f03d4f
commit 68ff9e2b38
10 changed files with 226 additions and 21 deletions

View File

@@ -294,7 +294,7 @@ public class ReservationInvoiceGenerationServiceImpl implements ReservationInvoi
errors.add(prefix + "room_type: 必填字段缺失。");
}
validatePositive(charge.quantity(), prefix + "quantity", errors);
validatePositive(charge.rate(), prefix + "rate", errors);
validateNonNegative(charge.rate(), prefix + "rate", errors);
validatePositive(charge.nights(), prefix + "nights", errors);
}
}
@@ -490,6 +490,16 @@ public class ReservationInvoiceGenerationServiceImpl implements ReservationInvoi
}
}
private void validateNonNegative(BigDecimal value, String fieldPath, List<String> errors) {
if (value == null) {
errors.add(fieldPath + ": 必填字段缺失。");
return;
}
if (value.compareTo(BigDecimal.ZERO) < 0) {
errors.add(fieldPath + ": 不能小于 0。");
}
}
private String writeJson(Object value) {
try {
return objectMapper.writeValueAsString(value);

View File

@@ -195,6 +195,34 @@ class ReservationInvoiceGenerationControllerTest {
verifyNoInteractions(excelToPdfConverter, objectStorageService);
}
@Test
void shouldAllowManualInvoiceChargeRateToBeZero() throws Exception {
byte[] pdfBytes = "%PDF-1.7\nmanual-invoice-zero-rate".getBytes(StandardCharsets.UTF_8);
when(excelToPdfConverter.convert(any())).thenReturn(new ExcelToPdfConvertedDocument(
"proforma-invoice.pdf",
MediaType.APPLICATION_PDF_VALUE,
(long) pdfBytes.length,
pdfBytes,
88L));
when(objectStorageService.putObject(any())).thenAnswer(invocation -> {
ObjectStoragePutRequest request = invocation.getArgument(0);
return new ObjectStoragePutResult(
request.objectKey(),
"https://oss.example.test/" + request.objectKey(),
request.contentType(),
request.sizeBytes());
});
String token = loginToken(mockMvc, "invoice-admin", "Admin@123456");
performAuthorized(mockMvc, token, post(ENDPOINT)
.contentType(MediaType.APPLICATION_JSON)
.content(validRequest().replace("\"rate\": 3000", "\"rate\": 0")))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.totals.subtotal").value(0.00))
.andExpect(jsonPath("$.totals.vat").value(0.00))
.andExpect(jsonPath("$.totals.total").value(0.00));
}
@Test
void shouldRejectManualInvoiceWhenTaskDoesNotBelongToOrder() throws Exception {
insertOrder(2080010000000000001L, 2080010000000000101L, "GRP-M009-ORDER-1");