Browse Source

售后管理

yzc 1 year ago
parent
commit
e24f4377d9
37 changed files with 1332 additions and 56 deletions
  1. 5 0
      code/src/test/java/DataSourceInfo.java
  2. 3 3
      code/src/test/java/SaleDataSource.java
  3. 9 0
      hx-common/src/main/java/com/fjhx/common/enums/CodingRuleEnum.java
  4. 68 0
      hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesController.java
  5. 34 0
      hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesDetailController.java
  6. 49 0
      hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesRecordsController.java
  7. 11 1
      hx-sale/src/main/java/com/fjhx/sale/controller/contract/ContractProductController.java
  8. 17 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDetailDto.java
  9. 17 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDetailSelectDto.java
  10. 22 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDto.java
  11. 17 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesRecordsDto.java
  12. 17 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesRecordsSelectDto.java
  13. 25 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesSelectDto.java
  14. 90 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSales.java
  15. 70 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSalesDetail.java
  16. 46 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSalesRecords.java
  17. 52 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesDetailVo.java
  18. 22 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesRecordsVo.java
  19. 24 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesVo.java
  20. 9 0
      hx-sale/src/main/java/com/fjhx/sale/entity/contract/vo/ContractBudgetVo.java
  21. 148 0
      hx-sale/src/main/java/com/fjhx/sale/flow/AfterSalesFlow.java
  22. 7 0
      hx-sale/src/main/java/com/fjhx/sale/flow/ContractFlow.java
  23. 26 0
      hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesDetailMapper.java
  24. 28 0
      hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesMapper.java
  25. 23 0
      hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesRecordsMapper.java
  26. 27 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesDetailService.java
  27. 39 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesRecordsService.java
  28. 42 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesService.java
  29. 61 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesDetailServiceImpl.java
  30. 49 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesRecordsServiceImpl.java
  31. 154 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesServiceImpl.java
  32. 29 30
      hx-sale/src/main/java/com/fjhx/sale/service/contract/impl/ContractProductServiceImpl.java
  33. 23 5
      hx-sale/src/main/java/com/fjhx/sale/service/contract/impl/ContractServiceImpl.java
  34. 10 0
      hx-sale/src/main/resources/mapper/after/AfterSalesDetailMapper.xml
  35. 39 0
      hx-sale/src/main/resources/mapper/after/AfterSalesMapper.xml
  36. 9 0
      hx-sale/src/main/resources/mapper/after/AfterSalesRecordsMapper.xml
  37. 11 17
      hx-sale/src/main/resources/mapper/contract/ContractProductMapper.xml

+ 5 - 0
code/src/test/java/DataSourceInfo.java

@@ -0,0 +1,5 @@
+public class DataSourceInfo {
+    public final static String URL = "jdbc:mysql://121.37.194.75:30102/%s?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai";
+    public final static String USER_NAME = "root";
+    public final static String PASSWORD = "5fWD*oa^nso@kmKa";
+}

+ 3 - 3
code/src/test/java/SaleDataSource.java

@@ -4,9 +4,9 @@ public class SaleDataSource {
 
     public static void main(String[] args) {
         GeneratorApplication.builder()
-                .url("jdbc:mysql://36.134.91.96:12333/bytesailing_sale?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true")
-                .username("root")
-                .password("Fjhx@pwd123")
+                .url(String.format(DataSourceInfo.URL, "bytesailing_sale"))
+                .username(DataSourceInfo.USER_NAME)
+                .password(DataSourceInfo.PASSWORD)
                 .port(9989)
                 .module("hx-sale")
                 .parent("com.fjhx.sale")

+ 9 - 0
hx-common/src/main/java/com/fjhx/common/enums/CodingRuleEnum.java

@@ -116,6 +116,15 @@ public enum CodingRuleEnum {
             getDefaultRule(RuleTypeEnum.DATE_FORMAT, "yyyyMM-"),
             getDefaultRule(RuleTypeEnum.AUTOINCREMENT, "3")
     )),
+
+    /**
+     * 售后
+     */
+    AFTER_SALES("AFTER_SALES", "售后管理", Arrays.asList(
+            getDefaultRule(RuleTypeEnum.CUSTOMIZE, "AS-"),
+            getDefaultRule(RuleTypeEnum.DATE_FORMAT, "yyyyMM-"),
+            getDefaultRule(RuleTypeEnum.AUTOINCREMENT, "3")
+    )),
     ;
 
     /**

+ 68 - 0
hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesController.java

@@ -0,0 +1,68 @@
+package com.fjhx.sale.controller.after;
+
+import org.springframework.web.bind.annotation.*;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.sale.entity.after.vo.AfterSalesVo;
+import com.fjhx.sale.entity.after.dto.AfterSalesSelectDto;
+import com.fjhx.sale.entity.after.dto.AfterSalesDto;
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import com.fjhx.sale.service.after.AfterSalesService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+
+/**
+ * <p>
+ * 售后管理 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@RestController
+@RequestMapping("/afterSales")
+public class AfterSalesController {
+
+    @Autowired
+    private AfterSalesService afterSalesService;
+
+    /**
+     * 售后管理分页
+     */
+    @PostMapping("/page")
+    public Page<AfterSalesVo> page(@RequestBody AfterSalesSelectDto dto) {
+        return afterSalesService.getPage(dto);
+    }
+
+    /**
+     * 售后管理明细
+     */
+    @PostMapping("/detail")
+    public AfterSalesVo detail(@RequestBody BaseSelectDto dto) {
+        return afterSalesService.detail(dto.getId());
+    }
+
+    /**
+     * 售后管理新增
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody AfterSalesDto afterSalesDto) {
+        afterSalesService.addOrEdit(afterSalesDto);
+    }
+
+    /**
+     * 售后管理编辑
+     */
+    @PostMapping("/edit")
+    public void edit(@RequestBody AfterSalesDto afterSalesDto) {
+        afterSalesService.addOrEdit(afterSalesDto);
+    }
+
+    /**
+     * 售后管理删除
+     */
+    @PostMapping("/delete")
+    public void delete(@RequestBody BaseSelectDto dto) {
+        afterSalesService.delete(dto.getId());
+    }
+
+}

+ 34 - 0
hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesDetailController.java

