修改提交
This commit is contained in:
+4
-4
@@ -126,7 +126,7 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
|| !Objects.equals(balance.getInboundOrderId(), item.sourceInboundOrderId())) {
|
||||
throw conflict("Selected inventory does not belong to this customer, operation warehouse and inbound order");
|
||||
}
|
||||
if (value(position.getAvailablePackages()) < item.totalPackageCount()) {
|
||||
if (value(position.getAvailablePackages()) < item.notifiedPackageCount()) {
|
||||
throw conflict("Available inventory changed for inbound " + balance.getInboundOrderNo());
|
||||
}
|
||||
sources.add(new SourceInventory(item, balance));
|
||||
@@ -137,7 +137,7 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
String relabelNo = orderNoGenerator.next("RELABEL", operationWarehouseId, applicationId);
|
||||
for (SourceInventory source : sources) {
|
||||
inventoryCommands.hold(customerId, operatorId, new InventoryCommandRequests.Move(
|
||||
source.request().sourceInventoryPositionId(), source.request().totalPackageCount(), relabelNo,
|
||||
source.request().sourceInventoryPositionId(), source.request().notifiedPackageCount(), relabelNo,
|
||||
null, "RELABEL:" + relabelNo, request.idempotencyKey().trim() + ":HOLD:"
|
||||
+ source.request().sourceInventoryPositionId(), "贴标申请冻结原入仓单库存"));
|
||||
}
|
||||
@@ -398,9 +398,9 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
|
||||
private void releaseInventory(String customerId, String operatorId, RelabelApplication application) {
|
||||
for (RelabelItem item : itemList(application.getId())) {
|
||||
if (item.getSourceInventoryPositionId() == null || item.getTotalPackageCount() == null) continue;
|
||||
if (item.getSourceInventoryPositionId() == null || item.getNotifiedPackageCount() == null) continue;
|
||||
inventoryCommands.release(customerId, operatorId, new InventoryCommandRequests.Move(
|
||||
item.getSourceInventoryPositionId(), item.getTotalPackageCount(), application.getRelabelNo(), null,
|
||||
item.getSourceInventoryPositionId(), item.getNotifiedPackageCount(), application.getRelabelNo(), null,
|
||||
"RELABEL:" + application.getRelabelNo(), application.getIdempotencyKey() + ":RELEASE:"
|
||||
+ item.getSourceInventoryPositionId(), "贴标结束释放库存至原入仓单"));
|
||||
}
|
||||
|
||||
+6
@@ -30,6 +30,12 @@ public class PlatformReturnInventoryController {
|
||||
return ApiResponse.success(service.platformCartonPage(request));
|
||||
}
|
||||
|
||||
@GetMapping("/movements")
|
||||
@PreAuthorize("hasAuthority('platform:overseas-warehouse:return-inventory:list')")
|
||||
public ApiResponse<PageResult<ReturnInventoryResponses.PlatformMovement>> movements(@Valid ReturnInventoryRequests.PlatformQuery request) {
|
||||
return ApiResponse.success(service.platformMovementPage(request));
|
||||
}
|
||||
|
||||
@GetMapping("/cartons/{cartonMark}")
|
||||
@PreAuthorize("hasAuthority('platform:overseas-warehouse:return-cartons:list')")
|
||||
public ApiResponse<ReturnInventoryResponses.CartonDetail> carton(@PathVariable String cartonMark) {
|
||||
|
||||
+6
-3
@@ -11,8 +11,8 @@ public final class ReturnInventoryResponses {
|
||||
String productNameZh, long quantity, int cartonSkuTypes, long cartonTotalQuantity,
|
||||
LocalDateTime receivedAt) { }
|
||||
public record SummaryItem(String overseasWarehouseId, String skuCode, String productNameZh,
|
||||
long availableQuantity, long cartonQuantity, LocalDateTime updatedAt) { }
|
||||
public record CartonDetail(String cartonMark, String overseasWarehouseId, String sourceBatchNo, String sourceReturnNo, String status,
|
||||
long totalQuantity, long availableQuantity, long cartonQuantity, LocalDateTime updatedAt) { }
|
||||
public record CartonDetail(String cartonMark, String customerId, String overseasWarehouseId, String sourceBatchNo, String sourceReturnNo, String status,
|
||||
int skuTypes, long totalQuantity, BigDecimal length, BigDecimal width, BigDecimal height,
|
||||
BigDecimal weight, LocalDateTime receivedAt, List<CartonItem> items) { }
|
||||
public record CartonItem(String skuCode, String productNameZh, long quantity) { }
|
||||
@@ -24,9 +24,12 @@ public final class ReturnInventoryResponses {
|
||||
public record PackingSku(String skuCode, String productNameZh, long availableQuantity) { }
|
||||
public record PackingPreview(List<PackingOrder> orders, String customerId, List<PackingSku> skus) { }
|
||||
public record PlatformStock(String customerId, String overseasWarehouseId, String skuCode, String productNameZh,
|
||||
long availableQuantity, long cartonQuantity, LocalDateTime updatedAt) { }
|
||||
long totalQuantity, long availableQuantity, long cartonQuantity, LocalDateTime updatedAt) { }
|
||||
public record PlatformCarton(String customerId, String overseasWarehouseId, String cartonMark, String sourceReturnNo,
|
||||
String sourceBatchNo, String status, int skuTypes, long totalQuantity,
|
||||
BigDecimal length, BigDecimal width, BigDecimal height, BigDecimal weight,
|
||||
LocalDateTime createdAt) { }
|
||||
public record PlatformMovement(String customerId, String overseasWarehouseId, String skuCode, String productNameZh,
|
||||
String movementType, String referenceNo, long totalDelta, long availableDelta,
|
||||
LocalDateTime occurredAt) { }
|
||||
}
|
||||
|
||||
+2
@@ -16,6 +16,8 @@ public class ReturnInventoryBalance {
|
||||
private String overseasWarehouseId;
|
||||
private String skuCode;
|
||||
private String productNameZh;
|
||||
/** 实物总库存;只有实际出库才会减少。 */
|
||||
private Long totalQuantity;
|
||||
private Long availableQuantity;
|
||||
private Long cartonQuantity;
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
+5
-4
@@ -11,13 +11,14 @@ import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ReturnInventoryBalanceMapper extends BaseMapper<ReturnInventoryBalance> {
|
||||
@Insert("INSERT INTO ll_return_inventory_balance (id,customer_id,overseas_warehouse_id,sku_code,product_name_zh,available_quantity,carton_quantity,created_at,updated_at) " +
|
||||
"VALUES (#{id},#{customerId},#{warehouseId},#{skuCode},#{productNameZh},#{quantity},#{cartons},NOW(3),NOW(3)) " +
|
||||
"ON DUPLICATE KEY UPDATE available_quantity=available_quantity+VALUES(available_quantity),carton_quantity=carton_quantity+VALUES(carton_quantity), " +
|
||||
@Insert("INSERT INTO ll_return_inventory_balance (id,customer_id,overseas_warehouse_id,sku_code,product_name_zh,total_quantity,available_quantity,carton_quantity,created_at,updated_at) " +
|
||||
"VALUES (#{id},#{customerId},#{warehouseId},#{skuCode},#{productNameZh},#{totalQuantity},#{availableQuantity},#{cartons},NOW(3),NOW(3)) " +
|
||||
"ON DUPLICATE KEY UPDATE total_quantity=total_quantity+VALUES(total_quantity),available_quantity=available_quantity+VALUES(available_quantity),carton_quantity=carton_quantity+VALUES(carton_quantity), " +
|
||||
"product_name_zh=COALESCE(NULLIF(VALUES(product_name_zh),''),product_name_zh),updated_at=NOW(3)")
|
||||
int adjust(@Param("id") long id, @Param("customerId") String customerId, @Param("warehouseId") String warehouseId,
|
||||
@Param("skuCode") String skuCode, @Param("productNameZh") String productNameZh,
|
||||
@Param("quantity") long quantity, @Param("cartons") long cartons);
|
||||
@Param("totalQuantity") long totalQuantity, @Param("availableQuantity") long availableQuantity,
|
||||
@Param("cartons") long cartons);
|
||||
|
||||
@Select("<script>SELECT COUNT(*) FROM ll_return_inventory_balance WHERE customer_id=#{customerId} " +
|
||||
"<if test='warehouseId != null and warehouseId != \"\"'>AND overseas_warehouse_id=#{warehouseId} </if>" +
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.baiyue.lastleg.returnreceipt.mapper;
|
||||
|
||||
import com.baiyue.lastleg.returnreceipt.dto.ReturnInventoryResponses;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Read-only return inventory movement ledger reconstructed from signed receipts and merged cartons. */
|
||||
@Mapper
|
||||
public interface ReturnInventoryMovementMapper {
|
||||
String MOVEMENTS = "SELECT o.customer_id customerId,o.overseas_warehouse_id overseasWarehouseId,ri.sku_code skuCode,oi.product_name_zh productNameZh," +
|
||||
"'RECEIPT' movementType,r.receipt_no referenceNo,ri.received_quantity totalDelta,ri.received_quantity availableDelta,r.signed_at occurredAt " +
|
||||
"FROM ll_return_receipt r JOIN ll_return_order o ON o.id=r.return_order_id JOIN ll_return_receipt_item ri ON ri.receipt_id=r.id " +
|
||||
"JOIN ll_return_order_item oi ON oi.id=ri.return_order_item_id " +
|
||||
"UNION ALL SELECT c.customer_id,c.overseas_warehouse_id,i.sku_code,i.product_name_zh,'MERGE',c.carton_mark,0,-i.quantity,c.created_at " +
|
||||
"FROM ll_return_inventory_carton c JOIN ll_return_inventory_carton_item i ON i.carton_id=c.id WHERE c.source_batch_no='MERGED'";
|
||||
|
||||
@Select("<script>SELECT COUNT(*) FROM (" + MOVEMENTS + ") m WHERE 1=1 " +
|
||||
"<if test='customerId != null and customerId != \"\"'>AND m.customerId=#{customerId} </if>" +
|
||||
"<if test='warehouseId != null and warehouseId != \"\"'>AND m.overseasWarehouseId=#{warehouseId} </if>" +
|
||||
"<if test='skuCode != null and skuCode != \"\"'>AND m.skuCode LIKE CONCAT('%',#{skuCode},'%') </if></script>")
|
||||
long platformCount(@Param("customerId") String customerId, @Param("warehouseId") String warehouseId, @Param("skuCode") String skuCode);
|
||||
|
||||
@Select("<script>SELECT * FROM (" + MOVEMENTS + ") m WHERE 1=1 " +
|
||||
"<if test='customerId != null and customerId != \"\"'>AND m.customerId=#{customerId} </if>" +
|
||||
"<if test='warehouseId != null and warehouseId != \"\"'>AND m.overseasWarehouseId=#{warehouseId} </if>" +
|
||||
"<if test='skuCode != null and skuCode != \"\"'>AND m.skuCode LIKE CONCAT('%',#{skuCode},'%') </if>" +
|
||||
"ORDER BY occurredAt DESC LIMIT #{offset},#{size}</script>")
|
||||
List<ReturnInventoryResponses.PlatformMovement> platformPage(@Param("customerId") String customerId, @Param("warehouseId") String warehouseId,
|
||||
@Param("skuCode") String skuCode, @Param("offset") long offset, @Param("size") long size);
|
||||
}
|
||||
+16
-5
@@ -15,6 +15,7 @@ import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryCartonItemMapper;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryCartonMapper;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryOperationMapper;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryQueryMapper;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryMovementMapper;
|
||||
import com.baiyue.lastleg.returnreceipt.model.ReturnInventoryRow;
|
||||
import com.baiyue.lastleg.service.LastlegOrderNoGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -47,6 +48,7 @@ public class ReturnInventoryService {
|
||||
@Resource private ReturnInventoryBalanceMapper balances;
|
||||
@Resource private ReturnInventoryOperationMapper operations;
|
||||
@Resource private ReturnInventoryQueryMapper queries;
|
||||
@Resource private ReturnInventoryMovementMapper movements;
|
||||
@Resource private LastlegOrderNoGenerator numbers;
|
||||
@Resource private com.baiyue.lastleg.returnreceipt.mapper.ReturnOrderMapper orders;
|
||||
@Resource private com.baiyue.lastleg.returnreceipt.mapper.ReturnReceiptMapper receiptMapper;
|
||||
@@ -72,7 +74,7 @@ public class ReturnInventoryService {
|
||||
item.setSkuCode(line.skuCode()); item.setProductNameZh(text(line.productNameZh())); item.setQuantity(line.quantity());
|
||||
cartonItems.insert(item);
|
||||
balances.adjust(IdWorker.getId(), order.getCustomerId(), order.getOverseasWarehouseId(), line.skuCode(),
|
||||
text(line.productNameZh()), line.quantity(), 1);
|
||||
text(line.productNameZh()), line.quantity(), line.quantity(), 1);
|
||||
}
|
||||
return carton;
|
||||
}
|
||||
@@ -105,7 +107,16 @@ public class ReturnInventoryService {
|
||||
List<ReturnInventoryResponses.PlatformStock> records = total == 0 ? List.of() : balances.platformPage(customerId, warehouseId, sku,
|
||||
(request.page() - 1) * request.size(), request.size()).stream().map(balance -> new ReturnInventoryResponses.PlatformStock(
|
||||
balance.getCustomerId(), balance.getOverseasWarehouseId(), balance.getSkuCode(), balance.getProductNameZh(),
|
||||
value(balance.getAvailableQuantity()), value(balance.getCartonQuantity()), balance.getUpdatedAt())).toList();
|
||||
value(balance.getTotalQuantity()), value(balance.getAvailableQuantity()), value(balance.getCartonQuantity()), balance.getUpdatedAt())).toList();
|
||||
return new PageResult<>(records, request.page(), request.size(), total, (total + request.size() - 1) / request.size());
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public PageResult<ReturnInventoryResponses.PlatformMovement> platformMovementPage(ReturnInventoryRequests.PlatformQuery request) {
|
||||
String customerId = text(request.customerId()); String warehouseId = text(request.overseasWarehouseId()); String sku = text(request.skuCode());
|
||||
long total = movements.platformCount(customerId, warehouseId, sku);
|
||||
List<ReturnInventoryResponses.PlatformMovement> records = total == 0 ? List.of() : movements.platformPage(customerId, warehouseId, sku,
|
||||
(request.page() - 1) * request.size(), request.size());
|
||||
return new PageResult<>(records, request.page(), request.size(), total, (total + request.size() - 1) / request.size());
|
||||
}
|
||||
|
||||
@@ -251,7 +262,7 @@ public class ReturnInventoryService {
|
||||
targetItem.setId(IdWorker.getId()); targetItem.setCartonId(targetId); targetItem.setCustomerId(customerId); targetItem.setSkuCode(entry.getKey());
|
||||
targetItem.setProductNameZh(productNames.get(entry.getKey())); targetItem.setQuantity(entry.getValue()); cartonItems.insert(targetItem);
|
||||
balances.adjust(IdWorker.getId(), customerId, target.getOverseasWarehouseId(), entry.getKey(), productNames.get(entry.getKey()), 0,
|
||||
1L - emptiedBySku.getOrDefault(entry.getKey(), 0));
|
||||
-entry.getValue(), 1L - emptiedBySku.getOrDefault(entry.getKey(), 0));
|
||||
}
|
||||
operation.setResultCartonId(targetId); operation.setUpdatedAt(now); operations.updateById(operation);
|
||||
return new ReturnInventoryResponses.MergeResult(target.getCartonMark(), requested.keySet().iterator().next(), total, label(target));
|
||||
@@ -281,13 +292,13 @@ public class ReturnInventoryService {
|
||||
|
||||
private ReturnInventoryResponses.SummaryItem summary(com.baiyue.lastleg.returnreceipt.entity.ReturnInventoryBalance balance) {
|
||||
return new ReturnInventoryResponses.SummaryItem(balance.getOverseasWarehouseId(), balance.getSkuCode(), balance.getProductNameZh(),
|
||||
value(balance.getAvailableQuantity()), value(balance.getCartonQuantity()), balance.getUpdatedAt());
|
||||
value(balance.getTotalQuantity()), value(balance.getAvailableQuantity()), value(balance.getCartonQuantity()), balance.getUpdatedAt());
|
||||
}
|
||||
|
||||
private ReturnInventoryResponses.CartonDetail cartonDetail(ReturnInventoryCarton carton) {
|
||||
List<ReturnInventoryResponses.CartonItem> items = cartonItems.listCarton(carton.getId()).stream()
|
||||
.map(item -> new ReturnInventoryResponses.CartonItem(item.getSkuCode(), item.getProductNameZh(), item.getQuantity())).toList();
|
||||
return new ReturnInventoryResponses.CartonDetail(carton.getCartonMark(), carton.getOverseasWarehouseId(), carton.getSourceBatchNo(), carton.getSourceReturnNo(),
|
||||
return new ReturnInventoryResponses.CartonDetail(carton.getCartonMark(), carton.getCustomerId(), carton.getOverseasWarehouseId(), carton.getSourceBatchNo(), carton.getSourceReturnNo(),
|
||||
carton.getStatus(), carton.getSkuTypes() == null ? 0 : carton.getSkuTypes(), value(carton.getTotalQuantity()), carton.getLength(), carton.getWidth(), carton.getHeight(), carton.getWeight(), carton.getCreatedAt(), items);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user