fix: deliver actual destuff pallet fees
This commit is contained in:
+4
-2
@@ -22,7 +22,9 @@ import java.util.Map;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DestuffingPalletCostService {
|
||||
static final String DESTUFF_BUSINESS_TYPE = "OVERSEAS_CONTAINER";
|
||||
static final String READY_BOOKINGS_SQL = "SELECT o.source_container_booking_id FROM ll_inbound_plan p JOIN ll_order o ON o.id=p.source_order_id JOIN ll_inbound_pda_task t ON t.plan_id=p.id AND t.customer_id=p.customer_id LEFT JOIN ll_destuff_pallet_cost c ON c.source_container_booking_id=o.source_container_booking_id WHERE o.source_container_booking_id IS NOT NULL AND c.id IS NULL GROUP BY o.source_container_booking_id HAVING COUNT(*)=SUM(CASE WHEN t.status='COMPLETED' THEN 1 ELSE 0 END) ORDER BY MAX(t.completed_at) DESC LIMIT 50";
|
||||
static final String RECEIVED_PALLET_IDS_SQL = "SELECT DISTINCT pp.warehouse_pallet_id FROM ll_inbound_plan_pallet pp JOIN ll_inbound_plan p ON p.id=pp.plan_id JOIN ll_order o ON o.id=p.source_order_id WHERE o.source_container_booking_id=? AND pp.warehouse_pallet_id IS NOT NULL AND pp.actual_package_count>0 AND pp.actual_volume_cbm>0 ORDER BY pp.warehouse_pallet_id";
|
||||
private final JdbcTemplate jdbc;
|
||||
private final PalletPhysicalGateway pallets;
|
||||
private final OverseasFeeSourceMapper feeSources;
|
||||
@@ -38,7 +40,7 @@ public class DestuffingPalletCostService {
|
||||
if (exists != null && exists > 0) return;
|
||||
List<Map<String,Object>> plans = jdbc.queryForList("SELECT p.id,p.customer_id,p.container_no,p.overseas_warehouse_id,t.status FROM ll_inbound_plan p JOIN ll_order o ON o.id=p.source_order_id LEFT JOIN ll_inbound_pda_task t ON t.plan_id=p.id AND t.customer_id=p.customer_id WHERE o.source_container_booking_id=? ORDER BY p.customer_id,p.id", bookingId);
|
||||
if (plans.isEmpty() || plans.stream().anyMatch(row -> !"COMPLETED".equals(row.get("status")))) return;
|
||||
List<Long> palletIds = jdbc.queryForList("SELECT DISTINCT pp.warehouse_pallet_id FROM ll_inbound_plan_pallet pp JOIN ll_inbound_plan p ON p.id=pp.plan_id JOIN ll_order o ON o.id=p.source_order_id WHERE o.source_container_booking_id=? AND pp.warehouse_pallet_id IS NOT NULL ORDER BY pp.warehouse_pallet_id", Long.class, bookingId);
|
||||
List<Long> palletIds = jdbc.queryForList(RECEIVED_PALLET_IDS_SQL, Long.class, bookingId);
|
||||
BigDecimal totalCost = BigDecimal.ZERO;
|
||||
for (Long palletId : palletIds) totalCost = totalCost.add(pallets.resolve(palletId).unitPrice());
|
||||
totalCost = totalCost.setScale(2, RoundingMode.HALF_UP);
|
||||
@@ -79,7 +81,7 @@ public class DestuffingPalletCostService {
|
||||
private OverseasFeeSource fee(long costId, String bookingId, String containerNo, Long warehouseId, CustomerVolume volume, BigDecimal amount, String operator) {
|
||||
LocalDateTime now=LocalDateTime.now(ZoneOffset.UTC); OverseasFeeSource v=new OverseasFeeSource();
|
||||
v.setId(IdWorker.getId()); v.setSourceFeeId(IdWorker.getId()); v.setSourceVersion(1); v.setCustomerId(volume.customerId());
|
||||
v.setSourceType("OVERSEAS_CONTAINER_FEE"); v.setSourceNo("DESTUFF-"+bookingId); v.setBusinessType("CONTAINER_DESTUFFING");
|
||||
v.setSourceType("OVERSEAS_CONTAINER_FEE"); v.setSourceNo("DESTUFF-"+bookingId); v.setBusinessType(DESTUFF_BUSINESS_TYPE);
|
||||
v.setBusinessId(costId); v.setBusinessNo("DESTUFF-"+bookingId); v.setContainerBookingId(parseLong(bookingId)); v.setContainerNo(containerNo);
|
||||
v.setWarehouseId(warehouseId); v.setFeeItemCode("DESTUFF_PALLET"); v.setFeeItemName("拆柜打托费"); v.setDirection("RECEIVABLE");
|
||||
v.setPaymentVoucherFileIds(List.of()); v.setBusinessDate(LocalDate.now()); v.setCurrency("CNY"); v.setAmount(amount);
|
||||
|
||||
+8
@@ -7,11 +7,19 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
class DestuffingPalletCostServiceTest {
|
||||
@Test void publishesDestuffingReceivableAsOverseasContainerBusiness() {
|
||||
assertThat(DestuffingPalletCostService.DESTUFF_BUSINESS_TYPE).isEqualTo("OVERSEAS_CONTAINER");
|
||||
}
|
||||
@Test void newestCompletedBookingsAreNotStarvedByOldUnbillableRows() {
|
||||
assertThat(DestuffingPalletCostService.READY_BOOKINGS_SQL)
|
||||
.contains("ORDER BY MAX(t.completed_at) DESC LIMIT 50")
|
||||
.doesNotContain("ORDER BY MIN(t.completed_at)");
|
||||
}
|
||||
@Test void chargesOnlyPalletsWithPositiveReceivedPackagesAndVolume() {
|
||||
assertThat(DestuffingPalletCostService.RECEIVED_PALLET_IDS_SQL)
|
||||
.contains("pp.actual_package_count>0")
|
||||
.contains("pp.actual_volume_cbm>0");
|
||||
}
|
||||
@Test void preservesTotalAndLetsFinalCustomerAbsorbRoundingRemainder() {
|
||||
List<BigDecimal> result = DestuffingPalletCostService.allocate(new BigDecimal("10.00"),
|
||||
List.of(new BigDecimal("1"), new BigDecimal("1"), new BigDecimal("1")));
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ test('托盘汇总和拆柜成本验证总数、分摊及跨区金额守恒', ()
|
||||
'/api/platform/v1/pallets/summary',
|
||||
'/api/platform/v1/warehouse-admin/pallets/summary',
|
||||
'/pallets/summary?page=1&size=20',
|
||||
'CONTAINER_DESTUFFING',
|
||||
'OVERSEAS_CONTAINER',
|
||||
'DESTUFF_PALLET',
|
||||
'expectedPalletCost',
|
||||
'sourceFeeId',
|
||||
|
||||
@@ -283,7 +283,7 @@ async function verifyDestuffCosts(context, completedFacts) {
|
||||
for (const fact of completedFacts) {
|
||||
const businessNo = `DESTUFF-${fact.containerBookingId}`
|
||||
const lastleg = await poll(async () => context.requestOverseas('GET', query('/api/platform/v1/last-leg/finance-fee-sources', {
|
||||
businessType: 'CONTAINER_DESTUFFING', businessNo,
|
||||
businessType: 'OVERSEAS_CONTAINER', businessNo,
|
||||
})), (response) => success(response) && rows(response.body.data).length > 0, 75)
|
||||
const sources = success(lastleg.result) ? rows(lastleg.result.body.data) : []
|
||||
const allocated = money(sources.reduce((sum, item) => sum + Number(item.amount || 0), 0))
|
||||
|
||||
Reference in New Issue
Block a user