优化
This commit is contained in:
@@ -155,6 +155,40 @@ public class FeeItemRepository {
|
||||
.set(InboundFeeDetailEntity::getUpdatedAt, now));
|
||||
}
|
||||
|
||||
public int supersedeFreight(long tenantId, long inboundId, long retainedSourceFeeId,
|
||||
long operatorId, LocalDateTime now) {
|
||||
return feeDetails.update(null, new LambdaUpdateWrapper<InboundFeeDetailEntity>()
|
||||
.eq(InboundFeeDetailEntity::getTenantId, tenantId)
|
||||
.eq(InboundFeeDetailEntity::getInboundId, inboundId)
|
||||
.eq(InboundFeeDetailEntity::getSourceType, "FBA_PRICING")
|
||||
.in(InboundFeeDetailEntity::getPublicationStatus, List.of("DRAFT", "PUBLISHED"))
|
||||
.ne(InboundFeeDetailEntity::getSourceFeeId, retainedSourceFeeId)
|
||||
.set(InboundFeeDetailEntity::getPublicationStatus, "SUPERSEDED")
|
||||
.set(InboundFeeDetailEntity::getSettlementIncluded, false)
|
||||
.set(InboundFeeDetailEntity::getUpdatedBy, operatorId)
|
||||
.set(InboundFeeDetailEntity::getUpdatedAt, now));
|
||||
}
|
||||
|
||||
public int publishCalculatedFreight(long tenantId, long sourceFeeId, long operatorId,
|
||||
String operatorName, LocalDateTime now) {
|
||||
return feeDetails.update(null, new LambdaUpdateWrapper<InboundFeeDetailEntity>()
|
||||
.eq(InboundFeeDetailEntity::getTenantId, tenantId)
|
||||
.eq(InboundFeeDetailEntity::getSourceType, "FBA_PRICING")
|
||||
.eq(InboundFeeDetailEntity::getSourceFeeId, sourceFeeId)
|
||||
.eq(InboundFeeDetailEntity::getPublicationStatus, "DRAFT")
|
||||
.set(InboundFeeDetailEntity::getReviewStatus, "APPROVED")
|
||||
.set(InboundFeeDetailEntity::getReviewerId, operatorId)
|
||||
.set(InboundFeeDetailEntity::getReviewerName, operatorName)
|
||||
.set(InboundFeeDetailEntity::getReviewedAt, now)
|
||||
.set(InboundFeeDetailEntity::getPublicationStatus, "PUBLISHED")
|
||||
.set(InboundFeeDetailEntity::getPublishedBy, operatorId)
|
||||
.set(InboundFeeDetailEntity::getPublishedByName, operatorName)
|
||||
.set(InboundFeeDetailEntity::getPublishedAt, now)
|
||||
.set(InboundFeeDetailEntity::getSettlementIncluded, true)
|
||||
.set(InboundFeeDetailEntity::getUpdatedBy, operatorId)
|
||||
.set(InboundFeeDetailEntity::getUpdatedAt, now));
|
||||
}
|
||||
|
||||
public void insertDetail(InboundFeeDetailEntity detail) {
|
||||
feeDetails.insert(detail);
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ public class FbaPricingService {
|
||||
estimate.chargeUnit(), chargeable) != 1) {
|
||||
throw conflict("入库单状态已变化,费用试算未保存");
|
||||
}
|
||||
feeDetails.materializeCalculatedFreight(tenantId, inboundId, fee.getId(), operatorId, now);
|
||||
complete(token, fee.getId(), now);
|
||||
String nextStatus = isCompletedInbound(inbound.getProcessStatus())
|
||||
? inbound.getProcessStatus() : "FEE_CONFIRMING";
|
||||
@@ -215,6 +216,9 @@ public class FbaPricingService {
|
||||
feeDetails.publishFreight(tenantId, inboundId, adjusted.getId(), operatorId, null, now);
|
||||
financeOutbox.publishInbound(FinanceFeeSourceOutboxService.ADJUSTED,
|
||||
tenantId, inboundId, adjusted.getId(), nextVersion, now);
|
||||
} else {
|
||||
feeDetails.materializeCalculatedFreight(
|
||||
tenantId, inboundId, adjusted.getId(), operatorId, now);
|
||||
}
|
||||
complete(token, adjusted.getId(), now);
|
||||
return response(tenantId, adjusted.getId(), inbound.getProcessStatus());
|
||||
|
||||
@@ -48,7 +48,7 @@ public class InboundFeeDetailService {
|
||||
long operatorId, String operatorName,
|
||||
LocalDateTime publishedAt) {
|
||||
InboundFeeDetailEntity existing = repository.findBySourceFee(tenantId, "FBA_PRICING", feeId);
|
||||
if (existing != null) return existing;
|
||||
if (existing != null && "PUBLISHED".equals(existing.getPublicationStatus())) return existing;
|
||||
InboundOrderEntity inbound = requiredInbound(tenantId, inboundId);
|
||||
InboundFeeEntity fee = pricingRepository.findFee(tenantId, feeId);
|
||||
if (fee == null || !Long.valueOf(inboundId).equals(fee.getInboundId())) {
|
||||
@@ -58,6 +58,14 @@ public class InboundFeeDetailService {
|
||||
throw conflict("只有已发送状态的计费快照才能生成客户运费明细");
|
||||
}
|
||||
LocalDateTime now = publishedAt == null ? LocalDateTime.now() : publishedAt;
|
||||
if (existing != null) {
|
||||
repository.supersedeFreight(tenantId, inboundId, feeId, operatorId, now);
|
||||
if (repository.publishCalculatedFreight(
|
||||
tenantId, feeId, operatorId, operatorName, now) != 1) {
|
||||
throw conflict("初算费用明细状态已变化,请刷新后重试");
|
||||
}
|
||||
return repository.findBySourceFee(tenantId, "FBA_PRICING", feeId);
|
||||
}
|
||||
FeeItemEntity feeItem = requiredFreightItem();
|
||||
InboundFeeItemEntity baseItem = pricingRepository.findBaseItem(tenantId, feeId);
|
||||
repository.supersedePublishedFreight(tenantId, inboundId, feeId, operatorId, now);
|
||||
@@ -121,6 +129,62 @@ public class InboundFeeDetailService {
|
||||
}
|
||||
}
|
||||
|
||||
/** 初算成功后生成后台可见的草稿运费明细,不发布 Finance。 */
|
||||
@Transactional
|
||||
public InboundFeeDetailEntity materializeCalculatedFreight(long tenantId, long inboundId, long feeId,
|
||||
long operatorId, LocalDateTime calculatedAt) {
|
||||
InboundFeeDetailEntity existing = repository.findBySourceFee(tenantId, "FBA_PRICING", feeId);
|
||||
if (existing != null) return existing;
|
||||
InboundOrderEntity inbound = requiredInbound(tenantId, inboundId);
|
||||
InboundFeeEntity fee = pricingRepository.findFee(tenantId, feeId);
|
||||
if (fee == null || !Long.valueOf(inboundId).equals(fee.getInboundId())) {
|
||||
throw new BizException(ResultCode.NOT_FOUND, "待展示的入库计费快照不存在");
|
||||
}
|
||||
if (!"CALCULATED".equals(fee.getFeeStatus())) {
|
||||
throw conflict("只有初算状态的计费快照可生成草稿运费明细");
|
||||
}
|
||||
LocalDateTime now = calculatedAt == null ? LocalDateTime.now() : calculatedAt;
|
||||
repository.supersedeFreight(tenantId, inboundId, feeId, operatorId, now);
|
||||
InboundFeeDetailEntity detail = freightDetail(
|
||||
tenantId, inboundId, operatorId, null, now, inbound, fee, requiredFreightItem(), false);
|
||||
repository.insertDetail(detail);
|
||||
return detail;
|
||||
}
|
||||
|
||||
private InboundFeeDetailEntity freightDetail(long tenantId, long inboundId, long operatorId,
|
||||
String operatorName, LocalDateTime now,
|
||||
InboundOrderEntity inbound, InboundFeeEntity fee,
|
||||
FeeItemEntity feeItem, boolean published) {
|
||||
InboundFeeItemEntity baseItem = pricingRepository.findBaseItem(tenantId, fee.getId());
|
||||
InboundFeeDetailEntity detail = new InboundFeeDetailEntity();
|
||||
detail.setTenantId(tenantId); detail.setInboundId(inboundId); detail.setFeeItemId(feeItem.getId());
|
||||
detail.setSourceType("FBA_PRICING"); detail.setSourceFeeId(fee.getId());
|
||||
detail.setSourceFeeVersion(fee.getFeeVersion()); detail.setSourceFeeNo(fee.getFeeNo());
|
||||
detail.setInboundCode(inbound.getInboundCode()); detail.setDirection("RECEIVABLE");
|
||||
detail.setBusinessDate(now.toLocalDate()); detail.setCustomerId(inbound.getCustomerId());
|
||||
detail.setCustomerName(inbound.getCustomerName()); detail.setInvoiceTitle(inbound.getCompanyName());
|
||||
detail.setFeeCategorySnapshot(feeItem.getCategory()); detail.setTradeScopeSnapshot(feeItem.getTradeScope());
|
||||
detail.setFeeTypeNameSnapshot(feeItem.getFeeTypeName()); detail.setChannelCode(inbound.getChannelCode());
|
||||
detail.setChannelName(inbound.getChannelName()); detail.setDestinationCode(inbound.getDestinationCode());
|
||||
detail.setDestinationName(inbound.getDestinationName()); detail.setPackageCount(inbound.getTotalPackageCount());
|
||||
detail.setActualGrossWeightKg(fee.getActualWeightKg()); detail.setActualVolumeCbm(fee.getActualVolumeCbm());
|
||||
detail.setVolumeWeightKg(inbound.getVolumeWeightKg());
|
||||
detail.setChargeableWeightKg("KG".equals(fee.getChargeUnit()) ? fee.getChargeableQuantity() : inbound.getChargeableWeightKg());
|
||||
detail.setChargeableVolumeCbm("CBM".equals(fee.getChargeUnit()) ? fee.getChargeableQuantity() : inbound.getChargeableVolumeCbm());
|
||||
detail.setChargeableQuantity(fee.getChargeableQuantity()); detail.setChargeUnit(fee.getChargeUnit());
|
||||
detail.setUnitPrice(baseItem == null ? effectiveUnitPrice(fee) : baseItem.getUnitPrice());
|
||||
detail.setCurrency(fee.getCurrency()); detail.setAmount(fee.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
|
||||
detail.setRemark("来源费用单:" + fee.getFeeNo());
|
||||
detail.setReviewStatus(published ? "APPROVED" : "PENDING");
|
||||
detail.setPublicationStatus(published ? "PUBLISHED" : "DRAFT");
|
||||
detail.setSettlementIncluded(published); detail.setCreatedBy(operatorId); detail.setUpdatedBy(operatorId);
|
||||
if (published) {
|
||||
detail.setReviewerId(operatorId); detail.setReviewerName(operatorName); detail.setReviewedAt(now);
|
||||
detail.setPublishedBy(operatorId); detail.setPublishedByName(operatorName); detail.setPublishedAt(now);
|
||||
}
|
||||
return detail;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public InboundFeeDetailEntity create(long tenantId, long inboundId, long operatorId,
|
||||
SaveRequest request) {
|
||||
|
||||
Reference in New Issue
Block a user