@@ -0,0 +1,34 @@
+package com.fjhx.sale.controller.after;
+
+import org.springframework.web.bind.annotation.*;
+import com.fjhx.sale.entity.after.vo.AfterSalesDetailVo;
+import com.fjhx.sale.entity.after.dto.AfterSalesDetailSelectDto;
+import com.fjhx.sale.service.after.AfterSalesDetailService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 售后明细 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@RestController
+@RequestMapping("/afterSalesDetail")
+public class AfterSalesDetailController {
+
+    @Autowired
+    private AfterSalesDetailService afterSalesDetailService;
+
+    /**
+     * 售后明细列表
+     */
+    @PostMapping("/list")
+    public List<AfterSalesDetailVo> list(@RequestBody AfterSalesDetailSelectDto dto) {
+        return afterSalesDetailService.getList(dto);
+    }
+
+}

+ 49 - 0
hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesRecordsController.java

@@ -0,0 +1,49 @@
+package com.fjhx.sale.controller.after;
+
+import org.springframework.web.bind.annotation.*;
+import com.fjhx.sale.entity.after.dto.AfterSalesRecordsDto;
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import com.fjhx.sale.service.after.AfterSalesRecordsService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+
+/**
+ * <p>
+ * 售后跟进记录 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@RestController
+@RequestMapping("/afterSalesRecords")
+public class AfterSalesRecordsController {
+
+    @Autowired
+    private AfterSalesRecordsService afterSalesRecordsService;
+
+    /**
+     * 售后跟进记录新增
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody AfterSalesRecordsDto afterSalesRecordsDto) {
+        afterSalesRecordsService.add(afterSalesRecordsDto);
+    }
+
+    /**
+     * 售后跟进记录编辑
+     */
+    @PostMapping("/edit")
+    public void edit(@RequestBody AfterSalesRecordsDto afterSalesRecordsDto) {
+        afterSalesRecordsService.edit(afterSalesRecordsDto);
+    }
+
+    /**
+     * 售后跟进记录删除
+     */
+    @PostMapping("/delete")
+    public void delete(@RequestBody BaseSelectDto dto) {
+        afterSalesRecordsService.delete(dto.getId());
+    }
+
+}

+ 11 - 1
hx-sale/src/main/java/com/fjhx/sale/controller/contract/ContractProductController.java

