提交
This commit is contained in:
+66
@@ -0,0 +1,66 @@
|
||||
package com.baiyue.lastleg.discard.repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baiyue.lastleg.discard.entity.CargoDiscardApplication;
|
||||
import com.baiyue.lastleg.discard.entity.CargoDiscardItem;
|
||||
import com.baiyue.lastleg.inventory.entity.InventoryLedger;
|
||||
import com.baiyue.lastleg.inventory.entity.InventoryPosition;
|
||||
import com.baiyue.lastleg.inventory.mapper.InventoryBalanceMapper;
|
||||
import com.baiyue.lastleg.inventory.mapper.InventoryLedgerMapper;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryBalanceMapper;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryCartonMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/** 废弃实物扣减对应的退货余额和普通库存总账。 */
|
||||
@Repository
|
||||
public class CargoDiscardStockLedgerRepository {
|
||||
@Resource private ReturnInventoryBalanceMapper returnBalances;
|
||||
@Resource private ReturnInventoryCartonMapper returnCartons;
|
||||
@Resource private InventoryBalanceMapper balances;
|
||||
@Resource private InventoryLedgerMapper ledgers;
|
||||
|
||||
/** 箱内 SKU 扣减时同步扣汇总,只有该 SKU 在箱内耗尽才减一箱。 */
|
||||
public void deductReturn(String customerId, CargoDiscardApplication application, CargoDiscardItem item,
|
||||
long before, long quantity) {
|
||||
var carton = returnCartons.lockId(item.getReturnCartonId());
|
||||
if (carton == null || !customerId.equals(carton.getCustomerId())
|
||||
|| !application.getOverseasWarehouseId().equals(carton.getOverseasWarehouseId())
|
||||
|| !"DISCARD_PENDING".equals(carton.getStatus())) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "退货废弃箱归属或状态已变化");
|
||||
}
|
||||
long boxes = before == quantity && !"PARCEL".equals(carton.getSourceUnitType()) ? 1 : 0;
|
||||
var balance = returnBalances.lockSku(customerId, carton.getOverseasWarehouseId(), item.getSkuCode());
|
||||
if (balance == null || returnBalances.deductConversion(customerId, carton.getOverseasWarehouseId(),
|
||||
item.getSkuCode(), quantity, boxes) != 1) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "退货库存汇总数量不足,不能完成废弃");
|
||||
}
|
||||
}
|
||||
|
||||
/** 一件代发已扣实物仓位后,按同事务余额快照追加库存总账。 */
|
||||
public void recordDropship(String customerId, CargoDiscardApplication application, CargoDiscardItem item,
|
||||
InventoryPosition position, long quantity, String operator, LocalDateTime at) {
|
||||
var balance = balances.selectById(position.getBalanceId());
|
||||
if (balance == null || !customerId.equals(balance.getCustomerId())) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "废弃库存余额不存在");
|
||||
}
|
||||
var fact = new InventoryLedger();
|
||||
fact.setId(IdWorker.getId()); fact.setCustomerId(customerId); fact.setCustomerName(balance.getCustomerName());
|
||||
fact.setBalanceId(balance.getId()); fact.setPositionId(position.getId());
|
||||
fact.setOverseasWarehouseId(balance.getOverseasWarehouseId()); fact.setDestinationWarehouseCode(balance.getDestinationWarehouseCode());
|
||||
fact.setInboundOrderId(balance.getInboundOrderId()); fact.setInboundCode(balance.getInboundCode());
|
||||
fact.setInboundOrderNo(balance.getInboundOrderNo()); fact.setPalletId(position.getPalletId());
|
||||
fact.setPalletNo(position.getPalletNo()); fact.setBatchNo(position.getBatchNo());
|
||||
fact.setWarehouseLocationCode(position.getWarehouseLocationCode()); fact.setSkuCode(item.getSkuCode());
|
||||
fact.setBusinessType("DISCARD"); fact.setBusinessOrderId(application.getId()); fact.setBusinessOrderNo(application.getDiscardNo());
|
||||
fact.setIdempotencyKey("CARGO_DISCARD:" + application.getId() + ":" + item.getId() + ":STOCK");
|
||||
fact.setStatusFrom("AVAILABLE"); fact.setStatusTo("DISCARDED");
|
||||
fact.setBeforePackages(balance.getAvailablePackages() + quantity); fact.setDeltaPackages(-quantity);
|
||||
fact.setAfterPackages(balance.getAvailablePackages()); fact.setOperatorId(operator);
|
||||
fact.setRemark("货物废弃"); fact.setOccurredAt(at); fact.setCreatedAt(at);
|
||||
if (ledgers.insert(fact) != 1) throw new IllegalStateException("废弃库存流水写入失败");
|
||||
}
|
||||
}
|
||||
+7
-2
@@ -33,6 +33,7 @@ import java.util.Map;
|
||||
/** Final inventory mutation for a warehouse-approved cargo discard. */
|
||||
@Service
|
||||
public class CargoDiscardInventoryAdjustmentService {
|
||||
@Resource private com.baiyue.lastleg.discard.repository.CargoDiscardStockLedgerRepository stockLedger;
|
||||
@Resource private CargoDiscardInventoryMapper inventory;
|
||||
@Resource private CargoDiscardStockService stockService;
|
||||
@Resource private DropshipCartonLedgerMapper cartonLedgers;
|
||||
@@ -44,6 +45,7 @@ public class CargoDiscardInventoryAdjustmentService {
|
||||
@Resource private ReturnInventoryCartonMapper returnCartons;
|
||||
@Resource private ReturnInventoryCartonItemMapper returnCartonItems;
|
||||
|
||||
/** 实物废弃、来源库存扣减与流水在同一事务内完成。 */
|
||||
@Transactional(propagation = Propagation.MANDATORY)
|
||||
public AdjustmentResult discardPalletItem(String customerId, CargoDiscardApplication application,
|
||||
CargoDiscardItem item, List<CargoDiscardCarton> links,
|
||||
@@ -53,7 +55,7 @@ public class CargoDiscardInventoryAdjustmentService {
|
||||
stockService.discard(customerId, operatorId, application, item, actualPackages);
|
||||
return new AdjustmentResult(item.getDiscardPackages(), actualPackages, 0);
|
||||
}
|
||||
if (isReturnItem(item)) return discardReturnItem(customerId, item, actualPackages);
|
||||
if (isReturnItem(item)) return discardReturnItem(customerId, application, item, actualPackages);
|
||||
if (actualPackages < 0 || actualPackages > links.size()) throw conflict("实际废弃数量超出该托盘申请数量");
|
||||
DropshipSkuInventory sku = inventory.lockSkuInventory(customerId, item.getSkuInventoryId());
|
||||
if (sku == null) throw conflict("托盘 SKU 库存不存在: " + item.getSkuCode());
|
||||
@@ -97,10 +99,12 @@ public class CargoDiscardInventoryAdjustmentService {
|
||||
}
|
||||
long after = value(inventory.skuPackages(customerId, sku.getId()));
|
||||
if (after != before - actualPackages) throw conflict("托盘 SKU 库存扣减不守恒");
|
||||
stockLedger.recordDropship(customerId, application, item, position, actualPackages, operatorId, occurredAt);
|
||||
return new AdjustmentResult(before, actualPackages, after);
|
||||
}
|
||||
|
||||
private AdjustmentResult discardReturnItem(String customerId, CargoDiscardItem item, int actualPackages) {
|
||||
/** 退货箱按件扣减,同时同步库存余额;完成事实由明细的 PDA 完成快照提供。 */
|
||||
private AdjustmentResult discardReturnItem(String customerId, CargoDiscardApplication application, CargoDiscardItem item, int actualPackages) {
|
||||
if (actualPackages < 0 || actualPackages > item.getDiscardPackages()) {
|
||||
throw conflict("实际废弃数量超出退货库存申请数量");
|
||||
}
|
||||
@@ -110,6 +114,7 @@ public class CargoDiscardInventoryAdjustmentService {
|
||||
if (before < actualPackages || (actualPackages > 0 && returnCartonItems.deduct(sku.getId(), actualPackages) != 1)) {
|
||||
throw conflict("退货库存数量不足");
|
||||
}
|
||||
if (actualPackages > 0) stockLedger.deductReturn(customerId, application, item, before, actualPackages);
|
||||
return new AdjustmentResult(before, actualPackages, before - actualPackages);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user