浏览代码

增加辅材采购申请单

FengChaoYu 8 月之前
父节点
当前提交
f07690c092

+ 95 - 0
mall-server-api/src/main/java/com/gree/mall/manager/bean/material/manage/WebsitMPurchaseBean.java

@@ -0,0 +1,95 @@
+package com.gree.mall.manager.bean.material.manage;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+@Data
+@ApiModel
+public class WebsitMPurchaseBean {
+
+    @ApiModelProperty(value = "单号")
+    private String purchaseId;
+
+    @ApiModelProperty(value = "商户编号")
+    private String companyWechatId;
+
+    @ApiModelProperty(value = "商户名称")
+    private String companyWechatName;
+
+    @ApiModelProperty(value = "网点编号")
+    private String websitId;
+
+    @ApiModelProperty(value = "网点名称")
+    private String websitName;
+
+    @ApiModelProperty(value = "商品类型")
+    private String goodsType;
+
+    @ApiModelProperty(value = "供应商编号")
+    private String venderId;
+
+    @ApiModelProperty(value = "供应商名称")
+    private String venderName;
+
+    @ApiModelProperty(value = "仓储id")
+    private String storageId;
+
+    @ApiModelProperty(value = "仓储名称")
+    private String storageName;
+
+    @ApiModelProperty(value = "采购日期")
+    private Date purchaseTime;
+
+    @ApiModelProperty(value = "附件地址")
+    private String imageUrl;
+
+    @ApiModelProperty(value = "采购总金额")
+    private BigDecimal totalAmount;
+
+    @ApiModelProperty(value = "单据状态 SAVE=保存 OK=通过 FAIL=失败")
+    private String flag;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "创建人")
+    private String createBy;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @ApiModelProperty(value = "更新人")
+    private String updateBy;
+
+    @ApiModelProperty(value = "更新时间")
+    private Date updateTime;
+
+    @ApiModelProperty(value = "审核人")
+    private String confirmBy;
+
+    @ApiModelProperty(value = "审核时间")
+    private Date confirmTime;
+
+    @ApiModelProperty(value = "提交人")
+    private String submitBy;
+
+    @ApiModelProperty(value = "提交时间")
+    private Date submitTime;
+
+    @ApiModelProperty(value = "核实人")
+    private String checkBy;
+
+    @ApiModelProperty(value = "核实时间")
+    private Date checkTime;
+
+    @ApiModelProperty(value = "是否导入数据 true=是 false=否")
+    private Boolean isImport;
+
+    @ApiModelProperty(value = "明细")
+    List<WebsitMPurchaseItemBean> items;
+}

+ 85 - 0
mall-server-api/src/main/java/com/gree/mall/manager/bean/material/manage/WebsitMPurchaseItemBean.java

