فهرست منبع

APP提交订单时除在线支付,都先减库存

FengChaoYu 3 هفته پیش
والد
کامیت
b9836a1edf

+ 194 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/bean/goods/GoodsMaterialStockDTO.java

@@ -0,0 +1,194 @@
+package com.gree.mall.miniapp.bean.goods;
+
+import com.gree.mall.miniapp.enums.material.DirectFlagEnum;
+import com.gree.mall.miniapp.exception.RemoteServiceException;
+import com.gree.mall.miniapp.plus.entity.GoodsMaterialStockAcc;
+import com.gree.mall.miniapp.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);
+    }
+}

+ 18 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/commonmapper/MaterialMapper.java

@@ -0,0 +1,18 @@
+package com.gree.mall.miniapp.commonmapper;
+
+import com.gree.mall.miniapp.bean.goods.GoodsMaterialStockDTO;
+import com.gree.mall.miniapp.plus.entity.GoodsMaterialStorage;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface MaterialMapper {
+    /**
+     * 带锁查询物料库存
+     * @param dto
+     * @param stockList
+     * @return
+     */
+    List<GoodsMaterialStorage> queryExistGoodsMaterialStockList(@Param("dto") GoodsMaterialStockDTO dto,
+                                                                @Param("stockList") List<GoodsMaterialStockDTO> stockList);
+}

+ 3 - 9
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/constant/Constant.java

@@ -43,23 +43,17 @@ public class Constant {
         public final static String LOCK_AUTH = "zfire:overseas:lock:auth";
         public final static String LOCK_AUTH = "zfire:overseas:lock:auth";
         public final static String SMS = "zfire:overseas:sms";
         public final static String SMS = "zfire:overseas:sms";
         public final static String VERIFICATION = "zfire:overseas:verification";
         public final static String VERIFICATION = "zfire:overseas:verification";
-        public final static String SMS_BIND_CODE= "zfire:overseas:sms:bind:";
         public final static String TOKEN_TAX = "zfire:overseas:token:tax";
         public final static String TOKEN_TAX = "zfire:overseas:token:tax";
-        public final static String TOKEN_GONGDAN = "zfire:overseas:token:gongdan";
         public final static String LOCK_EXCHANGE_CODE = "zfire:overseas:lock:exchangecode";
         public final static String LOCK_EXCHANGE_CODE = "zfire:overseas:lock:exchangecode";
         //订单号每日流水
         //订单号每日流水
         public final static String ORDER_NUM = "zfire:overseas:orderNo:";
         public final static String ORDER_NUM = "zfire:overseas:orderNo:";
-        public final static String MATERIAL_STOCK_LOCK = "zfire:overseas:lock:material:stock:";
-        public final static String LEASE_ORDER_LOCK = "zfire:overseas:lock:lease:order:";
-        public final static String ES_GOODS_LOCK = "zfire:overseas:lock:es:goods:";
+
 
 
         // 接口令牌
         // 接口令牌
         public final static String INF_TOKEN = "zfire:overseas:token:inf";
         public final static String INF_TOKEN = "zfire:overseas:token:inf";
 
 
-        // 查询通联支付订单信息
-        public final static String QUERY_ALLINPAY_ORDER = "zfire:overseas:lock:a:query:order:";
-        public static final String PARTS_SALES = "zfire:overseas:lock:parts:sales:";
-        public static final String WRITE_SALES_ITEM = "zfire:overseas:parts:write:sales:item:";
+        public final static String LOCK_GOODS_MATERIAL = "zfire:overseas:goods:material:";
+
     }
     }
 
 
     //礼品卡支持的市
     //礼品卡支持的市

+ 1 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/enums/OrderStatusEnum.java

@@ -11,6 +11,7 @@ public enum OrderStatusEnum {
     DFH("待发货"),
     DFH("待发货"),
     YFH("已发货"),
     YFH("已发货"),
     DPS("待配送"),
     DPS("待配送"),
+    PSDQ("配送待取"),
     PSZ("配送中"),
     PSZ("配送中"),
     DTK("待退款"),
     DTK("待退款"),
     OVER("已完成"),
     OVER("已完成"),

+ 5 - 1
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/logic/common/CommonLogic.java

@@ -384,9 +384,13 @@ public class CommonLogic {
 
 
     public List<OrderPickTimeConfig> orderPickTimeList(String storageId) {
     public List<OrderPickTimeConfig> orderPickTimeList(String storageId) {
         CurrentCompanyWechat currentCompanyWechat = getCurrentCompanyWechat();
         CurrentCompanyWechat currentCompanyWechat = getCurrentCompanyWechat();
-        return orderPickTimeConfigService.lambdaQuery()
+        final List<OrderPickTimeConfig> list = orderPickTimeConfigService.lambdaQuery()
                 .eq(OrderPickTimeConfig::getCompanyWechatId, currentCompanyWechat.getCompanyWechatId())
                 .eq(OrderPickTimeConfig::getCompanyWechatId, currentCompanyWechat.getCompanyWechatId())
                 .eq(OrderPickTimeConfig::getStorageId, storageId)
                 .eq(OrderPickTimeConfig::getStorageId, storageId)
                 .list();
                 .list();
+
+
+
+        return list;
     }
     }
 }
 }