@@ -34,13 +34,23 @@ public class ContractProductController {
     public Page<ContractProductVo> page(@RequestBody ContractProductSelectDto dto) {
         return contractProductService.getPage(dto);
     }
+
+    /**
+     * 售后合同产品分页
+     */
+    @PostMapping("/afterSalesPage")
+    public Page<ContractProductVo> AfterSalesPage(@RequestBody ContractProductSelectDto dto) {
+        return contractProductService.getPage(dto);
+    }
+
     /**
      * 根据合同ID和客户ID查询未包装的产品
      */
     @GetMapping("/getNoPackContractProductById")
-    public List<ContractProductVo> getNoPackContractProductById(@RequestParam("customerId")String customerId, @RequestParam("contractIds")String contractIds) {
+    public List<ContractProductVo> getNoPackContractProductById(@RequestParam("customerId") String customerId, @RequestParam("contractIds") String contractIds) {
         return contractProductService.getNoPackContractProductById(customerId, contractIds);
     }
+
     /**
      * 外销合同-产品ID集合查询产品
      */

+ 17 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDetailDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后明细新增编辑入参实体
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+public class AfterSalesDetailDto extends AfterSalesDetail {
+
+}

+ 17 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDetailSelectDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后明细列表查询入参实体
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+public class AfterSalesDetailSelectDto extends BaseSelectDto {
+
+}

+ 22 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDto.java

@@ -0,0 +1,22 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.fjhx.sale.entity.after.po.AfterSales;
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 售后管理新增编辑入参实体
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+public class AfterSalesDto extends AfterSales {
+
+    List<AfterSalesDetail> afterSalesDetailList;
+
+}

+ 17 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesRecordsDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后跟进记录新增编辑入参实体
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+public class AfterSalesRecordsDto extends AfterSalesRecords {
+
+}

+ 17 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesRecordsSelectDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后跟进记录列表查询入参实体
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+public class AfterSalesRecordsSelectDto extends BaseSelectDto {
+
+}

+ 25 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesSelectDto.java

@@ -0,0 +1,25 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后管理列表查询入参实体
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+public class AfterSalesSelectDto extends BaseSelectDto {
+    /**
+     * 售后类型 字典
+     */
+    private String type;
+
+    /**
+     * 售后状态 0进行中1关闭
+     */
+    private Integer status;
+}

+ 90 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSales.java

@@ -0,0 +1,90 @@
+package com.fjhx.sale.entity.after.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * <p>
+ * 售后管理
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+@TableName("after_sales")
+public class AfterSales extends BasePo {
+
+    /**
+     * 售后单号
+     */
+    private String code;
+
+    /**
+     * 售后类型 字典
+     */
+    private String type;
+
+    /**
+     * 说明
+     */
+    private String remark;
+
+    /**
+     * 原因
+     */
+    private String reason;
+
+    /**
+     * 售后金额
+     */
+    private BigDecimal amount;
+
+    /**
+     * 初判责任方
+     */
+    private String dutyParty;
+
+    /**
+     * 联系人名称
+     */
+    private String contactName;
+
+    /**
+     * 联系人电话
+     */
+    private String contactTel;
+
+    /**
+     * 开户行
+     */
+    private String accountBank;
+
+    /**
+     * 账户名
+     */
+    private String accountName;
+
+    /**
+     * 账号
+     */
+    private String accountNumber;
+
+    /**
+     * 售后状态 0进行中1关闭
+     */
+    private Integer status;
+
+    private Long flowId;
+
+    /**
+     * 销售合同id
+     */
+    private Long contractId;
+
+}

+ 70 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSalesDetail.java

@@ -0,0 +1,70 @@
+package com.fjhx.sale.entity.after.po;
+
+import com.ruoyi.common.core.domain.BasePo;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 售后明细
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+@TableName("after_sales_detail")
+public class AfterSalesDetail extends BasePo {
+
+    /**
+     * 售后id
+     */
+    private Long afterSalesId;
+
+    /**
+     * 产品id
+     */
+    private Long productId;
+
+    /**
+     * 售后数量
+     */
+    private BigDecimal quantity;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 合同产品明细id
+     */
+    private Long contractProductId;
+
+    /**
+     * 单价
+     */
+    private BigDecimal price;
+
+    /**
+     * 金额
+     */
+    private BigDecimal amount;
+
+    /**
+     * 售后状态 0进行中1关闭
+     */
+    private Integer status;
+
+    /**
+     * 合同id
+     */
+    private Long contractId;
+
+}

+ 46 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSalesRecords.java

@@ -0,0 +1,46 @@
+package com.fjhx.sale.entity.after.po;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.core.domain.BasePo;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.util.Date;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 售后跟进记录
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+@TableName("after_sales_records")
+public class AfterSalesRecords extends BasePo {
+
+    /**
+     * 售后id
+     */
+    private Long afterSalesId;
+
+    /**
+     * 跟进时间
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
+    private Date followUpTime;
+
+    /**
+     * 跟进用户id
+     */
+    private Long followUpUserId;
+
+    /**
+     * 说明
+     */
+    private String remark;
+
+}

+ 52 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesDetailVo.java

@@ -0,0 +1,52 @@
+package com.fjhx.sale.entity.after.vo;
+
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 售后明细列表查询返回值实体
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+public class AfterSalesDetailVo extends AfterSalesDetail {
+
+
+    /**
+     * 所属类型
+     */
+    private String productType;
+
+    /**
+     * 货品编码
+     */
+    private String productCode;
+
+    /**
+     * 货品名称
+     */
+    private String productName;
+
+    /**
+     * 规格型号
+     */
+    private String productSpec;
+
+    /**
+     * 单位
+     */
+    private String productUnit;
+
+    /**
+     * 商品型号
+     */
+    private String productModel;
+
+    private BigDecimal contractQuantity;
+
+}

+ 22 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesRecordsVo.java

@@ -0,0 +1,22 @@
+package com.fjhx.sale.entity.after.vo;
+
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后跟进记录列表查询返回值实体
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+public class AfterSalesRecordsVo extends AfterSalesRecords {
+
+    /**
+     * 跟进用户id
+     */
+    private String followUpUserName;
+
+}

+ 24 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesVo.java

@@ -0,0 +1,24 @@
+package com.fjhx.sale.entity.after.vo;
+
+import com.fjhx.sale.entity.after.po.AfterSales;
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 售后管理列表查询返回值实体
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Getter
+@Setter
+public class AfterSalesVo extends AfterSales {
+
+    List<AfterSalesRecordsVo> afterSalesRecordsList;
+    List<AfterSalesDetailVo> afterSalesDetailList;
+    private String contractCode;
+
+}

+ 9 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/contract/vo/ContractBudgetVo.java

@@ -246,6 +246,15 @@ public class ContractBudgetVo extends Contract {
          * 对比上一版本
          */
         private BigDecimal compareLastGross;
+
+        /**
+         * 合同id
+         */
+        private Long contractId;
+        /**
+         * 采购id
+         */
+        private Long purchaseId;
     }
 
 }

+ 148 - 0
hx-sale/src/main/java/com/fjhx/sale/flow/AfterSalesFlow.java

@@ -0,0 +1,148 @@
+package com.fjhx.sale.flow;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.fjhx.account.entity.account.dto.AccountPaymentDto;
+import com.fjhx.account.entity.account.enums.PaymentStatusEnum;
+import com.fjhx.account.service.account.AccountPaymentService;
+import com.fjhx.common.enums.CodingRuleEnum;
+import com.fjhx.common.enums.FlowStatusEnum1;
+import com.fjhx.common.service.coding.CodingRuleService;
+import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.entity.flow.dto.InitiateDto;
+import com.fjhx.flow.enums.FlowStatusEnum;
+import com.fjhx.flow.service.flow.FlowProcessService;
+import com.fjhx.sale.entity.after.dto.AfterSalesDto;
+import com.fjhx.sale.entity.after.po.AfterSales;
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import com.fjhx.sale.entity.contract.dto.ContractDto;
+import com.fjhx.sale.entity.contract.po.ContractProduct;
+import com.fjhx.sale.service.after.AfterSalesDetailService;
+import com.fjhx.sale.service.after.AfterSalesService;
+import com.fjhx.sale.service.contract.ContractService;
+import com.fjhx.tenant.utils.DictUtils;
+import com.ruoyi.common.utils.SecurityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class AfterSalesFlow extends FlowDelegate {
+
+    @Autowired
+    private AfterSalesService afterSalesService;
+    @Autowired
+    private AfterSalesDetailService afterSalesDetailService;
+    @Autowired
+    private CodingRuleService codingRuleService;
+    @Autowired
+    private AccountPaymentService accountPaymentService;
+    @Autowired
+    private ContractService contractService;
+    @Autowired
+    private FlowProcessService flowProcessService;
+
+    @Override
+    public String getFlowKey() {
+        return "after_sales_flow";
+    }
+
+    @Override
+    public Long start(Long flowId, JSONObject submitData) {
+        AfterSalesDto afterSalesDto = submitData.toJavaObject(AfterSalesDto.class);
+
+        afterSalesDto.setFlowId(flowId);
+        afterSalesDto.setStatus(FlowStatusEnum1.UNDER_REVIEW.getKey());
+        afterSalesDto.setCode(codingRuleService.createCode(CodingRuleEnum.AFTER_SALES.getKey(), null));
+        afterSalesService.addOrEdit(afterSalesDto);
+
+        return afterSalesDto.getId();
+    }
+
+    @Override
+    public void end(Long flowId, Long businessId, JSONObject submitData) {
+        afterSalesService.update(q -> q
+                .eq(AfterSales::getId, businessId)
+                .set(AfterSales::getStatus, FlowStatusEnum1.PASS.getKey())
+                .set(AfterSales::getUpdateTime, new Date())
+                .set(AfterSales::getUpdateUser, SecurityUtils.getUserId())
+        );
+
+        AfterSales afterSales = afterSalesService.getById(businessId);
+        Map<String, String> dictMap = DictUtils.getDictMap("after_sales_type");
+        String type = afterSales.getType();
+        type += dictMap.getOrDefault(type, "");
+        //(1)如果审批通过,且售后类型=退货退款:后续跟进补充运单号,自动生成财务打款数据
+        //(2)如果审批通过,且售后类型=仅退款:自动生成财务打款数据
+        if (type.contains("退货退款") || type.contains("仅退款")) {
+            AccountPaymentDto accountPayment = new AccountPaymentDto();
+//            accountPayment.setDepartmentId(accountRequestFunds.getDepartmentId());
+//            accountPayment.setCorporationId(accountRequestFunds.getCorporationId());
+            accountPayment.setBusinessId(afterSales.getId());
+            accountPayment.setPaymentTime(new Date());
+            accountPayment.setCurrency("CNY");
+            accountPayment.setStatus(PaymentStatusEnum.UNDER_REVIEW.getKey());
+            accountPayment.setType("40");//售后
+//            accountPayment.setPaymentRemark();
+            accountPayment.setPaymentMethod("bank");
+            accountPayment.setIncomeAmount(afterSales.getAmount());
+            accountPayment.setName(afterSales.getAccountName());
+//            accountPayment.setBusinessManagementId(accountRequestFunds.getAccountManagementId());
+            accountPayment.setOpeningBank(afterSales.getAccountBank());
+            accountPayment.setAccountOpening(afterSales.getAccountNumber());
+//            accountPayment.setInterbankNumber(accountRequestFunds.getInterbankNumber());
+            accountPayment.setDataUser(afterSales.getCreateUser());
+            accountPayment.setAmount(BigDecimal.ZERO);
+            accountPaymentService.save(accountPayment);
+        }
+        //(3)如果审批通过,且售后类型=补发/换货:自动生成订单,单价=0
+        if (type.contains("补发") || type.contains("换货")) {
+            ContractDto contractDto = BeanUtil.copyProperties(contractService.getById(afterSales.getContractId()), ContractDto.class);
+            contractDto.setId(null);
+            contractDto.setAmount(BigDecimal.ZERO);
+            List<AfterSalesDetail> afterSalesDetailList = afterSalesDetailService.list(q -> q.eq(AfterSalesDetail::getAfterSalesId, afterSales.getId()));
+            List<ContractProduct> contractProductList = new ArrayList<>();
+            for (AfterSalesDetail afterSalesDetail : afterSalesDetailList) {
+                ContractProduct contractProduct = new ContractProduct();
+                contractProduct.setProductId(afterSalesDetail.getProductId());
+                contractProduct.setPrice(BigDecimal.ZERO);
+                contractProduct.setAmount(BigDecimal.ZERO);
+                contractProduct.setQuantity(afterSalesDetail.getQuantity());
+                contractProductList.add(contractProduct);
+            }
+            contractDto.setContractProductList(contractProductList);
+
+            //生成合同审批数据
+            InitiateDto initiateDto = new InitiateDto();
+            initiateDto.setFlowKey("contract_flow");
+            initiateDto.setData(JSONObject.parseObject(JSONObject.toJSONString(contractDto)));
+            flowProcessService.initiate(initiateDto);
+        }
+    }
+
+    @Override
+    public void relaunch(Long flowId, Long businessId, FlowStatusEnum flowStatus, JSONObject submitData) {
+        AfterSalesDto afterSalesDto = submitData.toJavaObject(AfterSalesDto.class);
+        afterSalesService.addOrEdit(afterSalesDto);
+    }
+
+    @Override
+    public void reject(Long flowId, Long businessId, FlowStatusEnum flowStatus) {
+        afterSalesService.update(q -> q
+                .eq(AfterSales::getId, businessId)
+                .set(AfterSales::getStatus, FlowStatusEnum1.REJECT.getKey())
+                .set(AfterSales::getUpdateTime, new Date())
+                .set(AfterSales::getUpdateUser, SecurityUtils.getUserId())
+        );
+    }
+
+    @Override
+    public void cancellation(Long flowId, Long businessId, FlowStatusEnum flowStatus) {
+        afterSalesService.cancellation(businessId);
+    }
+}

+ 7 - 0
hx-sale/src/main/java/com/fjhx/sale/flow/ContractFlow.java

@@ -30,6 +30,7 @@ import com.ruoyi.common.utils.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
@@ -139,6 +140,9 @@ public class ContractFlow extends FlowDelegate {
 
         // 保存收费项目
         List<ContractProject> contractProjectList = contract.getContractProjectList();
+        if (ObjectUtils.isNull(contractProjectList)) {
+            contractProjectList = new ArrayList<>();
+        }
         //重新发起删除被删掉的收费项目
         contractProjectService.editLinked(contractProjectList, ContractProject::getContractId, contract.getId());
         if (CollectionUtils.isNotEmpty(contractProjectList)) {
@@ -150,6 +154,9 @@ public class ContractFlow extends FlowDelegate {
 
         // 保存自定义出货
         List<ContractShipment> contractShipmentList = contract.getContractShipmentList();
+        if (ObjectUtils.isNull(contractShipmentList)) {
+            contractShipmentList = new ArrayList<>();
+        }
         //重新发起删除被删掉的出货计划
         contractShipmentService.editLinked(contractShipmentList, ContractShipment::getContractId, contract.getId());
         if (CollectionUtils.isNotEmpty(contractShipmentList)) {

+ 26 - 0
hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesDetailMapper.java

@@ -0,0 +1,26 @@
+package com.fjhx.sale.mapper.after;
+
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fjhx.sale.entity.after.vo.AfterSalesDetailVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 售后明细 Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+public interface AfterSalesDetailMapper extends BaseMapper<AfterSalesDetail> {
+
+    /**
+     * 售后明细列表
+     */
+    List<AfterSalesDetailVo> getList(@Param("ew") IWrapper<AfterSalesDetail> wrapper);
+
+}

+ 28 - 0
hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesMapper.java

@@ -0,0 +1,28 @@
+package com.fjhx.sale.mapper.after;
+
+import com.fjhx.sale.entity.after.po.AfterSales;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.sale.entity.after.vo.AfterSalesVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+
+/**
+ * <p>
+ * 售后管理 Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+public interface AfterSalesMapper extends BaseMapper<AfterSales> {
+
+    /**
+     * 售后管理分页
+     */
+    Page<AfterSalesVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<AfterSales> wrapper);
+
+    AfterSalesVo detail(@Param("ew") IWrapper<Object> wrapper);
+
+}

+ 23 - 0
hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesRecordsMapper.java

@@ -0,0 +1,23 @@
+package com.fjhx.sale.mapper.after;
+
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fjhx.sale.entity.after.vo.AfterSalesRecordsVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+
+/**
+ * <p>
+ * 售后跟进记录 Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+public interface AfterSalesRecordsMapper extends BaseMapper<AfterSalesRecords> {
+
+    List<AfterSalesRecordsVo> getList(@Param("ew") IWrapper wrapper);
+}

+ 27 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesDetailService.java

@@ -0,0 +1,27 @@
+package com.fjhx.sale.service.after;
+
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import com.ruoyi.common.core.service.BaseService;
+import com.fjhx.sale.entity.after.vo.AfterSalesDetailVo;
+import com.fjhx.sale.entity.after.dto.AfterSalesDetailSelectDto;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 售后明细 服务类
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+public interface AfterSalesDetailService extends BaseService<AfterSalesDetail> {
+
+    /**
+     * 售后明细列表
+     */
+    List<AfterSalesDetailVo> getList(AfterSalesDetailSelectDto dto);
+
+    List<AfterSalesDetailVo> getList(IWrapper wrapper);
+}

+ 39 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesRecordsService.java

@@ -0,0 +1,39 @@
+package com.fjhx.sale.service.after;
+
+import com.fjhx.sale.entity.after.dto.AfterSalesRecordsDto;
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import com.fjhx.sale.entity.after.vo.AfterSalesRecordsVo;
+import com.ruoyi.common.core.service.BaseService;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+
+import java.util.List;
+
+
+/**
+ * <p>
+ * 售后跟进记录 服务类
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+public interface AfterSalesRecordsService extends BaseService<AfterSalesRecords> {
+
+    List<AfterSalesRecordsVo> getList(IWrapper wrapper);
+
+    /**
+     * 售后跟进记录新增
+     */
+    void add(AfterSalesRecordsDto afterSalesRecordsDto);
+
+    /**
+     * 售后跟进记录编辑
+     */
+    void edit(AfterSalesRecordsDto afterSalesRecordsDto);
+
+    /**
+     * 售后跟进记录删除
+     */
+    void delete(Long id);
+
+}

+ 42 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesService.java

@@ -0,0 +1,42 @@
+package com.fjhx.sale.service.after;
+
+import com.fjhx.sale.entity.after.po.AfterSales;
+import com.ruoyi.common.core.service.BaseService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.sale.entity.after.vo.AfterSalesVo;
+import com.fjhx.sale.entity.after.dto.AfterSalesSelectDto;
+import com.fjhx.sale.entity.after.dto.AfterSalesDto;
+
+
+/**
+ * <p>
+ * 售后管理 服务类
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+public interface AfterSalesService extends BaseService<AfterSales> {
+
+    /**
+     * 售后管理分页
+     */
+    Page<AfterSalesVo> getPage(AfterSalesSelectDto dto);
+
+    /**
+     * 售后管理明细
+     */
+    AfterSalesVo detail(Long id);
+
+    /**
+     * 售后管理新增
+     */
+    void addOrEdit(AfterSalesDto afterSalesDto);
+
+    /**
+     * 售后管理删除
+     */
+    void delete(Long id);
+
+    void cancellation(Long businessId);
+}

