ソースを参照

订单管理调整

FengChaoYu 1 ヶ月 前
コミット
f4d3ae4134
16 ファイル変更685 行追加83 行削除
  1. 195 0
      mall-server-api/src/main/java/com/gree/mall/manager/bean/goods/GoodsMaterialStockDTO.java
  2. 0 6
      mall-server-api/src/main/java/com/gree/mall/manager/bean/order/refund/OrderOfflineRefundVO.java
  3. 12 3
      mall-server-api/src/main/java/com/gree/mall/manager/commonmapper/MaterialMapper.java
  4. 2 2
      mall-server-api/src/main/java/com/gree/mall/manager/controller/goods/GoodsPurchaseController.java
  5. 1 1
      mall-server-api/src/main/java/com/gree/mall/manager/controller/order/OrderController.java
  6. 1 0
      mall-server-api/src/main/java/com/gree/mall/manager/logic/StorageLogic.java
  7. 9 0
      mall-server-api/src/main/java/com/gree/mall/manager/logic/goods/GoodsMaterialLogic.java
  8. 169 0
      mall-server-api/src/main/java/com/gree/mall/manager/logic/goods/GoodsMaterialStockLogic.java
  9. 63 17
      mall-server-api/src/main/java/com/gree/mall/manager/logic/goods/GoodsPurchaseLogic.java
  10. 44 3
      mall-server-api/src/main/java/com/gree/mall/manager/logic/goods/GoodsPurchaseRetLogic.java
  11. 1 1
      mall-server-api/src/main/java/com/gree/mall/manager/logic/order/OrderDeliveryLogic.java
  12. 57 4
      mall-server-api/src/main/java/com/gree/mall/manager/logic/order/OrderLogic.java
  13. 48 2
      mall-server-api/src/main/java/com/gree/mall/manager/logic/order/OrderOfflineLogic.java
  14. 62 43
      mall-server-api/src/main/java/com/gree/mall/manager/logic/order/OrderOfflineRefundLogic.java
  15. 2 1
      mall-server-api/src/main/java/com/gree/mall/manager/zfire/util/FieldUtils.java
  16. 19 0
      mall-server-api/src/main/resources/mapper/MaterialMapper.xml

+ 195 - 0
mall-server-api/src/main/java/com/gree/mall/manager/bean/goods/GoodsMaterialStockDTO.java

@@ -0,0 +1,195 @@
+package com.gree.mall.manager.bean.goods;
+
+import com.gree.mall.manager.enums.material.DirectFlagEnum;
+import com.gree.mall.manager.enums.material.PartsAttrEnum;
+import com.gree.mall.manager.exception.RemoteServiceException;
+import com.gree.mall.manager.plus.entity.GoodsMaterialStockAcc;
+import com.gree.mall.manager.plus.entity.GoodsMaterialStorage;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.springframework.beans.BeanUtils;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.Objects;
+
+@Data
+@Accessors(chain = true)
+public class GoodsMaterialStockDTO {
+
+    @NotBlank(message = "发生方向不能空")
+    @ApiModelProperty(value = "发生方向 ADD=增加 SUB=减少")
+    private String directFlag;
+
+    @NotBlank(message = "名称不能空")
+    @ApiModelProperty(value = "名称")
+    private String remindName;
+
+    @ApiModelProperty(value = "商户编号")
+    @NotBlank(message = "商户编号不能空")
+    private String companyWechatId;
+
+    @ApiModelProperty(value = "商户名称")
+    @NotBlank(message = "商户名称不能空")
+    private String companyWechatName;
+
+    @ApiModelProperty(value = "品牌id")
+    private String brandId;
+
+    @ApiModelProperty(value = "品牌名称")
+    private String brandName;
+
+    @ApiModelProperty(value = "产品大类id")
+    private String mainId;
+
+    @ApiModelProperty(value = "产品大类名称")
+    private String mainName;
+
+    @ApiModelProperty(value = "产品小类")
+    private String smallId;
+
+    @ApiModelProperty(value = "产品小类名称")
+    private String smallName;
+
+    @ApiModelProperty(value = "商品名称")
+    private String goodsName;
+
+    @ApiModelProperty(value = "系列名称")
+    private String seriesName;
+
+    @ApiModelProperty(value = "规格型号")
+    private String specsName;
+
+    @ApiModelProperty(value = "单位 C=整套 I=单个")
+    private String unit;
+
+    @ApiModelProperty(value = "内机数量")
+    private Integer insideQty;
+
+    @ApiModelProperty(value = "外机数量")
+    private Integer outQty;
+
+    @ApiModelProperty(value = "配件数量")
+    private Integer partsQty;
+
+    @ApiModelProperty(value = "发生价格")
+    private BigDecimal price;
+
+    @NotNull(message = "发生时间不能空")
+    @ApiModelProperty(value = "发生时间")
+    private Date sdate;
+
+    @NotNull(message = "变动数量不能空")
+    @ApiModelProperty(value = "变动数量")
+    private Integer changeQty;
+
+    @NotBlank(message = "相关单号不能空")
+    @ApiModelProperty(value = "相关单号")
+    private String refBillNo;
+
+    @ApiModelProperty(value = "相关单据类型")
+    @NotBlank(message = "相关单据类型不能空")
+    private String refBillType;
+
+    @NotNull(message = "仓库不能空")
+    @ApiModelProperty(value = "仓储id")
+    private String storageId;
+
+    @NotNull(message = "仓库不能空")
+    @ApiModelProperty(value = "仓储名称")
+    private String storageName;
+
+    @NotBlank(message = "物料不能空")
+    @ApiModelProperty(value = "物料id")
+    private String goodsMaterialId;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty("操作人")
+    @NotBlank(message = "操作人不能空")
+    private String operateBy;
+
+    public GoodsMaterialStorage createGoodsMaterialStock() {
+        GoodsMaterialStorage goodsMaterialStorage = new GoodsMaterialStorage();
+        BeanUtils.copyProperties(this, goodsMaterialStorage);
+        goodsMaterialStorage.setId(null)
+                .setAmount(BigDecimal.ZERO)
+                .setCostAmount(BigDecimal.ZERO)
+//                .setInsideQty(0)
+//                .setOutQty(0)
+//                .setPartsQty(0)
+                .setStockQty(0)
+                .setWaitSend(0);
+        return goodsMaterialStorage;
+    }
+
+    public void computeGoodsMaterialStock(GoodsMaterialStorage goodsMaterialStorage, GoodsMaterialStockAcc stockAcc) {
+        Integer qty = goodsMaterialStorage.getStockQty();
+        if (Objects.isNull(this.directFlag)) {
+            throw new RemoteServiceException("发生方向不符");
+        }
+        Integer direct = this.directFlag.equals(DirectFlagEnum.ADD.getKey()) ? 1 : -1;
+        Integer closeQty = qty + (this.changeQty * direct);
+        if (closeQty  < 0 && direct < 0) {
+            throw new RemoteServiceException("\""+ remindName + "\"库存不允许为负");
+        }
+
+        // 注入三级帐
+        stockAcc.setCompanyWechatId(this.companyWechatId)
+                .setCompanyWechatName(this.companyWechatName)
+                .setBrandId(this.brandId)
+                .setBrandName(this.brandName)
+                .setMainId(this.mainId)
+                .setMainName(this.mainName)
+                .setSmallId(this.smallId)
+                .setSmallName(this.smallName)
+                .setGoodsMaterialId(this.goodsMaterialId)
+                .setGoodsMaterialName(this.goodsName)
+                .setGoodsSpecsName(this.specsName)
+                .setUnit(this.unit)
+                .setPrice(this.price)
+                .setSdate(this.sdate)
+                .setDirectFlag(this.directFlag)
+                .setChangeQty(this.changeQty)
+                .setQty(qty)
+                .setCloseQty(closeQty)
+                .setRefBillNo(this.refBillNo)
+                .setRefBillType(this.refBillType)
+                .setStorageId(this.storageId)
+                .setStorageName(this.storageName)
+                .setOperateBy(this.operateBy);
+
+        // 最近采购价
+        if (this.refBillType.equals("采购入库单")) {
+            goodsMaterialStorage.setAmount(this.price);
+        }
+
+        // 初始化物料明细数量
+        if (Objects.isNull(goodsMaterialStorage.getInsideQty()) || (goodsMaterialStorage.getStockQty() == 0 && Objects.nonNull(this.insideQty))) {
+            goodsMaterialStorage.setInsideQty(this.insideQty);
+        }
+
+        if (Objects.isNull(goodsMaterialStorage.getOutQty()) || (goodsMaterialStorage.getStockQty() == 0 && Objects.nonNull(this.outQty))) {
+            goodsMaterialStorage.setOutQty(this.outQty);
+        }
+
+        if (Objects.isNull(goodsMaterialStorage.getPartsQty()) || (goodsMaterialStorage.getStockQty() == 0 && Objects.nonNull(this.partsQty))) {
+            goodsMaterialStorage.setPartsQty(this.partsQty);
+        }
+
+//        if (Objects.isNull(goodsMaterialStorage.getInsideQty())
+//                || Objects.isNull(goodsMaterialStorage.getOutQty())
+//                || Objects.isNull(goodsMaterialStorage.getPartsQty())) {
+//            // 如果基础数量为空,初始化物料明细数量
+//            goodsMaterialStorage.setInsideQty(this.insideQty)
+//                    .setOutQty(this.outQty)
+//                    .setPartsQty(this.partsQty);
+//        }
+        // 注入库存
+        goodsMaterialStorage.setStockQty(closeQty);
+    }
+}

