Przeglądaj źródła

移动端配件销售单

FengChaoYu 8 miesięcy temu
rodzic
commit
7d9eb5815b
15 zmienionych plików z 1080 dodań i 64 usunięć
  1. 0 27
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/bean/material/WebsitPartsSalesBean.java
  2. 0 12
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/bean/material/WebsitPartsSalesItemBean.java
  3. 23 0
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/bean/material/parts/OldRefundManageRecordBean.java
  4. 41 0
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/bean/material/parts/PartsSalesOrderBean.java
  5. 18 0
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/bean/material/parts/PartsSalesOrderItemBean.java
  6. 13 2
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/commonmapper/MaterialMapper.java
  7. 132 0
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/controller/material/parts/SalesOrderController.java
  8. 28 0
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/enums/IsEnum.java
  9. 28 0
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/enums/StateEnum.java
  10. 21 0
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/enums/material/NormTypeEnum.java
  11. 175 0
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/logic/material/parts/WebsitPartsSalesLogic.java
  12. 430 15
      mall-miniapp-service/src/main/java/com/gree/mall/miniapp/logic/material/parts/WebsitPartsSalesOrderLogic.java
  13. 95 0
      mall-miniapp-service/src/main/resources/mapper/MaterialMapper.xml
  14. 75 7
      mall-server-api/src/main/java/com/gree/mall/manager/logic/material/manage/WebsitPartsSalesLogic.java
  15. 1 1
      mall-server-api/src/main/resources/mapper/MaterialMapper.xml

+ 0 - 27
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/bean/material/WebsitPartsSalesBean.java

@@ -1,27 +0,0 @@
-package com.gree.mall.miniapp.bean.material;
-
-import com.gree.mall.miniapp.plus.entity.WebsitPartsSales;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.util.List;
-
-@EqualsAndHashCode(callSuper = true)
-@Data
-@ApiModel
-public class WebsitPartsSalesBean extends WebsitPartsSales {
-
-    @ApiModelProperty(value = "订单配件信息", required = true)
-    private List<WebsitPartsSalesItemBean> itemList;
-
-//    @ApiModelProperty(value = "支付记录列表", required = true)
-//    private List<WebsitSalesPayOrder> payList;
-//
-//    @ApiModelProperty(value = "支付记录列表", required = true)
-//    private List<WebsitSalesPayOrder> allPayList;
-//
-//    @ApiModelProperty(value = "订单明细使用信息", required = true)
-//    private List<OldRefundManageRecordBean> oldRefundManageRecordBeanList;
-}

+ 0 - 12
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/bean/material/WebsitPartsSalesItemBean.java

@@ -1,12 +0,0 @@
-package com.gree.mall.miniapp.bean.material;
-
-import com.gree.mall.miniapp.plus.entity.WebsitPartsSalesItem;
-import io.swagger.annotations.ApiModel;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-@EqualsAndHashCode(callSuper = true)
-@Data
-@ApiModel
-public class WebsitPartsSalesItemBean extends WebsitPartsSalesItem {
-}

+ 23 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/bean/material/parts/OldRefundManageRecordBean.java

@@ -0,0 +1,23 @@
+package com.gree.mall.miniapp.bean.material.parts;
+
+import com.gree.mall.miniapp.plus.entity.WebsitPartsOldRefundManageRecord;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel
+public class OldRefundManageRecordBean extends WebsitPartsOldRefundManageRecord {
+
+    @ApiModelProperty("退款状态")
+    private String refundStateName;
+
+    @ApiModelProperty("维修标识 INNER=保内 OUTSIDE=保外")
+    private String repairFlagName;
+
+    @ApiModelProperty("是否备用件 false=否 true=是")
+    private String isBackupName;
+
+}

+ 41 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/bean/material/parts/PartsSalesOrderBean.java

@@ -0,0 +1,41 @@
+package com.gree.mall.miniapp.bean.material.parts;
+
+import com.gree.mall.miniapp.plus.entity.WebsitPartsSales;
+import com.gree.mall.miniapp.plus.entity.WebsitSalesPayOrder;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel
+public class PartsSalesOrderBean extends WebsitPartsSales {
+
+    @ApiModelProperty("购买方式")
+    private String buyTypeName;
+
+    @ApiModelProperty("单据状态")
+    private String stateName;
+
+    @ApiModelProperty("下推标志")
+    private String pushFlagName;
+
+    @ApiModelProperty("提货状态名称")
+    private String pickupStateName;
+
+    @ApiModelProperty(value = "订单配件信息", required = true)
+    private List<PartsSalesOrderItemBean> itemList;
+
+    @ApiModelProperty(value = "支付记录列表", required = true)
+    private List<WebsitSalesPayOrder> payList;
+
+    @ApiModelProperty(value = "全部支付记录列表")
+    private List<WebsitSalesPayOrder> allPayList;
+
+    @ApiModelProperty(value = "订单明细使用信息", required = true)
+    private List<OldRefundManageRecordBean> oldRefundManageRecordBeanList;
+
+}

+ 18 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/bean/material/parts/PartsSalesOrderItemBean.java

@@ -0,0 +1,18 @@
+package com.gree.mall.miniapp.bean.material.parts;
+
+import com.gree.mall.miniapp.plus.entity.WebsitPartsSalesItem;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel
+public class PartsSalesOrderItemBean extends WebsitPartsSalesItem {
+
+	@ApiModelProperty("可用库存")
+    private BigDecimal stockQty;
+}

+ 13 - 2
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/commonmapper/MaterialMapper.java

@@ -4,8 +4,7 @@ import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.gree.mall.miniapp.bean.material.*;
-import com.gree.mall.miniapp.bean.material.parts.NewRefundManageBean;
-import com.gree.mall.miniapp.bean.material.parts.SalesItemRecordDTO;
+import com.gree.mall.miniapp.bean.material.parts.*;
 import com.gree.mall.miniapp.bean.material.stock.WorkerNormStockBean;
 import com.gree.mall.miniapp.plus.entity.WebsitPartsSalesItem;
 import org.apache.ibatis.annotations.Mapper;
@@ -111,6 +110,14 @@ public interface MaterialMapper {
                                        @Param("identity") String identity,
                                        @Param("partsNumber") String partsNumber);
 
+    @InterceptorIgnore(tenantLine = "1", blockAttack = "1", illegalSql = "1")
+    IPage<PartsSalesOrderBean> appSalesList(Page page,
+                                            @Param("identity") String identity,
+                                            @Param("salesId") String salesId,
+                                            @Param("status") String status,
+                                            @Param("pushFlag") String pushFlag,
+                                            @Param("partsNumber") String partsNumber);
+
     /**
      * 带锁的查询
      * @param websitId
@@ -123,4 +130,8 @@ public interface MaterialMapper {
      */
     List<WebsitPartsSalesItem> querySalesPushFlagItem(String websitId, String salesId, String partsWebsitId,
                                                       String identity, String pushFlag, List<SalesItemRecordDTO> records);
+
+    List<PartsSalesOrderItemBean> selectItemBySalesOrderId(@Param("id") String id);
+
+    List<OldRefundManageRecordBean> queryOldRefundRecordById(@Param("id") String id);
 }

+ 132 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/controller/material/parts/SalesOrderController.java

