|
@@ -0,0 +1,476 @@
|
|
|
|
|
+package com.fs.his.service.impl;
|
|
|
|
|
+
|
|
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
|
|
+import com.fs.common.exception.CustomException;
|
|
|
|
|
+import com.fs.common.utils.DateUtils;
|
|
|
|
|
+import com.fs.common.utils.SecurityUtils;
|
|
|
|
|
+import com.fs.his.domain.FsInventoryTransfer;
|
|
|
|
|
+import com.fs.his.domain.FsInventoryTransferItem;
|
|
|
|
|
+import com.fs.his.domain.FsInventoryTransferLog;
|
|
|
|
|
+import com.fs.his.domain.FsStore;
|
|
|
|
|
+import com.fs.his.mapper.FsInventoryTransferItemMapper;
|
|
|
|
|
+import com.fs.his.mapper.FsInventoryTransferLogMapper;
|
|
|
|
|
+import com.fs.his.mapper.FsInventoryTransferMapper;
|
|
|
|
|
+import com.fs.his.param.InventoryTransferAuditParam;
|
|
|
|
|
+import com.fs.his.param.InventoryTransferItemParam;
|
|
|
|
|
+import com.fs.his.param.InventoryTransferParam;
|
|
|
|
|
+import com.fs.his.param.InventoryTransferQueryParam;
|
|
|
|
|
+import com.fs.his.param.InventoryTransferReceiveParam;
|
|
|
|
|
+import com.fs.his.service.IFsInventoryTransferService;
|
|
|
|
|
+import com.fs.his.service.IFsStoreProductService;
|
|
|
|
|
+import com.fs.his.service.IFsStoreService;
|
|
|
|
|
+import com.fs.his.vo.InventoryTransferItemVO;
|
|
|
|
|
+import com.fs.his.vo.InventoryTransferLogVO;
|
|
|
|
|
+import com.fs.his.vo.InventoryTransferVO;
|
|
|
|
|
+import com.fs.utils.TwelveDigitSnowflake;
|
|
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
+
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.Date;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 库存调拨 Service 实现
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author fs
|
|
|
|
|
+ * @date 2026-07-25
|
|
|
|
|
+ */
|
|
|
|
|
+@Service
|
|
|
|
|
+public class FsInventoryTransferServiceImpl implements IFsInventoryTransferService {
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private FsInventoryTransferMapper transferMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private FsInventoryTransferItemMapper transferItemMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private FsInventoryTransferLogMapper transferLogMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private IFsStoreService storeService;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private IFsStoreProductService storeProductService;
|
|
|
|
|
+
|
|
|
|
|
+ private static final TwelveDigitSnowflake SNOWFLAKE = new TwelveDigitSnowflake(1);
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 调拨单状态常量
|
|
|
|
|
+ */
|
|
|
|
|
+ public static final String STATUS_DRAFT = "DRAFT";
|
|
|
|
|
+ public static final String STATUS_SUBMITTED = "SUBMITTED";
|
|
|
|
|
+ public static final String STATUS_APPROVED = "APPROVED";
|
|
|
|
|
+ public static final String STATUS_REJECTED = "REJECTED";
|
|
|
|
|
+ public static final String STATUS_IN_TRANSIT = "IN_TRANSIT";
|
|
|
|
|
+ public static final String STATUS_RECEIVED = "RECEIVED";
|
|
|
|
|
+ public static final String STATUS_CANCELLED = "CANCELLED";
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<InventoryTransferVO> selectTransferList(InventoryTransferQueryParam param) {
|
|
|
|
|
+ LambdaQueryWrapper<FsInventoryTransfer> wrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ wrapper.eq(param.getFromStoreId() != null, FsInventoryTransfer::getFromStoreId, param.getFromStoreId());
|
|
|
|
|
+ wrapper.eq(param.getToStoreId() != null, FsInventoryTransfer::getToStoreId, param.getToStoreId());
|
|
|
|
|
+ wrapper.eq(StrUtil.isNotBlank(param.getStatus()), FsInventoryTransfer::getStatus, param.getStatus());
|
|
|
|
|
+ wrapper.eq(param.getApplyUserId() != null, FsInventoryTransfer::getApplyUserId, param.getApplyUserId());
|
|
|
|
|
+ wrapper.eq(StrUtil.isNotBlank(param.getTransferNo()), FsInventoryTransfer::getTransferNo, param.getTransferNo());
|
|
|
|
|
+ wrapper.apply(StrUtil.isNotBlank(param.getBeginTime()), "create_time >= '" + param.getBeginTime() + "'");
|
|
|
|
|
+ wrapper.apply(StrUtil.isNotBlank(param.getEndTime()), "create_time <= '" + param.getEndTime() + "'");
|
|
|
|
|
+ wrapper.orderByDesc(FsInventoryTransfer::getCreateTime);
|
|
|
|
|
+
|
|
|
|
|
+ List<FsInventoryTransfer> list = transferMapper.selectList(wrapper);
|
|
|
|
|
+ return list.stream().map(this::convertToVO).collect(Collectors.toList());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public InventoryTransferVO selectTransferDetail(String transferNo) {
|
|
|
|
|
+ FsInventoryTransfer transfer = getByTransferNo(transferNo);
|
|
|
|
|
+ InventoryTransferVO vo = convertToVO(transfer);
|
|
|
|
|
+
|
|
|
|
|
+ // 查询明细
|
|
|
|
|
+ List<FsInventoryTransferItem> items = transferItemMapper.selectByTransferNo(transferNo);
|
|
|
|
|
+ vo.setItems(items.stream().map(this::convertItemToVO).collect(Collectors.toList()));
|
|
|
|
|
+
|
|
|
|
|
+ // 查询操作日志
|
|
|
|
|
+ List<FsInventoryTransferLog> logs = transferLogMapper.selectByTransferNo(transferNo);
|
|
|
|
|
+ vo.setLogs(logs.stream().map(this::convertLogToVO).collect(Collectors.toList()));
|
|
|
|
|
+
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public String createTransfer(InventoryTransferParam param) {
|
|
|
|
|
+ // 校验调出门店和调入门店不能相同
|
|
|
|
|
+ if (param.getFromStoreId().equals(param.getToStoreId())) {
|
|
|
|
|
+ throw new CustomException("调出门店和调入门店不能相同");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 生成调拨单号
|
|
|
|
|
+ String transferNo = generateTransferNo();
|
|
|
|
|
+
|
|
|
|
|
+ // 计算总数量和总金额
|
|
|
|
|
+ int totalQuantity = 0;
|
|
|
|
|
+ BigDecimal totalAmount = BigDecimal.ZERO;
|
|
|
|
|
+ for (InventoryTransferItemParam itemParam : param.getItems()) {
|
|
|
|
|
+ totalQuantity += itemParam.getQuantity();
|
|
|
|
|
+ if (itemParam.getTotalAmount() != null) {
|
|
|
|
|
+ totalAmount = totalAmount.add(itemParam.getTotalAmount());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 构建调拨单
|
|
|
|
|
+ FsInventoryTransfer transfer = new FsInventoryTransfer();
|
|
|
|
|
+ transfer.setTransferNo(transferNo);
|
|
|
|
|
+ transfer.setFromStoreId(param.getFromStoreId());
|
|
|
|
|
+ transfer.setToStoreId(param.getToStoreId());
|
|
|
|
|
+ transfer.setTotalQuantity(totalQuantity);
|
|
|
|
|
+ transfer.setTotalAmount(totalAmount);
|
|
|
|
|
+ transfer.setStatus(STATUS_DRAFT);
|
|
|
|
|
+ transfer.setApplyUserId(SecurityUtils.getUserId());
|
|
|
|
|
+ transfer.setApplyUserName(SecurityUtils.getUsername());
|
|
|
|
|
+ transfer.setApplyTime(new Date());
|
|
|
|
|
+ transfer.setRemark(param.getRemark());
|
|
|
|
|
+
|
|
|
|
|
+ // 设置创建人
|
|
|
|
|
+ transfer.setCreateBy(SecurityUtils.getUsername());
|
|
|
|
|
+ transfer.setCreateTime(DateUtils.getNowDate());
|
|
|
|
|
+
|
|
|
|
|
+ // 设置门店名称
|
|
|
|
|
+ resolveStoreName(transfer);
|
|
|
|
|
+
|
|
|
|
|
+ transferMapper.insert(transfer);
|
|
|
|
|
+
|
|
|
|
|
+ // 保存明细
|
|
|
|
|
+ saveTransferItems(transferNo, param.getItems());
|
|
|
|
|
+
|
|
|
|
|
+ // 记录日志
|
|
|
|
|
+ addLog(transferNo, "CREATE", "创建调拨单");
|
|
|
|
|
+
|
|
|
|
|
+ return transferNo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void updateTransfer(InventoryTransferParam param) {
|
|
|
|
|
+ FsInventoryTransfer transfer = getByTransferNo(param.getTransferNo());
|
|
|
|
|
+ if (!STATUS_DRAFT.equals(transfer.getStatus())) {
|
|
|
|
|
+ throw new CustomException("仅草稿状态的调拨单可修改");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 校验调出门店和调入门店不能相同
|
|
|
|
|
+ if (param.getFromStoreId().equals(param.getToStoreId())) {
|
|
|
|
|
+ throw new CustomException("调出门店和调入门店不能相同");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 计算总数量和总金额
|
|
|
|
|
+ int totalQuantity = 0;
|
|
|
|
|
+ BigDecimal totalAmount = BigDecimal.ZERO;
|
|
|
|
|
+ for (InventoryTransferItemParam itemParam : param.getItems()) {
|
|
|
|
|
+ totalQuantity += itemParam.getQuantity();
|
|
|
|
|
+ if (itemParam.getTotalAmount() != null) {
|
|
|
|
|
+ totalAmount = totalAmount.add(itemParam.getTotalAmount());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 更新调拨单
|
|
|
|
|
+ transfer.setFromStoreId(param.getFromStoreId());
|
|
|
|
|
+ transfer.setToStoreId(param.getToStoreId());
|
|
|
|
|
+ transfer.setTotalQuantity(totalQuantity);
|
|
|
|
|
+ transfer.setTotalAmount(totalAmount);
|
|
|
|
|
+ transfer.setRemark(param.getRemark());
|
|
|
|
|
+ transfer.setUpdateBy(SecurityUtils.getUsername());
|
|
|
|
|
+ transfer.setUpdateTime(DateUtils.getNowDate());
|
|
|
|
|
+ resolveStoreName(transfer);
|
|
|
|
|
+ transferMapper.updateById(transfer);
|
|
|
|
|
+
|
|
|
|
|
+ // 删除旧明细,重新插入
|
|
|
|
|
+ transferItemMapper.deleteByTransferNo(param.getTransferNo());
|
|
|
|
|
+ saveTransferItems(param.getTransferNo(), param.getItems());
|
|
|
|
|
+
|
|
|
|
|
+ // 记录日志
|
|
|
|
|
+ addLog(param.getTransferNo(), "UPDATE", "修改调拨单");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void deleteTransfer(String transferNo) {
|
|
|
|
|
+ FsInventoryTransfer transfer = getByTransferNo(transferNo);
|
|
|
|
|
+ if (!STATUS_DRAFT.equals(transfer.getStatus())) {
|
|
|
|
|
+ throw new CustomException("仅草稿状态的调拨单可删除");
|
|
|
|
|
+ }
|
|
|
|
|
+ transferItemMapper.deleteByTransferNo(transferNo);
|
|
|
|
|
+ transferMapper.deleteById(transfer.getId());
|
|
|
|
|
+ // 清理日志
|
|
|
|
|
+ LambdaQueryWrapper<FsInventoryTransferLog> wrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ wrapper.eq(FsInventoryTransferLog::getTransferNo, transferNo);
|
|
|
|
|
+ transferLogMapper.delete(wrapper);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void submitTransfer(String transferNo) {
|
|
|
|
|
+ FsInventoryTransfer transfer = getByTransferNo(transferNo);
|
|
|
|
|
+ if (!STATUS_DRAFT.equals(transfer.getStatus())) {
|
|
|
|
|
+ throw new CustomException("仅草稿状态的调拨单可提交");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 校验调拨单至少有一条明细
|
|
|
|
|
+ List<FsInventoryTransferItem> items = transferItemMapper.selectByTransferNo(transferNo);
|
|
|
|
|
+ if (items.isEmpty()) {
|
|
|
|
|
+ throw new CustomException("调拨单至少需要一条明细");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ transfer.setStatus(STATUS_SUBMITTED);
|
|
|
|
|
+ transfer.setApplyTime(new Date());
|
|
|
|
|
+ transfer.setUpdateBy(SecurityUtils.getUsername());
|
|
|
|
|
+ transfer.setUpdateTime(DateUtils.getNowDate());
|
|
|
|
|
+ transferMapper.updateById(transfer);
|
|
|
|
|
+
|
|
|
|
|
+ addLog(transferNo, "SUBMIT", "提交调拨单");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void auditTransfer(InventoryTransferAuditParam param) {
|
|
|
|
|
+ FsInventoryTransfer transfer = getByTransferNo(param.getTransferNo());
|
|
|
|
|
+ if (!STATUS_SUBMITTED.equals(transfer.getStatus())) {
|
|
|
|
|
+ throw new CustomException("仅待审核状态的调拨单可审批");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (STATUS_APPROVED.equals(param.getApproveResult())) {
|
|
|
|
|
+ transfer.setStatus(STATUS_APPROVED);
|
|
|
|
|
+ } else if (STATUS_REJECTED.equals(param.getApproveResult())) {
|
|
|
|
|
+ transfer.setStatus(STATUS_REJECTED);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ throw new CustomException("审批结果不正确");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ transfer.setApproveUserId(SecurityUtils.getUserId());
|
|
|
|
|
+ transfer.setApproveUserName(SecurityUtils.getUsername());
|
|
|
|
|
+ transfer.setApproveTime(new Date());
|
|
|
|
|
+ transfer.setApproveRemark(param.getApproveRemark());
|
|
|
|
|
+ transfer.setUpdateBy(SecurityUtils.getUsername());
|
|
|
|
|
+ transfer.setUpdateTime(DateUtils.getNowDate());
|
|
|
|
|
+ transferMapper.updateById(transfer);
|
|
|
|
|
+
|
|
|
|
|
+ String operation = STATUS_APPROVED.equals(param.getApproveResult()) ? "APPROVE" : "REJECT";
|
|
|
|
|
+ String content = STATUS_APPROVED.equals(param.getApproveResult()) ?
|
|
|
|
|
+ "审批通过" + (StrUtil.isNotBlank(param.getApproveRemark()) ? ":" + param.getApproveRemark() : "") :
|
|
|
|
|
+ "审批驳回" + (StrUtil.isNotBlank(param.getApproveRemark()) ? ":" + param.getApproveRemark() : "");
|
|
|
|
|
+ addLog(param.getTransferNo(), operation, content);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void shipTransfer(String transferNo) {
|
|
|
|
|
+ FsInventoryTransfer transfer = getByTransferNo(transferNo);
|
|
|
|
|
+ if (!STATUS_APPROVED.equals(transfer.getStatus())) {
|
|
|
|
|
+ throw new CustomException("仅已审核状态的调拨单可发货");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 扣减调出门店的库存
|
|
|
|
|
+ List<FsInventoryTransferItem> items = transferItemMapper.selectByTransferNo(transferNo);
|
|
|
|
|
+ for (FsInventoryTransferItem item : items) {
|
|
|
|
|
+ // 记录调出前库存
|
|
|
|
|
+ Integer fromStockBefore = storeProductService.getStoreProductStock(transfer.getFromStoreId(), item.getProductId());
|
|
|
|
|
+ item.setFromStockBefore(fromStockBefore);
|
|
|
|
|
+
|
|
|
|
|
+ // 扣减调出门店库存
|
|
|
|
|
+ storeProductService.deductStoreProductStock(transfer.getFromStoreId(), item.getProductId(), item.getQuantity());
|
|
|
|
|
+
|
|
|
|
|
+ // 记录调出后库存
|
|
|
|
|
+ Integer fromStockAfter = storeProductService.getStoreProductStock(transfer.getFromStoreId(), item.getProductId());
|
|
|
|
|
+ item.setFromStockAfter(fromStockAfter);
|
|
|
|
|
+
|
|
|
|
|
+ transferItemMapper.updateById(item);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ transfer.setStatus(STATUS_IN_TRANSIT);
|
|
|
|
|
+ transfer.setShipUserId(SecurityUtils.getUserId());
|
|
|
|
|
+ transfer.setShipUserName(SecurityUtils.getUsername());
|
|
|
|
|
+ transfer.setShipTime(new Date());
|
|
|
|
|
+ transfer.setUpdateBy(SecurityUtils.getUsername());
|
|
|
|
|
+ transfer.setUpdateTime(DateUtils.getNowDate());
|
|
|
|
|
+ transferMapper.updateById(transfer);
|
|
|
|
|
+
|
|
|
|
|
+ addLog(transferNo, "SHIP", "发货出库");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void receiveTransfer(InventoryTransferReceiveParam param) {
|
|
|
|
|
+ FsInventoryTransfer transfer = getByTransferNo(param.getTransferNo());
|
|
|
|
|
+ if (!STATUS_IN_TRANSIT.equals(transfer.getStatus())) {
|
|
|
|
|
+ throw new CustomException("仅运输中状态的调拨单可收货");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 增加调入门店的库存
|
|
|
|
|
+ List<FsInventoryTransferItem> items = transferItemMapper.selectByTransferNo(param.getTransferNo());
|
|
|
|
|
+ for (FsInventoryTransferItem item : items) {
|
|
|
|
|
+ // 记录调入前库存
|
|
|
|
|
+ Integer toStockBefore = storeProductService.getStoreProductStock(transfer.getToStoreId(), item.getProductId());
|
|
|
|
|
+ item.setToStockBefore(toStockBefore);
|
|
|
|
|
+
|
|
|
|
|
+ // 增加调入门店库存
|
|
|
|
|
+ storeProductService.addStoreProductStock(transfer.getToStoreId(), item.getProductId(), item.getQuantity());
|
|
|
|
|
+
|
|
|
|
|
+ // 记录调入后库存
|
|
|
|
|
+ Integer toStockAfter = storeProductService.getStoreProductStock(transfer.getToStoreId(), item.getProductId());
|
|
|
|
|
+ item.setToStockAfter(toStockAfter);
|
|
|
|
|
+
|
|
|
|
|
+ transferItemMapper.updateById(item);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ transfer.setStatus(STATUS_RECEIVED);
|
|
|
|
|
+ transfer.setReceiveUserId(SecurityUtils.getUserId());
|
|
|
|
|
+ transfer.setReceiveUserName(SecurityUtils.getUsername());
|
|
|
|
|
+ transfer.setReceiveTime(new Date());
|
|
|
|
|
+ transfer.setReceiveRemark(param.getReceiveRemark());
|
|
|
|
|
+ transfer.setUpdateBy(SecurityUtils.getUsername());
|
|
|
|
|
+ transfer.setUpdateTime(DateUtils.getNowDate());
|
|
|
|
|
+ transferMapper.updateById(transfer);
|
|
|
|
|
+
|
|
|
|
|
+ addLog(param.getTransferNo(), "RECEIVE", "收货入库" +
|
|
|
|
|
+ (StrUtil.isNotBlank(param.getReceiveRemark()) ? ":" + param.getReceiveRemark() : ""));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void cancelTransfer(String transferNo) {
|
|
|
|
|
+ FsInventoryTransfer transfer = getByTransferNo(transferNo);
|
|
|
|
|
+ if (!(STATUS_DRAFT.equals(transfer.getStatus()) || STATUS_SUBMITTED.equals(transfer.getStatus()))) {
|
|
|
|
|
+ throw new CustomException("仅草稿或待审核状态的调拨单可取消");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ transfer.setStatus(STATUS_CANCELLED);
|
|
|
|
|
+ transfer.setUpdateBy(SecurityUtils.getUsername());
|
|
|
|
|
+ transfer.setUpdateTime(DateUtils.getNowDate());
|
|
|
|
|
+ transferMapper.updateById(transfer);
|
|
|
|
|
+
|
|
|
|
|
+ addLog(transferNo, "CANCEL", "取消调拨单");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<InventoryTransferLogVO> selectTransferLogs(String transferNo) {
|
|
|
|
|
+ List<FsInventoryTransferLog> logs = transferLogMapper.selectByTransferNo(transferNo);
|
|
|
|
|
+ return logs.stream().map(this::convertLogToVO).collect(Collectors.toList());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ==================== 私有方法 ====================
|
|
|
|
|
+
|
|
|
|
|
+ private String generateTransferNo() {
|
|
|
|
|
+ String datePart = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
|
|
|
|
+ long seq = SNOWFLAKE.nextId();
|
|
|
|
|
+ return "DB" + datePart + String.format("%06d", seq % 1000000);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private FsInventoryTransfer getByTransferNo(String transferNo) {
|
|
|
|
|
+ LambdaQueryWrapper<FsInventoryTransfer> wrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ wrapper.eq(FsInventoryTransfer::getTransferNo, transferNo);
|
|
|
|
|
+ FsInventoryTransfer transfer = transferMapper.selectOne(wrapper);
|
|
|
|
|
+ if (transfer == null) {
|
|
|
|
|
+ throw new CustomException("调拨单不存在:" + transferNo);
|
|
|
|
|
+ }
|
|
|
|
|
+ return transfer;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void resolveStoreName(FsInventoryTransfer transfer) {
|
|
|
|
|
+ if (transfer.getFromStoreId() != null) {
|
|
|
|
|
+ FsStore fromStore = storeService.selectFsStoreByStoreId(transfer.getFromStoreId());
|
|
|
|
|
+ if (fromStore != null) {
|
|
|
|
|
+ transfer.setFromStoreName(fromStore.getStoreName());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (transfer.getToStoreId() != null) {
|
|
|
|
|
+ FsStore toStore = storeService.selectFsStoreByStoreId(transfer.getToStoreId());
|
|
|
|
|
+ if (toStore != null) {
|
|
|
|
|
+ transfer.setToStoreName(toStore.getStoreName());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void saveTransferItems(String transferNo, List<InventoryTransferItemParam> items) {
|
|
|
|
|
+ for (InventoryTransferItemParam itemParam : items) {
|
|
|
|
|
+ FsInventoryTransferItem item = new FsInventoryTransferItem();
|
|
|
|
|
+ item.setTransferNo(transferNo);
|
|
|
|
|
+ item.setProductId(itemParam.getProductId());
|
|
|
|
|
+ item.setProductName(itemParam.getProductName());
|
|
|
|
|
+ item.setProductImage(itemParam.getProductImage());
|
|
|
|
|
+ item.setProductSpec(itemParam.getProductSpec());
|
|
|
|
|
+ item.setUnit(itemParam.getUnit());
|
|
|
|
|
+ item.setQuantity(itemParam.getQuantity());
|
|
|
|
|
+ item.setCostPrice(itemParam.getCostPrice());
|
|
|
|
|
+ item.setTotalAmount(itemParam.getTotalAmount());
|
|
|
|
|
+ item.setCreateTime(new Date());
|
|
|
|
|
+ transferItemMapper.insert(item);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void addLog(String transferNo, String operation, String content) {
|
|
|
|
|
+ FsInventoryTransferLog log = new FsInventoryTransferLog();
|
|
|
|
|
+ log.setTransferNo(transferNo);
|
|
|
|
|
+ log.setOperation(operation);
|
|
|
|
|
+ log.setOperatorId(SecurityUtils.getUserId());
|
|
|
|
|
+ log.setOperatorName(SecurityUtils.getUsername());
|
|
|
|
|
+ log.setContent(content);
|
|
|
|
|
+ log.setCreateTime(new Date());
|
|
|
|
|
+ transferLogMapper.insert(log);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private InventoryTransferVO convertToVO(FsInventoryTransfer transfer) {
|
|
|
|
|
+ InventoryTransferVO vo = new InventoryTransferVO();
|
|
|
|
|
+ BeanUtils.copyProperties(transfer, vo);
|
|
|
|
|
+ vo.setStatusName(getStatusName(transfer.getStatus()));
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private InventoryTransferItemVO convertItemToVO(FsInventoryTransferItem item) {
|
|
|
|
|
+ InventoryTransferItemVO vo = new InventoryTransferItemVO();
|
|
|
|
|
+ BeanUtils.copyProperties(item, vo);
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private InventoryTransferLogVO convertLogToVO(FsInventoryTransferLog log) {
|
|
|
|
|
+ InventoryTransferLogVO vo = new InventoryTransferLogVO();
|
|
|
|
|
+ BeanUtils.copyProperties(log, vo);
|
|
|
|
|
+ vo.setOperationName(getOperationName(log.getOperation()));
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String getStatusName(String status) {
|
|
|
|
|
+ switch (status) {
|
|
|
|
|
+ case STATUS_DRAFT: return "草稿";
|
|
|
|
|
+ case STATUS_SUBMITTED: return "待审核";
|
|
|
|
|
+ case STATUS_APPROVED: return "已审核";
|
|
|
|
|
+ case STATUS_REJECTED: return "已驳回";
|
|
|
|
|
+ case STATUS_IN_TRANSIT: return "运输中";
|
|
|
|
|
+ case STATUS_RECEIVED: return "已收货";
|
|
|
|
|
+ case STATUS_CANCELLED: return "已取消";
|
|
|
|
|
+ default: return status;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String getOperationName(String operation) {
|
|
|
|
|
+ switch (operation) {
|
|
|
|
|
+ case "CREATE": return "创建";
|
|
|
|
|
+ case "UPDATE": return "修改";
|
|
|
|
|
+ case "SUBMIT": return "提交";
|
|
|
|
|
+ case "APPROVE": return "审批通过";
|
|
|
|
|
+ case "REJECT": return "审批驳回";
|
|
|
|
|
+ case "SHIP": return "发货";
|
|
|
|
|
+ case "RECEIVE": return "收货";
|
|
|
|
|
+ case "CANCEL": return "取消";
|
|
|
|
|
+ default: return operation;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|