+ 61 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesDetailServiceImpl.java

@@ -0,0 +1,61 @@
+package com.fjhx.sale.service.after.impl;
+
+import com.alibaba.druid.sql.visitor.functions.Concat;
+import com.fjhx.item.service.product.ProductInfoService;
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import com.fjhx.sale.mapper.after.AfterSalesDetailMapper;
+import com.fjhx.sale.service.after.AfterSalesDetailService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.sale.service.contract.ContractProductService;
+import com.fjhx.wms.entity.arrival.vo.ArrivalStockRecordsDetailsVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.fjhx.sale.entity.after.vo.AfterSalesDetailVo;
+import com.fjhx.sale.entity.after.dto.AfterSalesDetailSelectDto;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 售后明细 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Service
+public class AfterSalesDetailServiceImpl extends ServiceImpl<AfterSalesDetailMapper, AfterSalesDetail> implements AfterSalesDetailService {
+    @Autowired
+    private ProductInfoService productInfoService;
+    @Autowired
+    private ContractProductService contractProductService;
+
+    @Override
+    public List<AfterSalesDetailVo> getList(AfterSalesDetailSelectDto dto) {
+        IWrapper<AfterSalesDetail> wrapper = getWrapper();
+        wrapper.orderByDesc("asd", AfterSalesDetail::getId);
+        List<AfterSalesDetailVo> list = this.getList(wrapper);
+        return list;
+    }
+
+    @Override
+    public List<AfterSalesDetailVo> getList(IWrapper wrapper) {
+        List<AfterSalesDetailVo> list = this.baseMapper.getList(wrapper);
+        //赋值产品信息
+        productInfoService.attributeAssign(list, AfterSalesDetailVo::getProductId, (item, productInfo) -> {
+            item.setProductName(productInfo.getName());
+            item.setProductType(productInfo.getType());
+            item.setProductCode(productInfo.getCustomCode());
+            item.setProductUnit(productInfo.getUnit());
+            item.setProductSpec(productInfo.getSpec());
+        });
+        //赋值产品信息
+        contractProductService.attributeAssign(list, AfterSalesDetailVo::getContractProductId, (item, contractProduct) -> {
+            item.setProductModel(contractProduct.getProductModel());
+            item.setContractQuantity(contractProduct.getQuantity());
+        });
+        return list;
+    }
+
+}

