Ver Fonte

供应链 申购方法

home há 2 anos atrás
pai
commit
1925eeba47

+ 1 - 1
hx-common/common-tool/src/main/java/com/fjhx/constants/ErrorMsgConstant.java

@@ -5,7 +5,7 @@ package com.fjhx.constants;
  */
 public interface ErrorMsgConstant {
 
-    // 乐观锁修改失败,或等待超时 异常提示
+    // 乐观锁修改失败,或分布式锁等待超时 异常提示
     String SYSTEM_BUSY_ERROR = "系统繁忙,请稍后再试";
 
 }

+ 18 - 0
hx-common/library-supply/src/main/java/com/fjhx/constants/LibrarySupplyLockConstant.java

@@ -0,0 +1,18 @@
+package com.fjhx.constants;
+
+/**
+ * 锁常量
+ */
+public interface LibrarySupplyLockConstant {
+
+    /**
+     * 添加前缀,防止其他模块出现共用一把锁的情况
+     */
+    String PREFIX = "library-supply-";
+
+    /**
+     * 保证申购单编码唯一
+     */
+    String APPLY_PURCHASE_CODE_LOCK = PREFIX + "applyPurchaseCodeLock-";
+
+}

+ 14 - 24
hx-common/library-supply/src/main/java/com/fjhx/entity/ApplyPurchase.java

@@ -1,17 +1,15 @@
 package com.fjhx.entity;
 
-import java.math.BigDecimal;
-import com.baomidou.mybatisplus.annotation.IdType;
-import java.util.Date;
-import com.baomidou.mybatisplus.annotation.Version;
-import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.TableLogic;
-import com.fjhx.base.BaseEntity;
 import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.Version;
+import com.fjhx.base.BaseEntity;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import java.math.BigDecimal;
+import java.util.Date;
+
 /**
  * <p>
  * 申购单
@@ -86,29 +84,29 @@ public class ApplyPurchase extends BaseEntity {
     private Date planArrivalTime;
 
     /**
-     * 锁定数量(发起退货审批,但还没通过的数量)
+     * 申购状态 1待发起 2审批中 3未通过 4已通过/待采购 5已采购 6部分到货 7全部到货/结束 8已作废
      */
-    private BigDecimal lockQuantity;
+    private Integer status;
 
     /**
-     * 退货数量
+     * 完成状态 0未完成 1已完成
      */
-    private BigDecimal backQuantity;
+    private Integer completeStatus;
 
     /**
-     * 退货金额
+     * 流程关联编号
      */
-    private BigDecimal backPrice;
+    private Long flowLinkNo;
 
     /**
      * 申购原因
      */
-    private String remark;
+    private String cause;
 
     /**
-     * 申购状态 1待发起 2待采购 3已采购 4部分到货 5全部到货/结束 6已作废
+     * 采购备注
      */
-    private Integer status;
+    private String remark;
 
     /**
      * 乐观锁
@@ -117,12 +115,4 @@ public class ApplyPurchase extends BaseEntity {
     @Version
     private Integer version;
 
-    /**
-     * 逻辑删除 0未删除 1已删除
-     */
-    @TableField(fill = FieldFill.INSERT)
-    @TableLogic
-    private Integer delFlag;
-
-
 }

+ 0 - 8
hx-common/library-supply/src/main/java/com/fjhx/entity/BackGoods.java

@@ -71,12 +71,4 @@ public class BackGoods extends BaseEntity {
     @Version
     private Integer version;
 
-    /**
-     * 逻辑删除 0未删除 1已删除
-     */
-    @TableField(fill = FieldFill.INSERT)
-    @TableLogic
-    private Integer delFlag;
-
-
 }

+ 0 - 8
hx-common/library-supply/src/main/java/com/fjhx/entity/Order.java

@@ -43,12 +43,4 @@ public class Order extends BaseEntity {
      */
     private Integer complete;
 
-    /**
-     * 逻辑删除 0未删除 1已删除
-     */
-    @TableField(fill = FieldFill.INSERT)
-    @TableLogic
-    private Integer delFlag;
-
-
 }

+ 42 - 0
hx-common/library-supply/src/main/java/com/fjhx/enums/ApplyPurchaseStatusEnum.java