@@ -0,0 +1,85 @@
+package com.gree.mall.manager.bean.material.manage;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@ApiModel
+public class WebsitMPurchaseItemBean {
+
+    @ApiModelProperty(value = "商户编号")
+    private String companyWechatId;
+
+    @ApiModelProperty(value = "网点编号")
+    private String websitId;
+
+    @ApiModelProperty(value = "网点名称")
+    private String websitName;
+
+    @ApiModelProperty(value = "单号")
+    private String purchaseId;
+
+    @ApiModelProperty(value = "商品类型 M=辅材 P=配件")
+    private String goodsType;
+
+    @ApiModelProperty(value = "商品编号")
+    private String goodsId;
+
+    @ApiModelProperty(value = "商品名称")
+    private String goodsName;
+
+    @ApiModelProperty(value = "预估进价")
+    private BigDecimal applyCost;
+
+    @ApiModelProperty(value = "预估进价金额")
+    private BigDecimal applyCostValue;
+
+    @ApiModelProperty(value = "申请数量")
+    private BigDecimal applyQty;
+
+    @ApiModelProperty(value = "核实数量")
+    private BigDecimal checkQty;
+
+    @ApiModelProperty(value = "进价")
+    private BigDecimal cost;
+
+    @ApiModelProperty(value = "验收金额")
+    private BigDecimal costValue;
+
+    @ApiModelProperty(value = "验收数量")
+    private BigDecimal recQty;
+
+    @ApiModelProperty(value = "验收赠品数量")
+    private BigDecimal recGiftQty;
+
+    @ApiModelProperty(value = "商品代码")
+    private String goodsCode;
+
+    @ApiModelProperty(value = "库存单位")
+    private String goodsStockUnit;
+
+    @ApiModelProperty(value = "规格型号")
+    private String goodsSpecification;
+
+    @ApiModelProperty(value = "商品父类编号")
+    private String parentCategoryId;
+
+    @ApiModelProperty(value = "商品父类名称")
+    private String parentCategoryName;
+
+    @ApiModelProperty(value = "商品小类编号")
+    private String goodsCategoryId;
+
+    @ApiModelProperty(value = "商品小类名称")
+    private String goodsCategoryName;
+
+    @ApiModelProperty(value = "退货数量")
+    private BigDecimal retQty;
+
+    @ApiModelProperty(value = "备注")
+    private String note;
+
+}

+ 63 - 0
mall-server-api/src/main/java/com/gree/mall/manager/bean/material/manage/WebsitPurchaseApplyVO.java

@@ -0,0 +1,63 @@
+package com.gree.mall.manager.bean.material.manage;
+
+import com.gree.mall.manager.annotation.ZfireField;
+import com.gree.mall.manager.enums.material.MaterialFlagEnum;
+import com.gree.mall.manager.enums.material.WebsitGoodsTypeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@ApiModel
+@ZfireField(tbName = "a")
+public class WebsitPurchaseApplyVO {
+
+    @ApiModelProperty(value = "单号")
+    private String purchaseId;
+
+    @ApiModelProperty(value = "商户名称")
+    private String companyWechatName;
+
+    @ZfireField(hide = true)
+    @ApiModelProperty(value = "网点编号")
+    private String websitId;
+
+    @ApiModelProperty(value = "网点名称")
+    private String websitName;
+
+    @ZfireField(hide = true)
+    @ApiModelProperty(value = "商品类型")
+    private WebsitGoodsTypeEnum goodsType;
+
+    @ZfireField(hide = true)
+    @ApiModelProperty(value = "供应商编号")
+    private String venderId;
+
+    @ApiModelProperty(value = "供应商名称")
+    private String venderName;
+
+    @ApiModelProperty(value = "采购总金额")
+    private String totalAmount;
+
+    @ZfireField(hide = true)
+    @ApiModelProperty(value = "单据状态")
+    private MaterialFlagEnum flag;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "创建人")
+    private String createBy;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @ApiModelProperty(value = "更新人")
+    private String updateBy;
+
+    @ApiModelProperty(value = "更新时间")
+    private Date updateTime;
+
+}

+ 12 - 0
mall-server-api/src/main/java/com/gree/mall/manager/bean/material/vender/WebsitVenderGoodsRelaVO.java