+ 49 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesRecordsServiceImpl.java

@@ -0,0 +1,49 @@
+package com.fjhx.sale.service.after.impl;
+
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import com.fjhx.sale.entity.after.vo.AfterSalesRecordsVo;
+import com.fjhx.sale.mapper.after.AfterSalesRecordsMapper;
+import com.fjhx.sale.service.after.AfterSalesRecordsService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.ruoyi.system.utils.UserUtil;
+import org.springframework.stereotype.Service;
+import com.fjhx.sale.entity.after.dto.AfterSalesRecordsDto;
+
+import java.util.List;
+
+
+/**
+ * <p>
+ * 售后跟进记录 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Service
+public class AfterSalesRecordsServiceImpl extends ServiceImpl<AfterSalesRecordsMapper, AfterSalesRecords> implements AfterSalesRecordsService {
+
+    @Override
+    public List<AfterSalesRecordsVo> getList(IWrapper wrapper) {
+        List<AfterSalesRecordsVo> list = baseMapper.getList(wrapper);
+        UserUtil.assignmentNickName(list, AfterSalesRecords::getFollowUpUserId, AfterSalesRecordsVo::setFollowUpUserName);
+        return list;
+    }
+
+    @Override
+    public void add(AfterSalesRecordsDto afterSalesRecordsDto) {
+        this.save(afterSalesRecordsDto);
+    }
+
+    @Override
+    public void edit(AfterSalesRecordsDto afterSalesRecordsDto) {
+        this.updateById(afterSalesRecordsDto);
+    }
+
+    @Override
+    public void delete(Long id) {
+        this.removeById(id);
+    }
+
+}

+ 154 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesServiceImpl.java

@@ -0,0 +1,154 @@
+package com.fjhx.sale.service.after.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.common.constant.SourceConstant;
+import com.fjhx.common.enums.FlowStatusEnum1;
+import com.fjhx.flow.entity.flow.po.FlowExample;
+import com.fjhx.flow.enums.FlowStatusEnum;
+import com.fjhx.flow.service.flow.FlowExampleService;
+import com.fjhx.sale.entity.after.dto.AfterSalesDto;
+import com.fjhx.sale.entity.after.dto.AfterSalesSelectDto;
+import com.fjhx.sale.entity.after.po.AfterSales;
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import com.fjhx.sale.entity.after.vo.AfterSalesDetailVo;
+import com.fjhx.sale.entity.after.vo.AfterSalesRecordsVo;
+import com.fjhx.sale.entity.after.vo.AfterSalesVo;
+import com.fjhx.sale.mapper.after.AfterSalesMapper;
+import com.fjhx.sale.service.after.AfterSalesDetailService;
+import com.fjhx.sale.service.after.AfterSalesRecordsService;
+import com.fjhx.sale.service.after.AfterSalesService;
+import com.fjhx.sale.service.contract.ContractProductService;
+import com.ruoyi.common.core.domain.BasePo;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.ruoyi.common.utils.wrapper.SqlField;
+import com.ruoyi.system.utils.UserUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+/**
+ * <p>
+ * 售后管理 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2024-04-07
+ */
+@Service
+public class AfterSalesServiceImpl extends ServiceImpl<AfterSalesMapper, AfterSales> implements AfterSalesService {
+
+    @Autowired
+    private ContractProductService contractProductService;
+    @Autowired
+    private AfterSalesDetailService afterSalesDetailService;
+    @Autowired
+    private FlowExampleService flowExampleService;
+    @Autowired
+    private AfterSalesRecordsService afterSalesRecordsService;
+
+    @Override
+    public Page<AfterSalesVo> getPage(AfterSalesSelectDto dto) {
+        IWrapper<AfterSales> wrapper = getWrapper();
+
+        wrapper.keyword(dto.getKeyword(), new SqlField("c.code"));
+
+        wrapper.eq("as1", AfterSales::getStatus, dto.getStatus());
+        wrapper.eq("as1", AfterSales::getType, dto.getType());
+
+        wrapper.orderByDesc("as1", AfterSales::getId);
+        Page<AfterSalesVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+        List<AfterSalesVo> records = page.getRecords();
+        setInfo(records);
+        return page;
+    }
+
+    private void setInfo(List<AfterSalesVo> records) {
+        if (ObjectUtil.isEmpty(records)) {
+            return;
+        }
+        List<Long> asIds = records.stream().map(AfterSales::getId).collect(Collectors.toList());
+        //赋值跟进记录
+        List<AfterSalesRecordsVo> afterSalesRecordList = afterSalesRecordsService.getList(IWrapper.getWrapper().in(AfterSalesRecords::getAfterSalesId, asIds));
+        Map<Long, List<AfterSalesRecordsVo>> collect = afterSalesRecordList.stream().collect(Collectors.groupingBy(AfterSalesRecords::getAfterSalesId));
+        for (AfterSalesVo record : records) {
+            record.setAfterSalesRecordsList(collect.getOrDefault(record.getId(), new ArrayList<>()));
+        }
+    }
+
+    private void setDetail(List<AfterSalesVo> records) {
+        if (ObjectUtil.isEmpty(records)) {
+            return;
+        }
+        List<Long> asIds = records.stream().map(AfterSales::getId).collect(Collectors.toList());
+        //赋值明细
+        List<AfterSalesDetailVo> afterSalesDetailVos = afterSalesDetailService.getList(IWrapper.getWrapper().in("asd", AfterSalesDetail::getAfterSalesId, asIds));
+        Map<Long, List<AfterSalesDetailVo>> collect = afterSalesDetailVos.stream().collect(Collectors.groupingBy(AfterSalesDetail::getAfterSalesId));
+        for (AfterSalesVo record : records) {
+            record.setAfterSalesDetailList(collect.getOrDefault(record.getId(), new ArrayList<>()));
+        }
+    }
+
+    @Override
+    public AfterSalesVo detail(Long id) {
+        AfterSalesVo result = baseMapper.detail(IWrapper.getWrapper().eq("as1", AfterSales::getId, id));
+
+        setInfo(Arrays.asList(result));
+        setDetail(Arrays.asList(result));
+        return result;
+    }
+
+    @DSTransactional
+    @Override
+    public void addOrEdit(AfterSalesDto dto) {
+        List<AfterSalesDetail> afterSalesDetailList = dto.getAfterSalesDetailList();
+        contractProductService.attributeAssign(afterSalesDetailList, AfterSalesDetail::getContractProductId, (item, contractProduct) -> {
+            item.setContractId(contractProduct.getContractId());
+        });
+
+        this.saveOrUpdate(dto);
+        for (AfterSalesDetail afterSalesDetail : afterSalesDetailList) {
+            afterSalesDetail.setAfterSalesId(dto.getId());
+        }
+        afterSalesDetailService.editLinked(afterSalesDetailList, AfterSalesDetail::getAfterSalesId, dto.getId());
+    }
+
+    @Override
+    public void delete(Long id) {
+        this.removeById(id);
+    }
+
+    @DSTransactional
+    @Override
+    public void cancellation(Long id) {
+        AfterSales afterSales = getById(id);
+        this.update(q -> q
+                .eq(AfterSales::getId, id)
+                .set(AfterSales::getStatus, FlowStatusEnum1.CANCELLATION.getKey())
+                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+                .set(BasePo::getUpdateTime, new Date())
+        );
+
+        //销毁审批中的流程
+        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
+        flowExampleService.update(q -> q
+                .eq(FlowExample::getId, afterSales.getFlowId())
+                .in(FlowExample::getStatus, FlowStatusEnum.READY_START.getKey(), FlowStatusEnum.IN_PROGRESS.getKey())
+                .set(FlowExample::getStatus, FlowStatusEnum.CANCELLATION.getKey())
+                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+                .set(BasePo::getUpdateTime, new Date())
+        );
+        DynamicDataSourceContextHolder.poll();
+    }
+
+}