@@ -0,0 +1,42 @@
+package com.fjhx.enums;
+
+import lombok.Getter;
+
+import java.util.HashMap;
+
+@Getter
+public enum ApplyPurchaseStatusEnum {
+
+    WAIT_START(1), // 待发起
+    IN_APPROVAL(2), // 审批中
+    NOT_PASS(3), // 未通过
+    PASS(4), // 已通过/待采购
+    PURCHASED(5), // 已采购
+    PART_ARRIVAL(6), // 部分到货
+    ARRIVAL(7), // 全部到货
+    DISCARD(8), // 作废
+    ;
+
+    ApplyPurchaseStatusEnum(Integer value) {
+        this.value = value;
+    }
+
+    private final Integer value;
+
+    private static final HashMap<Integer, ApplyPurchaseStatusEnum> map = new HashMap<>();
+
+    static {
+        for (ApplyPurchaseStatusEnum value : ApplyPurchaseStatusEnum.values()) {
+            map.put(value.getValue(), value);
+        }
+    }
+
+    /**
+     * 根据value值获取枚举
+     */
+    public static ApplyPurchaseStatusEnum get(Integer value) {
+        return map.get(value);
+    }
+
+
+}

+ 66 - 0
hx-common/library-supply/src/main/java/com/fjhx/service/ApplyPurchaseService.java

@@ -3,6 +3,9 @@ package com.fjhx.service;
 import com.fjhx.base.BaseService;
 import com.fjhx.entity.ApplyPurchase;
 
+import java.math.BigDecimal;
+import java.util.List;
+
 /**
  * <p>
  * 申购单 服务类
@@ -13,4 +16,67 @@ import com.fjhx.entity.ApplyPurchase;
  */
 public interface ApplyPurchaseService extends BaseService<ApplyPurchase> {
 
+    /**
+     * 添加申购单
+     *
+     * @param applyPurchase 申购对象
+     */
+    void add(ApplyPurchase applyPurchase);
+
+    /**
+     * 发起申购
+     *
+     * @param applyPurchaseList 申购列表
+     * @param flowLinkNo        流程关联编号
+     */
+    void initiateSubscription(List<ApplyPurchase> applyPurchaseList, Long flowLinkNo);
+
+    /**
+     * 审批通过
+     *
+     * @param flowLinkNo 流程关联编号
+     */
+    void flowPass(Long flowLinkNo);
+
+    /**
+     * 审批不通过
+     *
+     * @param flowLinkNo 流程关联编号
+     */
+    void flowNotPass(Long flowLinkNo);
+
+    /**
+     * 申购绑定订单
+     *
+     * @param applyPurchaseList 申购列表
+     * @param orderId           订单id
+     * @param orderCode         订单编码
+     * @param supplierId        供应商id
+     * @param accountPeriod     供应商账期/天
+     */
+    void bindingOrder(List<ApplyPurchase> applyPurchaseList, Long orderId, String orderCode, Long supplierId, Integer accountPeriod);
+
+    /**
+     * 到货
+     *
+     * @param applyPurchaseId 订单id
+     * @param arrivalQuantity 到货数量
+     * @param autoComplete    是否自动更新订单完成
+     */
+    void arrival(Long applyPurchaseId, BigDecimal arrivalQuantity, Boolean autoComplete);
+
+    /**
+     * 结束申购单
+     *
+     * @param applyPurchaseId 申购单id
+     */
+    void endApplyPurchase(Long applyPurchaseId);
+
+    /**
+     * 作废申购单
+     *
+     * @param applyPurchaseId 申购单id
+     */
+    void discardApplyPurchase(Long applyPurchaseId);
+
 }

+ 195 - 0
hx-common/library-supply/src/main/java/com/fjhx/service/impl/ApplyPurchaseServiceImpl.java

@@ -1,11 +1,26 @@
 package com.fjhx.service.impl;
 
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.base.BaseEntity;
+import com.fjhx.constants.ErrorMsgConstant;
+import com.fjhx.constants.LibrarySupplyLockConstant;
+import com.fjhx.constants.StatusConstant;
 import com.fjhx.entity.ApplyPurchase;
+import com.fjhx.enums.ApplyPurchaseStatusEnum;
 import com.fjhx.mapper.ApplyPurchaseMapper;
 import com.fjhx.service.ApplyPurchaseService;