+ 0 - 6
mall-server-api/src/main/java/com/gree/mall/manager/bean/order/refund/OrderOfflineRefundVO.java

@@ -40,12 +40,6 @@ public class OrderOfflineRefundVO   {
     private String deliveryId;
 
     @ZfireField(tbName = "b")
-    @ApiModelProperty("业务员")
-    private String saleName;
-    @ZfireField(tbName = "b")
-    @ApiModelProperty("业务员电话")
-    private String saleMobile;
-    @ZfireField(tbName = "b")
     @ApiModelProperty("客户名称")
     private String userName;
     @ZfireField(tbName = "b")

+ 12 - 3
mall-server-api/src/main/java/com/gree/mall/manager/commonmapper/MaterialMapper.java

@@ -2,13 +2,14 @@ package com.gree.mall.manager.commonmapper;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.gree.mall.manager.bean.material.vender.WebsitPurchaseCheckVO;
-import com.gree.mall.manager.bean.material.vender.WebsitVenderGoodsRelaVO;
-import com.gree.mall.manager.bean.material.vender.WebsitVenderGoodsVO;
+import com.gree.mall.manager.bean.goods.GoodsMaterialStockDTO;
 import com.gree.mall.manager.bean.material.vender.WebsitVenderVO;
+import com.gree.mall.manager.plus.entity.GoodsMaterialStorage;
 import com.gree.mall.manager.zfire.bean.ZfireParamBean;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 public interface MaterialMapper {
 
     /**
@@ -19,4 +20,12 @@ public interface MaterialMapper {
      */
     IPage<WebsitVenderVO> websitVenderPage(Page page, @Param("ex") ZfireParamBean zfireParamBean);
 
+    /**
+     * 带锁查询物料库存
+     * @param dto
+     * @param stockList
+     * @return
+     */
+    List<GoodsMaterialStorage> queryExistGoodsMaterialStockList(@Param("dto") GoodsMaterialStockDTO dto,
+                                                                @Param("stockList") List<GoodsMaterialStockDTO> stockList);
 }

+ 2 - 2
mall-server-api/src/main/java/com/gree/mall/manager/controller/goods/GoodsPurchaseController.java

@@ -235,7 +235,7 @@ public class GoodsPurchaseController {
     @ApiOperation(value = "商品采购入库-提交")
     public ResponseHelper submit(
             @ApiParam(value = "id",required = true) @RequestParam String id
-    ) throws RemoteServiceException, InterruptedException {
+    ) throws Exception {
         AdminUserCom adminUser = commonLogic.getAdminUser();
         String lockKey = "";
         if (Objects.nonNull(adminUser.getAdminCompanyWechat())) {
@@ -260,7 +260,7 @@ public class GoodsPurchaseController {
     public ResponseHelper confirm(
             @ApiParam(value = "id",required = true) @RequestParam String id,
             @ApiParam(value = "FAIL=驳回 OK=审核通过", required = true) @RequestParam ExamineStatusEnum statusEnum
-    ) throws RemoteServiceException, InterruptedException {
+    ) throws Exception {
         AdminUserCom adminUser = commonLogic.getAdminUser();
         String lockKey = "";
         if (Objects.nonNull(adminUser.getAdminCompanyWechat())) {

+ 1 - 1
mall-server-api/src/main/java/com/gree/mall/manager/controller/order/OrderController.java

@@ -139,7 +139,7 @@ public class OrderController {
     @ApiOperation("取消订单")
     public ResponseHelper remark(
             @ApiParam(value = "订单号", required = true) @RequestParam(required = true) String orderId
-    ) throws RemoteServiceException {
+    ) throws Exception {
         orderLogic.cancel(orderId);
         return ResponseHelper.success();
     }

+ 1 - 0
mall-server-api/src/main/java/com/gree/mall/manager/logic/StorageLogic.java

@@ -55,6 +55,7 @@ public class StorageLogic {
                 .like(!StringUtils.isEmpty(type), Storage::getType, type)
                 .eq(Objects.nonNull(status), Storage::getStatus, status)
                 .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()), Storage::getCompanyWechatId, adminUser.getCompanyWechatIds())
+                .in(Storage::getStorageId, adminUser.getStorageIds())
                 .page(new Page<>(pageNum, pageSize));
     }
 

+ 9 - 0
mall-server-api/src/main/java/com/gree/mall/manager/logic/goods/GoodsMaterialLogic.java

@@ -239,6 +239,15 @@ public class GoodsMaterialLogic {
 //        if (count > 0) {
 //            throw new RemoteServiceException("已有商品条码记录, 不能再变动内容");
 //        }
+        final GoodsMaterialStorage goodsMaterialStorage = goodsMaterialStorageService.lambdaQuery()
+                .eq(GoodsMaterialStorage::getGoodsMaterialId, goodsMaterial.getId())
+                .ne(GoodsMaterialStorage::getStockQty, 0)
+                .last("limit 1")
+                .one();
+        if (Objects.nonNull(goodsMaterialStorage)) {
+            throw new RemoteServiceException(goodsMaterialStorage.getStorageName() + goodsMaterialStorage.getStockQty() + "库存数量不为0, 不能变动内容");
+        }
+
 
         // 检查参数
         this.checkParams(bean, goodsMaterial.getId());

+ 169 - 0
mall-server-api/src/main/java/com/gree/mall/manager/logic/goods/GoodsMaterialStockLogic.java

@@ -0,0 +1,169 @@
+package com.gree.mall.manager.logic.goods;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.gree.mall.manager.bean.goods.GoodsMaterialStockDTO;
+import com.gree.mall.manager.commonmapper.MaterialMapper;
+import com.gree.mall.manager.constant.Constant;
+import com.gree.mall.manager.enums.material.DirectFlagEnum;
+import com.gree.mall.manager.exception.RemoteServiceException;
+import com.gree.mall.manager.plus.entity.GoodsMaterialAcc;
+import com.gree.mall.manager.plus.entity.GoodsMaterialStockAcc;
+import com.gree.mall.manager.plus.entity.GoodsMaterialStorage;
+import com.gree.mall.manager.plus.service.GoodsMaterialAccService;
+import com.gree.mall.manager.plus.service.GoodsMaterialStockAccService;
+import com.gree.mall.manager.plus.service.GoodsMaterialStorageService;
+import com.gree.mall.manager.utils.ValidateUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.integration.redis.util.RedisLockRegistry;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.support.TransactionSynchronization;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
+
+import javax.validation.ValidationException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class GoodsMaterialStockLogic {
+
+    private final RedisLockRegistry redisLockRegistry;
+    private final GoodsMaterialStorageService goodsMaterialStorageService;
+    private final GoodsMaterialStockAccService goodsMaterialStockAccService;
+    private final MaterialMapper materialMapper;
+    private final GoodsMaterialAccService goodsMaterialAccService;
+
+    /**
+     * 单个仓库库存处理
+     * @param stockList
+     * @throws Exception
+     */
+    public void handleGoodsMaterialStock(List<GoodsMaterialStockDTO> stockList) throws Exception {
+        if(!TransactionSynchronizationManager.isSynchronizationActive()) {
+            throw new RemoteServiceException("请先开启事务");
+        }
+        if (CollectionUtil.isEmpty(stockList)) {
+            return;
+        }
+        // 检查传入的参数
+        for (int i = 0; i < stockList.size(); i++) {
+            GoodsMaterialStockDTO stockDTO = stockList.get(i);
+            try {
+                ValidateUtil.validate(stockDTO);
+                if (stockDTO.getChangeQty().compareTo(0) <= 0) {
+                    throw new RemoteServiceException("变动数量不能少于0");
+                }
+            } catch (ValidationException ve) {
+                throw new RemoteServiceException("执行数据第" + (i+1) + "行" + ve.getMessage());
+            }
+        }
+        // 锁定网点库存
+        GoodsMaterialStockDTO dto = stockList.get(0);
+        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_GOODS_MATERIAL +
+                dto.getCompanyWechatId() + ":" +
+                dto.getStorageId());
+        if(!obtain.tryLock(10, TimeUnit.SECONDS)){
+            throw new RemoteServiceException("库存已冻结:" + dto.getStorageName());
+        }
+        // 处理仓库库存
+        try{
+            this.saveGoodsMaterialStock(dto, stockList);
+
+        } finally {
+            this.txCallUnlock(obtain);
+        }
+    }
+
+    private void saveGoodsMaterialStock(GoodsMaterialStockDTO dto, List<GoodsMaterialStockDTO> stockList) {
+        // 查询存在的仓库物料库存
+        List<GoodsMaterialStorage> existStockList = materialMapper.queryExistGoodsMaterialStockList(dto, stockList);
+        // 全部仓库物料库存
+        Map<String, GoodsMaterialStorage> existStockMap = this.createNotExistStock(stockList, existStockList);
+        // 计算仓库物料库存
+        List<GoodsMaterialStockAcc> stockAccList = new ArrayList<>();
+        this.computeGoodsMaterialStock(stockList, existStockMap, stockAccList);
+
+        if (CollectionUtil.isEmpty(stockAccList)) {
+            throw new RemoteServiceException("物料库存处理失败");
+        }
+
+        if (dto.getRefBillType().equals("采购入库单") || dto.getRefBillType().equals("采购退货单")) {
+            // 商品采购入库单添加三级账
+            this.addGoodsMaterialAcc(stockList);
+        }
+
+        goodsMaterialStorageService.saveOrUpdateBatch(existStockMap.values());
+        goodsMaterialStockAccService.saveBatch(stockAccList);
+
+    }
+
+    private void computeGoodsMaterialStock(List<GoodsMaterialStockDTO> stockList, Map<String, GoodsMaterialStorage> existStockMap, List<GoodsMaterialStockAcc> stockAccList) {
+        for (GoodsMaterialStockDTO goodsMaterialStockDTO : stockList) {
+            GoodsMaterialStorage goodsMaterialStorage = existStockMap.get(goodsMaterialStockDTO.getGoodsMaterialId());
+            GoodsMaterialStockAcc stockAcc = new GoodsMaterialStockAcc();
+            goodsMaterialStockDTO.computeGoodsMaterialStock(goodsMaterialStorage, stockAcc);
+            stockAccList.add(stockAcc);
+        }
+    }
+
+    private Map<String, GoodsMaterialStorage> createNotExistStock(List<GoodsMaterialStockDTO> stockList, List<GoodsMaterialStorage> existStockList) {
+        // 已存在的库存转成Map
+        Map<String, GoodsMaterialStorage> existStockMap = existStockList.stream()
+                .collect(Collectors.toMap(GoodsMaterialStorage::getGoodsMaterialId, Function.identity()));
+
+        // 找出不存在的配件库存并存入新配件库存List
+        for (GoodsMaterialStockDTO stockDTO : stockList) {
+            GoodsMaterialStorage goodsMaterialStorage = existStockMap.get(stockDTO.getGoodsMaterialId());
+            if (Objects.isNull(goodsMaterialStorage)) {
+                goodsMaterialStorage = stockDTO.createGoodsMaterialStock();
+                existStockMap.put(stockDTO.getGoodsMaterialId(), goodsMaterialStorage);
+            }
+//            if (stockDTO.getRefType().equals("采购入库")) {
+//                goodsMaterialStorage.setLastCost(stockDTO.getPrice());
+//            }
+        }
+        return existStockMap;
+    }
+
+    private void addGoodsMaterialAcc(List<GoodsMaterialStockDTO> stockList) {
+        List<GoodsMaterialAcc> accList = new ArrayList<>();
+        for (GoodsMaterialStockDTO dto : stockList) {
+            Integer direct = dto.getDirectFlag().equals(DirectFlagEnum.ADD.getKey()) ? 1 : -1;
+            GoodsMaterialAcc acc = new GoodsMaterialAcc();
+            acc.setGoodsMaterialId(dto.getGoodsMaterialId())
+                    .setOrderId(dto.getRefBillNo())
+                    .setPrice(dto.getPrice())
+                    .setStockQty(direct * dto.getChangeQty());
+            accList.add(acc);
+        }
+        goodsMaterialAccService.saveBatch(accList);
+    }
+
+    private void txCallUnlock(Lock obtain) {
+        //事务提交完成后才释放锁,此方法禁止执行mysql相关操作,否则将导致重大问题。
+        if (TransactionSynchronizationManager.isActualTransactionActive()) {
+            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
+                @Override
+                public void afterCompletion(int status) {
+
+                    if(TransactionSynchronization.STATUS_COMMITTED == status){
+                        log.info("=========【物料库存】======事务提交==============");
+                    }else if(TransactionSynchronization.STATUS_ROLLED_BACK == status){
+                        log.info("========【物料库存】=========事务回滚============");
+                    }
+
+                    obtain.unlock();
+                }
+            });
+        } else {
+            log.info("【物料库存】====没有事务===释放锁");
+            obtain.unlock();
+        }
+    }
+
+}

+ 63 - 17
mall-server-api/src/main/java/com/gree/mall/manager/logic/goods/GoodsPurchaseLogic.java

@@ -2,6 +2,7 @@ package com.gree.mall.manager.logic.goods;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -16,12 +17,12 @@ import com.gree.mall.manager.enums.ExamineStatusEnum;
 import com.gree.mall.manager.enums.IsYesNoEnum;
 import com.gree.mall.manager.enums.admin.AdminWebsitTypeEnum;
 import com.gree.mall.manager.enums.base.BaseEnum;
+import com.gree.mall.manager.enums.material.DirectFlagEnum;
 import com.gree.mall.manager.enums.material.GoodsMaterialTypeEnum;
 import com.gree.mall.manager.exception.RemoteServiceException;
 import com.gree.mall.manager.logic.common.CommonLogic;
 import com.gree.mall.manager.plus.entity.*;
 import com.gree.mall.manager.plus.service.*;
-import com.gree.mall.manager.utils.StringUtil;
 import com.gree.mall.manager.utils.excel.ExcelUtils;
 import com.gree.mall.manager.zfire.bean.QueryParamBean;
 import com.gree.mall.manager.zfire.bean.ZfireParamBean;
@@ -56,6 +57,7 @@ public class GoodsPurchaseLogic {
     private final AdminWebsitService adminWebsitService;
     private final JxGoodsLogic jxGoodsLogic;
     private final GoodsMaterialStorageService goodsMaterialStorageService;
+    private final GoodsMaterialStockLogic goodsMaterialStockLogic;
 
     public IPage<GoodsPurchaseVO> page(ZfireParamBean zfireParamBean) {
         final AdminUserCom adminUser = commonAddQueryFilterParam(zfireParamBean);
@@ -134,15 +136,15 @@ public class GoodsPurchaseLogic {
         bean.setCompanyWechatId(adminUser.getAdminCompanyWechat().getCompanyWechatId());
         bean.setCompanyWechatName(adminUser.getAdminCompanyWechat().getCompanyName());
 
-        AdminWebsit adminWebsit = adminWebsitService.lambdaQuery()
-                .eq(AdminWebsit::getCompanyWechatId, adminUser.getCompanyWechatId())
-                .eq(AdminWebsit::getType, AdminWebsitTypeEnum.B.getKey())
-                .last("limit 1")
-                .one();
+//        AdminWebsit adminWebsit = adminWebsitService.lambdaQuery()
+//                .eq(AdminWebsit::getCompanyWechatId, adminUser.getCompanyWechatId())
+//                .eq(AdminWebsit::getType, AdminWebsitTypeEnum.B.getKey())
+//                .last("limit 1")
+//                .one();
 
-        if (Objects.isNull(adminWebsit)) {
-            throw new RemoteServiceException("未能找到当前账号归属商户信息");
-        }
+//        if (Objects.isNull(adminWebsit)) {
+//            throw new RemoteServiceException("未能找到当前账号归属商户信息");
+//        }
 
         if (StringUtils.isBlank(bean.getVenderId())) {
             throw new RemoteServiceException("请选择供应商");
@@ -153,7 +155,7 @@ public class GoodsPurchaseLogic {
         }
 
         bean.setId(IdWorker.getIdStr())
-                .setJoinCode(adminWebsit.getJoinCode())
+                .setJoinCode(adminUser.getJoinCode())
                 .setStatus(ExamineStatusEnum.SAVE.getKey());
 
         // 检查商品信息唯一
@@ -368,13 +370,13 @@ public class GoodsPurchaseLogic {
     }
 
     @Transactional(rollbackFor = Exception.class)
-    public void submit(String id) throws InterruptedException {
+    public void submit(String id) throws Exception {
         this.commonHandlePurchase(id, ExamineStatusEnum.WAIT);
 
 
     }
 
-    private void commonHandlePurchase(String id, ExamineStatusEnum statusEnum) throws InterruptedException {
+    private void commonHandlePurchase(String id, ExamineStatusEnum statusEnum) throws Exception {
         AdminUserCom adminUser = commonLogic.getAdminUser();
 
         String companyId = null;
@@ -446,28 +448,72 @@ public class GoodsPurchaseLogic {
             }
         }
 
+        final DateTime curDate = DateUtil.date();
         // 更新商品采购入库单状态
         goodsPurchaseService.lambdaUpdate()
                 .set(GoodsPurchase::getStatus, statusEnum.getKey().equals(ExamineStatusEnum.FAIL.getKey()) ? ExamineStatusEnum.SAVE.getKey() : statusEnum.getKey())
                 .set(statusEnum.getKey().equals(ExamineStatusEnum.WAIT.getKey()), GoodsPurchase::getSubmitBy, adminUser.getNickName())
-                .set(statusEnum.getKey().equals(ExamineStatusEnum.WAIT.getKey()), GoodsPurchase::getSubmitTime, DateUtil.date())
+                .set(statusEnum.getKey().equals(ExamineStatusEnum.WAIT.getKey()), GoodsPurchase::getSubmitTime, curDate)
                 .set(statusEnum.getKey().equals(ExamineStatusEnum.OK.getKey())
                         || statusEnum.getKey().equals(ExamineStatusEnum.FAIL.getKey()),
                         GoodsPurchase::getExamineBy, adminUser.getNickName())
                 .set(statusEnum.getKey().equals(ExamineStatusEnum.OK.getKey())
                         || statusEnum.getKey().equals(ExamineStatusEnum.FAIL.getKey()),
-                        GoodsPurchase::getExamineTime, DateUtil.date())
+                        GoodsPurchase::getExamineTime, curDate)
                 .eq(GoodsPurchase::getId, id)
                 .eq(GoodsPurchase::getCompanyWechatId, companyId)
                 .update();
 
         //审核通过加库存操作
         if (statusEnum.getKey().equals(ExamineStatusEnum.OK.getKey())) {
-            jxGoodsLogic.addStock(id);
-
+//            jxGoodsLogic.addStock(id);
+//          物料库存处理方法
+            purchase.setExamineTime(curDate);
+            this.handleGoodsMaterialStock(purchase, purchaseItemList, materialItemGroupMap, adminUser);
         }
     }
 
+    private void handleGoodsMaterialStock(GoodsPurchase purchase, List<GoodsPurchaseItem> purchaseItemList,
+                                          Map<String, List<GoodsMaterialItem>> materialItemGroupMap, AdminUserCom adminUser) throws Exception {
+        List<GoodsMaterialStockDTO> dtoList = new ArrayList<>();
+        for (GoodsPurchaseItem purchaseItem : purchaseItemList) {
+            final Map<String, GoodsMaterialItem> materialItemMap = materialItemGroupMap.get(purchaseItem.getGoodsMaterialId())
+                    .stream()
+                    .collect(Collectors.toMap(GoodsMaterialItem::getType, Function.identity()));
+            GoodsMaterialStockDTO dto = new GoodsMaterialStockDTO();
+            dto.setDirectFlag(DirectFlagEnum.ADD.getKey())
+                    .setRemindName(purchaseItem.getGoodsMaterialName())
+                    .setCompanyWechatId(purchase.getCompanyWechatId())
+                    .setCompanyWechatName(purchase.getCompanyWechatName())
+                    .setBrandId(purchaseItem.getBrandId())
+                    .setBrandName(purchaseItem.getBrandName())
+                    .setMainId(purchaseItem.getMainId())
+                    .setMainName(purchaseItem.getMainName())
+                    .setSmallId(purchaseItem.getSmallId())
+                    .setSmallName(purchaseItem.getSmallName())
+                    .setGoodsName(purchaseItem.getGoodsMaterialName())
+                    .setSeriesName(purchaseItem.getSeriesName())
+                    .setSpecsName(purchaseItem.getSpecsName())
+                    .setUnit(purchaseItem.getUnit())
+                    .setInsideQty(Objects.nonNull(materialItemMap.get(GoodsMaterialTypeEnum.INSIDE.getKey())) ? materialItemMap.get(GoodsMaterialTypeEnum.INSIDE.getKey()).getQty() : 0)
+                    .setOutQty(Objects.nonNull(materialItemMap.get(GoodsMaterialTypeEnum.OUT.getKey())) ? materialItemMap.get(GoodsMaterialTypeEnum.OUT.getKey()).getQty() : 0)
+                    .setPartsQty(Objects.nonNull(materialItemMap.get(GoodsMaterialTypeEnum.PARTS.getKey())) ? materialItemMap.get(GoodsMaterialTypeEnum.PARTS.getKey()).getQty() : 0)
+                    .setPrice(purchaseItem.getPrice())
+                    .setSdate(purchase.getExamineTime())
+                    .setChangeQty(purchaseItem.getQty())
+                    .setRefBillNo(purchase.getId())
+                    .setRefBillType("采购入库单")
+                    .setStorageId(purchase.getStorageId())
+                    .setStorageName(purchase.getStorageName())
+                    .setGoodsMaterialId(purchaseItem.getGoodsMaterialId())
+                    .setRemark(purchase.getRemark())
+                    .setOperateBy(adminUser.getAdminUserId());
+            dtoList.add(dto);
+        }
+
+        goodsMaterialStockLogic.handleGoodsMaterialStock(dtoList);
+    }
+
     private void checkCodeQty(GoodsPurchaseItem item, Map<String, List<GoodsMaterialItem>> materialItemGroupMap, Map<String, List<GoodsPurchaseCode>> codeGroupMap) {
         List<GoodsMaterialItem> materialItems = materialItemGroupMap.get(item.getGoodsMaterialId());
         for (GoodsMaterialItem materialItem : materialItems) {
@@ -488,7 +534,7 @@ public class GoodsPurchaseLogic {
     }
 
     @Transactional(rollbackFor = Exception.class)
-    public void confirm(String id, ExamineStatusEnum statusEnum) throws InterruptedException {
+    public void confirm(String id, ExamineStatusEnum statusEnum) throws Exception {
         this.commonHandlePurchase(id, statusEnum);
     }
 

+ 44 - 3
mall-server-api/src/main/java/com/gree/mall/manager/logic/goods/GoodsPurchaseRetLogic.java

@@ -2,6 +2,7 @@ package com.gree.mall.manager.logic.goods;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -13,6 +14,7 @@ import com.gree.mall.manager.commonmapper.CommonMapper;
 import com.gree.mall.manager.enums.ExamineStatusEnum;
 import com.gree.mall.manager.enums.IsYesNoEnum;
 import com.gree.mall.manager.enums.base.BaseEnum;
+import com.gree.mall.manager.enums.material.DirectFlagEnum;
 import com.gree.mall.manager.enums.material.GoodsMaterialTypeEnum;
 import com.gree.mall.manager.exception.RemoteServiceException;
 import com.gree.mall.manager.logic.common.CommonLogic;
@@ -56,6 +58,7 @@ public class GoodsPurchaseRetLogic {
     private final GoodsCodeService goodsCodeService;
     private final JxGoodsLogic jxGoodsLogic;
     private final GoodsMaterialStorageService goodsMaterialStorageService;
+    private final GoodsMaterialStockLogic goodsMaterialStockLogic;
 
     public IPage<GoodsPurchaseRetVO> page(ZfireParamBean zfireParamBean) {
         FieldUtils.supplyParam(zfireParamBean, GoodsPurchaseRetVO.class, commonLogic.getAdminUser());
@@ -567,17 +570,18 @@ public class GoodsPurchaseRetLogic {
         }
 
 
+        final DateTime curDate = DateUtil.date();
         // 更新商品采购退货单状态
         goodsPurchaseRetService.lambdaUpdate()
                 .set(GoodsPurchaseRet::getStatus, statusEnum.getKey().equals(ExamineStatusEnum.FAIL.getKey()) ? ExamineStatusEnum.SAVE.getKey() : statusEnum.getKey())
                 .set(statusEnum.getKey().equals(ExamineStatusEnum.WAIT.getKey()), GoodsPurchaseRet::getSubmitBy, adminUser.getNickName())
-                .set(statusEnum.getKey().equals(ExamineStatusEnum.WAIT.getKey()), GoodsPurchaseRet::getSubmitTime, DateUtil.date())
+                .set(statusEnum.getKey().equals(ExamineStatusEnum.WAIT.getKey()), GoodsPurchaseRet::getSubmitTime, curDate)
                 .set(statusEnum.getKey().equals(ExamineStatusEnum.OK.getKey())
                         || statusEnum.getKey().equals(ExamineStatusEnum.FAIL.getKey()),
                         GoodsPurchaseRet::getExamineBy, adminUser.getNickName())
                 .set(statusEnum.getKey().equals(ExamineStatusEnum.OK.getKey())
                         || statusEnum.getKey().equals(ExamineStatusEnum.FAIL.getKey()),
-                        GoodsPurchaseRet::getExamineTime, DateUtil.date())
+                        GoodsPurchaseRet::getExamineTime, curDate)
                 .eq(GoodsPurchaseRet::getId, id)
                 .eq(GoodsPurchaseRet::getCompanyWechatId, companyId)
                 .update();
@@ -588,10 +592,47 @@ public class GoodsPurchaseRetLogic {
                 goodsPurchaseCodeService.saveOrUpdateBatch(goodsPurchaseCodeList);
             }
             //处理库存
-            jxGoodsLogic.refundStockQty(id);
+//            jxGoodsLogic.refundStockQty(id);
+            // 物料库存处理方法
+            purchase.setExamineTime(curDate);
+            this.handleGoodsMaterialStock(purchase, purchaseItemList, adminUser);
         }
     }
 
+    private void handleGoodsMaterialStock(GoodsPurchaseRet purchase, List<GoodsPurchaseRetItem> purchaseItemList, AdminUserCom adminUser) throws Exception {
+        List<GoodsMaterialStockDTO> dtoList = new ArrayList<>();
+        for (GoodsPurchaseRetItem purchaseRetItem : purchaseItemList) {
+            GoodsMaterialStockDTO dto = new GoodsMaterialStockDTO();
+            dto.setDirectFlag(DirectFlagEnum.SUB.getKey())
+                    .setRemindName(purchaseRetItem.getGoodsMaterialName())
+                    .setCompanyWechatId(purchase.getCompanyWechatId())
+                    .setCompanyWechatName(purchase.getCompanyWechatName())
+                    .setBrandId(purchaseRetItem.getBrandId())
+                    .setBrandName(purchaseRetItem.getBrandName())
+                    .setMainId(purchaseRetItem.getMainId())
+                    .setMainName(purchaseRetItem.getMainName())
+                    .setSmallId(purchaseRetItem.getSmallId())
+                    .setSmallName(purchaseRetItem.getSmallName())
+                    .setGoodsName(purchaseRetItem.getGoodsMaterialName())
+                    .setSeriesName(purchaseRetItem.getSeriesName())
+                    .setSpecsName(purchaseRetItem.getSpecsName())
+                    .setUnit(purchaseRetItem.getUnit())
+                    .setPrice(purchaseRetItem.getPrice())
+                    .setSdate(purchase.getExamineTime())
+                    .setChangeQty(purchaseRetItem.getRetQty())
+                    .setRefBillNo(purchase.getId())
+                    .setRefBillType("采购退货单")
+                    .setStorageId(purchase.getStorageId())
+                    .setStorageName(purchase.getStorageName())
+                    .setGoodsMaterialId(purchaseRetItem.getGoodsMaterialId())
+                    .setRemark(purchase.getRemark())
+                    .setOperateBy(adminUser.getAdminUserId());
+            dtoList.add(dto);
+        }
+
+        goodsMaterialStockLogic.handleGoodsMaterialStock(dtoList);
+    }
+
     private void checkRetCodeQty(GoodsPurchaseRetItem item, Map<String, List<GoodsMaterialItem>> materialItemGroupMap, Map<String, List<GoodsPurchaseRetCode>> codeGroupMap) {
         List<GoodsMaterialItem> materialItems = materialItemGroupMap.get(item.getGoodsMaterialId());
         for (GoodsMaterialItem materialItem : materialItems) {

+ 1 - 1
mall-server-api/src/main/java/com/gree/mall/manager/logic/order/OrderDeliveryLogic.java

@@ -126,7 +126,7 @@ public class OrderDeliveryLogic {
                 , sendOrderBody.getPickName(), sendOrderBody.getPickPhone(), sendOrderBody.getPickType());
 
         //减少库存+减去条码
-        this.subStock(sendOrderBody, delivery);
+//        this.subStock(sendOrderBody, delivery);
     }
 
     /**

+ 57 - 4
mall-server-api/src/main/java/com/gree/mall/manager/logic/order/OrderLogic.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.google.common.collect.Lists;
 import com.gree.mall.manager.bean.ExcelData;
 import com.gree.mall.manager.bean.admin.AdminUserCom;
+import com.gree.mall.manager.bean.goods.GoodsMaterialStockDTO;
 import com.gree.mall.manager.bean.order.*;
 import com.gree.mall.manager.bean.workorder.OrderAddBean2DTO;
 import com.gree.mall.manager.commonmapper.OrderMapper;
@@ -23,6 +24,7 @@ import com.gree.mall.manager.logic.ExpressLogic;
 import com.gree.mall.manager.logic.StorageLogic;
 import com.gree.mall.manager.logic.common.CommonLogic;
 import com.gree.mall.manager.logic.goods.GoodsMaterialStockAccLogic;
+import com.gree.mall.manager.logic.goods.GoodsMaterialStockLogic;
 import com.gree.mall.manager.logic.goods.JxGoodsLogic;
 import com.gree.mall.manager.logic.user.UserLogic;
 import com.gree.mall.manager.logic.workorder.OrderBaseLogic;
@@ -43,6 +45,7 @@ import org.springframework.integration.redis.util.RedisLockRegistry;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
@@ -136,6 +139,8 @@ public class OrderLogic {
 
     @Autowired
     GoodsMaterialStorageService goodsMaterialStorageService;
+    @Resource
+    GoodsMaterialStockLogic goodsMaterialStockLogic;
     /**
      * 订单列表
      *
@@ -327,21 +332,68 @@ public class OrderLogic {
     /**
      * 取消订单
      */
-    public void cancel(String orderId) throws RemoteServiceException {
+    public void cancel(String orderId) throws Exception {
+        AdminUserCom adminUser = commonLogic.getAdminUser();
         OrderInfo orderInfo = orderInfoService.getById(orderId);
 
-        if(!orderInfo.getOrderStatus().equals(OrderStatusEnum.NOPAY.toString()) && !orderInfo.getOrderStatus().equals(OrderStatusEnum.DFH.toString())) {
+        if(!orderInfo.getOrderStatus().equals(OrderStatusEnum.NOPAY.toString())) {
             throw new RemoteServiceException("订单当前状态不可取消");
         }
+
         if(StringUtils.equals(orderInfo.getOrderStatus(),OrderStatusEnum.DFH.toString())) {
             log.info("【退款开始:】退款金额{}", orderInfo.getPayAmount().doubleValue());
             if(orderInfo.getPayTypeId().equals(PayTypeEnum.WECHAT.getKey())) {
                 orderShareLogic.reloadAmount(orderId, null, 1);
             }
         }
+
+//        if (orderInfo.getSaleType().equals(SaleTypeEnum.OFFLINE.getValue())
+//                && orderInfo.getOrderStatus().equals(OrderStatusEnum.DQR.toString())
+//                && orderInfo.getExamineStatus().equals(ExamineStatusEnum.OK.getKey())) {
+//            // 线下销售订单并且待确认并且审核通过的回退库存
+//            final List<OrderDetail> orderDetailList = orderDetailService.lambdaQuery()
+//                    .eq(OrderDetail::getOrderId, orderId)
+//                    .list();
+//            this.handleGoodsMaterialStock(orderInfo, orderDetailList, adminUser);
+//        }
+
         this.updateOrderStatus(orderId, OrderStatusEnum.CLOSE.toString());
     }
 
+    private void handleGoodsMaterialStock(OrderInfo orderInfo, List<OrderDetail> orderDetailList, AdminUserCom adminUser) throws Exception {
+        List<GoodsMaterialStockDTO> dtoList = new ArrayList<>();
+        for (OrderDetail orderDetail : orderDetailList) {
+            GoodsMaterialStockDTO dto = new GoodsMaterialStockDTO();
+            dto.setDirectFlag(DirectFlagEnum.ADD.getKey())
+                    .setRemindName(orderDetail.getGoodsMaterialName())
+                    .setCompanyWechatId(orderInfo.getCompanyWechatId())
+                    .setCompanyWechatName(orderInfo.getCompanyWechatName())
+                    .setBrandId(orderDetail.getBrandId())
+                    .setBrandName(orderDetail.getBrandName())
+                    .setMainId(orderDetail.getMainNumber())
+                    .setMainName(orderDetail.getMainName())
+                    .setSmallId(orderDetail.getSmallNumber())
+                    .setSmallName(orderDetail.getSmallName())
+                    .setGoodsName(orderDetail.getGoodsMaterialName())
+                    .setSeriesName(orderDetail.getGoodsMaterialSeriesName())
+                    .setSpecsName(orderDetail.getGoodsSpecValue())
+                    .setUnit(orderDetail.getGoodsMaterialUnit())
+                    .setPrice(orderDetail.getPrice())
+                    .setSdate(orderInfo.getExamineTime())
+                    .setChangeQty(orderDetail.getNum())
+                    .setRefBillNo(orderInfo.getOrderId())
+                    .setRefBillType("线下销售单")
+                    .setStorageId(orderInfo.getPickStorageId())
+                    .setStorageName(orderInfo.getPickStorageName())
+                    .setGoodsMaterialId(orderDetail.getGoodsMaterialId())
+                    .setRemark("取消订单")
+                    .setOperateBy(adminUser.getAdminUserId());
+            dtoList.add(dto);
+        }
+
+        goodsMaterialStockLogic.handleGoodsMaterialStock(dtoList);
+    }
+
     /**
      * 确定收款
      */
@@ -835,9 +887,10 @@ public class OrderLogic {
     public void updateOrderStatus(String orderId, String orderStatus) {
         orderInfoService.lambdaUpdate()
                 .set(OrderInfo::getOrderStatus, orderStatus)
-                .eq(OrderInfo::getOrderId, orderId).update();
+                .eq(OrderInfo::getOrderId, orderId)
+                .update();
 
-        orderShareLogic.updateOrderStatus(orderId, orderStatus);
+//        orderShareLogic.updateOrderStatus(orderId, orderStatus);
     }
 
     /**

+ 48 - 2
mall-server-api/src/main/java/com/gree/mall/manager/logic/order/OrderOfflineLogic.java

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.gree.mall.manager.bean.PayDetail;
 import com.gree.mall.manager.bean.admin.AdminUserCom;
+import com.gree.mall.manager.bean.goods.GoodsMaterialStockDTO;
 import com.gree.mall.manager.bean.listvo.OrderInfoVO;
 import com.gree.mall.manager.bean.order.OrderInfoAddBean;
 import com.gree.mall.manager.bean.order.OrderInfoDetailBean;
@@ -16,11 +17,13 @@ import com.gree.mall.manager.commonmapper.CommonMapper;
 import com.gree.mall.manager.enums.ExamineStatusEnum;
 import com.gree.mall.manager.enums.IsYesNoEnum;
 import com.gree.mall.manager.enums.OrderStatusEnum;
+import com.gree.mall.manager.enums.material.DirectFlagEnum;
 import com.gree.mall.manager.enums.material.GoodsMaterialTypeEnum;
 import com.gree.mall.manager.enums.material.PayTypeEnum;
 import com.gree.mall.manager.enums.material.StateEnum;
 import com.gree.mall.manager.exception.RemoteServiceException;
 import com.gree.mall.manager.logic.common.CommonLogic;
+import com.gree.mall.manager.logic.goods.GoodsMaterialStockLogic;
 import com.gree.mall.manager.plus.entity.*;
 import com.gree.mall.manager.plus.service.*;
 import com.gree.mall.manager.utils.StringUtil;
@@ -61,6 +64,7 @@ public class OrderOfflineLogic {
     private final OrderOldProductService orderOldProductService;
     private final OrderOldProductItemService orderOldProductItemService;
     private final GoodsMaterialStorageService goodsMaterialStorageService;
+    private final GoodsMaterialStockLogic goodsMaterialStockLogic;
 
     /**
      * 线下销售单列表
@@ -247,6 +251,7 @@ public class OrderOfflineLogic {
         orderDetail.setGoodsName(gm.getGoodsName());
         orderDetail.setGoodsMaterialId(gm.getId());
         orderDetail.setGoodsMaterialName(gm.getGoodsName());
+        orderDetail.setGoodsMaterialSeriesName(gm.getSeriesName());
         orderDetail.setGoodsSpecName(gm.getSpecsName());
         orderDetail.setGoodsMaterialUnit(gm.getUnit());
         orderDetail.setImgUrl(goodsCategory.getImgUrl());
@@ -328,6 +333,7 @@ public class OrderOfflineLogic {
      * @param orderId
      * @param examineStatus
      */
+    @Transactional
     public PayDetail examine(String orderId, ExamineStatusEnum examineStatus, String examineRemark, String ip) throws Exception {
         AdminUserCom adminUser = commonLogic.getAdminUser();
         OrderInfo orderInfo = orderInfoService.getById(orderId);
@@ -348,6 +354,10 @@ public class OrderOfflineLogic {
         orderInfo.setExamineRemark(examineRemark);
         orderInfo.setExamineTime(new Date());
 
+        final List<OrderDetail> orderDetailList = orderDetailService.lambdaQuery()
+                .eq(OrderDetail::getOrderId, orderId)
+                .list();
+
         PayDetail payDetail = new PayDetail().setIsPay(false);
         if (examineStatus.getKey().equals(ExamineStatusEnum.OK.getKey())) {
             if (orderInfo.getPayTypeId().equals(PayTypeEnum.WECHAT.getKey())) {
@@ -355,10 +365,11 @@ public class OrderOfflineLogic {
                 orderInfo.setExamineStatus(ExamineStatusEnum.WAIT.getKey());
                 orderInfo.setExamineTime(null);
             } else {
-                orderInfo.setOrderStatus(OrderStatusEnum.DQR.toString());
+                orderInfo.setOrderStatus(OrderStatusEnum.DFH.toString());
                 orderInfo.setPayTime(new Date());
 
-                // TODO 待完善减物料库存逻辑
+                // 减物料库存逻辑
+                this.handleGoodsMaterialStock(orderInfo, orderDetailList, adminUser);
             }
         }
         orderInfo.updateById();
@@ -366,5 +377,40 @@ public class OrderOfflineLogic {
         return payDetail;
     }
 
+    private void handleGoodsMaterialStock(OrderInfo orderInfo, List<OrderDetail> orderDetailList, AdminUserCom adminUser) throws Exception {
+
+        List<GoodsMaterialStockDTO> dtoList = new ArrayList<>();
+        for (OrderDetail orderDetail : orderDetailList) {
+            GoodsMaterialStockDTO dto = new GoodsMaterialStockDTO();
+            dto.setDirectFlag(DirectFlagEnum.SUB.getKey())
+                    .setRemindName(orderDetail.getGoodsSpecName())
+                    .setCompanyWechatId(orderInfo.getCompanyWechatId())
+                    .setCompanyWechatName(orderInfo.getCompanyWechatName())
+                    .setBrandId(orderDetail.getBrandId())
+                    .setBrandName(orderDetail.getBrandName())
+                    .setMainId(orderDetail.getMainNumber())
+                    .setMainName(orderDetail.getMainName())
+                    .setSmallId(orderDetail.getSmallNumber())
+                    .setSmallName(orderDetail.getSmallName())
+                    .setGoodsName(orderDetail.getGoodsMaterialName())
+                    .setSeriesName(orderDetail.getGoodsMaterialSeriesName())
+                    .setSpecsName(orderDetail.getGoodsSpecValue())
+                    .setUnit(orderDetail.getGoodsMaterialUnit())
+                    .setPrice(orderDetail.getPrice())
+                    .setSdate(orderInfo.getExamineTime())
+                    .setChangeQty(orderDetail.getNum())
+                    .setRefBillNo(orderInfo.getOrderId())
+                    .setRefBillType("线下销售单")
+                    .setStorageId(orderInfo.getPickStorageId())
+                    .setStorageName(orderInfo.getPickStorageName())
+                    .setGoodsMaterialId(orderDetail.getGoodsMaterialId())
+                    .setRemark(orderInfo.getRemark())
+                    .setOperateBy(adminUser.getAdminUserId());
+            dtoList.add(dto);
+        }
+
+        goodsMaterialStockLogic.handleGoodsMaterialStock(dtoList);
+    }
+
 
 }

+ 62 - 43
mall-server-api/src/main/java/com/gree/mall/manager/logic/order/OrderOfflineRefundLogic.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.gree.mall.manager.bean.admin.AdminUserCom;
+import com.gree.mall.manager.bean.goods.GoodsMaterialStockDTO;
 import com.gree.mall.manager.bean.order.OrderOldProductDTO;
 import com.gree.mall.manager.bean.order.refund.OrderOfflineRefundAddBean;
 import com.gree.mall.manager.bean.order.refund.OrderOfflineRefundDetailBean;
@@ -21,6 +22,7 @@ import com.gree.mall.manager.enums.material.PayTypeEnum;
 import com.gree.mall.manager.exception.RemoteServiceException;
 import com.gree.mall.manager.logic.common.CommonLogic;
 import com.gree.mall.manager.logic.goods.GoodsMaterialStockAccLogic;
+import com.gree.mall.manager.logic.goods.GoodsMaterialStockLogic;
 import com.gree.mall.manager.logic.goods.JxGoodsLogic;
 import com.gree.mall.manager.plus.entity.*;
 import com.gree.mall.manager.plus.service.*;
@@ -72,6 +74,7 @@ public class OrderOfflineRefundLogic {
     private final OrderDeliveryService orderDeliveryService;
     private final OrderDeliveryDetailService orderDeliveryDetailService;
     private final GoodsSaleLedgerService goodsSaleLedgerService;
+    private final GoodsMaterialStockLogic goodsMaterialStockLogic;
 
     /**
      * 退货单列表
@@ -203,33 +206,6 @@ public class OrderOfflineRefundLogic {
         }
         orderOfflineRefundItemService.saveBatch(orderOfflineRefundItems);
 
-        //旧机退货
-
-        orderOfflineRefundOldItemService.lambdaUpdate().eq(OrderOfflineRefundOldItem::getOrderOfflineRefundId,orderOfflineRefund.getId()).remove();
-        if (!CollectionUtils.isEmpty(orderOfflineRefundAddBean.getIds())){
-
-            if (orderOldProductService.lambdaQuery().in(OrderOldProduct::getId,orderOfflineRefundAddBean.getIds())
-                    .eq(OrderOldProduct::getRefund,true).count() > 0) {
-                throw new RemoteServiceException("存在已经退货得旧机");
-            }
-
-            List<OrderOfflineRefundOldItem> orderOfflineRefundOldItems = new ArrayList<>();
-            for (String orderOfflineRefundOldItem : orderOfflineRefundAddBean.getIds()) {
-                OrderOldProduct orderOldProduct = orderOldProductService.getById(orderOfflineRefundOldItem);
-
-                OrderOfflineRefundOldItem orderOfflineRefundOldItemAdd = new OrderOfflineRefundOldItem();
-                orderOfflineRefundOldItemAdd.setOrderOfflineRefundId(orderOfflineRefund.getId());
-                orderOfflineRefundOldItemAdd.setOrderOldProductId(orderOldProduct.getId());
-                orderOfflineRefundOldItemAdd.setRefundNum(orderOldProduct.getNum());
-                orderOfflineRefundOldItemAdd.setRefundAmount(orderOldProduct.getPayAmount());
-                orderOfflineRefundOldItemAdd.setOrderId(orderOldProduct.getOrderId());
-                orderOfflineRefundOldItemAdd.setId(null);
-
-                orderOfflineRefundOldItems.add(orderOfflineRefundOldItemAdd);
-            }
-
-            orderOfflineRefundOldItemService.saveBatch(orderOfflineRefundOldItems);
-        }
     }
 
     /**
@@ -251,6 +227,7 @@ public class OrderOfflineRefundLogic {
                 bean.setSmallName(orderDetail.getSmallName());
                 bean.setGoodsName(orderDetail.getGoodsName());
                 bean.setGoodsSpecName(orderDetail.getGoodsSpecName());
+                bean.setGoodsMaterialUnit(orderDetail.getGoodsMaterialUnit());
                 bean.setPrice(orderDetail.getPrice());
                 bean.setNum(orderDetail.getNum());
                 bean.setPayAmount(orderDetail.getPayAmount());
@@ -302,7 +279,7 @@ public class OrderOfflineRefundLogic {
      * @param remark
      */
     @Transactional
-    public void examine(String id,ExamineStatusEnum examineStatusEnum,String remark) throws InterruptedException {
+    public void examine(String id,ExamineStatusEnum examineStatusEnum,String remark) throws Exception {
         AdminUserCom adminUser = commonLogic.getAdminUser();
         OrderOfflineRefund orderOfflineRefund = orderOfflineRefundService.getById(id);
         if(!orderOfflineRefund.getExamineStatus().equals(ExamineStatusEnum.WAIT.getKey())){
@@ -324,8 +301,8 @@ public class OrderOfflineRefundLogic {
         List<OrderDeliveryDetail> orderDeliveryDetails = orderDeliveryDetailService.lambdaQuery().eq(OrderDeliveryDetail::getDeliveryId, orderOfflineRefund.getDeliveryId()).list();
         List<OrderDetail> orderDetails = orderDetailService.lambdaQuery().eq(OrderDetail::getOrderId, orderOfflineRefund.getOrderId()).list();
         //订单明细map
-        Map<String, OrderDetail> orderDetailMap = orderDetails.stream().collect(Collectors.toMap(v -> v.getOrderDetailId(), Function.identity()));
-        Map<String, OrderDeliveryDetail> orderDeliveryDetailMap = orderDeliveryDetails.stream().collect(Collectors.toMap(v -> v.getOrderDetailId(), Function.identity()));
+        Map<String, OrderDetail> orderDetailMap = orderDetails.stream().collect(Collectors.toMap(OrderDetail::getOrderDetailId, Function.identity()));
+        Map<String, OrderDeliveryDetail> orderDeliveryDetailMap = orderDeliveryDetails.stream().collect(Collectors.toMap(OrderDeliveryDetail::getOrderDetailId, Function.identity()));
 
         if(examineStatusEnum.getKey().equals(ExamineStatusEnum.OK.getKey())){
 
@@ -381,24 +358,24 @@ public class OrderOfflineRefundLogic {
 
                 //回退仓库库存
                 if (!StringUtil.isEmpty(orderDetail.getGoodsMaterialId()) && !adminUser.getJoinCode().equals("NO")) {
-
-                    jxGoodsLogic.addMaterialStock(orderDetail.getGoodsMaterialId(), item.getRefundNum(),orderOfflineRefund.getStorageStockId(),orderDelivery.getStorageStockId());
-                    goodsMaterialStockAccLogic.add(orderDetail.getGoodsMaterialId(), orderDetail.getPrice(), item.getRefundNum(),
-                            DirectFlagEnum.ADD, orderRefund.getOrderId(), GoodsMaterialStockAccBillTypeEnum.E,orderOfflineRefund.getStorageStockId(),orderOfflineRefund.getStorageName());
-                    if (adminUser.getJoinCode().equals("CODE")) {
-                        //加条码
-                        if (!CollectionUtils.isEmpty(codeList))
-                            jxGoodsLogic.addCodeAccOffline(codeList,orderOfflineRefund.getStorageStockId());
-
-                    }
+//                    jxGoodsLogic.addMaterialStock(orderDetail.getGoodsMaterialId(), item.getRefundNum(),orderOfflineRefund.getStorageStockId(),orderDelivery.getStorageStockId());
+//                    goodsMaterialStockAccLogic.add(orderDetail.getGoodsMaterialId(), orderDetail.getPrice(), item.getRefundNum(),
+//                            DirectFlagEnum.ADD, orderRefund.getOrderId(), GoodsMaterialStockAccBillTypeEnum.E,orderOfflineRefund.getStorageStockId(),orderOfflineRefund.getStorageName());
+//                    if (adminUser.getJoinCode().equals("CODE")) {
+//                        //加条码
+//                        if (!CollectionUtils.isEmpty(codeList))
+//                            jxGoodsLogic.addCodeAccOffline(codeList,orderOfflineRefund.getStorageStockId());
+//
+//                    }
+                    this.handleGoodsMaterialStock(orderOfflineRefund, orderOfflineRefundItems, orderDetailMap, adminUser);
                 }
 
             }
             orderDelivery.updateById();
             //线上支付,需退款
-            if (orderInfo.getPayTypeId().equals(PayTypeEnum.WECHAT.getKey())) {
-                orderRefundLogic.refund(orderRefund);
-            }
+//            if (orderInfo.getPayTypeId().equals(PayTypeEnum.WECHAT.getKey())) {
+//                orderRefundLogic.refund(orderRefund);
+//            }
 
             List<GoodsSaleLedger> goodsSaleLedgers = goodsSaleLedgerService.lambdaQuery()
                     .eq(GoodsSaleLedger::getDeliveryId, orderDelivery.getDeliveryId()).list();
@@ -418,6 +395,48 @@ public class OrderOfflineRefundLogic {
 
     }
 
+    private void handleGoodsMaterialStock(OrderOfflineRefund orderOfflineRefund, List<OrderOfflineRefundItem> orderOfflineRefundItems,
+                                          Map<String, OrderDetail> orderDetailMap, AdminUserCom adminUser) throws Exception {
+        List<GoodsMaterialStockDTO> dtoList = new ArrayList<>();
+        for (OrderOfflineRefundItem refundItem : orderOfflineRefundItems) {
+            GoodsMaterialStockDTO dto = new GoodsMaterialStockDTO();
+            final OrderDetail orderDetail = orderDetailMap.get(refundItem.getOrderDetailId());
+            int insideNum = orderDetail.getInsideNum() == 0 ? 0 : (orderDetail.getInsideNum() / orderDetail.getNum());
+            int outNum = orderDetail.getOutNum() == 0 ? 0 : (orderDetail.getOutNum() / orderDetail.getNum());
+            int partNum = orderDetail.getPartNum() == 0 ? 0 : (orderDetail.getPartNum() / orderDetail.getNum());
+            dto.setDirectFlag(DirectFlagEnum.ADD.getKey())
+                    .setRemindName(orderDetail.getGoodsSpecName())
+                    .setCompanyWechatId(orderOfflineRefund.getCompanyWechatId())
+                    .setCompanyWechatName(orderOfflineRefund.getCompanyWechatName())
+                    .setBrandId(orderDetail.getBrandId())
+                    .setBrandName(orderDetail.getBrandName())
+                    .setMainId(orderDetail.getMainNumber())
+                    .setMainName(orderDetail.getMainName())
+                    .setSmallId(orderDetail.getSmallNumber())
+                    .setSmallName(orderDetail.getSmallName())
+                    .setGoodsName(orderDetail.getGoodsMaterialName())
+                    .setSeriesName(orderDetail.getGoodsMaterialSeriesName())
+                    .setSpecsName(orderDetail.getGoodsSpecValue())
+                    .setUnit(orderDetail.getGoodsMaterialUnit())
+                    .setInsideQty(insideNum)
+                    .setOutQty(outNum)
+                    .setPartsQty(partNum)
+                    .setPrice(orderDetail.getPrice())
+                    .setSdate(orderOfflineRefund.getExamineTime())
+                    .setChangeQty(refundItem.getRefundNum())
+                    .setRefBillNo(orderOfflineRefund.getId())
+                    .setRefBillType("销售退货单")
+                    .setStorageId(orderOfflineRefund.getStorageStockId())
+                    .setStorageName(orderOfflineRefund.getStorageStockName())
+                    .setGoodsMaterialId(orderDetail.getGoodsMaterialId())
+                    .setRemark(orderOfflineRefund.getRemark())
+                    .setOperateBy(adminUser.getAdminUserId());
+            dtoList.add(dto);
+        }
+
+        goodsMaterialStockLogic.handleGoodsMaterialStock(dtoList);
+    }
+
 
     private void refundOver(String orderId){
         List<OrderDetail> orderDetails = orderDetailService.lambdaQuery().eq(OrderDetail::getOrderId, orderId).list();

+ 2 - 1
mall-server-api/src/main/java/com/gree/mall/manager/zfire/util/FieldUtils.java

@@ -233,8 +233,9 @@ public class FieldUtils {
 
                 value = replaceValue(value);
 
-                if (StringUtils.equals(paramBean.getCompare(), "LIKE")) {
+                if (StringUtils.equals(paramBean.getCompare(), "like")) {
                     value = "%" + value + "%";
+                    paramBean.setCompare("LIKE");
                 }
                 sb.append("AND ").append(paramBean.getParam()).append(" ").append(paramBean.getCompare());
                 if (value.equals("true") || value.equals("false")) {

+ 19 - 0
mall-server-api/src/main/resources/mapper/MaterialMapper.xml

@@ -13,5 +13,24 @@
         ${ex.orderBy}
     </select>
 
+    <select id="queryExistGoodsMaterialStockList"
+            resultType="com.gree.mall.manager.plus.entity.GoodsMaterialStorage">
+        SELECT
+            *
+        FROM
+            goods_material_storage
+        WHERE
+            company_wechat_id = #{dto.companyWechatId}
+            AND
+            storage_id = #{dto.storageId}
+            AND
+            goods_material_id IN
+            <foreach item="item" index="index" collection="stockList" open="(" separator=","
+                     close=")">
+                #{item.goodsMaterialId}
+            </foreach>
+        FOR UPDATE
+    </select>
+
 
 </mapper>