@@ -36,6 +36,10 @@ public class WebsitVenderGoodsRelaVO {
     @ApiModelProperty(value = "商品名称")
     private String goodsName;
 
+    @ZfireField(tbName = "b", hide = true)
+    @ApiModelProperty(value = "商品代码")
+    private String goodsCode;
+
     @ApiModelProperty(value = "进价")
     private BigDecimal cost;
 
@@ -81,4 +85,12 @@ public class WebsitVenderGoodsRelaVO {
     @ZfireField(tbName = "b", hide = true)
     @ApiModelProperty(value = "是否入师傅库存")
     private JudgeEnum manageWorkerStock;
+
+    @ZfireField(tbName = "b", hide = true)
+    @ApiModelProperty(value = "进价范围最小")
+    private BigDecimal costRangeMini;
+
+    @ZfireField(tbName = "b", hide = true)
+    @ApiModelProperty(value = "进价范围最大")
+    private BigDecimal costRangeMax;
 }

+ 8 - 0
mall-server-api/src/main/java/com/gree/mall/manager/commonmapper/MaterialMapper.java

@@ -217,4 +217,12 @@ public interface MaterialMapper {
      * @return
      */
     IPage<WebsitVenderGoodsRelaVO> websitVenderGoodsRalaPage(Page page, @Param("ex") ZfireParamBean zfireParamBean);
+
+    /**
+     * 网点申请单列表
+     * @param page
+     * @param zfireParamBean
+     * @return
+     */
+    IPage<WebsitPurchaseApplyVO> websitPurchaseApplyPage(Page page, @Param("ex") ZfireParamBean zfireParamBean);
 }

+ 1 - 0
mall-server-api/src/main/java/com/gree/mall/manager/constant/Constant.java

@@ -81,6 +81,7 @@ public class Constant {
         public final static String BALANCE_SEL_MOBILE_SMS = "jsm:SETTLE:BALANCE:SMS";
         public final static String ISSUE_SAL_MOBILE_SMS = "jsm:SETTLE:ISSUE:SMS";
         public final static String LOCK_SUMMARY_ISSUE = "jsm:SETTLE:lock:issue:summary";
+        public static final String LOCK_MATERIAL_PURCHASE = "jsm:sxb:material:purchase:";
     }
     public class ChatMessage {
         public final static String MSG_TYPE_DOC = "docmsg";

+ 139 - 0
mall-server-api/src/main/java/com/gree/mall/manager/controller/material/manage/WebsitPurchaseApplyController.java

@@ -0,0 +1,139 @@
+package com.gree.mall.manager.controller.material.manage;
+
+import cn.hutool.core.lang.TypeReference;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.gree.mall.manager.annotation.ZfireList;
+import com.gree.mall.manager.bean.material.manage.WebsitMPurchaseBean;
+import com.gree.mall.manager.bean.material.manage.WebsitPurchaseApplyVO;
+import com.gree.mall.manager.constant.Constant;
+import com.gree.mall.manager.exception.RemoteServiceException;
+import com.gree.mall.manager.helper.ResponseHelper;
+import com.gree.mall.manager.logic.material.manage.WebsitMPurchaseLogic;
+import com.gree.mall.manager.zfire.bean.ZfireParamBean;
+import com.gree.mall.manager.zfire.util.FieldUtils;
+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.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+
+@Slf4j
+@RestController
+@Api(value = "网点采购申请API", tags ={"网点采购申请API"} )
+@Validated
+@RequestMapping(value = "/websit/purchase/apply", produces = "application/json; charset=utf-8")
+public class WebsitPurchaseApplyController {
+
+    @Resource
+    WebsitMPurchaseLogic websitMPurchaseLogic;
+    @Resource
+    RedisLockRegistry redisLockRegistry;
+
+    @ZfireList
+    @PostMapping("/list")
+    @ApiOperation(value = "网点采购申请-列表")
+    public ResponseHelper<IPage<WebsitPurchaseApplyVO>> page(
+            @RequestBody ZfireParamBean zfireParamBean
+    ) {
+        IPage<WebsitPurchaseApplyVO> page = websitMPurchaseLogic.page(zfireParamBean);
+        return ResponseHelper.success(page, new TypeReference<WebsitPurchaseApplyVO>() {});
+    }
+
+    @PostMapping("/list/export")
+    @ApiOperation("网点采购申请-导出")
+    public void listExport(
+            @RequestBody ZfireParamBean zfireParamBean,
+            HttpServletRequest request,
+            HttpServletResponse response
+    ) throws Exception {
+        //2.查询要导出的内容
+        IPage<WebsitPurchaseApplyVO> baseVOIPage = websitMPurchaseLogic.page(zfireParamBean);
+        //3.导出
+        FieldUtils.exportData(baseVOIPage.getRecords(), zfireParamBean.getExportFields(), request, response);
+    }
+
+    @PostMapping("/detail")
+    @ApiOperation(value = "网点采购申请-详情")
+    public ResponseHelper<WebsitMPurchaseBean> detail(
+            @ApiParam(value = "purchaseId", required = true) @RequestParam String purchaseId
+    ) throws RemoteServiceException {
+        WebsitMPurchaseBean bean = websitMPurchaseLogic.detail(purchaseId);
+        return ResponseHelper.success(bean);
+    }
+
+    @PostMapping("/add")
+    @ApiOperation(value = "网点采购申请-添加")
+    public ResponseHelper add(
+            @RequestBody WebsitMPurchaseBean bean
+    ) throws Exception {
+        websitMPurchaseLogic.add(bean);
+        return ResponseHelper.success();
+    }
+
+    @PostMapping("/edit")
+    @ApiOperation(value = "网点采购申请-编辑")
+    public ResponseHelper edit(
+            @RequestBody WebsitMPurchaseBean bean
+    ) throws Exception {
+        websitMPurchaseLogic.edit(bean);
+
+        return ResponseHelper.success();
+    }
+
+    @PostMapping("/batch/del")
+    @ApiOperation(value = "网点采购申请-批量删除")
+    public ResponseHelper batchDel(@RequestBody List<String> purchaseIds)
+            throws RemoteServiceException {
+        websitMPurchaseLogic.batchDel(purchaseIds);
+        return ResponseHelper.success();
+    }
+
+    @PostMapping("/revoke")
+    @ApiOperation(value = "网点采购申请-撤消")
+    public ResponseHelper revoke(@ApiParam(value = "采购申请单id",required = true) @RequestParam String purchaseId)
+            throws RemoteServiceException {
+        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_MATERIAL_PURCHASE + purchaseId);
+        try {
+            if (!obtain.tryLock(10, TimeUnit.SECONDS)) {
+                log.error("获取采购申请单锁超时!");
+            }
+            websitMPurchaseLogic.revoke(purchaseId);
+        } catch (InterruptedException e) {
+            log.error(purchaseId + " 撤消失败!", e);
+            throw new RemoteServiceException(purchaseId + " 撤消失败!" + e.getMessage());
+        } finally {
+            obtain.unlock();
+        }
+        return ResponseHelper.success();
+    }
+
+    @PostMapping("/submit")
+    @ApiOperation(value = "网点采购申请-提交")
+    public ResponseHelper submit(@ApiParam(value = "采购申请单id",required = true) @RequestParam String purchaseId)
+            throws RemoteServiceException {
+        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_MATERIAL_PURCHASE + purchaseId);
+        try {
+            if (!obtain.tryLock(10, TimeUnit.SECONDS)) {
+                log.error("获取采购申请单锁超时!");
+            }
+            websitMPurchaseLogic.submit(purchaseId);
+        } catch (InterruptedException e) {
+            log.error(purchaseId + " 提交失败!", e);
+            throw new RemoteServiceException(purchaseId + " 提交失败!" + e.getMessage());
+        } finally {
+            obtain.unlock();
+        }
+
+        return ResponseHelper.success();
+    }
+
+}