+ 172 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/logic/goods/GoodsMaterialStockLogic.java

@@ -0,0 +1,172 @@
+package com.gree.mall.miniapp.logic.goods;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.gree.mall.miniapp.bean.goods.GoodsMaterialStockDTO;
+import com.gree.mall.miniapp.commonmapper.MaterialMapper;
+import com.gree.mall.miniapp.constant.Constant;
+import com.gree.mall.miniapp.enums.material.DirectFlagEnum;
+import com.gree.mall.miniapp.exception.RemoteServiceException;
+import com.gree.mall.miniapp.plus.entity.GoodsMaterialAcc;
+import com.gree.mall.miniapp.plus.entity.GoodsMaterialStockAcc;
+import com.gree.mall.miniapp.plus.entity.GoodsMaterialStorage;
+import com.gree.mall.miniapp.plus.service.GoodsMaterialAccService;
+import com.gree.mall.miniapp.plus.service.GoodsMaterialStockAccService;
+import com.gree.mall.miniapp.plus.service.GoodsMaterialStorageService;
+import com.gree.mall.miniapp.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.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Service
+@Slf4j
+@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();
+        }
+    }
+
+}

+ 53 - 16
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/logic/order/OrderLogic.java

@@ -2,7 +2,6 @@ package com.gree.mall.miniapp.logic.order;
 
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -11,6 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.gree.mall.miniapp.bean.PayDetail;
 import com.gree.mall.miniapp.bean.PayDetail;
 import com.gree.mall.miniapp.bean.coupon.UserCouponBean;
 import com.gree.mall.miniapp.bean.coupon.UserCouponBean;
 import com.gree.mall.miniapp.bean.goods.AckGoodsBean;
 import com.gree.mall.miniapp.bean.goods.AckGoodsBean;
+import com.gree.mall.miniapp.bean.goods.GoodsMaterialStockDTO;
 import com.gree.mall.miniapp.bean.order.*;
 import com.gree.mall.miniapp.bean.order.*;
 import com.gree.mall.miniapp.bean.user.CurrentCompanyWechat;
 import com.gree.mall.miniapp.bean.user.CurrentCompanyWechat;
 import com.gree.mall.miniapp.bean.workorder.PgOrderSettleNormBean;
 import com.gree.mall.miniapp.bean.workorder.PgOrderSettleNormBean;
@@ -18,6 +18,7 @@ import com.gree.mall.miniapp.commonmapper.*;
 import com.gree.mall.miniapp.constant.Constant;
 import com.gree.mall.miniapp.constant.Constant;
 import com.gree.mall.miniapp.enums.*;
 import com.gree.mall.miniapp.enums.*;
 import com.gree.mall.miniapp.enums.base.BaseEnum;
 import com.gree.mall.miniapp.enums.base.BaseEnum;
+import com.gree.mall.miniapp.enums.material.DirectFlagEnum;
 import com.gree.mall.miniapp.enums.material.GoodsMaterialTypeEnum;
 import com.gree.mall.miniapp.enums.material.GoodsMaterialTypeEnum;
 import com.gree.mall.miniapp.enums.workorder.SettleNormTypeEnum;
 import com.gree.mall.miniapp.enums.workorder.SettleNormTypeEnum;
 import com.gree.mall.miniapp.exception.RemoteServiceException;
 import com.gree.mall.miniapp.exception.RemoteServiceException;
@@ -28,6 +29,7 @@ import com.gree.mall.miniapp.logic.common.outside.WechatLogic;
 import com.gree.mall.miniapp.logic.coupon.CouponLogic;
 import com.gree.mall.miniapp.logic.coupon.CouponLogic;
 import com.gree.mall.miniapp.logic.goods.GoodsCategoryLogic;
 import com.gree.mall.miniapp.logic.goods.GoodsCategoryLogic;
 import com.gree.mall.miniapp.logic.goods.GoodsLogic;
 import com.gree.mall.miniapp.logic.goods.GoodsLogic;