+ 29 - 30
hx-sale/src/main/java/com/fjhx/sale/service/contract/impl/ContractProductServiceImpl.java

@@ -93,21 +93,23 @@ public class ContractProductServiceImpl extends ServiceImpl<ContractProductMappe
     @Override
     public Page<ContractProductVo> getPage(ContractProductSelectDto dto) {
         IWrapper<ContractProduct> wrapper = getWrapper();
-        wrapper.orderByDesc("t1", ContractProduct::getCreateTime);
-        wrapper.ne("t1", ContractProduct::getExpendQuantity, 0);
-        wrapper.between("t2", Contract::getStatus, FlowStatusEnum1.PASS.getKey(), FlowStatusEnum1.CANCELLATION.getKey() - 1);
-        if (ObjectUtil.isNotEmpty(dto.getDataType()) && dto.getDataType() == 0) {//合同交接单
-            wrapper.ne("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
-        }
-        if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 2) {//已采购
-            wrapper.eq("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
-        } else if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 1) {//部分采购
-            wrapper.gt("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
-            wrapper.apply("t1.expend_quantity <t1.quantity");
-        } else if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 0) {//未采购
-            wrapper.apply("t1.expend_quantity = t1.quantity");
-        }
-        wrapper.eq("t2", Contract::getIssue, 1);
+//        wrapper.ne("t1", ContractProduct::getExpendQuantity, 0);
+//        wrapper.between("t2", Contract::getStatus, FlowStatusEnum1.PASS.getKey(), FlowStatusEnum1.CANCELLATION.getKey() - 1);
+//        if (ObjectUtil.isNotEmpty(dto.getDataType()) && dto.getDataType() == 0) {//合同交接单
+//            wrapper.ne("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
+//        }
+//        if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 2) {//已采购
+//            wrapper.eq("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
+//        } else if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 1) {//部分采购
+//            wrapper.gt("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
+//            wrapper.apply("t1.expend_quantity <t1.quantity");
+//        } else if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 0) {//未采购
+//            wrapper.apply("t1.expend_quantity = t1.quantity");
+//        }
+//        wrapper.eq("t2", Contract::getIssue, 1);
+
+        wrapper.in("t2", Contract::getStatus, 10, 30, 60);
+
         if (StringUtils.isNotEmpty(dto.getKeyword())) {
             wrapper.keyword(dto.getKeyword(), new SqlField("t2.`code`"), new SqlField("t2.`user_name`"));
         }
@@ -120,35 +122,32 @@ public class ContractProductServiceImpl extends ServiceImpl<ContractProductMappe
             }
             wrapper.in("t2.contract_template_id", ctIds);
         }