+ 304 - 0
mall-server-api/src/main/java/com/gree/mall/manager/logic/material/manage/WebsitMPurchaseLogic.java

@@ -0,0 +1,304 @@
+package com.gree.mall.manager.logic.material.manage;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.gree.mall.manager.bean.admin.AdminUserCom;
+import com.gree.mall.manager.bean.material.manage.WebsitMPurchaseBean;
+import com.gree.mall.manager.bean.material.manage.WebsitMPurchaseItemBean;
+import com.gree.mall.manager.bean.material.manage.WebsitPurchaseApplyVO;
+import com.gree.mall.manager.bean.material.vender.WebsitVenderGoodsRelaVO;
+import com.gree.mall.manager.commonmapper.MaterialMapper;
+import com.gree.mall.manager.enums.IsYesNoEnum;
+import com.gree.mall.manager.enums.material.MaterialFlagEnum;
+import com.gree.mall.manager.enums.material.StateEnum;
+import com.gree.mall.manager.enums.material.WebsitGoodsTypeEnum;
+import com.gree.mall.manager.exception.RemoteServiceException;
+import com.gree.mall.manager.logic.common.CommonLogic;
+import com.gree.mall.manager.logic.material.vender.VenderGoodsLogic;
+import com.gree.mall.manager.plus.entity.WebsitPurchase;
+import com.gree.mall.manager.plus.entity.WebsitPurchaseItem;
+import com.gree.mall.manager.plus.entity.WebsitVender;
+import com.gree.mall.manager.plus.service.WebsitPurchaseItemService;
+import com.gree.mall.manager.plus.service.WebsitPurchaseService;
+import com.gree.mall.manager.plus.service.WebsitVenderService;
+import com.gree.mall.manager.zfire.bean.QueryParamBean;
+import com.gree.mall.manager.zfire.bean.ZfireParamBean;
+import com.gree.mall.manager.zfire.util.FieldUtils;
+import lombok.RequiredArgsConstructor;
+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 java.math.BigDecimal;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class WebsitMPurchaseLogic {
+
+    private final CommonLogic commonLogic;
+    private final MaterialMapper materialMapper;
+    private final WebsitPurchaseService websitPurchaseService;
+    private final WebsitPurchaseItemService websitPurchaseItemService;
+    private final VenderGoodsLogic venderGoodsLogic;
+    private final WebsitVenderService websitVenderService;
+
+    public IPage<WebsitPurchaseApplyVO> page(ZfireParamBean zfireParamBean) {
+        AdminUserCom adminUser = commonLogic.getAdminUser();
+        FieldUtils.materialParam(zfireParamBean, WebsitPurchaseApplyVO.class, adminUser);
+
+        return materialMapper.websitPurchaseApplyPage(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
+    }
+
+    public WebsitMPurchaseBean detail(String purchaseId) {
+        AdminUserCom adminUser = commonLogic.getAdminUser();
+        WebsitMPurchaseBean bean = new WebsitMPurchaseBean();
+        WebsitPurchase purchase = websitPurchaseService.getById(purchaseId);
+        BeanUtils.copyProperties(purchase, bean);
+        bean.setImageUrl(purchase.getImageUrl());
+        String companyId = Objects.isNull(adminUser.getAdminCompanyWechat()) ? null : adminUser.getAdminCompanyWechat().getCompanyWechatId();
+        List<WebsitMPurchaseItemBean> list = websitPurchaseItemService.lambdaQuery()
+                .eq(StringUtils.isNotBlank(companyId), WebsitPurchaseItem::getCompanyWechatId, companyId)
+                .eq(WebsitPurchaseItem::getPurchaseId, purchaseId)
+                .list()
+                .stream()
+                .map(v -> {
+                    WebsitMPurchaseItemBean item = new WebsitMPurchaseItemBean();
+                    BeanUtils.copyProperties(v, item);
+                    return item;
+                }).collect(Collectors.toList());
+        bean.setItems(list);
+
+        return bean;
+    }
+
+    @Transactional
+    public void add(WebsitMPurchaseBean bean) {
+        AdminUserCom adminUser = commonLogic.getAdminUser();
+
+        if (adminUser.getType() == 2) {
+            throw new RemoteServiceException("平台账号禁用操作");
+        }
+
+        bean.setCompanyWechatId(adminUser.getAdminCompanyWechat().getCompanyWechatId());
+        bean.setCompanyWechatName(adminUser.getAdminCompanyWechat().getCompanyName());
+
+        bean.setFlag(MaterialFlagEnum.SAVE.getKey());
+
+        // 检查参数值
+        this.validApplyParams(bean);
+
+        WebsitPurchase purchase = new WebsitPurchase();
+        BeanUtils.copyProperties(bean, purchase);
+
+        purchase.insert();
+
+        List<WebsitPurchaseItem> itemList = new ArrayList<>();
+        for (WebsitMPurchaseItemBean beanItem : bean.getItems()) {
+            WebsitPurchaseItem item = new WebsitPurchaseItem();
+            BeanUtils.copyProperties(beanItem, item);
+            item.setPurchaseId(purchase.getPurchaseId())
+                    .setCompanyWechatId(bean.getCompanyWechatId())
+                    .setWebsitId(bean.getWebsitId())
+                    .setWebsitName(bean.getWebsitName())
+                    .setGoodsType(WebsitGoodsTypeEnum.M.getKey());
+            itemList.add(item);
+        }
+
+        websitPurchaseItemService.saveBatch(itemList);
+    }
+
+    public void edit(WebsitMPurchaseBean bean) {
+        AdminUserCom adminUser = commonLogic.getAdminUser();
+
+        bean.setFlag(MaterialFlagEnum.SAVE.getKey());
+
+        final WebsitPurchase oldPurchase = websitPurchaseService.getById(bean.getPurchaseId());
+
+        if (Objects.isNull(oldPurchase)) {
+            throw new RemoteServiceException("单据不存在");
+        }
+
+        // 检查参数值
+        this.validApplyParams(bean);
+
+        WebsitPurchase purchase = new WebsitPurchase();
+        BeanUtils.copyProperties(bean, purchase);
+        purchase.setCreateBy(oldPurchase.getCreateBy())
+                .setCreateTime(oldPurchase.getCreateTime());
+
+        purchase.updateById();
+
+        List<WebsitPurchaseItem> itemList = new ArrayList<>();
+        websitPurchaseItemService.lambdaUpdate()
+                .eq(WebsitPurchaseItem::getPurchaseId, bean.getPurchaseId())
+                .remove();
+        for (WebsitMPurchaseItemBean beanItem : bean.getItems()) {
+            WebsitPurchaseItem item = new WebsitPurchaseItem();
+            BeanUtils.copyProperties(beanItem, item);
+            item.setPurchaseId(purchase.getPurchaseId())
+                    .setCompanyWechatId(bean.getCompanyWechatId())
+                    .setWebsitId(bean.getWebsitId())
+                    .setWebsitName(bean.getWebsitName())
+                    .setGoodsType(WebsitGoodsTypeEnum.M.getKey());
+            itemList.add(item);
+        }
+
+        websitPurchaseItemService.saveBatch(itemList);
+    }
+
+    private void validApplyParams(WebsitMPurchaseBean bean) {
+        if (StringUtils.isBlank(bean.getWebsitId()) || StringUtils.isBlank(bean.getWebsitName())) {
+            throw new RemoteServiceException("请选择网点");
+        }
+        if (StringUtils.isBlank(bean.getVenderId()) || StringUtils.isBlank(bean.getVenderName())) {
+            throw new RemoteServiceException("请选择供应商");
+        }
+        if (CollectionUtil.isEmpty(bean.getItems())) {
+            throw new RemoteServiceException("请先添加明细");
+        }
+
+        for (int i = 0; i < bean.getItems().size(); i++) {
+            WebsitMPurchaseItemBean itemBean = bean.getItems().get(i);
+            String preStr = "第" + (i+1) + "行, ";
+            if (StringUtils.isBlank(itemBean.getGoodsId()) || StringUtils.isBlank(itemBean.getGoodsName())) {
+                throw new RemoteServiceException(preStr + "辅材编号不能为空");
+            }
+            if (Objects.isNull(itemBean.getApplyCost())) {
+                throw new RemoteServiceException(preStr + "预估进价不能为空");
+            }
+            if (Objects.isNull(itemBean.getApplyQty()) || itemBean.getApplyQty().compareTo(BigDecimal.ZERO) <= 0) {
+                throw new RemoteServiceException(preStr + "申请数量不能为空或少于等于0");
+            }
+        }
+
+        // 检查明细重复辅材编号
+        Map<String, List<WebsitMPurchaseItemBean>> goodsGroup = bean.getItems().stream().collect(Collectors.groupingBy(WebsitMPurchaseItemBean::getGoodsId));
+        for (Map.Entry<String, List<WebsitMPurchaseItemBean>> entry : goodsGroup.entrySet()) {
+            if (entry.getValue().size() > 1) {
+                throw new RemoteServiceException("明细有重复的辅材编号 " + entry.getKey());
+            }
+        }
+
+        // 获取供应商商品记录
+        List<WebsitVenderGoodsRelaVO> relaList = this.queryVenderGoods(bean);
+        final Map<String, WebsitVenderGoodsRelaVO> relaMap = relaList.stream()
+                .collect(Collectors.toMap(WebsitVenderGoodsRelaVO::getGoodsId, Function.identity()));
+
+        // 校验供应商商品
+        this.validVendorGoods(bean, relaMap);
+    }
+
+    private void validVendorGoods(WebsitMPurchaseBean bean, Map<String, WebsitVenderGoodsRelaVO> relaMap) {
+        for (int i = 0; i < bean.getItems().size(); i++) {
+            WebsitMPurchaseItemBean itemBean = bean.getItems().get(i);
+            String preStr = "第" + (i+1) + "行, ";
+            final WebsitVenderGoodsRelaVO relaGoods = relaMap.get(itemBean.getGoodsId());
+            if (Objects.isNull(relaGoods)) {
+                throw new RemoteServiceException(preStr + "供应商辅材不存在或无效");
+            }
+            if (StrUtil.equals(relaGoods.getStatus().getKey(), StateEnum.OFF.getKey())) {
+                throw new RemoteServiceException(preStr + "供应商辅材资料无效");
+            }
+            if (bean.getFlag().equals(MaterialFlagEnum.SAVE.getKey())) {
+                // 检查进价范围值
+                if (Objects.nonNull(relaGoods.getCostRangeMini())
+                        && itemBean.getApplyCost().compareTo(relaGoods.getCostRangeMini()) < 0) {
+                    throw new RemoteServiceException(preStr + "不能低于辅材资料最小进价范围值");
+                }
+                if (Objects.nonNull(relaGoods.getCostRangeMax())
+                        && itemBean.getApplyCost().compareTo(relaGoods.getCostRangeMax()) > 0) {
+                    throw new RemoteServiceException(preStr + "不能高于辅材资料最大进价范围值");
+                }
+            }
+            // 申请进价*申请数量=申请进价金额
+            itemBean.setApplyCostValue(itemBean.getApplyCost().multiply(itemBean.getApplyQty()).setScale(2, BigDecimal.ROUND_HALF_UP));
+            itemBean.setCheckQty(itemBean.getApplyCost());
+            itemBean.setGoodsCode(relaGoods.getGoodsCode());
+            itemBean.setGoodsSpecification(relaGoods.getGoodsSpecification());
+            itemBean.setGoodsStockUnit(relaGoods.getGoodsStockUnit());
+            itemBean.setParentCategoryId(relaGoods.getParentCategoryId());
+            itemBean.setParentCategoryName(relaGoods.getParentCategoryName());
+            itemBean.setGoodsCategoryId(relaGoods.getGoodsCategoryId());
+            itemBean.setGoodsCategoryName(relaGoods.getCategoryName());
+        }
+    }
+
+    private List<WebsitVenderGoodsRelaVO> queryVenderGoods(WebsitMPurchaseBean bean) {
+        ZfireParamBean zfireParamBean = new ZfireParamBean();
+        zfireParamBean.setPageNum(1);
+        zfireParamBean.setPageSize(-1);
+        zfireParamBean.setParams(new ArrayList<>());
+        QueryParamBean paramBean = new QueryParamBean();
+        paramBean.setParam("a.vender_id").setCompare("=").setValue(bean.getVenderId());
+        QueryParamBean paramBean2 = new QueryParamBean();
+        paramBean2.setParam("a.rela_status").setCompare("=").setValue(StateEnum.ON.getKey());
+        zfireParamBean.getParams().add(paramBean);
+        zfireParamBean.getParams().add(paramBean2);
+
+        final IPage<WebsitVenderGoodsRelaVO> page = venderGoodsLogic.ralaPage(zfireParamBean);
+        if (CollectionUtil.isEmpty(page.getRecords())) {
+            throw new RemoteServiceException(bean.getVenderName() + "供应商没有可供应的辅材记录");
+        }
+        return page.getRecords();
+    }
+
+    @Transactional
+    public void batchDel(List<String> purchaseIds) {
+        if (CollectionUtil.isEmpty(purchaseIds)) {
+            throw new RemoteServiceException("请选择记录");
+        }
+
+        websitPurchaseService.lambdaUpdate()
+                .in(WebsitPurchase::getPurchaseId, purchaseIds)
+                .remove();
+
+        websitPurchaseItemService.lambdaUpdate()
+                .in(WebsitPurchaseItem::getPurchaseId, purchaseIds)
+                .remove();
+    }
+
+    @Transactional
+    public void revoke(String purchaseId) {
+        if (!websitPurchaseService.lambdaUpdate()
+                .eq(WebsitPurchase::getPurchaseId, purchaseId)
+                .eq(WebsitPurchase::getFlag, MaterialFlagEnum.SUBMIT.getKey())
+                .eq(WebsitPurchase::getIsRecheck, IsYesNoEnum.NO.getKey())
+                .set(WebsitPurchase::getFlag, MaterialFlagEnum.SAVE.getKey())
+                .update()) {
+            throw new RemoteServiceException("撤消失败,单据状态已发生变化,非“提交待核实”");
+        }
+    }
+
+    @Transactional
+    public void submit(String purchaseId) {
+        AdminUserCom adminUser = commonLogic.getAdminUser();
+        WebsitPurchase purchase = websitPurchaseService.getById(purchaseId);
+
+        if (Objects.isNull(purchase) || !StrUtil.equals(purchase.getFlag(), MaterialFlagEnum.SAVE.getKey())) {
+            throw new RemoteServiceException("单据不存在或状态已发生变化");
+        }
+
+        final WebsitVender vender = websitVenderService.getById(purchase.getVenderId());
+
+        // 供应商为自动审核时
+        if (StrUtil.equals(vender.getIsAuto(), IsYesNoEnum.YES.getKey())) {
+            purchase.setIsRecheck(IsYesNoEnum.YES.getKey())
+                    .setCheckBy(adminUser.getNickName())
+                    .setCheckTime(DateUtil.date());
+        }
+
+        purchase.setFlag(MaterialFlagEnum.SUBMIT.getKey())
+                .setSubmitBy(adminUser.getNickName())
+                .setSubmitTime(DateUtil.date())
+                .updateById();
+    }
+}

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

@@ -421,4 +421,17 @@
         </if>
         ${ex.orderBy}
     </select>
+
+    <select id="websitPurchaseApplyPage"
+            resultType="com.gree.mall.manager.bean.material.manage.WebsitPurchaseApplyVO">
+        SELECT
+            ${ex.selected}
+        FROM
+            websit_purchase a
+        ${ex.query}
+        <if test="ex.orderBy == null or ex.orderBy ==''">
+            ORDER BY a.create_time DESC
+        </if>
+        ${ex.orderBy}
+    </select>
 </mapper>