+import com.gree.mall.miniapp.logic.goods.GoodsMaterialStockLogic;
 import com.gree.mall.miniapp.logic.promotion.PromotionFullPieceLogic;
 import com.gree.mall.miniapp.logic.promotion.PromotionFullPieceLogic;
 import com.gree.mall.miniapp.logic.promotion.PromotionGroupLogic;
 import com.gree.mall.miniapp.logic.promotion.PromotionGroupLogic;
 import com.gree.mall.miniapp.logic.user.PayLogic;
 import com.gree.mall.miniapp.logic.user.PayLogic;
@@ -37,7 +39,6 @@ import com.gree.mall.miniapp.plus.service.*;
 import com.gree.mall.miniapp.utils.ArithUtils;
 import com.gree.mall.miniapp.utils.ArithUtils;
 import com.gree.mall.miniapp.utils.CommonUtils;
 import com.gree.mall.miniapp.utils.CommonUtils;
 import com.gree.mall.miniapp.utils.DateUtils;
 import com.gree.mall.miniapp.utils.DateUtils;
-import com.gree.mall.miniapp.utils.IpUtil;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
@@ -49,7 +50,6 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.Resource;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.text.ParseException;
 import java.text.ParseException;
 import java.util.*;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeUnit;
@@ -153,6 +153,8 @@ public class OrderLogic {
     StorageService storageService;
     StorageService storageService;
     @Resource
     @Resource
     OrderPickTimeConfigService orderPickTimeConfigService;
     OrderPickTimeConfigService orderPickTimeConfigService;
+    @Resource
+    GoodsMaterialStockLogic goodsMaterialStockLogic;
 
 
     /**
     /**
      * 立即购买
      * 立即购买
@@ -174,10 +176,9 @@ public class OrderLogic {
                 && orderBuyBean.getTakeGoodsType().equals(TakeGoodsTypeEnum.Y.getKey())) {
                 && orderBuyBean.getTakeGoodsType().equals(TakeGoodsTypeEnum.Y.getKey())) {
             throw new RemoteServiceException(1100, "请选择收货地址");
             throw new RemoteServiceException(1100, "请选择收货地址");
         }
         }
-        if (orderBuyBean.getTakeGoodsType().equals(TakeGoodsTypeEnum.Z.getKey())
-                && (Objects.isNull(orderBuyBean.getAppointmentPickStartTime())
-                || Objects.isNull(orderBuyBean.getAppointmentPickEndTime()))) {
-            throw new RemoteServiceException(1100, "请选择提货时间");
+        if (Objects.isNull(orderBuyBean.getAppointmentPickStartTime())
+                || Objects.isNull(orderBuyBean.getAppointmentPickEndTime())) {
+            throw new RemoteServiceException(1100, orderBuyBean.getTakeGoodsType().equals(TakeGoodsTypeEnum.Z.getKey()) ? "请选择提货时间" : "请选择配送时间");
         }
         }
         CurrentCompanyWechat currentCompanyWechat = commonLogic.getCurrentCompanyWechat(request);
         CurrentCompanyWechat currentCompanyWechat = commonLogic.getCurrentCompanyWechat(request);
 
 
@@ -421,6 +422,10 @@ public class OrderLogic {
             payDetail.setIsPay(false);
             payDetail.setIsPay(false);
         }
         }
 
 
+        if (!StringUtils.equals(orderBuyBean.getPayTypeId(), PayTypeEnum.ONLINE.getKey())) {
+            this.handleGoodsMaterialStock(orderInfo, orderDetails, currentCompanyWechat, DirectFlagEnum.SUB, "提交订单", "提交订单");
+        }
+
         //不需要支付
         //不需要支付
         if (!payDetail.getIsPay()) {
         if (!payDetail.getIsPay()) {
             payLogic.payCall(payDetail.getId(), "", orderInfo.getPayAmount());
             payLogic.payCall(payDetail.getId(), "", orderInfo.getPayAmount());
@@ -429,16 +434,48 @@ public class OrderLogic {
         return payDetail;
         return payDetail;
     }
     }
 
 
-    private OrderOldProductItem productCategoryItem(GoodsCategoryItem goodsCategoryItem) {
-        OrderOldProductItem orderOldProductItem = BeanUtil.toBean(goodsCategoryItem, OrderOldProductItem.class);
-        return orderOldProductItem;
-    }
+    /**
+     *
+     * @param orderInfo
+     * @param orderDetailList
+     * @param currentCompanyWechat
+     * @param flagEnum
+     * @param refBillType
+     * @param remark
+     */
+    private void handleGoodsMaterialStock(OrderInfo orderInfo, List<OrderDetail> orderDetailList, CurrentCompanyWechat currentCompanyWechat,
+                                          DirectFlagEnum flagEnum, String refBillType, String remark) throws Exception {
+        List<GoodsMaterialStockDTO> dtoList = new ArrayList<>();
+        for (OrderDetail orderDetail : orderDetailList) {
+            GoodsMaterialStockDTO dto = new GoodsMaterialStockDTO();
+            dto.setDirectFlag(flagEnum.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(refBillType)
+                    .setStorageId(orderInfo.getPickStorageId())
+                    .setStorageName(orderInfo.getPickStorageName())
+                    .setGoodsMaterialId(orderDetail.getGoodsMaterialId())
+                    .setRemark(remark)
+                    .setOperateBy(currentCompanyWechat.getUserId());
+            dtoList.add(dto);
+        }
 
 
-    private void productCategory(OrderOldProduct orderOldProduct, GoodsCategoryItem goodsCategoryItem) {
-        BeanUtil.copyProperties(goodsCategoryItem,orderOldProduct);
-        orderOldProduct.setPrice(goodsCategoryItem.getPrice());
-        orderOldProduct.setSpecId(goodsCategoryItem.getId());
-        orderOldProduct.setSpecName(goodsCategoryItem.getDictName());
+        goodsMaterialStockLogic.handleGoodsMaterialStock(dtoList);
     }
     }
 
 
 
 

+ 22 - 0
mall-miniapp-service/src/main/resources/mapper/MaterialMapper.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.gree.mall.miniapp.commonmapper.MaterialMapper">
+    <select id="queryExistGoodsMaterialStockList"
+            resultType="com.gree.mall.miniapp.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>

+ 6 - 0
mall-server-api/src/main/java/com/gree/mall/manager/enums/OrderStatusEnum.java

@@ -13,6 +13,7 @@ public enum OrderStatusEnum {
     JHZ("拣货中"),
     JHZ("拣货中"),
     DFH("待发货"),
     DFH("待发货"),
     DPS("待配送"),
     DPS("待配送"),
+    PSDQ("配送待取"),
     PSZ("配送中"),
     PSZ("配送中"),
     DTK("待退款"),
     DTK("待退款"),
     OVER("已完成"),
     OVER("已完成"),
@@ -33,4 +34,9 @@ public enum OrderStatusEnum {
                 OrderStatusEnum.OVER.toString(), OrderStatusEnum.CLOSE.toString());
                 OrderStatusEnum.OVER.toString(), OrderStatusEnum.CLOSE.toString());
         return orderStatusList.contains(value);
         return orderStatusList.contains(value);
     }
     }