-        //是否到账过滤
-        if (ObjectUtil.isNotEmpty(dto.getIsReceived())) {
-            if (1 == dto.getIsReceived()) {
-                wrapper.isNotNull("co.id");
-            } else {
-                wrapper.isNull("co.id");
-            }
-        }
-        wrapper.groupBy("t1.id");
+//        //是否到账过滤
+//        if (ObjectUtil.isNotEmpty(dto.getIsReceived())) {
+//            if (1 == dto.getIsReceived()) {
+//                wrapper.isNotNull("co.id");
+//            } else {
+//                wrapper.isNull("co.id");
+//            }
+//        }
+
+//        wrapper.groupBy("t1.id");
+        wrapper.orderByDesc("t1", ContractProduct::getCreateTime);
         Page<ContractProductVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
         List<ContractProductVo> list = page.getRecords();
-        List<Long> idList = list.stream().map(ContractProductVo::getId).collect(Collectors.toList());
         if (list.size() == 0) {
             return page;
         }
 
         // 赋值产品属性
         productInfoService.attributeAssign(list, ContractProductVo::getProductId, (item, product) -> {
-            item.setProductCode(product.getCode());
+            item.setProductCode(product.getCustomCode());
             item.setProductUnit(product.getUnit());
             item.setProductType(product.getType());
             item.setProductName(product.getName());
             item.setProductSpec(product.getSpec());
             item.setProductCategoryId(product.getProductClassifyId());
         });