+import com.fjhx.utils.Assert;
+import org.springblade.core.redis.lock.RedisLockClient;
+import org.springblade.core.secure.utils.AuthUtil;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
 /**
  * <p>
  * 申购单 服务实现类
@@ -17,4 +32,184 @@ import org.springframework.stereotype.Service;
 @Service
 public class ApplyPurchaseServiceImpl extends ServiceImpl<ApplyPurchaseMapper, ApplyPurchase> implements ApplyPurchaseService {
 
+    @Resource
+    private RedisLockClient redisLockClient;
+
+    @Override
+    public void add(ApplyPurchase applyPurchase) {
+        Assert.notEmpty(applyPurchase.getGoodsId(), "物品id不能为空");
+        Assert.notEmpty(applyPurchase.getQuantity(), "申购数量不能为空");
+        Assert.notEmpty(applyPurchase.getPlanArrivalTime(), "到货时间不能为空");
+
+        applyPurchase.setStatus(ApplyPurchaseStatusEnum.WAIT_START.getValue());
+
+        save(applyPurchase);
+    }
+
+    @Override
+    public void initiateSubscription(List<ApplyPurchase> applyPurchaseList, Long flowLinkNo) {
+
+        String tenantId = AuthUtil.getTenantId();
+
+        Boolean flag = redisLockClient.lockFair(LibrarySupplyLockConstant.APPLY_PURCHASE_CODE_LOCK + tenantId,
+                () -> {
+                    String applyPurchaseCode = createApplyPurchaseCode();
+                    applyPurchaseList.forEach(applyPurchase -> {
+                        // 赋值申购单号
+                        applyPurchase.setCode(applyPurchaseCode);
+                        // 状态改为审批中
+                        applyPurchase.setStatus(ApplyPurchaseStatusEnum.IN_APPROVAL.getValue());
+                        // 赋值流程id
+                        applyPurchase.setFlowLinkNo(flowLinkNo);
+                    });
+                    updateBatchById(applyPurchaseList);
+                    return true;
+                });
+
+        Assert.eqTrue(flag, ErrorMsgConstant.SYSTEM_BUSY_ERROR);
+
+    }
+
+    @Override
+    public void flowPass(Long flowLinkNo) {
+        updateFlowStatus(flowLinkNo, ApplyPurchaseStatusEnum.PASS);
+    }
+
+    @Override
+    public void flowNotPass(Long flowLinkNo) {
+        updateFlowStatus(flowLinkNo, ApplyPurchaseStatusEnum.NOT_PASS);
+    }
+
+    @Override
+    public void bindingOrder(List<ApplyPurchase> applyPurchaseList, Long orderId, String orderCode, Long supplierId, Integer accountPeriod) {
+
+        for (ApplyPurchase applyPurchase : applyPurchaseList) {
+
+            Long id = applyPurchase.getId();
+            Assert.notEmpty(id, "申购单id不能为空");
+
+            BigDecimal unitPrice = applyPurchase.getUnitPrice();
+            Assert.notEmpty(unitPrice, "单价不能为空");
+
+            applyPurchase.setVersion(null);
+            applyPurchase.setOrderId(orderId);
+            applyPurchase.setOrderCode(orderCode);
+            applyPurchase.setSupplierId(supplierId);
+            applyPurchase.setAccountPeriod(accountPeriod);
+            applyPurchase.setStatus(ApplyPurchaseStatusEnum.PURCHASED.getValue());
+
+            // 申购金额
+            applyPurchase.setApplyPrice(unitPrice.multiply(applyPurchase.getQuantity()));
+
+            // 到货数量
+            applyPurchase.setArrivalQuantity(BigDecimal.ZERO);
+
+            // 到货金额
+            applyPurchase.setArrivalPrice(BigDecimal.ZERO);
+
+        }
+
+        updateBatchById(applyPurchaseList);
+
+    }
+
+    @Override
+    public void arrival(Long applyPurchaseId, BigDecimal arrivalQuantity, Boolean autoComplete) {
+
+        ApplyPurchase applyPurchase = getById(applyPurchaseId);
+        Assert.notEmpty(applyPurchase, "申购单号为空");
+
+        // 添加到货数量
+        BigDecimal totalArrivalQuantity = applyPurchase.getArrivalQuantity().add(arrivalQuantity);
+        applyPurchase.setArrivalQuantity(totalArrivalQuantity);
+
+        // 赋值到货金额
+        applyPurchase.setArrivalPrice(totalArrivalQuantity.multiply(applyPurchase.getUnitPrice()));
+
+        // 是否全部到货
+        BigDecimal quantity = applyPurchase.getQuantity();
+        if (totalArrivalQuantity.compareTo(quantity) >= 0) {
+            applyPurchase.setStatus(ApplyPurchaseStatusEnum.ARRIVAL.getValue());
+            if (autoComplete) {
+                applyPurchase.setCompleteStatus(StatusConstant.YES);
+            }
+        } else {
+            applyPurchase.setStatus(ApplyPurchaseStatusEnum.PART_ARRIVAL.getValue());
+        }
+
+        boolean b = updateById(applyPurchase);
+
+        Assert.eqTrue(b, ErrorMsgConstant.SYSTEM_BUSY_ERROR);
+
+        // TODO 完成订单
+        if (totalArrivalQuantity.compareTo(quantity) >= 0 && autoComplete) {
+
+        }
+
+    }
+
+    @Override
+    public void endApplyPurchase(Long applyPurchaseId) {
+        update(Wrappers.<ApplyPurchase>lambdaUpdate()
+                .eq(ApplyPurchase::getId, applyPurchaseId)
+                .set(BaseEntity::getCreateTime, new Date())
+                .set(BaseEntity::getUpdateUser, AuthUtil.getUserId())
+                .set(ApplyPurchase::getCompleteStatus, StatusConstant.YES));
+    }
+
+    @Override
+    public void discardApplyPurchase(Long applyPurchaseId) {
+        update(Wrappers.<ApplyPurchase>lambdaUpdate()
+                .eq(ApplyPurchase::getId, applyPurchaseId)
+                .set(BaseEntity::getCreateTime, new Date())
+                .set(BaseEntity::getUpdateUser, AuthUtil.getUserId())
+                .set(ApplyPurchase::getStatus, ApplyPurchaseStatusEnum.DISCARD.getValue()));
+    }
+
+
+    /**
+     * 生成申购单号
+     */
+    private String createApplyPurchaseCode() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("PA");
+        builder.append(DateUtil.format(new Date(), "yyyyMM"));
+        builder.append("-");
+
+        String codePrefix = builder.toString();
+
+        ApplyPurchase applyPurchase = getOne(Wrappers.<ApplyPurchase>lambdaQuery()
+                .select(ApplyPurchase::getCode)
+                .eq(BaseEntity::getTenantId, AuthUtil.getTenantId())
+                .likeRight(ApplyPurchase::getCode, codePrefix)
+                .orderByDesc(ApplyPurchase::getCode)
+                .last("limit 1")
+        );
+
+        if (applyPurchase == null) {
+            return builder.append("001").toString();
+        }
+
+        int codeNum = Integer.parseInt(applyPurchase.getCode().replace(codePrefix, ""));
+
+        if (codeNum < 9) {
+            builder.append("00");
+        } else if (codeNum < 99) {
+            builder.append("0");
+        }
+
+        return builder.append(codeNum + 1).toString();
+    }
+
+    /**
+     * 修改合同审批状态
+     */
+    private void updateFlowStatus(Long flowLinkNo, ApplyPurchaseStatusEnum applyPurchaseStatusEnum) {
+        update(Wrappers.<ApplyPurchase>lambdaUpdate()
+                .eq(ApplyPurchase::getFlowLinkNo, flowLinkNo)
+                .set(BaseEntity::getCreateTime, new Date())
+                .set(BaseEntity::getUpdateUser, AuthUtil.getUserId())
+                .set(ApplyPurchase::getStatus, applyPurchaseStatusEnum.getValue()));
+    }
+
 }