+
+    public static boolean addDeliveryContains(String value) {
+        List<String> orderStatusList = Arrays.asList(OrderStatusEnum.DPS.toString(), OrderStatusEnum.PSDQ.toString());
+        return orderStatusList.contains(value);
+    }
 }
 }

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

@@ -345,10 +345,12 @@ public class OrderLogic {
             throw new RemoteServiceException("订单当前状态不可取消");
             throw new RemoteServiceException("订单当前状态不可取消");
         }
         }
 
 
-        if ((orderInfo.getOrderStatus().equals(OrderStatusEnum.DJH.toString())
+        if ((orderInfo.getOrderStatus().equals(OrderStatusEnum.DQR.toString())
+                || orderInfo.getOrderStatus().equals(OrderStatusEnum.DJH.toString())
                 || orderInfo.getOrderStatus().equals(OrderStatusEnum.JHZ.toString())
                 || orderInfo.getOrderStatus().equals(OrderStatusEnum.JHZ.toString())
                 || orderInfo.getOrderStatus().equals(OrderStatusEnum.DFH.toString())
                 || orderInfo.getOrderStatus().equals(OrderStatusEnum.DFH.toString())
-                || orderInfo.getOrderStatus().equals(OrderStatusEnum.DPS.toString()))
+                || orderInfo.getOrderStatus().equals(OrderStatusEnum.DPS.toString())
+                || orderInfo.getOrderStatus().equals(OrderStatusEnum.PSDQ.toString()))
                 && orderInfo.getExamineStatus().equals(ExamineStatusEnum.OK.getKey())) {
                 && orderInfo.getExamineStatus().equals(ExamineStatusEnum.OK.getKey())) {
             // 待拣货\待发货\待配送取消订单回退库存
             // 待拣货\待发货\待配送取消订单回退库存
             final List<OrderDetail> orderDetailList = orderDetailService.lambdaQuery()
             final List<OrderDetail> orderDetailList = orderDetailService.lambdaQuery()
@@ -1416,10 +1418,10 @@ public class OrderLogic {
     public void startDeliver(List<String> orderIds) {
     public void startDeliver(List<String> orderIds) {
         final List<OrderInfo> orderInfoList = orderInfoService.lambdaQuery().in(OrderInfo::getOrderId, orderIds).list();
         final List<OrderInfo> orderInfoList = orderInfoService.lambdaQuery().in(OrderInfo::getOrderId, orderIds).list();
 
 
-        final long count = orderInfoList.stream().filter(v -> !v.getOrderStatus().equals(OrderStatusEnum.DPS.toString())).count();
+        final long count = orderInfoList.stream().filter(v -> !v.getOrderStatus().equals(OrderStatusEnum.PSDQ.toString())).count();
 
 
         if (count > 0) {
         if (count > 0) {
-            throw new RemoteServiceException("有非“配送”单,请刷新列表检查");
+            throw new RemoteServiceException("有非“配送待取”单,请刷新列表检查");
         }
         }
 
 
         final long notDeliveryCount = orderInfoList.stream().filter(v -> StringUtils.isBlank(v.getDeliveryUserId())).count();
         final long notDeliveryCount = orderInfoList.stream().filter(v -> StringUtils.isBlank(v.getDeliveryUserId())).count();
@@ -1430,7 +1432,7 @@ public class OrderLogic {
 
 
         orderInfoService.lambdaUpdate()
         orderInfoService.lambdaUpdate()
                 .set(OrderInfo::getOrderStatus, OrderStatusEnum.PSZ.toString())
                 .set(OrderInfo::getOrderStatus, OrderStatusEnum.PSZ.toString())
-                .set(OrderInfo::getLastOrderStatus, OrderStatusEnum.DPS.toString())
+                .set(OrderInfo::getLastOrderStatus, OrderStatusEnum.PSDQ.toString())
                 .set(OrderInfo::getDeliverTime, DateUtil.date())
                 .set(OrderInfo::getDeliverTime, DateUtil.date())
                 .in(OrderInfo::getOrderId, orderIds)
                 .in(OrderInfo::getOrderId, orderIds)
                 .update();
                 .update();
@@ -1444,10 +1446,10 @@ public class OrderLogic {
     public void addDelivery(List<String> orderIds, String userId) {
     public void addDelivery(List<String> orderIds, String userId) {
         final List<OrderInfo> orderInfoList = orderInfoService.lambdaQuery().in(OrderInfo::getOrderId, orderIds).list();
         final List<OrderInfo> orderInfoList = orderInfoService.lambdaQuery().in(OrderInfo::getOrderId, orderIds).list();
 
 
-        final long count = orderInfoList.stream().filter(v -> !v.getOrderStatus().equals(OrderStatusEnum.DPS.toString())).count();
+        final long count = orderInfoList.stream().filter(v -> !OrderStatusEnum.addDeliveryContains(v.getOrderStatus())).count();
 
 
         if (count > 0) {
         if (count > 0) {
-            throw new RemoteServiceException("有非“待配送”单,请刷新列表检查");
+            throw new RemoteServiceException("已选订单中发现不能再添加配送员状态,请刷新列表检查");
         }
         }
 
 
         AdminUserCom adminUser = commonLogic.getAdminUser();
         AdminUserCom adminUser = commonLogic.getAdminUser();
@@ -1464,6 +1466,8 @@ public class OrderLogic {
         orderInfoService.lambdaUpdate()
         orderInfoService.lambdaUpdate()
                 .set(OrderInfo::getDeliveryUserId, user.getUserId())
                 .set(OrderInfo::getDeliveryUserId, user.getUserId())
                 .set(OrderInfo::getDeliveryUserName, user.getNickName() + "(" + user.getMobile() + ")")
                 .set(OrderInfo::getDeliveryUserName, user.getNickName() + "(" + user.getMobile() + ")")
+                .set(OrderInfo::getOrderStatus, OrderStatusEnum.PSDQ.toString())
+                .set(OrderInfo::getLastOrderStatus, OrderStatusEnum.DPS.toString())
                 .in(OrderInfo::getOrderId, orderIds)
                 .in(OrderInfo::getOrderId, orderIds)
                 .update();
                 .update();
     }
     }