-        //赋值已发起采购数量
-//        List<PurchaseDetailVo> purchaseDetailVoList = purchaseDetailService.getSumCountByDataResourceId(idList);
-//        Map<Long,BigDecimal> pMap = purchaseDetailVoList.stream().collect(Collectors.toMap(PurchaseDetailVo::getDataResourceId,PurchaseDetailVo::getSumCount));
-//        list.forEach(i -> i.setStartPurchaseCount(MapUtils.isNotEmpty(pMap)?BigDecimal.ZERO:pMap.getOrDefault(i.getId(),BigDecimal.ZERO)));
         // 赋值产品分类名称
         productClassifyService.attributeAssign(list, ContractProductVo::getProductCategoryId, (item, productClassify) -> {
             item.setProductCategory(productClassify.getName());

+ 23 - 5
hx-sale/src/main/java/com/fjhx/sale/service/contract/impl/ContractServiceImpl.java

@@ -597,9 +597,11 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract>
                     .sorted(Comparator.comparing(ContractBudgetVo.GrossProfitInfo::getCreateTime)).collect(Collectors.toList());
 
             //计数采购价格
+            Long lastContractId = null;
             BigDecimal lastContractAmount = BigDecimal.ZERO;
             String lastContractCurrency = "";
             BigDecimal lastContractRmbAmount = BigDecimal.ZERO;
+            Long lastPurchaseId = null;
             BigDecimal lastPurchaseAmount = BigDecimal.ZERO;
             for (int i = 0; i < grossProfitInfoList.size(); i++) {
                 ContractBudgetVo.GrossProfitInfo grossProfitInfo = grossProfitInfoList.get(i);
@@ -634,12 +636,22 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract>
 
                     grossProfitInfo.setPurchaseAmount(purchaseAmount);
                     lastPurchaseAmount = purchaseAmount;
+
+                    lastPurchaseId = grossProfitInfo.getId();
+
+                    grossProfitInfo.setPurchaseId(grossProfitInfo.getId());
+                    grossProfitInfo.setContractId(lastContractId);
                 } else {
                     //销售合同节点
                     lastContractAmount = grossProfitInfo.getContractAmount();
                     lastContractRmbAmount = grossProfitInfo.getContractRmbAmount();
                     lastContractCurrency = grossProfitInfo.getContractCurrency();
                     grossProfitInfo.setPurchaseAmount(lastPurchaseAmount);
+
+                    lastContractId = grossProfitInfo.getId();
+
+                    grossProfitInfo.setPurchaseId(lastPurchaseId);
+                    grossProfitInfo.setContractId(grossProfitInfo.getId());
                 }
 //            }
 //
@@ -684,10 +696,13 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract>
                 grossProfitInfo.setGross(grossProfit.setScale(2, BigDecimal.ROUND_HALF_UP));
 
                 //毛利率(毛利/合同金额*100%)
-                BigDecimal grossRate = grossProfitInfo.getGross()
-                        .divide(grossProfitInfo.getContractRmbAmount(), 2, BigDecimal.ROUND_HALF_UP)
-                        .multiply(BigDecimal.valueOf(100));
-                grossProfitInfo.setGrossRate(grossRate);
+                grossProfitInfo.setGrossRate(BigDecimal.ZERO);
+                if (BigDecimal.ZERO.compareTo(grossProfitInfo.getContractRmbAmount()) != 0) {
+                    BigDecimal grossRate = grossProfitInfo.getGross()
+                            .divide(grossProfitInfo.getContractRmbAmount(), 2, BigDecimal.ROUND_HALF_UP)
+                            .multiply(BigDecimal.valueOf(100));
+                    grossProfitInfo.setGrossRate(grossRate);
+                }
                 //对比上一版本利润
                 grossProfitInfo.setCompareLastGross(BigDecimal.ZERO);
                 if ((i - 1) >= 0) {
@@ -874,7 +889,10 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract>
             //计算毛利 收入-支出
             v.setGross(v.getIncomeAmount().subtract(v.getExpenditureAmount()));
             //计算毛利率 毛利/收入
-            v.setGrossRate(v.getGross().divide(v.getIncomeAmount(), RoundingMode.CEILING).multiply(new BigDecimal("100")));
+            v.setGrossRate(BigDecimal.ZERO);
+            if (BigDecimal.ZERO.compareTo(v.getIncomeAmount()) != 0) {
+                v.setGrossRate(v.getGross().divide(v.getIncomeAmount(), RoundingMode.CEILING).multiply(new BigDecimal("100")));
+            }
         }
     }
 

+ 10 - 0
hx-sale/src/main/resources/mapper/after/AfterSalesDetailMapper.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.sale.mapper.after.AfterSalesDetailMapper">
+    <select id="getList" resultType="com.fjhx.sale.entity.after.vo.AfterSalesDetailVo">
+        select asd.*
+        from after_sales_detail asd
+            ${ew.customSqlSegment}
+    </select>
+
+</mapper>

+ 39 - 0
hx-sale/src/main/resources/mapper/after/AfterSalesMapper.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.sale.mapper.after.AfterSalesMapper">
+    <sql id="list">
+        SELECT as1.id,
+               as1.customer_id,
+               as1.contract_id,
+               as1.contract_ids,
+               as1.code,
+               as1.type,
+               as1.remark,
+               as1.reason,
+               as1.amount,
+               as1.duty_party,
+               as1.contact_name,
+               as1.contact_tel,
+               as1.account_bank,
+               as1.account_name,
+               as1.account_number,
+               as1.`status`,
+               as1.flow_id,
+               as1.create_user,
+               as1.create_time,
+               as1.update_user,
+               as1.update_time,
+               c.`code` as contractCode
+        FROM after_sales as1
+                 left join contract c on c.id = as1.contract_id
+    </sql>
+    <select id="getPage" resultType="com.fjhx.sale.entity.after.vo.AfterSalesVo">
+        <include refid="list"/>
+        ${ew.customSqlSegment}
+    </select>
+    <select id="detail" resultType="com.fjhx.sale.entity.after.vo.AfterSalesVo">
+        <include refid="list"/>
+        ${ew.customSqlSegment}
+    </select>
+
+</mapper>

+ 9 - 0
hx-sale/src/main/resources/mapper/after/AfterSalesRecordsMapper.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.sale.mapper.after.AfterSalesRecordsMapper">
+    <select id="getList" resultType="com.fjhx.sale.entity.after.vo.AfterSalesRecordsVo">
+        SELECT asr.*
+        FROM after_sales_records asr
+            ${ew.customSqlSegment}
+    </select>
+</mapper>

+ 11 - 17
hx-sale/src/main/resources/mapper/contract/ContractProductMapper.xml

@@ -4,26 +4,20 @@
 
     <select id="getPage" resultType="com.fjhx.sale.entity.contract.vo.ContractProductVo">
         SELECT t1.id,
-               t2.create_time AS contractTime,
+               t2.create_time          AS contractTime,
                t1.contract_id,
                t1.product_id,
-               t2.`code`          AS contractCode,
-               t2.user_name       AS userName,
-               t2.create_user     AS salesmanId,
-               t2.version         AS contractVersion,
-               t1.expend_quantity AS expendQuantity,
-               (SELECT create_time
-                FROM claim_contract
-                WHERE contract_id = t2.id
-                ORDER BY create_time DESC
-                                     LIMIT 1)               AS claimTime,
-               t2.contract_template_id AS contractTemplateId,
-               t1.quantity
+               t1.product_model,
+               t1.quantity,
+               t1.price,
+               t1.expend_quantity      AS expendQuantity,
+               t2.`code`               AS contractCode,
+               t2.user_name            AS userName,
+               t2.create_user          AS salesmanId,
+               t2.version              AS contractVersion,
+               t2.contract_template_id AS contractTemplateId
         FROM contract_product t1
-            LEFT JOIN contract t2
-            LEFT JOIN claim_contract co
-        on co.contract_id = t2.id
-            ON t1.contract_id = t2.id
+                 JOIN contract t2 ON t1.contract_id = t2.id
             ${ew.customSqlSegment}
     </select>