+ 4 - 4
hx-common/service-flow/src/main/java/com/fjhx/feign/FlowClient.java

@@ -49,11 +49,11 @@ public class FlowClient implements IFlowClient {
 
     @PostMapping(GET_FLOW_INFO)
     @Override
-    public R<FlowInfo> getProcessTenant(Long businessId, String code) {
+    public R<FlowInfo> getProcessTenant(Long flowLinkNo, String code) {
 
         ExampleInfo exampleInfo = exampleInfoService.getOne(
                 Wrappers.<ExampleInfo>lambdaQuery()
-                        .eq(ExampleInfo::getBusinessId, businessId)
+                        .eq(ExampleInfo::getFlowLinkNo, flowLinkNo)
                         .eq(ExampleInfo::getComplete, StatusConstant.No));
 
         Assert.empty(exampleInfo, FlowExplainConstant.EXPLAIN_NOT_EXIST);
@@ -123,11 +123,11 @@ public class FlowClient implements IFlowClient {
     }
 
     @Override
-    public R<ExampleInfo> getExampleInfo(Long businessId) {
+    public R<ExampleInfo> getExampleInfo(Long flowLinkNo) {
 
         ExampleInfo exampleInfo = exampleInfoService.getOne(
                 Wrappers.<ExampleInfo>lambdaQuery()
-                        .eq(ExampleInfo::getBusinessId, businessId)
+                        .eq(ExampleInfo::getFlowLinkNo, flowLinkNo)
                         .eq(ExampleInfo::getComplete, StatusConstant.No));
 
         Assert.notEmpty(exampleInfo, FlowExplainConstant.EXAMPLE_INFO_NULL);

+ 1 - 1
hx-service-api/service-flow-api/src/main/java/com/fjhx/entity/example/ExampleInfo.java

@@ -47,7 +47,7 @@ public class ExampleInfo extends BaseEntity {
     /**
      * 业务id
      */
-    private Long businessId;
+    private Long flowLinkNo;
 
     /**
      * 缓存数据

+ 2 - 2
hx-service-api/service-flow-api/src/main/java/com/fjhx/feign/IFlowClient.java

@@ -27,7 +27,7 @@ public interface IFlowClient {
      * 通过流程编码获取流程信息
      */
     @PostMapping(GET_FLOW_INFO)
-    R<FlowInfo> getProcessTenant(@RequestParam("businessId") Long businessId, @RequestParam("code") String code);
+    R<FlowInfo> getProcessTenant(@RequestParam("flowLinkNo") Long flowLinkNo, @RequestParam("code") String code);
 
     /**
      * 获取下一节点
@@ -45,6 +45,6 @@ public interface IFlowClient {
      * 获取流程实例
      */
     @PostMapping(GET_EXAMPLE_INFO)
-    R<ExampleInfo> getExampleInfo(@RequestParam("businessId") Long businessId);
+    R<ExampleInfo> getExampleInfo(@RequestParam("flowLinkNo") Long flowLinkNo);
 
 }

+ 7 - 7
hx-service-api/service-flow-api/src/main/java/com/fjhx/utils/FlowConstructor.java

@@ -40,24 +40,24 @@ public class FlowConstructor {
     /**
      * 创建流程
      *
-     * @param businessId 给予流程关联业务id
+     * @param flowLinkNo 流程关联编号
      * @return 流程实例对象
      */
-    public ExampleInfo create(Long businessId, String remarks) {
+    public ExampleInfo create(Long flowLinkNo, String remarks) {
 
         // 获取流程编码
         String code = exampleAbstract.getCode();
         Assert.notEmpty(code, FlowExplainConstant.CODE_EMPTY);
 
         // 获取租户流程
-        R<FlowInfo> r = flowClient.getProcessTenant(businessId, code);
+        R<FlowInfo> r = flowClient.getProcessTenant(flowLinkNo, code);
         Assert.eqTrue(r.isSuccess(), r.getMsg());
         FlowInfo flowInfo = r.getData();
 
         // 创建流程实例
         ExampleInfoEx exampleInfo = new ExampleInfoEx();
         exampleInfo.setProcessInfoId(flowInfo.getId());
-        exampleInfo.setBusinessId(businessId);
+        exampleInfo.setFlowLinkNo(flowLinkNo);
         exampleInfo.setCacheData(JSONObject.toJSONString(exampleAbstract.cacheData));
 
         ExampleDetails startExampleDetails = new ExampleDetails();
@@ -126,13 +126,13 @@ public class FlowConstructor {
     /**
      * 流程跳转
      *
-     * @param businessId 业务id
+     * @param flowLinkNo 流程关联编号
      * @param buttonId   按钮id
      * @param remarks    审批意见
      */
-    public void jump(Long businessId, Long buttonId, String remarks) {
+    public void jump(Long flowLinkNo, Long buttonId, String remarks) {
 
-        R<ExampleInfo> exampleInfoResult = flowClient.getExampleInfo(businessId);
+        R<ExampleInfo> exampleInfoResult = flowClient.getExampleInfo(flowLinkNo);
         Assert.eqTrue(exampleInfoResult.isSuccess(), exampleInfoResult.getMsg());
 
         ExampleInfo exampleInfo = exampleInfoResult.getData();