@@ -0,0 +1,132 @@
+package com.gree.mall.miniapp.controller.material.parts;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean;
+import com.gree.mall.miniapp.constant.Constant;
+import com.gree.mall.miniapp.enums.material.BuyPeopleEnum;
+import com.gree.mall.miniapp.enums.material.PartsOrderStatusEnum;
+import com.gree.mall.miniapp.enums.material.PartsPushFlagEnum;
+import com.gree.mall.miniapp.exception.RemoteServiceException;
+import com.gree.mall.miniapp.helper.ResponseHelper;
+import com.gree.mall.miniapp.logic.material.parts.WebsitPartsSalesLogic;
+import com.gree.mall.miniapp.logic.material.parts.WebsitPartsSalesOrderLogic;
+import com.gree.mall.miniapp.plus.entity.AdminWebsit;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.integration.redis.util.RedisLockRegistry;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+
+@Slf4j
+@RestController
+@Api(value = "配件销售订单", tags ={"配件销售订单"} )
+@RequestMapping(value = "/app/worker/parts-sales", produces = "application/json; charset=utf-8")
+public class SalesOrderController {
+
+    @Resource
+    WebsitPartsSalesLogic websitPartsSalesLogic;
+    @Resource
+    WebsitPartsSalesOrderLogic websitPartsSalesOrderLogic;
+    @Resource
+    RedisLockRegistry redisLockRegistry;
+
+    @GetMapping("/exist/websit/list")
+    @ApiOperation(value = "查询师傅未转销售订单网点")
+    public ResponseHelper<List<AdminWebsit>> existWebsitList (
+            @ApiParam(value = "师傅身份证",required = true) @RequestParam String identity,
+            @ApiParam(value = "网点编号") @RequestParam(required = false) String websitId
+    ) throws RemoteServiceException {
+        return ResponseHelper.success(websitPartsSalesLogic.existWebsitList(identity, websitId));
+    }
+
+    @GetMapping("/list")
+    @ApiOperation(value = "销售订单列表")
+    public ResponseHelper<IPage<PartsSalesOrderBean>> appList(
+            @ApiParam(value = "师傅身份证", required = true) @RequestParam String identity,
+            @ApiParam(value = "销售订单号") @RequestParam(required = false) String salesId,
+            @ApiParam(value = "单据状态 SAVE-保存未提交 SUBMIT-已提交 PAYED-已支付 END-已完成 CANCEL-已取消") @RequestParam(required = false) PartsOrderStatusEnum status,
+            @ApiParam(value = "下推标志 SALES=销售 TRANS=转销售 END=完结") @RequestParam(required = false) PartsPushFlagEnum pushFlag,
+            @ApiParam(value = "配件编码") @RequestParam(required = false) String partsNumber,
+            @ApiParam(value = "页号",required = true) @RequestParam Integer pageNo,
+            @ApiParam(value = "页大小",required = true) @RequestParam Integer pageSize
+    ) throws RemoteServiceException {
+        return ResponseHelper.success(websitPartsSalesLogic.appList(identity, salesId, status, pushFlag, partsNumber, pageNo, pageSize));
+    }
+
+    @GetMapping("/detail")
+    @ApiOperation(value = "销售订单详情")
+    public ResponseHelper<IPage<PartsSalesOrderBean>> appDetail(
+            @ApiParam(value = "师傅身份证", required = true) @RequestParam String identity,
+            @ApiParam(value = "销售订单号", required = true) @RequestParam String salesId,
+            @ApiParam(value = "下推标志 SALES=销售 TRANS=转销售 END=完结") @RequestParam(required = false) String pushFlag
+    ) throws RemoteServiceException {
+        return ResponseHelper.success(websitPartsSalesLogic.appDetail(identity, salesId, pushFlag));
+    }
+
+
+    @PostMapping("/add")
+    @ApiOperation("配件销售单新增")
+    public ResponseHelper<PartsSalesOrderBean> add(
+            @RequestBody PartsSalesOrderBean partsSalesOrderBean
+    ) throws RemoteServiceException {
+        partsSalesOrderBean.setOrderSource("ONLINE");
+        partsSalesOrderBean.setBuyPeople(BuyPeopleEnum.WORKER.getKey());
+        partsSalesOrderBean.setIsApply(Boolean.FALSE);
+
+        websitPartsSalesOrderLogic.add(partsSalesOrderBean);
+        return ResponseHelper.success(partsSalesOrderBean);
+    }
+
+    @ApiOperation("配件销售单根据id获取")
+    @GetMapping("/loadSalesOrderById")
+    public ResponseHelper<PartsSalesOrderBean> loadSalesOrderById(
+            @RequestParam String id
+    ) throws RemoteServiceException {
+        return ResponseHelper.success(websitPartsSalesOrderLogic.loadSalesOrderById(id));
+    }
+
+    @ApiOperation("提交订单")
+    @GetMapping("/submit")
+    public ResponseHelper<PartsSalesOrderBean> submit(@ApiParam(value = "销售单id",required = true) @RequestParam String id) throws InterruptedException {
+        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.PARTS_SALES + id);
+        if (!obtain.tryLock(10, TimeUnit.SECONDS)) {
+            throw new RemoteServiceException("销售单冻结中");
+        }
+        try {
+            return ResponseHelper.success(websitPartsSalesOrderLogic.submit(id));
+        } catch(Exception e) {
+            log.error("【提交订单处理】失败",e);
+            throw e;
+        } finally {
+            obtain.unlock();
+        }
+    }
+    
+    @ApiOperation("师傅提货")
+	@GetMapping("/workerConfirmDelivery")
+	public ResponseHelper workerConfirmDelivery(
+			@ApiParam(value = "销售单号",required = true) @RequestParam String id
+			) throws Exception {
+        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.PARTS_SALES + id);
+        if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
+            throw new RemoteServiceException("销售单冻结中");
+        }
+        try {
+            websitPartsSalesOrderLogic.workerConfirmDelivery(id);
+        } catch(Exception e) {
+            log.error("【师傅提货处理】失败",e);
+            throw e;
+        } finally {
+            obtain.unlock();
+        }
+
+		return ResponseHelper.success();
+	}
+
+}

+ 28 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/enums/IsEnum.java

@@ -0,0 +1,28 @@
+package com.gree.mall.miniapp.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.baomidou.mybatisplus.annotation.IEnum;
+import com.fasterxml.jackson.annotation.JsonValue;
+import com.gree.mall.miniapp.enums.base.BaseEnum;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+public enum IsEnum implements BaseEnum,IEnum<Boolean> {
+    Y("true","是"),
+    N("false","否"),
+    ;
+
+    @EnumValue
+    @JsonValue
+    private final String key;
+    private final String remark;
+
+
+    @Override
+    public Boolean getValue() {
+        return Boolean.parseBoolean(key);
+    }
+}

+ 28 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/enums/StateEnum.java

@@ -0,0 +1,28 @@
+package com.gree.mall.miniapp.enums;
+
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+import com.gree.mall.miniapp.enums.base.BaseEnum;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+public enum StateEnum implements BaseEnum {
+    ON("ON","有效"),
+    OFF("OFF","无效");
+
+    @EnumValue
+    @JsonValue
+    private final String key;
+
+    private final String remark;
+
+    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
+    public static StateEnum create(String key) {
+        return BaseEnum.keyToEnum(StateEnum.class, key);
+    }
+}

+ 21 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/enums/material/NormTypeEnum.java

@@ -0,0 +1,21 @@
+package com.gree.mall.miniapp.enums.material;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.fasterxml.jackson.annotation.JsonValue;
+import com.gree.mall.miniapp.enums.base.BaseEnum;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+public enum NormTypeEnum implements BaseEnum {
+    M("M","物料收费"),
+    S("S","服务收费");
+
+    @EnumValue
+    @JsonValue
+    private final String key;
+
+    private final String remark;
+}

+ 175 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/logic/material/parts/WebsitPartsSalesLogic.java

