|
|
@@ -34,7 +34,8 @@ public class InventoryService {
|
|
|
|
|
|
@Transactional
|
|
|
public Result<Map<String, Object>> createInboundOrder(Long supplierId, String supplierName,
|
|
|
- List<Map<String, Object>> items, Long operatorId, String remark) {
|
|
|
+ List<Map<String, Object>> items, Long operatorId,
|
|
|
+ String remark, Date inboundDate, Integer totalAmount) {
|
|
|
if (items == null || items.isEmpty()) {
|
|
|
return Result.error("入库明细不能为空");
|
|
|
}
|
|
|
@@ -47,6 +48,8 @@ public class InventoryService {
|
|
|
order.setSupplierName(supplierName);
|
|
|
order.setStatus("pending");
|
|
|
order.setTotalItems(items.size());
|
|
|
+ order.setTotalAmount(totalAmount != null ? totalAmount : 0);
|
|
|
+ order.setInboundDate(inboundDate);
|
|
|
order.setOperatorId(operatorId);
|
|
|
order.setRemark(remark);
|
|
|
order.setCreatedAt(new Date());
|
|
|
@@ -470,4 +473,72 @@ public class InventoryService {
|
|
|
}
|
|
|
return Result.success("库存充足");
|
|
|
}
|
|
|
+
|
|
|
+ // ========== 手动出库 ==========
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ public Result<String> createManualOutbound(Long productId, Long skuId, Integer quantity,
|
|
|
+ String reason, Long operatorId, Date outboundDate, String remark) {
|
|
|
+ Product product = productMapper.selectById(productId);
|
|
|
+ if (product == null) return Result.error("商品不存在");
|
|
|
+
|
|
|
+ if (skuId != null) {
|
|
|
+ ProductSku sku = productSkuMapper.selectById(skuId);
|
|
|
+ if (sku == null || sku.getStock() == null || sku.getStock() < quantity) {
|
|
|
+ return Result.error("SKU库存不足");
|
|
|
+ }
|
|
|
+ sku.setStock(sku.getStock() - quantity);
|
|
|
+ sku.setUpdateTime(new Date());
|
|
|
+ productSkuMapper.updateById(sku);
|
|
|
+ } else {
|
|
|
+ if (product.getStock() == null || product.getStock() < quantity) {
|
|
|
+ return Result.error("库存不足");
|
|
|
+ }
|
|
|
+ product.setStock(product.getStock() - quantity);
|
|
|
+ product.setUpdatedAt(new Date());
|
|
|
+ productMapper.updateById(product);
|
|
|
+ }
|
|
|
+
|
|
|
+ InventoryTransaction tx = new InventoryTransaction();
|
|
|
+ tx.setProductId(productId);
|
|
|
+ tx.setSkuId(skuId);
|
|
|
+ tx.setType("outbound");
|
|
|
+ tx.setDirection(-1);
|
|
|
+ tx.setQuantity(quantity);
|
|
|
+ tx.setBeforeStock(product.getStock() != null ? product.getStock() + quantity : quantity);
|
|
|
+ tx.setAfterStock(product.getStock() != null ? product.getStock() : 0);
|
|
|
+ tx.setReferenceType("manual_outbound");
|
|
|
+ tx.setOperatorId(operatorId);
|
|
|
+ tx.setRemark("手动出库: " + (reason != null ? reason : "") + (remark != null ? " - " + remark : ""));
|
|
|
+ tx.setCreatedAt(new Date());
|
|
|
+ transactionMapper.insert(tx);
|
|
|
+ return Result.success("出库成功");
|
|
|
+ }
|
|
|
+
|
|
|
+ public Result<Map<String, Object>> listManualOutboundTransactions(int page, int size, String startDate, String endDate) {
|
|
|
+ Page<InventoryTransaction> pageParam = new Page<>(page, size);
|
|
|
+ LambdaQueryWrapper<InventoryTransaction> wrapper = new LambdaQueryWrapper<InventoryTransaction>()
|
|
|
+ .eq(InventoryTransaction::getReferenceType, "manual_outbound")
|
|
|
+ .orderByDesc(InventoryTransaction::getCreatedAt);
|
|
|
+ if (startDate != null && !startDate.isEmpty()) {
|
|
|
+ try {
|
|
|
+ wrapper.ge(InventoryTransaction::getCreatedAt, new SimpleDateFormat("yyyy-MM-dd").parse(startDate));
|
|
|
+ } catch (Exception ignored) {}
|
|
|
+ }
|
|
|
+ if (endDate != null && !endDate.isEmpty()) {
|
|
|
+ try {
|
|
|
+ Calendar cal = Calendar.getInstance();
|
|
|
+ cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(endDate));
|
|
|
+ cal.add(Calendar.DAY_OF_MONTH, 1);
|
|
|
+ wrapper.lt(InventoryTransaction::getCreatedAt, cal.getTime());
|
|
|
+ } catch (Exception ignored) {}
|
|
|
+ }
|
|
|
+ Page<InventoryTransaction> result = transactionMapper.selectPage(pageParam, wrapper);
|
|
|
+ Map<String, Object> data = new HashMap<>();
|
|
|
+ data.put("records", result.getRecords());
|
|
|
+ data.put("total", result.getTotal());
|
|
|
+ data.put("page", result.getCurrent());
|
|
|
+ data.put("size", result.getSize());
|
|
|
+ return Result.success(data);
|
|
|
+ }
|
|
|
}
|