@@ -0,0 +1,175 @@
+package com.gree.mall.miniapp.logic.material.parts;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean;
+import com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderItemBean;
+import com.gree.mall.miniapp.bean.user.CurrentCompanyWechat;
+import com.gree.mall.miniapp.commonmapper.MaterialMapper;
+import com.gree.mall.miniapp.enums.IsYesNoEnum;
+import com.gree.mall.miniapp.enums.base.BaseEnum;
+import com.gree.mall.miniapp.enums.material.PartsOrderStatusEnum;
+import com.gree.mall.miniapp.enums.material.PartsPushFlagEnum;
+import com.gree.mall.miniapp.logic.common.CommonLogic;
+import com.gree.mall.miniapp.plus.entity.AdminWebsit;
+import com.gree.mall.miniapp.plus.entity.WebsitPartsSales;
+import com.gree.mall.miniapp.plus.entity.WebsitPartsSalesItem;
+import com.gree.mall.miniapp.plus.entity.WebsitSalesPayOrder;
+import com.gree.mall.miniapp.plus.service.AdminWebsitService;
+import com.gree.mall.miniapp.plus.service.WebsitPartsSalesItemService;
+import com.gree.mall.miniapp.plus.service.WebsitPartsSalesService;
+import com.gree.mall.miniapp.plus.service.WebsitSalesPayOrderService;
+import io.jsonwebtoken.lang.Collections;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+
+@Service
+@Slf4j
+public class WebsitPartsSalesLogic {
+
+    @Resource
+    CommonLogic commonLogic;
+    @Resource
+    MaterialMapper materialMapper;
+    @Resource
+    WebsitPartsSalesService websitPartsSalesService;
+    @Resource
+    WebsitPartsSalesItemService websitPartsSalesItemService;
+    @Resource
+    AdminWebsitService adminWebsitService;
+    @Resource
+    WebsitSalesPayOrderService websitSalesPayOrderService;
+
+    public List<AdminWebsit> existWebsitList(String identity, String websitId) {
+        CurrentCompanyWechat wechat = commonLogic.getCurrentCompanyWechat();
+        List<WebsitPartsSales> partsSalesOrderList = websitPartsSalesService.lambdaQuery()
+                .eq(WebsitPartsSales::getCompanyWechatId, wechat.getCompanyWechatId())
+                .eq(WebsitPartsSales::getIdentity, identity)
+                .eq(StringUtils.isNotBlank(websitId), WebsitPartsSales::getWebsitId, websitId)
+                .eq(WebsitPartsSales::getPushFlag, PartsPushFlagEnum.SALES.getKey())
+                .groupBy(WebsitPartsSales::getWebsitId)
+                .list();
+        List<AdminWebsit> shopList = new ArrayList<>();
+        for (WebsitPartsSales partsSalesOrder : partsSalesOrderList) {
+            AdminWebsit shop = adminWebsitService.lambdaQuery()
+                    .eq(AdminWebsit::getCompanyWechatId, wechat.getCompanyWechatId())
+                    .eq(AdminWebsit::getWebsitId, partsSalesOrder.getWebsitId())
+                    .one();
+            shopList.add(shop);
+        }
+        return shopList;
+    }
+
+    public IPage<PartsSalesOrderBean> appList(String identity, String salesId, PartsOrderStatusEnum status, PartsPushFlagEnum pushFlag,
+                                              String partsNumber, Integer pageNo, Integer pageSize) {
+        IPage<PartsSalesOrderBean> page = materialMapper.appSalesList(new Page(pageNo, pageSize), identity, salesId, status.getKey(), pushFlag.getKey(), partsNumber);
+
+        List<PartsSalesOrderBean> partsSalesOrderBeanList = new ArrayList<>();
+        for (Object record : page.getRecords()) {
+            PartsSalesOrderBean salesOrderBean = new PartsSalesOrderBean();
+            BeanUtils.copyProperties(record, salesOrderBean, PartsSalesOrderBean.class);
+            List<WebsitPartsSalesItem> partsSalesOrderItems = websitPartsSalesItemService.lambdaQuery()
+                    .eq(WebsitPartsSalesItem::getSalesId, salesOrderBean.getId())
+                    .gt(pushFlag.getKey().equals(PartsPushFlagEnum.SALES.getKey()), WebsitPartsSalesItem::getQty, 0)
+                    .list();
+            List<PartsSalesOrderItemBean> itemList = new ArrayList<>();
+            if(!Collections.isEmpty(partsSalesOrderItems)) {
+                for(WebsitPartsSalesItem partsSalesOrderItem: partsSalesOrderItems) {
+                    PartsSalesOrderItemBean item = new PartsSalesOrderItemBean();
+                    BeanUtils.copyProperties(partsSalesOrderItem, item, PartsSalesOrderItemBean.class);
+                    itemList.add(item);
+                }
+            }
+            salesOrderBean.setItemList(itemList);
+            partsSalesOrderBeanList.add(salesOrderBean);
+        }
+        page.setRecords(partsSalesOrderBeanList);
+        return page;
+    }
+
+    public PartsSalesOrderBean appDetail(String identity, String salesId, String pushFlag) {
+        WebsitPartsSales partsSalesOrder = websitPartsSalesService.lambdaQuery()
+                .eq(WebsitPartsSales::getIdentity, identity)
+                .eq(WebsitPartsSales::getId, salesId)
+                .eq(StringUtils.isNotBlank(pushFlag), WebsitPartsSales::getPushFlag, pushFlag)
+                .one();
+        PartsSalesOrderBean salesOrderBean = new PartsSalesOrderBean();
+        BeanUtils.copyProperties(partsSalesOrder, salesOrderBean, PartsSalesOrderBean.class);
+        salesOrderBean.setBuyTypeName(partsSalesOrder.getOrderSource().equals("ONLINE") ? "在线订单" : "自建订单");
+//        salesOrderBean.setStateName(this.getStateName(partsSalesOrder.getState()));
+        salesOrderBean.setStateName(this.getStateName(partsSalesOrder.getStatus(), partsSalesOrder.getWorkerConfirmDate(), partsSalesOrder.getWebsitConfirmDate()));
+//        salesOrderBean.setPushFlagName(PartsPushFlagEnum.valueOf(pushFlag).getDesc());
+        salesOrderBean.setPushFlagName(StringUtils.isBlank(pushFlag) ? "" : BaseEnum.keyToEnumNotNull(PartsPushFlagEnum.class, pushFlag).getRemark());
+        //提货状态
+        if(!Objects.isNull(salesOrderBean.getWorkerConfirmDate()) && !Objects.isNull(salesOrderBean.getWebsitConfirmDate())) {
+            salesOrderBean.setPickupStateName("已提货");
+        }else if(!Objects.isNull(salesOrderBean.getWorkerConfirmDate())) {
+            salesOrderBean.setPickupStateName("师傅已提货");
+        }else if(!Objects.isNull(salesOrderBean.getWebsitConfirmDate())) {
+            salesOrderBean.setPickupStateName("网点已提货");
+        }else {
+            salesOrderBean.setPickupStateName("未提货");
+        }
+        List<WebsitPartsSalesItem> partsSalesOrderItems = websitPartsSalesItemService.lambdaQuery()
+                .eq(WebsitPartsSalesItem::getSalesId, salesOrderBean.getId())
+                .gt(StringUtils.isNotBlank(pushFlag)
+                        && pushFlag.equals(PartsPushFlagEnum.SALES.toString()), WebsitPartsSalesItem::getQty, 0)
+                .list();
+
+        List<PartsSalesOrderItemBean> itemList = new ArrayList<>();
+        if(!Collections.isEmpty(partsSalesOrderItems)) {
+            for(WebsitPartsSalesItem partsSalesOrderItem: partsSalesOrderItems) {
+                PartsSalesOrderItemBean item = new PartsSalesOrderItemBean();
+                BeanUtils.copyProperties(partsSalesOrderItem, item, PartsSalesOrderItemBean.class);
+                itemList.add(item);
+            }
+            salesOrderBean.setItemList(itemList);
+        }
+        List<WebsitSalesPayOrder> payList = websitSalesPayOrderService.lambdaQuery()
+                .eq(WebsitSalesPayOrder::getPayFlag, IsYesNoEnum.YES.getKey())
+                .eq(WebsitSalesPayOrder::getOrderId, salesOrderBean.getId())
+                .list();
+        salesOrderBean.setPayList(payList);
+        return salesOrderBean;
+    }
+
+    private String getStateName(String status, Date workerConfirmDate, Date shopConfirmDate) {
+        String stateName = "";
+        switch (status) {
+            case "SAVE":
+                stateName = "已保存";
+                break;
+            case "SUBMIT":
+                stateName = "已提交";
+                break;
+            case "PAYED":
+                if(!Objects.isNull(workerConfirmDate) && !Objects.isNull(shopConfirmDate)) {
+                    stateName = "已完成";
+                }else if(!Objects.isNull(workerConfirmDate)) {
+                    stateName = "师傅已提货";
+                }else if(!Objects.isNull(shopConfirmDate)) {
+                    stateName = "网点已提货";
+                }else {
+                    stateName = "已支付";
+                }
+                break;
+            case "END":
+                stateName = "已完成";
+                break;
+            case "CANCEL":
+                stateName = "已取消";
+                break;
+            default:
+        }
+        return stateName;
+    }
+}

+ 430 - 15
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/logic/material/parts/WebsitPartsSalesOrderLogic.java

@@ -1,28 +1,38 @@
 package com.gree.mall.miniapp.logic.material.parts;
 
 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 com.gree.mall.miniapp.bean.material.WebsitPartsSalesBean;
-import com.gree.mall.miniapp.bean.material.WebsitPartsSalesItemBean;
+import com.gree.mall.miniapp.bean.material.parts.OldRefundManageRecordBean;
+import com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean;
+import com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderItemBean;
 import com.gree.mall.miniapp.bean.material.stock.WebsitStockDTO;
 import com.gree.mall.miniapp.bean.material.stock.WorkerStockDTO;
+import com.gree.mall.miniapp.bean.user.CurrentCompanyWechat;
+import com.gree.mall.miniapp.commonmapper.MaterialMapper;
+import com.gree.mall.miniapp.enums.IsEnum;
+import com.gree.mall.miniapp.enums.IsYesNoEnum;
+import com.gree.mall.miniapp.enums.PayTypeEnum;
+import com.gree.mall.miniapp.enums.StateEnum;
 import com.gree.mall.miniapp.enums.material.*;
+import com.gree.mall.miniapp.exception.RemoteServiceException;
+import com.gree.mall.miniapp.logic.common.CommonLogic;
 import com.gree.mall.miniapp.logic.material.stock.MaterialGoodsStockLogic;
-import com.gree.mall.miniapp.plus.entity.WebsitPartsSales;
-import com.gree.mall.miniapp.plus.entity.WebsitPartsSalesItem;
-import com.gree.mall.miniapp.plus.entity.WebsitSalesPayOrder;
-import com.gree.mall.miniapp.plus.service.WebsitPartsSalesItemService;
-import com.gree.mall.miniapp.plus.service.WebsitPartsSalesService;
+import com.gree.mall.miniapp.plus.entity.*;
+import com.gree.mall.miniapp.plus.service.*;
 import io.jsonwebtoken.lang.Collections;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 @Service
 @Slf4j
@@ -34,6 +44,24 @@ public class WebsitPartsSalesOrderLogic {
     WebsitPartsSalesItemService websitPartsSalesItemService;
     @Resource
     MaterialGoodsStockLogic materialGoodsStockLogic;
+    @Resource
+    CommonLogic commonLogic;
+    @Resource
+    AdminWebsitService adminWebsitService;
+    @Resource
+    StorageService storageService;
+    @Resource
+    WebsitGoodsService websitGoodsService;
+    @Resource
+    WebsitPartsRefundConfigService websitPartsRefundConfigService;
+    @Resource
+    WebsitStockService websitStockService;
+    @Resource
+    MaterialConfigService materialConfigService;
+    @Resource
+    MaterialMapper materialMapper;
+    @Resource
+    WebsitSalesPayOrderService websitSalesPayOrderService;
 
     public void handlePaySuccessMethod(WebsitSalesPayOrder order) throws Exception {
         // 更新配件销售单状态为已支付
@@ -57,9 +85,9 @@ public class WebsitPartsSalesOrderLogic {
                     .list();
 
             if (!partsSalesOrder.getIsApply()) {
-                WebsitPartsSalesBean partsSalesOrderBean = new WebsitPartsSalesBean();
+                PartsSalesOrderBean partsSalesOrderBean = new PartsSalesOrderBean();
                 BeanUtils.copyProperties(partsSalesOrder, partsSalesOrderBean);
-                List<WebsitPartsSalesItemBean> partsSalesOrderItemBeanList = BeanUtil.copyToList(partsSalesOrderItems, WebsitPartsSalesItemBean.class);
+                List<PartsSalesOrderItemBean> partsSalesOrderItemBeanList = BeanUtil.copyToList(partsSalesOrderItems, PartsSalesOrderItemBean.class);
 
                 partsSalesOrderBean.setItemList(partsSalesOrderItemBeanList);
 
@@ -70,7 +98,7 @@ public class WebsitPartsSalesOrderLogic {
         }
     }
 
-    private void handleForwardShopAndWorkerStock(WebsitPartsSalesBean partsSalesOrderBean) throws Exception {
+    private void handleForwardShopAndWorkerStock(PartsSalesOrderBean partsSalesOrderBean) throws Exception {
         // 扣减网点库存
         List<WebsitStockDTO> websitStockDTOList = this.getWebsitStock(partsSalesOrderBean, DirectFlagEnum.SUB);
         materialGoodsStockLogic.handleWebsitStock(websitStockDTOList);
@@ -86,7 +114,7 @@ public class WebsitPartsSalesOrderLogic {
         }
     }
 
-    public List<WebsitStockDTO> getWebsitStock(WebsitPartsSalesBean partsSalesOrderBean, DirectFlagEnum directFlag){
+    public List<WebsitStockDTO> getWebsitStock(PartsSalesOrderBean partsSalesOrderBean, DirectFlagEnum directFlag){
         if(Collections.isEmpty(partsSalesOrderBean.getItemList())) {
             return null;
         }
@@ -119,7 +147,7 @@ public class WebsitPartsSalesOrderLogic {
         return websitStockDTOList;
     }
 
-    public List<WorkerStockDTO> getWorkerStock(WebsitPartsSalesBean partsSalesOrderBean, String refType, String partsAttr1,
+    public List<WorkerStockDTO> getWorkerStock(PartsSalesOrderBean partsSalesOrderBean, String refType, String partsAttr1,
                                                String partsAttr2){
         if(Collections.isEmpty(partsSalesOrderBean.getItemList())) {
             return null;
@@ -180,4 +208,391 @@ public class WebsitPartsSalesOrderLogic {
         }
         return workerStockDTOList;
     }
+
+    @Transactional
+    public void add(com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean partsSalesOrderBean) {
+        CurrentCompanyWechat wechat = commonLogic.getCurrentCompanyWechat();
+        partsSalesOrderBean.setCompanyWechatId(wechat.getCompanyWechatId())
+                .setCompanyWechatName(wechat.getCompanyName());
+        //一系列校验
+        Map<String, Object> validateMap = this.validate(partsSalesOrderBean);
+        if(validateMap.containsKey("isSuccess") && !Boolean.parseBoolean(validateMap.get("isSuccess").toString())) {
+            throw new RemoteServiceException(validateMap.get("msg").toString());
+        }
+        //获取登录人昵称
+        DateTime curDate = DateUtil.date();
+
+        if (Objects.isNull(partsSalesOrderBean.getPayType())) {
+            // 默认通联
+            partsSalesOrderBean.setPayType(PayTypeEnum.ALLINPAY.getKey());
+        }
+        List<com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderItemBean> itemList = partsSalesOrderBean.getItemList();
+        BigDecimal totalPrice = BigDecimal.ZERO;
+
+        if (CollectionUtil.isEmpty(itemList)) {
+            throw new RemoteServiceException("请选择配件");
+        }
+
+        for(WebsitPartsSalesItem partsSalesOrderItem : itemList) {
+            partsSalesOrderItem.setTotalAmount(partsSalesOrderItem.getSalesPrice().multiply(partsSalesOrderItem.getQty())
+                    .setScale(2, BigDecimal.ROUND_HALF_UP));
+            totalPrice = totalPrice.add(partsSalesOrderItem.getTotalAmount());
+        }
+
+        // 记录总金额
+        partsSalesOrderBean.setTotalAmount(totalPrice);
+        partsSalesOrderBean.setStatus(PartsOrderStatusEnum.SAVE.getKey());
+        // 生成订单号
+        String sheetId = commonLogic.generateMaterialNo(wechat.getCompanyWechatId(), "PJ", PartsRefTypeEnum.SALES.getKey(), 13);
+        partsSalesOrderBean.setId(sheetId);
+        websitPartsSalesService.save(partsSalesOrderBean);
+
+        // 保存销售单明细
+        List<WebsitPartsSalesItem> partsSalesOrderItems = this.createSalesOrderItem(partsSalesOrderBean, itemList);
+        websitPartsSalesItemService.saveBatch(partsSalesOrderItems);
+    }
+
+    private Map<String, Object> validate(com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean partsSalesOrderBean) {
+        Map<String, Object> result = new HashMap<>();
+        result.put("isSuccess" , Boolean.TRUE);
+
+        if(StringUtils.isBlank(partsSalesOrderBean.getWebsitId())) {
+            result.put("isSuccess", Boolean.FALSE);
+            result.put("msg", "新增配件销售单失败,没有网点");
+            return result;
+        }
+
+        if (StringUtils.isBlank(partsSalesOrderBean.getBuyPeople())) {
+            result.put("isSuccess", Boolean.FALSE);
+            result.put("msg", "请选择销售类型");
+            return result;
+        }
+
+        if (BuyPeopleEnum.WORKER.getKey().equals(partsSalesOrderBean.getBuyPeople())) {
+            if(StringUtils.isBlank(partsSalesOrderBean.getIdentity())) {
+                result.put("isSuccess", Boolean.FALSE);
+                result.put("msg", "新增配件销售单失败,服务人员身份证不能为空,请选择服务人员");
+                return result;
+            }
+        }
+
+        //获取申请类别
+        if(StringUtils.isBlank(partsSalesOrderBean.getApplyCategory())) {
+            result.put("isSuccess", Boolean.FALSE);
+            result.put("msg", "新增配件销售单失败,请选择申请类别");
+            return result;
+        }
+
+        // 获取对应网点
+        AdminWebsit websit = adminWebsitService.getById(partsSalesOrderBean.getWebsitId());
+        if (Objects.isNull(websit) || StringUtils.isBlank(websit.getPartsWebsitId())) {
+            result.put("isSuccess", Boolean.FALSE);
+            result.put("msg", "新增配件销售单失败,没有找到该网点" + partsSalesOrderBean.getWebsitId());
+            return result;
+        }
+        partsSalesOrderBean.setWebsitName(websit.getName());
+        partsSalesOrderBean.setPartsWebsitId(websit.getPartsWebsitId());
+
+        if (StringUtils.isBlank(partsSalesOrderBean.getStorageId())) {
+            final Storage storage = storageService.lambdaQuery()
+                    .eq(Storage::getCompanyWechatId, partsSalesOrderBean.getCompanyWechatId())
+                    .eq(Storage::getWebsitId, partsSalesOrderBean.getWebsitId())
+                    .eq(Storage::getIsDefault, IsEnum.Y.getValue())
+                    .one();
+            partsSalesOrderBean.setStorageId(storage.getStorageId())
+                    .setStorageName(storage.getStorageName());
+        }
+
+        if (Objects.isNull(partsSalesOrderBean.getApplyType())) {
+            result.put("isSuccess", Boolean.FALSE);
+            result.put("msg", "新增配件销售单失败,没有申请类型");
+            return result;
+        }
+        if (Objects.isNull(partsSalesOrderBean.getDeliveryType())) {
+            result.put("isSuccess", Boolean.FALSE);
+            result.put("msg", "新增配件销售单失败,请先选择发货方式");
+            return result;
+        }
+        if (Collections.isEmpty(partsSalesOrderBean.getItemList())) {
+            result.put("isSuccess", Boolean.FALSE);
+            result.put("msg", "新增配件销售单失败,没有配件明细信息");
+            return result;
+        }
+
+        // 快递必填详细地址
+        if (partsSalesOrderBean.getDeliveryType().equals(DeliveryTypeEnum.EXPRESS.getValue())
+                && StringUtils.isBlank(partsSalesOrderBean.getAddr())) {
+            result.put("isSuccess", Boolean.FALSE);
+            result.put("msg", "新增配件销售单失败,请填写详细地址");
+            return result;
+        }
+        //校验配件明细列表
+        LinkedHashSet<String> partsNumbers = new LinkedHashSet<>();
+        for(WebsitPartsSalesItem item : partsSalesOrderBean.getItemList()) {
+            if(StringUtils.isEmpty(item.getPartsNumber())) {
+                result.put("isSuccess", Boolean.FALSE);
+                result.put("msg", "新增配件销售单失败,配件编码不能为空");
+                return result;
+            }
+            if(Objects.isNull(item.getQty()) || Integer.parseInt(item.getQty().toString()) <= 0) {
+                result.put("isSuccess", Boolean.FALSE);
+                result.put("msg", "新增配件销售单失败,配件编码"+item.getPartsNumber() + "数量不能小于或等于0");
+                return result;
+            }
+            item.setCompanyWechatId(partsSalesOrderBean.getCompanyWechatId())
+                    .setWebsitId(partsSalesOrderBean.getWebsitId())
+                    .setPartsWebsitId(partsSalesOrderBean.getPartsWebsitId());
+
+            partsNumbers.add(item.getPartsNumber());
+        }
+        //根据配件编码查询对应的配件列表
+        final List<WebsitGoods> partsList = websitGoodsService.lambdaQuery()
+                .eq(WebsitGoods::getGoodsType, WebsitGoodsTypeEnum.P.toString())
+                .eq(WebsitGoods::getNormType, NormTypeEnum.M.getKey())
+                .in(WebsitGoods::getGoodsCode, partsNumbers)
+                .eq(WebsitGoods::getStatus, StateEnum.ON.getKey())
+                .list();
+
+        if(Collections.isEmpty(partsList)) {
+            result.put("isSuccess", Boolean.FALSE);
+            result.put("msg", "新增配件销售单失败,系统找不到该配件配件编码: " + String.join(",", partsNumbers));
+            return result;
+        }
+        final Map<String, WebsitGoods> partsMap = partsList.stream().collect(Collectors.toMap(WebsitGoods::getGoodsCode, Function.identity()));
+        //检验每个配件明细是否在数据库里查到
+        LinkedHashSet<String> notExsistisPartsNumbers = new LinkedHashSet<>();
+        for(String partsNumber : partsNumbers) {
+            if( !partsMap.containsKey(partsNumber) || Objects.isNull(partsMap.get(partsNumber))) {
+                notExsistisPartsNumbers.add(partsNumber);
+            }
+        }
+        if(!Collections.isEmpty(notExsistisPartsNumbers)) {
+            result.put("isSuccess", Boolean.FALSE);
+            result.put("msg", "新增配件销售单失败,以下配件配件编码不存在: "+String.join(",", notExsistisPartsNumbers));
+            return result;
+        }
+        List<com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderItemBean> values = new ArrayList<>(partsSalesOrderBean.getItemList().stream()
+                .collect(Collectors.toMap(com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderItemBean::getPartsNumber, Function.identity(), (key1, key2) -> {
+                    key1.setQty(key1.getQty().add(key2.getQty()));
+                    return key1;
+                })).values());
+        partsSalesOrderBean.getItemList().clear();
+        partsSalesOrderBean.setItemList(values);
+
+        if(CollectionUtil.isNotEmpty(partsSalesOrderBean.getItemList())) {
+            WebsitPartsRefundConfig partsConfig = websitPartsRefundConfigService.lambdaQuery()
+                    .eq(WebsitPartsRefundConfig::getCompanyWechatId, partsSalesOrderBean.getCompanyWechatId())
+                    .eq(WebsitPartsRefundConfig::getIsDefault, Boolean.TRUE)
+                    .one();
+
+            //检查是否有可用库存
+            final List<WebsitStock> partsWebsitStockList = websitStockService.lambdaQuery()
+                    .in(WebsitStock::getGoodsId, partsNumbers)
+                    .eq(WebsitStock::getCompanyWechatId, partsSalesOrderBean.getCompanyWechatId())
+                    .eq(WebsitStock::getWebsitId, partsSalesOrderBean.getWebsitId())
+                    .list();
+
+            for (WebsitPartsSalesItem item : partsSalesOrderBean.getItemList()) {
+                if (!partsMap.containsKey(item.getPartsNumber()) || Objects.isNull(partsMap.get(item.getPartsNumber()))) {
+                    continue;
+                }
+                if (StringUtils.isEmpty(item.getPartsWebsitId())) {
+                    result.put("isSuccess", Boolean.FALSE);
+                    result.put("msg", "配件网点编号不能为空");
+                    break;
+                }
+                if (StringUtils.isEmpty(item.getPartsNumber())) {
+                    result.put("isSuccess", Boolean.FALSE);
+                    result.put("msg", "配件编号不能为空");
+                    break;
+                }
+                // 非申请单检验配件网点库存是否大于0
+                if (partsSalesOrderBean.getIsApply()) {
+                    if (partsWebsitStockList.stream().noneMatch(o ->
+                            item.getPartsWebsitId().equals(o.getPartsWebsitId())
+                                    && item.getPartsNumber().equals(o.getGoodsId())
+                    )) {
+                        result.put("isSuccess", Boolean.FALSE);
+                        result.put("msg", String.join("配件编号:", item.getPartsNumber(), ",在网点编号:", partsSalesOrderBean.getWebsitId(), "没有库存"));
+                        break;
+                    }
+                    List<WebsitStock> stockList = partsWebsitStockList.stream().filter(o ->
+                            item.getPartsWebsitId().equals(o.getPartsWebsitId())
+                                    && item.getPartsNumber().equals(o.getGoodsId())
+                    ).collect(Collectors.toList());
+                    WebsitGoods parts = partsMap.get(item.getPartsNumber());
+                    item.setWebsitId(partsSalesOrderBean.getWebsitId());
+                    item.setPartsId(parts.getGoodsId());
+                    item.setMaterialGroupName(parts.getMaterialGroupName());
+                    item.setGoodsStockUnit(parts.getGoodsStockUnit());
+                    item.setPartsWebsitId(stockList.get(0).getPartsWebsitId());
+                    item.setPartsNumber(stockList.get(0).getGoodsId());
+                    item.setMarketPrice(parts.getMarketPrice());
+                    item.setExamineQty(item.getQty());
+                    item.setSecondPrice(parts.getSecondPrice());
+                    computeSalesPrice(partsConfig, parts, item, result);
+                } else {
+                    WebsitGoods parts = partsMap.get(item.getPartsNumber());
+                    item.setWebsitId(partsSalesOrderBean.getWebsitId());
+                    item.setPartsId(parts.getGoodsId());
+                    item.setMaterialGroupName(parts.getMaterialGroupName());
+                    item.setGoodsStockUnit(parts.getGoodsStockUnit());
+                    item.setPartsWebsitId(partsSalesOrderBean.getPartsWebsitId());
+                    item.setPartsNumber(parts.getGoodsId());
+                    item.setMarketPrice(parts.getMarketPrice());
+                    item.setExamineQty(item.getQty());
+                    item.setSecondPrice(parts.getSecondPrice());
+                    computeSalesPrice(partsConfig, parts, item, result);
+                }
+            }
+        }
+        return result;
+    }
+
+    private void computeSalesPrice(WebsitPartsRefundConfig partsConfig, WebsitGoods parts, WebsitPartsSalesItem item, Map<String, Object> result) {
+        final MaterialConfig materialConfig = materialConfigService.lambdaQuery()
+                .eq(MaterialConfig::getCompanyWechatId, partsConfig.getCompanyWechatId())
+                .one();
+        switch (Optional.ofNullable(parts.getPartType()).orElse("")) {
+            case "":
+                result.put("isSuccess", Boolean.FALSE);
+                result.put("msg", "配件类型不能为空");
+                break;
+            case "空调":
+                item.setSalesPrice(item.getMarketPrice().multiply(materialConfig.getPriceRate1()).setScale(2, BigDecimal.ROUND_HALF_UP));
+                break;
+            case "冰箱":
+                item.setSalesPrice(item.getMarketPrice().multiply(materialConfig.getPriceRate2()).setScale(2, BigDecimal.ROUND_HALF_UP));
+                break;
+            case "生活电器":
+                item.setSalesPrice(item.getMarketPrice().multiply(materialConfig.getPriceRate3()).setScale(2, BigDecimal.ROUND_HALF_UP));
+                break;
+            default:
+                item.setSalesPrice(item.getMarketPrice().multiply(new BigDecimal("1.2")).setScale(2, BigDecimal.ROUND_HALF_UP));
+                break;
+        }
+    }
+
+    private List<WebsitPartsSalesItem> createSalesOrderItem(com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean partsSalesOrderBean, List<com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderItemBean> itemList) {
+        List<WebsitPartsSalesItem> partsSalesOrderItems = new ArrayList<>();
+        for(com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderItemBean partsSalesOrderItemBean : itemList) {
+            WebsitPartsSalesItem partsSalesOrderItem = new WebsitPartsSalesItem();
+            BeanUtils.copyProperties(partsSalesOrderItemBean, partsSalesOrderItem);
+            partsSalesOrderItem.setSalesId(partsSalesOrderBean.getId())
+                    .setWebsitId(partsSalesOrderBean.getWebsitId())
+                    .setIdentity(partsSalesOrderBean.getIdentity());
+            partsSalesOrderItems.add(partsSalesOrderItem);
+        }
+        return partsSalesOrderItems;
+    }
+
+    public com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean loadSalesOrderById(String id) {
+        WebsitPartsSales partsSalesOrder = websitPartsSalesService.getById(id);
+
+        if(Objects.isNull(partsSalesOrder)) {
+            throw new RemoteServiceException("获取配件销售单失败") ;
+        }
+
+        com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean partsSalesOrderBean = new com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean();
+        BeanUtils.copyProperties(partsSalesOrder, partsSalesOrderBean, PartsSalesOrderBean.class);
+        List<com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderItemBean> itemList = materialMapper.selectItemBySalesOrderId(partsSalesOrderBean.getId());
+        partsSalesOrderBean.setItemList(Collections.isEmpty(itemList) ? null : itemList);
+        List<WebsitSalesPayOrder> payList = websitSalesPayOrderService.lambdaQuery()
+                .eq(WebsitSalesPayOrder::getCompanyWechatId, partsSalesOrder.getCompanyWechatId())
+                .eq(WebsitSalesPayOrder::getPayFlag, IsYesNoEnum.YES.getKey())
+                .eq(WebsitSalesPayOrder::getOrderId, partsSalesOrderBean.getId())
+                .list();
+        List<WebsitSalesPayOrder> allPayList = websitSalesPayOrderService.lambdaQuery()
+                .eq(WebsitSalesPayOrder::getCompanyWechatId, partsSalesOrder.getCompanyWechatId())
+                .eq(WebsitSalesPayOrder::getOrderId, partsSalesOrderBean.getId())
+                .list();
+
+        partsSalesOrderBean.setPayList(payList);
+        partsSalesOrderBean.setAllPayList(allPayList);
+
+        // 配件使用记录
+        List<OldRefundManageRecordBean> oldRefundManageRecordBeans = materialMapper.queryOldRefundRecordById(partsSalesOrder.getId());
+        partsSalesOrderBean.setOldRefundManageRecordBeanList(oldRefundManageRecordBeans);
+
+
+        return partsSalesOrderBean;
+    }
+
+    public Object submit(String id) {
+        CurrentCompanyWechat wechat = commonLogic.getCurrentCompanyWechat();
+        com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean partsSalesOrderBean = loadSalesOrderById(id);
+        if(Objects.isNull(partsSalesOrderBean)) {
+            throw new RemoteServiceException("配件单提交失败,销售单信息不能为空") ;
+        }
+        if(!partsSalesOrderBean.getStatus().equals(PartsOrderStatusEnum.SAVE.getKey())) {
+            throw new RemoteServiceException("该配件销售单已提交,不能重复提交");
+        }
+        // 先保存一下页面信息,再提交状态
+
+        // 更新状态为1-已提交
+        partsSalesOrderBean.setStatus(PartsOrderStatusEnum.SUBMIT.getKey());
+        partsSalesOrderBean.setSubmitBy(wechat.getUser().getNickName());
+        partsSalesOrderBean.setSubmitTime(DateUtil.date());
+
+        websitPartsSalesService.saveOrUpdate(partsSalesOrderBean);
+        return loadSalesOrderById(id);
+    }
+
+    /**
+     * 师傅app端确认提货
+     * @param id
+     * @throws RemoteServiceException
+     */
+    @Transactional
+    public void workerConfirmDelivery(String id) throws Exception {
+        com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean partsSalesOrderBean = loadSalesOrderById(id);
+        if(Objects.isNull(partsSalesOrderBean)) {
+            throw new RemoteServiceException("配件单提交失败,单号=" + id) ;
+        }
+        if(!PartsOrderStatusEnum.PAYED.getKey().equals(partsSalesOrderBean.getStatus())) {
+            throw new RemoteServiceException("非已支付状态,不能提货");
+        }
+        DateTime curDate = DateUtil.date();
+        partsSalesOrderBean.setWorkerConfirmDate(curDate);
+        if(Objects.nonNull(partsSalesOrderBean.getWebsitConfirmDate())) {
+			 /* 网点确认时间不为空,说明网点已确认,则除了更新师傅确认时间之外,
+			    还需要更新订单状态为已完成,流程结束时间,更新审核人,审核时间和pushFlag标志位;
+			    同时还需要增加师傅库存.
+			  */
+            partsSalesOrderBean.setStatus(PartsOrderStatusEnum.END.getKey());
+            partsSalesOrderBean.setEndTime(curDate);
+            partsSalesOrderBean.setExamineBy(partsSalesOrderBean.getWorkerName());
+            partsSalesOrderBean.setExamineTime(curDate);
+            partsSalesOrderBean.setPushFlag(PartsPushFlagEnum.SALES.toString());
+            partsSalesOrderBean.setPayFlag(PartsPayFlagEnum.PAY_TAKE.getKey());
+            // 师傅在途库存转移到新件库存
+            List<WorkerStockDTO> workerWayStockDTOList = this.getWorkerStock(partsSalesOrderBean, PartsRefTypeEnum.SALES.toString(),
+                    PartsAttrEnum.WAY.getKey(), PartsAttrEnum.NEW.getKey());
+            materialGoodsStockLogic.handleWorkerStock(workerWayStockDTOList);
+
+            this.updateSalesItem(partsSalesOrderBean);
+        }
+        websitPartsSalesService.updateById(partsSalesOrderBean);
+    }
+
+    /**
+     * 更新销售明细的信息
+     * @param partsSalesOrderBean
+     */
+    private void updateSalesItem(PartsSalesOrderBean partsSalesOrderBean) {
+        if(CollectionUtil.isNotEmpty(partsSalesOrderBean.getItemList())) {
+            List<WebsitPartsSalesItem> itemList = new ArrayList<>();
+            for(PartsSalesOrderItemBean itemBean : partsSalesOrderBean.getItemList()) {
+                itemBean.setPushFlag(partsSalesOrderBean.getPushFlag());
+                itemBean.setExamineTime(partsSalesOrderBean.getExamineTime());
+                if (partsSalesOrderBean.getPayType().equals(PayTypeEnum.CASH.getKey())) {
+                    itemBean.setRefundAmountMode(PayTypeEnum.CASH.getKey());
+                } else {
+                    itemBean.setRefundAmountMode(PayTypeEnum.WECHAT.getKey());
+                }
+                itemList.add(itemBean);
+            }
+            websitPartsSalesItemService.saveOrUpdateBatch(itemList);
+        }
+    }
 }

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

@@ -295,4 +295,99 @@
             examine_time
         FOR UPDATE
     </select>
+
+    <select id="appSalesList" resultType="com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean">
+        SELECT
+        a.*,
+        CASE a.order_source WHEN 'SELF' THEN '自建订单'
+        WHEN 'ONLINE' THEN '在线订单'
+        ELSE '' END AS buyTypeName,
+        CASE a.status WHEN 'SAVE' THEN '保存未提交'
+        WHEN 'SUBMIT' THEN '已提交'
+        <!--                       WHEN '2' THEN '已支付' -->
+        WHEN 'PAYED' THEN
+        <!--                       WHEN '3' THEN '已提货' -->
+        (case when a.worker_confirm_date is not null and a.websit_confirm_date is not null then '已提货'
+        when a.worker_confirm_date is not null then '师傅已提货'
+        when a.websit_confirm_date is not null then '网点已提货' else '已支付' end)
+        WHEN 'END' THEN '已完成'
+        WHEN 'CANCEL' THEN '已取消'
+        ELSE '' END AS stateName,
+        CASE a.pushFlag WHEN 'SALES' THEN '销售'
+        WHEN 'TRANS' THEN '转销售'
+        WHEN 'END' THEN '完结'
+        ELSE '' END AS pushFlagName
+        FROM
+            websit_parts_sales a, websit_parts_sales_item b
+        WHERE
+            a.id = b.sales_id
+        AND a.del = 0
+        AND a.identity = #{identity}
+        <if test="salesId != null and salesId != ''">
+            AND a.id = #{salesId}
+        </if>
+        <if test="status != null and status != ''">
+            <!--             	and 1 = 0 -->
+            <if test="status == 'SAVE'.toString() or status == 'SUBMIT'.toString() or status == 'END'.toString() or status == 'CANCEL'.toString()">
+                AND a.status = #{state}
+            </if>
+            <if test="state == 'PAYED'.toString()">
+                AND a.status = 'PAYED' AND (a.worker_confirm_date is null and a.websit_confirm_date is null)
+            </if>
+        </if>
+
+        <if test="pushFlag != null and pushFlag != ''">
+            AND a.pushFlag = #{pushFlag}
+            AND b.qty > 0
+        </if>
+        <if test="partsNumber != null and partsNumber != ''">
+            AND b.parts_number = #{partsNumber}
+        </if>
+        GROUP BY
+        a.identity, a.id, a.create_time
+        ORDER BY
+        a.create_time DESC
+    </select>
+    <select id="selectItemBySalesOrderId"
+            resultType="com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderItemBean">
+        select
+            a.id ,
+            a.identity ,
+            a.websit_id,
+            a.parts_websit_id,
+            a.parts_id,
+            a.parts_number,
+            a.parts_name,
+            a.material_group_name,
+            a.goods_stock_unit,
+            a.sales_id,
+            a.sales_price,
+            a.market_price,
+            a.second_price,
+            IF(d.status = 'END', a.examine_qty, a.qty) AS qty,
+            a.examine_qty,
+            a.new_refund_qty,
+            a.old_refund_qty ,
+            a.total_amount,
+            a.push_flag ,
+            a.create_by ,
+            a.create_time,
+            a.update_by,
+            a.update_time,
+            IFNULL(c.qty, 0) stockQty
+        FROM websit_parts_sales_item a JOIN websit_goods b ON a.parts_id = b.goods_id
+                                       LEFT JOIN websit_stock c ON a.websit_id = c.websit_id AND a.parts_number = c.goods_id AND a.parts_websit_id = c.parts_websit_id
+                                       JOIN websit_parts_sales d ON a.sales_id = d.id
+        WHERE a.sales_id = #{id}
+    </select>
+
+    <select id="queryOldRefundRecordById"
+            resultType="com.gree.mall.miniapp.bean.material.parts.OldRefundManageRecordBean">
+        SELECT
+            a.*
+        FROM
+            websit_parts_old_refund_manage_record a
+        WHERE
+            sales_id = #{id}
+    </select>
 </mapper>

+ 75 - 7
mall-server-api/src/main/java/com/gree/mall/manager/logic/material/manage/WebsitPartsSalesLogic.java

@@ -2,11 +2,11 @@ package com.gree.mall.manager.logic.material.manage;
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.date.DateUtil;
+import com.gree.mall.manager.bean.material.stock.WorkerStockDTO;
 import com.gree.mall.manager.commonmapper.MaterialMapper;
-import com.gree.mall.manager.enums.material.PartsOrderFlagEnum;
-import com.gree.mall.manager.enums.material.PartsPushFlagEnum;
-import com.gree.mall.manager.enums.material.PartsRefTypeEnum;
+import com.gree.mall.manager.enums.material.*;
 import com.gree.mall.manager.logic.common.CommonLogic;
+import com.gree.mall.manager.logic.material.stock.MaterialGoodsStockLogic;
 import com.gree.mall.manager.plus.entity.WebsitPartsChangeSales;
 import com.gree.mall.manager.plus.entity.WebsitPartsChangeSalesItem;
 import com.gree.mall.manager.plus.entity.WebsitPartsSales;
@@ -15,6 +15,7 @@ import com.gree.mall.manager.plus.service.WebsitPartsChangeSalesItemService;
 import com.gree.mall.manager.plus.service.WebsitPartsSalesItemService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -30,8 +31,9 @@ public class WebsitPartsSalesLogic {
     private final MaterialMapper materialMapper;
     private final WebsitPartsSalesItemService websitPartsSalesItemService;
     private final WebsitPartsChangeSalesItemService websitPartsChangeSalesItemService;
+    private final MaterialGoodsStockLogic materialGoodsStockLogic;
 
-    public void updatePartsSalesOrder(WebsitPartsSales salesOrder) {
+    public void updatePartsSalesOrder(WebsitPartsSales salesOrder) throws Exception {
         String sheetId = commonLogic.generateMaterialNo(salesOrder.getCompanyWechatId(), "ZX", PartsRefTypeEnum.CHANGE_SALES.getKey(), 13);
 
         List<WebsitPartsSalesItem> partsSalesOrderItemList = websitPartsSalesItemService.lambdaQuery()
@@ -103,8 +105,74 @@ public class WebsitPartsSalesLogic {
         websitPartsChangeSalesItemService.saveBatch(partsChangeSalesItemList);
 
         // 师傅新件库存减 临占新件库存加
-//        List<WorkerStockDTO> workerStockDTOList = this.createWorkerStockDTO(partsChangeSales, partsChangeSalesItemList, PartsRefTypeEnum.CHANGE_SALES.toString(),
-//                PartsStockPartsAttrEnum.NEW.toString(), PartsStockPartsAttrEnum.TEMP_NEW.toString());
-//        partsStockLogic.handleWorkerStock(workerStockDTOList);
+        List<WorkerStockDTO> workerStockDTOList = this.createWorkerStockDTO(partsChangeSales, partsChangeSalesItemList, PartsRefTypeEnum.CHANGE_SALES.toString(),
+                PartsAttrEnum.NEW.getKey(), PartsAttrEnum.TEMP_NEW.getKey());
+        materialGoodsStockLogic.handleWorkerStock(workerStockDTOList);
+    }
+
+    private List<WorkerStockDTO> createWorkerStockDTO(WebsitPartsChangeSales partsChangeSales,
+                                                      List<WebsitPartsChangeSalesItem> partsChangeSalesItemList,
+                                                      String refType, String partsAttr1,
+                                                      String partsAttr2) {
+        List<WorkerStockDTO> workerStockDTOList = new ArrayList<>();
+        if (StringUtils.isNotBlank(partsAttr1)) {
+            for (WebsitPartsChangeSalesItem partsChangeSalesItem : partsChangeSalesItemList) {
+                WorkerStockDTO workerStockDTO = new WorkerStockDTO();
+                workerStockDTO.setCompanyWechatId(partsChangeSales.getCompanyWechatId());
+                workerStockDTO.setCompanyWechatName(partsChangeSales.getCompanyWechatName());
+                workerStockDTO.setIdentity(partsChangeSales.getIdentity());
+                workerStockDTO.setWorkerId(partsChangeSales.getWorkerId());
+                workerStockDTO.setWorkerName(partsChangeSales.getWorkerName());
+                workerStockDTO.setWebsitId(partsChangeSales.getWebsitId());
+                workerStockDTO.setWebsitName(partsChangeSales.getWebsitName());
+                workerStockDTO.setPartsWebsitId(partsChangeSales.getPartsWebsitId());
+                workerStockDTO.setSdate(DateUtil.date());
+                workerStockDTO.setGoodsId(partsChangeSalesItem.getPartsNumber());
+                workerStockDTO.setGoodsName(partsChangeSalesItem.getPartsName());
+                workerStockDTO.setMaterialGroupName(partsChangeSalesItem.getMaterialGroupName());
+                workerStockDTO.setGoodsStockUnit(partsChangeSalesItem.getGoodsStockUnit());
+                workerStockDTO.setPrice(partsChangeSalesItem.getSalesPrice());
+                workerStockDTO.setRef(partsChangeSales.getChangeSalesNo());
+                workerStockDTO.setRefType(refType);
+                workerStockDTO.setPartsAttr(partsAttr1);
+                workerStockDTO.setChangeQty(partsChangeSalesItem.getQty());
+                workerStockDTO.setDirectFlag(DirectFlagEnum.SUB.getKey());
+                workerStockDTO.setRemark("");
+                workerStockDTO.setOperateBy("自动处理");
+                workerStockDTO.setOperateTime(DateUtil.date());
+
+                workerStockDTOList.add(workerStockDTO);
+            }
+        }
+        if (StringUtils.isNotBlank(partsAttr2)) {
+            for (WebsitPartsChangeSalesItem partsChangeSalesItem : partsChangeSalesItemList) {
+                WorkerStockDTO workerStockDTO = new WorkerStockDTO();
+                workerStockDTO.setCompanyWechatId(partsChangeSales.getCompanyWechatId());
+                workerStockDTO.setCompanyWechatName(partsChangeSales.getCompanyWechatName());
+                workerStockDTO.setIdentity(partsChangeSales.getIdentity());
+                workerStockDTO.setWorkerId(partsChangeSales.getWorkerId());
+                workerStockDTO.setWorkerName(partsChangeSales.getWorkerName());
+                workerStockDTO.setWebsitId(partsChangeSales.getWebsitId());
+                workerStockDTO.setWebsitName(partsChangeSales.getWebsitName());
+                workerStockDTO.setPartsWebsitId(partsChangeSales.getPartsWebsitId());
+                workerStockDTO.setSdate(DateUtil.date());
+                workerStockDTO.setGoodsId(partsChangeSalesItem.getPartsNumber());
+                workerStockDTO.setGoodsName(partsChangeSalesItem.getPartsName());
+                workerStockDTO.setMaterialGroupName(partsChangeSalesItem.getMaterialGroupName());
+                workerStockDTO.setGoodsStockUnit(partsChangeSalesItem.getGoodsStockUnit());
+                workerStockDTO.setPrice(partsChangeSalesItem.getSalesPrice());
+                workerStockDTO.setRef(partsChangeSalesItem.getChangeSalesNo());
+                workerStockDTO.setRefType(refType);
+                workerStockDTO.setPartsAttr(partsAttr2);
+                workerStockDTO.setChangeQty(partsChangeSalesItem.getQty());
+                workerStockDTO.setDirectFlag(DirectFlagEnum.ADD.getKey());
+                workerStockDTO.setRemark("");
+                workerStockDTO.setOperateBy("自动处理");
+                workerStockDTO.setOperateTime(DateUtil.date());
+
+                workerStockDTOList.add(workerStockDTO);
+            }
+        }
+        return workerStockDTOList;
     }
 }

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

@@ -631,7 +631,7 @@
             a.parts_number,
             a.parts_name,
             a.material_group_name,
-            a.unit_name,
+            a.goods_stock_unit,
             a.sales_id,
             a.sales_price,
             a.market_price,