Browse Source

增加技术人员提成抵扣功能

wucl 2 years ago
parent
commit
b3dfee5bdf
24 changed files with 934 additions and 43 deletions
  1. 83 0
      biz-base/src/main/java/com/dayou/controller/ItemBrokerageTechnicistController.java
  2. 83 0
      biz-base/src/main/java/com/dayou/controller/ItemBrokerageTechnicistDeductionController.java
  3. 1 11
      biz-base/src/main/java/com/dayou/controller/MarketLogController.java
  4. 1 1
      biz-base/src/main/resources/application-local.yml
  5. 21 0
      dao/src/main/java/com/dayou/mapper/ItemBrokerageTechnicistDeductionMapper.java
  6. 21 0
      dao/src/main/java/com/dayou/mapper/ItemBrokerageTechnicistMapper.java
  7. 36 0
      dao/src/main/resources/mapper/ItemBrokerageTechnicistDeductionMapper.xml
  8. 35 0
      dao/src/main/resources/mapper/ItemBrokerageTechnicistMapper.xml
  9. 8 2
      dao/src/main/resources/mapper/ItemMapper.xml
  10. 22 0
      domain/src/main/java/com/dayou/dto/DeductionDTO.java
  11. 0 1
      domain/src/main/java/com/dayou/entity/ItemBrokerageSequence.java
  12. 5 0
      domain/src/main/java/com/dayou/entity/ItemBrokerageSequenceDetail.java
  13. 56 0
      domain/src/main/java/com/dayou/entity/ItemBrokerageTechnicist.java
  14. 43 0
      domain/src/main/java/com/dayou/entity/ItemBrokerageTechnicistDeduction.java
  15. 2 1
      service/src/main/java/com/dayou/brokerage/config/BrokerageSettleSchedule.java
  16. 5 1
      service/src/main/java/com/dayou/brokerage/constants/BrokerageBusiness.java
  17. 7 2
      service/src/main/java/com/dayou/brokerage/constants/BrokerageMsg.java
  18. 8 0
      service/src/main/java/com/dayou/service/IItemBrokerageSequenceService.java
  19. 28 0
      service/src/main/java/com/dayou/service/IItemBrokerageTechnicistDeductionService.java
  20. 28 0
      service/src/main/java/com/dayou/service/IItemBrokerageTechnicistService.java
  21. 4 1
      service/src/main/java/com/dayou/service/impl/GisVisitedServiceImpl.java
  22. 305 23
      service/src/main/java/com/dayou/service/impl/ItemBrokerageSequenceServiceImpl.java
  23. 66 0
      service/src/main/java/com/dayou/service/impl/ItemBrokerageTechnicistDeductionServiceImpl.java
  24. 66 0
      service/src/main/java/com/dayou/service/impl/ItemBrokerageTechnicistServiceImpl.java

+ 83 - 0
biz-base/src/main/java/com/dayou/controller/ItemBrokerageTechnicistController.java

@@ -0,0 +1,83 @@
+package com.dayou.controller;
+
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springframework.web.bind.annotation.RestController;
+import com.dayou.controller.BaseController;
+import com.dayou.service.IItemBrokerageTechnicistService;
+import com.dayou.entity.ItemBrokerageTechnicist;
+import com.dayou.common.RestResponse;
+import org.springframework.web.bind.annotation.*;
+import com.dayou.utils.ConvertUtil;
+import com.dayou.utils.HttpKit;
+import com.dayou.exception.ErrorCode;
+import java.util.Date;
+import java.util.List;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.springframework.http.MediaType;
+import org.springframework.web.multipart.MultipartFile;
+/**
+ * 技术人员项目提成总表
+ *
+ * @author wucl
+ * @since 2023-06-06
+ */
+@RestController
+@RequestMapping("itemBrokerageTechnicist")
+@Slf4j
+public class ItemBrokerageTechnicistController extends BaseController {
+    @Autowired
+    private IItemBrokerageTechnicistService itemBrokerageTechnicistService;
+
+    /**
+    * 技术人员项目提成总表列表
+    */
+    @GetMapping("")
+    public RestResponse<Page<ItemBrokerageTechnicist>> page(ItemBrokerageTechnicist itemBrokerageTechnicist, Page page){
+        Page<ItemBrokerageTechnicist> pages=itemBrokerageTechnicistService.selectPage(page,itemBrokerageTechnicist);
+        return RestResponse.data(pages);
+    }
+
+    /**
+     * 技术人员项目提成总表详情
+     */
+    @GetMapping("/{id}")
+    public RestResponse<ItemBrokerageTechnicist> detail(@PathVariable Long id){
+        ItemBrokerageTechnicist xItemBrokerageTechnicist =itemBrokerageTechnicistService.detail(id);
+        return RestResponse.data(xItemBrokerageTechnicist);
+     }
+
+    /**
+     * 技术人员项目提成总表新增
+     */
+    @PostMapping("")
+    public RestResponse<Boolean> save(@RequestBody ItemBrokerageTechnicist itemBrokerageTechnicist) {
+        Boolean ret = itemBrokerageTechnicistService.add(itemBrokerageTechnicist);
+        return RestResponse.data(ret);
+    }
+
+    /**
+     * 技术人员项目提成总表更新
+     */
+    @PutMapping("")
+    public RestResponse<Boolean> update(@RequestBody ItemBrokerageTechnicist itemBrokerageTechnicist) {
+        Boolean ret = itemBrokerageTechnicistService.update(itemBrokerageTechnicist);
+        return RestResponse.data(ret);
+    }
+
+    /**
+     * 技术人员项目提成总表删除
+     */
+    @DeleteMapping("/{id}")
+    public RestResponse<Boolean> delete(@PathVariable Long id) {
+        Boolean ret = itemBrokerageTechnicistService.delete(id);
+        return RestResponse.data(ret);
+    }
+
+
+}
+

+ 83 - 0
biz-base/src/main/java/com/dayou/controller/ItemBrokerageTechnicistDeductionController.java

@@ -0,0 +1,83 @@
+package com.dayou.controller;
+
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springframework.web.bind.annotation.RestController;
+import com.dayou.controller.BaseController;
+import com.dayou.service.IItemBrokerageTechnicistDeductionService;
+import com.dayou.entity.ItemBrokerageTechnicistDeduction;
+import com.dayou.common.RestResponse;
+import org.springframework.web.bind.annotation.*;
+import com.dayou.utils.ConvertUtil;
+import com.dayou.utils.HttpKit;
+import com.dayou.exception.ErrorCode;
+import java.util.Date;
+import java.util.List;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.springframework.http.MediaType;
+import org.springframework.web.multipart.MultipartFile;
+/**
+ * 技术人员提成抵扣记录
+ *
+ * @author wucl
+ * @since 2023-06-06
+ */
+@RestController
+@RequestMapping("itemBrokerageTechnicistDeduction")
+@Slf4j
+public class ItemBrokerageTechnicistDeductionController extends BaseController {
+    @Autowired
+    private IItemBrokerageTechnicistDeductionService itemBrokerageTechnicistDeductionService;
+
+    /**
+    * 技术人员提成抵扣记录列表
+    */
+    @GetMapping("")
+    public RestResponse<Page<ItemBrokerageTechnicistDeduction>> page(ItemBrokerageTechnicistDeduction itemBrokerageTechnicistDeduction, Page page){
+        Page<ItemBrokerageTechnicistDeduction> pages=itemBrokerageTechnicistDeductionService.selectPage(page,itemBrokerageTechnicistDeduction);
+        return RestResponse.data(pages);
+    }
+
+    /**
+     * 技术人员提成抵扣记录详情
+     */
+    @GetMapping("/{id}")
+    public RestResponse<ItemBrokerageTechnicistDeduction> detail(@PathVariable Long id){
+        ItemBrokerageTechnicistDeduction xItemBrokerageTechnicistDeduction =itemBrokerageTechnicistDeductionService.detail(id);
+        return RestResponse.data(xItemBrokerageTechnicistDeduction);
+     }
+
+    /**
+     * 技术人员提成抵扣记录新增
+     */
+    @PostMapping("")
+    public RestResponse<Boolean> save(@RequestBody ItemBrokerageTechnicistDeduction itemBrokerageTechnicistDeduction) {
+        Boolean ret = itemBrokerageTechnicistDeductionService.add(itemBrokerageTechnicistDeduction);
+        return RestResponse.data(ret);
+    }
+
+    /**
+     * 技术人员提成抵扣记录更新
+     */
+    @PutMapping("")
+    public RestResponse<Boolean> update(@RequestBody ItemBrokerageTechnicistDeduction itemBrokerageTechnicistDeduction) {
+        Boolean ret = itemBrokerageTechnicistDeductionService.update(itemBrokerageTechnicistDeduction);
+        return RestResponse.data(ret);
+    }
+
+    /**
+     * 技术人员提成抵扣记录删除
+     */
+    @DeleteMapping("/{id}")
+    public RestResponse<Boolean> delete(@PathVariable Long id) {
+        Boolean ret = itemBrokerageTechnicistDeductionService.delete(id);
+        return RestResponse.data(ret);
+    }
+
+
+}
+

+ 1 - 11
biz-base/src/main/java/com/dayou/controller/MarketLogController.java

@@ -5,28 +5,18 @@ import com.dayou.annotation.OperLog;
 import com.dayou.dto.DataPermissionCondition;
 import com.dayou.vo.ItemLogCollectVO;
 import com.dayou.vo.MarketLogVO;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestMapping;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springframework.web.bind.annotation.RestController;
-import com.dayou.controller.BaseController;
 import com.dayou.service.IMarketLogService;
 import com.dayou.entity.MarketLog;
 import com.dayou.common.RestResponse;
 import org.springframework.web.bind.annotation.*;
-import com.dayou.utils.ConvertUtil;
-import com.dayou.utils.HttpKit;
-import com.dayou.exception.ErrorCode;
 
-import java.time.LocalDate;
-import java.util.Date;
 import java.util.List;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import org.springframework.http.MediaType;
-import org.springframework.web.multipart.MultipartFile;
+
 
 import static com.dayou.common.Constants.MANAGER_OFFICE;
 

+ 1 - 1
biz-base/src/main/resources/application-local.yml

@@ -3,7 +3,7 @@ server:
 
 spring:
   datasource:
-    url: jdbc:mysql://localhost:3306/prod_test?autoReconnect=true&useUnicode=true&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true&characterEncoding=UTF-8&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true
+    url: jdbc:mysql://localhost:3306/item-management?autoReconnect=true&useUnicode=true&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true&characterEncoding=UTF-8&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true
     username: root
     password: 914851221
     initialSize: 10 #初始化连接数D

+ 21 - 0
dao/src/main/java/com/dayou/mapper/ItemBrokerageTechnicistDeductionMapper.java

@@ -0,0 +1,21 @@
+package com.dayou.mapper;
+
+import com.dayou.dto.DeductionDTO;
+import com.dayou.entity.ItemBrokerageTechnicistDeduction;
+import com.dayou.dao.CustomBaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 技术人员提成抵扣记录 Mapper 接口
+ * </p>
+ *
+ * @author wucl
+ * @since 2023-06-06
+ */
+public interface ItemBrokerageTechnicistDeductionMapper extends CustomBaseMapper<ItemBrokerageTechnicistDeduction> {
+
+    List<DeductionDTO> notDeductionDefaultSettle(@Param("userId") Long userId);
+}

+ 21 - 0
dao/src/main/java/com/dayou/mapper/ItemBrokerageTechnicistMapper.java

@@ -0,0 +1,21 @@
+package com.dayou.mapper;
+
+import com.dayou.entity.ItemBrokerageTechnicist;
+import com.dayou.dao.CustomBaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * <p>
+ * 技术人员项目提成总表 Mapper 接口
+ * </p>
+ *
+ * @author wucl
+ * @since 2023-06-06
+ */
+public interface ItemBrokerageTechnicistMapper extends CustomBaseMapper<ItemBrokerageTechnicist> {
+
+    List<ItemBrokerageTechnicist> notSettleForTechnicist(@Param("userId") Long userId);
+}

+ 36 - 0
dao/src/main/resources/mapper/ItemBrokerageTechnicistDeductionMapper.xml

@@ -0,0 +1,36 @@
+<?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.dayou.mapper.ItemBrokerageTechnicistDeductionMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.dayou.entity.ItemBrokerageTechnicistDeduction">
+        <result column="id" property="id" />
+        <result column="created" property="created" />
+        <result column="brokerage_technicist_id" property="brokerageTechnicistId" />
+        <result column="brokerage_sequence_id" property="brokerageSequenceId" />
+        <result column="deduction_amount" property="deductionAmount" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id,
+        created,
+        brokerage_technicist_id, brokerage_sequence_id,deduction_amount
+    </sql>
+
+    <select id="notDeductionDefaultSettle" parameterType="java.lang.Long" resultType="com.dayou.dto.DeductionDTO">
+        SELECT
+
+            ibs.id as sequenceId,
+            ibs.brokerage_amount as totalAmount,
+            (ibs.brokerage_amount- ifnull(ibtd.deduDone,0)) as notDeduAmount
+        FROM
+            item_brokerage_sequence ibs
+                LEFT JOIN (select brokerage_sequence_id,sum(deduction_amount) as deduDone from item_brokerage_technicist_deduction GROUP BY brokerage_sequence_id) ibtd ON ibtd.brokerage_sequence_id = ibs.id
+        WHERE
+            ibs.user_id = #{userId} and ibs.cate = 'DEFAULT_AHEAD' and
+            ifnull(ibtd.deduDone,0) &lt; ibs.brokerage_amount
+                                      order by ibs.id ASC
+    </select>
+
+</mapper>

+ 35 - 0
dao/src/main/resources/mapper/ItemBrokerageTechnicistMapper.xml

@@ -0,0 +1,35 @@
+<?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.dayou.mapper.ItemBrokerageTechnicistMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.dayou.entity.ItemBrokerageTechnicist">
+        <result column="id" property="id" />
+        <result column="modified" property="modified" />
+        <result column="sequence_id" property="sequenceId" />
+        <result column="item_id" property="itemId" />
+        <result column="user_id" property="userId" />
+        <result column="amount" property="amount" />
+        <result column="residue_amount" property="residueAmount" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id,
+        modified,
+        sequence_id, item_id, user_id, amount, residue_amount
+    </sql>
+
+    <select id="notSettleForTechnicist" parameterType="java.lang.Long" resultType="com.dayou.entity.ItemBrokerageTechnicist">
+        SELECT
+            ibt.*
+        FROM
+            item_brokerage_technicist ibt
+                LEFT JOIN item_brokerage_general ibg ON ibt.item_id = ibg.item_id
+        WHERE
+                (select amount from item where  id = ibt.item_id and deleted = 0 )  =
+                (select sum(amount) from payment_collection where item_id = ibt.item_id)
+          AND ibt.residue_amount != 0
+	AND  ibt.user_id = #{userId}
+    </select>
+</mapper>

+ 8 - 2
dao/src/main/resources/mapper/ItemMapper.xml

@@ -111,7 +111,10 @@
     </select>
 
     <select id="xDetail" parameterType="java.lang.Long" resultMap="BaseResultMap">
-        select <include refid="Base_Column_List"/>, d.name as departmentName from item i left join department d on d.id = i.department_id left join user u on u.id = i.user_id where i.deleted = 0  and i.id =#{id}
+        select <include refid="Base_Column_List"/>, d.name as departmentName
+        from item i left join department d on d.id = i.department_id left join user u on u.id = i.user_id
+                                           left join customer c on c.id = i.customer_id
+                                           where i.deleted = 0  and i.id =#{id}
     </select>
 
     <select id="selectItemUserId" parameterType="java.lang.Long" resultType="java.lang.Long">
@@ -372,7 +375,10 @@
     </select>
 
     <select id="getItemByBrokerageGeneralId" parameterType="java.lang.Long" resultType="com.dayou.dto.ItemDTO">
-        select <include refid="Base_Column_List"/>,ibg.brokerage_rate as ratio from item_brokerage_general ibg left join item i on i.id = ibg.item_id where i.deleted = 0 and ibg.deleted = 0 and ibg.id = #{generalId}
+        select <include refid="Base_Column_List"/>,ibg.brokerage_rate as ratio
+        from item_brokerage_general ibg left join item i on i.id = ibg.item_id
+                                                         left join customer c on c.id = i.customer_id left join user u on u.id = i.user_id
+                                                         where i.deleted = 0 and ibg.deleted = 0 and ibg.id = #{generalId}
     </select>
 
     <select id="getLastMonthTeamItems" resultType="com.dayou.dto.ItemBrokerageGeneralDTO">

+ 22 - 0
domain/src/main/java/com/dayou/dto/DeductionDTO.java

@@ -0,0 +1,22 @@
+package com.dayou.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/6/7
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class DeductionDTO {
+
+    private Long sequenceId;
+
+    private BigDecimal totalAmount;
+
+    private BigDecimal notDeduAmount;
+}

+ 0 - 1
domain/src/main/java/com/dayou/entity/ItemBrokerageSequence.java

@@ -63,5 +63,4 @@ public class ItemBrokerageSequence extends BaseEntity {
      * 结算类型(项目结算,默认预提)
      */
     private String cate;
-
 }

+ 5 - 0
domain/src/main/java/com/dayou/entity/ItemBrokerageSequenceDetail.java

@@ -72,5 +72,10 @@ public class ItemBrokerageSequenceDetail extends BaseEntity {
     @TableField(exist = false)
     private Long generalId;
 
+    /**
+     * 项目id
+     */
+    @TableField(exist = false)
+    private Long itemId;
 
 }

+ 56 - 0
domain/src/main/java/com/dayou/entity/ItemBrokerageTechnicist.java

@@ -0,0 +1,56 @@
+package com.dayou.entity;
+import java.math.BigDecimal;
+import com.dayou.common.BaseEntity;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import com.dayou.annotation.ExcelSheet;
+import com.dayou.annotation.ExportCell;
+import com.dayou.annotation.ImportCell;
+/**
+ * <p>
+ * 技术人员项目提成总表
+ * </p>
+ *
+ * @author wucl
+ * @since 2023-06-06
+ */
+@Builder
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ExcelSheet(sheetName = "技术人员项目提成总表")
+public class ItemBrokerageTechnicist extends BaseEntity {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 项目结算流水表id
+     */
+    private Long sequenceId;
+
+    /**
+     * 项目id
+     */
+    private Long itemId;
+
+    /**
+     * 技术人员id
+     */
+    private Long userId;
+
+    /**
+     * 提成总金额
+     */
+    @ImportCell
+    @ExportCell(columnName = "提成总金额")
+    private BigDecimal amount;
+
+    /**
+     * 剩余金额
+     */
+    @ImportCell
+    @ExportCell(columnName = "剩余金额")
+    private BigDecimal residueAmount;
+
+
+}

+ 43 - 0
domain/src/main/java/com/dayou/entity/ItemBrokerageTechnicistDeduction.java

@@ -0,0 +1,43 @@
+package com.dayou.entity;
+import com.dayou.common.BaseEntity;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import com.dayou.annotation.ExcelSheet;
+import com.dayou.annotation.ExportCell;
+import com.dayou.annotation.ImportCell;
+
+import java.math.BigDecimal;
+
+/**
+ * <p>
+ * 技术人员提成抵扣记录
+ * </p>
+ *
+ * @author wucl
+ * @since 2023-06-06
+ */
+@Builder
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ExcelSheet(sheetName = "技术人员提成抵扣记录")
+public class ItemBrokerageTechnicistDeduction extends BaseEntity {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 技术人员提成总表id
+     */
+    private Long brokerageTechnicistId;
+
+    /**
+     * 提成流水表id
+     */
+    private Long brokerageSequenceId;
+
+    /**
+     * 抵扣金额
+     */
+    private BigDecimal deductionAmount;
+
+}

+ 2 - 1
service/src/main/java/com/dayou/brokerage/config/BrokerageSettleSchedule.java

@@ -31,6 +31,7 @@ public class BrokerageSettleSchedule {
     private IItemBrokerageSequenceService itemBrokerageSequenceService;
 
     @Scheduled(cron = "59 59 23 23 * ?")
+//    @Scheduled(cron = "0 0/2 * * * ?")
     public void doBrokerageSettle(){
         AsyncManager.me().execute(new AsyncManager.BizHandler() {
             @Override
@@ -38,7 +39,7 @@ public class BrokerageSettleSchedule {
                 Date now = new Date();
                 int year = DateUtils.getYear(now);
                 int month = DateUtils.getMonth(now);
-                String embody = BROKERAGE_SEQUENCE_EMBODY.replace(YEARMONTH, year + "-" + (month + 1));
+                String embody = BROKERAGE_SEQUENCE_EMBODY.replace(YEARMONTH, year + "-" + (month));
                 int count = itemBrokerageSequenceService.count(new LambdaQueryWrapper<ItemBrokerageSequence>().eq(ItemBrokerageSequence::getEmbody, embody).eq(BaseEntity::getDeleted, Boolean.FALSE));
                 if (count!=0){
                     log.info(embody+"提成已被结算,无需重复结算.");

+ 5 - 1
service/src/main/java/com/dayou/brokerage/constants/BrokerageBusiness.java

@@ -20,7 +20,11 @@ public enum BrokerageBusiness {
 
     PAYMENT_SETTLE("回款结算","PAYMENT_SETTLE"),
 
-    COMPENSATION("补偿结算","COMPENSATION");
+    COMPENSATION("补偿结算","COMPENSATION"),
+
+    POOL_SETTLE("奖金池结算","POOL_SETTLE"),
+
+    ONCE_SETTLE("一次性结算","ONCE_SETTLE");
 
     private String name;
 

+ 7 - 2
service/src/main/java/com/dayou/brokerage/constants/BrokerageMsg.java

@@ -11,12 +11,17 @@ import java.math.BigDecimal;
  */
 public class BrokerageMsg {
 
-    public static final String BROKERAGE_SEQUENCE_REMARK = "系统每月23日零点自动结算项目提成,您上月可结算(包含预提)项目个数:[sum]个.";
+    public static final String BROKERAGE_SEQUENCE_REMARK = "系统每月23日零点自动结算项目提成,您上月可结算(包含预提)项目个数:[sum]个";
 
-    public static final String NON_MARKETER_BASE_SEQUENCE_REMARK = "非市场人员默认提成,此提成与项目暂不挂钩.若有项目结算将与固定提成抵扣.";
+    public static final String POOL_SETTLE_REMARK = "系统每月23日零点自动结算阶段流程已完成且已被评价的项目,结算金额已转移至个人奖金池。";
+    public static final String NON_MARKETER_BASE_SEQUENCE_REMARK = "技术人员默认提成,此提成与个人奖金池剩余金额抵扣。";
+
+    public static final String NON_MARKETER_ALL_PAYMENT_REMARK = "此项目已全额回款,其提成金额若有剩余将一次性发放。";
 
     public static final String BROKERAGE_SEQUENCE_EMBODY = "[year-month]薪资";
 
+    public static final String BROKERAGE_POOL_EMBODY = "[year-month]转移";
+
     /**
      * 客户经理预提比例
      */

+ 8 - 0
service/src/main/java/com/dayou/service/IItemBrokerageSequenceService.java

@@ -1,13 +1,17 @@
 package com.dayou.service;
+import com.dayou.dto.DeductionDTO;
 import com.dayou.dto.SalarySettleDTO;
 import com.dayou.entity.ItemBrokerageSequence;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.dayou.entity.ItemBrokerageTechnicist;
+import com.dayou.entity.ItemBrokerageTechnicistDeduction;
 import com.dayou.vo.BrokerageSequenceVO;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -37,4 +41,8 @@ public interface IItemBrokerageSequenceService extends IService<ItemBrokerageSeq
         List<BrokerageSequenceVO> deduction(BrokerageSequenceVO brokerageSequenceVO);
 
         List<BrokerageSequenceVO> xList(BrokerageSequenceVO brokerageSequenceVO);
+
+        void deduction(List<ItemBrokerageTechnicist> itemBrokerages, List<DeductionDTO> deductionDTOS);
+
+        void extracted(BigDecimal defaultAmount, ItemBrokerageSequence defaultSequence, List<ItemBrokerageTechnicist> deductionAble);
 }

+ 28 - 0
service/src/main/java/com/dayou/service/IItemBrokerageTechnicistDeductionService.java

@@ -0,0 +1,28 @@
+package com.dayou.service;
+import com.dayou.entity.ItemBrokerageTechnicistDeduction;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.web.multipart.MultipartFile;
+/**
+ * <p>
+ * 技术人员提成抵扣记录 服务类
+ * </p>
+ *
+ * @author wucl
+ * @since 2023-06-06
+ */
+public interface IItemBrokerageTechnicistDeductionService extends IService<ItemBrokerageTechnicistDeduction> {
+
+        Page<ItemBrokerageTechnicistDeduction> selectPage(Page page,ItemBrokerageTechnicistDeduction itemBrokerageTechnicistDeduction);
+
+        ItemBrokerageTechnicistDeduction detail(Long id);
+
+        Boolean add(ItemBrokerageTechnicistDeduction itemBrokerageTechnicistDeduction);
+
+        Boolean update(ItemBrokerageTechnicistDeduction itemBrokerageTechnicistDeduction);
+
+        Boolean delete(Long id);
+
+}

+ 28 - 0
service/src/main/java/com/dayou/service/IItemBrokerageTechnicistService.java

@@ -0,0 +1,28 @@
+package com.dayou.service;
+import com.dayou.entity.ItemBrokerageTechnicist;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.web.multipart.MultipartFile;
+/**
+ * <p>
+ * 技术人员项目提成总表 服务类
+ * </p>
+ *
+ * @author wucl
+ * @since 2023-06-06
+ */
+public interface IItemBrokerageTechnicistService extends IService<ItemBrokerageTechnicist> {
+
+        Page<ItemBrokerageTechnicist> selectPage(Page page,ItemBrokerageTechnicist itemBrokerageTechnicist);
+
+        ItemBrokerageTechnicist detail(Long id);
+
+        Boolean add(ItemBrokerageTechnicist itemBrokerageTechnicist);
+
+        Boolean update(ItemBrokerageTechnicist itemBrokerageTechnicist);
+
+        Boolean delete(Long id);
+
+}

+ 4 - 1
service/src/main/java/com/dayou/service/impl/GisVisitedServiceImpl.java

@@ -1,5 +1,6 @@
 package com.dayou.service.impl;
 
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.dayou.entity.GisVisited;
 import com.dayou.mapper.GisVisitedMapper;
@@ -45,7 +46,9 @@ public class GisVisitedServiceImpl extends ServiceImpl<GisVisitedMapper, GisVisi
     @Override
     @SuppressWarnings("unchecked")
     public Page<GisVisited> selectPage(Page page,GisVisited gisVisited){
-        return this.page(page, new QueryWrapper<GisVisited>(gisVisited));
+        LambdaQueryWrapper<GisVisited> condition = new LambdaQueryWrapper<GisVisited>().like(StrUtil.isNotBlank(gisVisited.getRemoteAddr()), GisVisited::getRemoteAddr,gisVisited.getRemoteAddr());
+        return this.page(page, condition);
+
     }
 
 

+ 305 - 23
service/src/main/java/com/dayou/service/impl/ItemBrokerageSequenceServiceImpl.java

@@ -9,21 +9,26 @@ import com.dayou.brokerage.constants.BrokerageRule;
 import com.dayou.brokerage.constants.BrokerageState;
 import com.dayou.brokerage.handler.LandMarketerBrokerageHandler;
 import com.dayou.common.BaseEntity;
+import com.dayou.dto.DeductionDTO;
 import com.dayou.dto.ItemDTO;
 import com.dayou.dto.PaymentDetailDTO;
 import com.dayou.dto.SequenceSimpleDTO;
 import com.dayou.entity.*;
 import com.dayou.mapper.ItemBrokerageSequenceMapper;
+import com.dayou.mapper.ItemBrokerageTechnicistDeductionMapper;
+import com.dayou.mapper.ItemBrokerageTechnicistMapper;
 import com.dayou.service.*;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.dayou.utils.DateUtils;
 import com.dayou.vo.BrokerageSequenceDetailVO;
 import com.dayou.vo.BrokerageSequenceVO;
+import com.dayou.vo.IdNameVO;
 import com.google.common.cache.Cache;
 import com.google.common.cache.LoadingCache;
 import com.google.common.collect.Sets;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.compress.utils.Lists;
 import org.checkerframework.checker.units.qual.A;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -39,8 +44,7 @@ import java.util.stream.Collectors;
 
 import org.springframework.transaction.annotation.Transactional;
 
-import static com.dayou.brokerage.constants.BrokerageBusiness.COMPENSATION;
-import static com.dayou.brokerage.constants.BrokerageBusiness.PAYMENT_SETTLE;
+import static com.dayou.brokerage.constants.BrokerageBusiness.*;
 import static com.dayou.brokerage.constants.BrokerageMsg.*;
 import static com.dayou.brokerage.constants.BrokerageRule.LAND_SUPERVISOR_RULE;
 import static com.dayou.common.Constants.*;
@@ -90,6 +94,21 @@ public class ItemBrokerageSequenceServiceImpl extends ServiceImpl<ItemBrokerageS
     @Autowired
     private IMarketStatService marketStatService;
 
+    @Autowired
+    private IUserService userService;
+
+    @Autowired
+    private IItemBrokerageTechnicistService technicistService;
+
+    @Autowired
+    private ItemBrokerageTechnicistMapper technicistMapper;
+
+    @Autowired
+    private IItemBrokerageTechnicistDeductionService deductionService;
+
+    @Autowired
+    private ItemBrokerageTechnicistDeductionMapper deductionMapper;
+
     @Override
     @SuppressWarnings("unchecked")
     public Page<BrokerageSequenceVO> selectPage(Page page, BrokerageSequenceVO itemBrokerageSequence){
@@ -123,26 +142,137 @@ public class ItemBrokerageSequenceServiceImpl extends ServiceImpl<ItemBrokerageS
      * 非市场人员固定预提结算
      * @return
      */
+    @Transactional
     @Override
     public synchronized Boolean doNonMarketerAheadSettle() {
         ConcurrentMap<Long, BigDecimal> nonMarketerAheadAmounts = baseAmountsCache.asMap();
         Date now = new Date();
         int year = DateUtils.getYear(now);
         int month = DateUtils.getMonth(now);
-        List<ItemBrokerageSequence> sequences = new ArrayList<>();
         for (Map.Entry<Long,BigDecimal> nonMarketerAheadAmount : nonMarketerAheadAmounts.entrySet()){
-            ItemBrokerageSequence sequence = ItemBrokerageSequence.builder()
-                    .brokerageAmount(nonMarketerAheadAmount.getValue())
-                    .userId(nonMarketerAheadAmount.getKey())
+            Long userId = nonMarketerAheadAmount.getKey();
+            BigDecimal defaultAmount = nonMarketerAheadAmount.getValue();
+            ItemBrokerageSequence defaultSequence = ItemBrokerageSequence.builder()
+                    .brokerageAmount(defaultAmount)
+                    .userId(userId)
                     .cate(BrokerageBusiness.DEFAULT_AHEAD.getCode())
-                    .embody(BROKERAGE_SEQUENCE_EMBODY.replace(YEARMONTH,year+"-"+(month+1)))
+                    .embody(BROKERAGE_SEQUENCE_EMBODY.replace(YEARMONTH,year+"-"+month))
                     .remark(NON_MARKETER_BASE_SEQUENCE_REMARK)
                     .year(year)
-                    .month(month+1)
+                    .month(month)
                     .build();
-            sequences.add(sequence);
+            this.save(defaultSequence);
+            //若有全额回款的项目一次性结算提成
+            List<ItemBrokerageTechnicist> brokerages = technicistMapper.notSettleForTechnicist(userId);
+            if (CollectionUtils.isNotEmpty(brokerages)){
+                for (ItemBrokerageTechnicist brokerage : brokerages){
+                    if (brokerage!=null && brokerage.getResidueAmount()!=null){
+                        ItemBrokerageSequence itemSequence = ItemBrokerageSequence.builder()
+                                .brokerageAmount(brokerage.getResidueAmount())
+                                .userId(userId)
+                                .cate(BrokerageBusiness.ONCE_SETTLE.getCode())
+                                .embody(BROKERAGE_SEQUENCE_EMBODY.replace(YEARMONTH,year+"-"+month))
+                                .remark(NON_MARKETER_ALL_PAYMENT_REMARK)
+                                .year(year)
+                                .month(month)
+                                .build();
+                        technicistService.update(new LambdaUpdateWrapper<ItemBrokerageTechnicist>().set(ItemBrokerageTechnicist::getResidueAmount,BigDecimal.ZERO).eq(BaseEntity::getId,brokerage.getId()));
+                        this.save(itemSequence);
+                    }
+                }
+            }
+
+            //抵扣逻辑
+            //可抵扣的项目
+            List<ItemBrokerageTechnicist> deductionAble = technicistService.list(new LambdaQueryWrapper<ItemBrokerageTechnicist>()
+                    .eq(ItemBrokerageTechnicist::getUserId, userId).ne(ItemBrokerageTechnicist::getResidueAmount, BigDecimal.ZERO).orderByAsc(BaseEntity::getId));
+
+            //存在可抵扣的项目
+            if (CollectionUtils.isNotEmpty(deductionAble)) {
+                List<ItemBrokerageTechnicistDeduction> deductionDoneList = new ArrayList<>();
+                List<ItemBrokerageTechnicist> xdeductionAble = new ArrayList<>();
+                BigDecimal res = BigDecimal.ZERO;
+                for (ItemBrokerageTechnicist deduction : deductionAble) {
+                    if (defaultAmount.compareTo(BigDecimal.ZERO) != 1) {
+                        break;
+                    }
+                    if (res.compareTo(BigDecimal.ZERO) == -1) {
+                        res = deduction.getResidueAmount().subtract(res.negate());
+                    }else {
+                        res = deduction.getResidueAmount().subtract(defaultSequence.getBrokerageAmount());
+                    }
+                    //可抵扣减去预提的金额  剩余部分
+                    //剩下为大于等于0
+                    if (res.compareTo(BigDecimal.ZERO) != -1) {
+                        ItemBrokerageTechnicistDeduction deductionDone = ItemBrokerageTechnicistDeduction.builder()
+                                .brokerageSequenceId(defaultSequence.getId())
+                                .brokerageTechnicistId(deduction.getId())
+                                .deductionAmount(defaultAmount)
+                                .build();
+                        deductionDoneList.add(deductionDone);
+                        deduction.setResidueAmount(res);
+                        xdeductionAble.add(deduction);
+                        break;
+                    } else {
+                        ItemBrokerageTechnicistDeduction deductionDone = ItemBrokerageTechnicistDeduction.builder()
+                                .brokerageSequenceId(defaultSequence.getId())
+                                .brokerageTechnicistId(deduction.getId())
+                                .deductionAmount(deduction.getResidueAmount())
+                                .build();
+                        deductionDoneList.add(deductionDone);
+                        deduction.setResidueAmount(BigDecimal.ZERO);
+                        xdeductionAble.add(deduction);
+                    }
+                }
+                deductionService.saveBatch(deductionDoneList);
+                technicistService.updateBatchById(xdeductionAble);
+            }
+        }
+        return Boolean.TRUE;
+    }
+
+    //仅供单元测试用,后面删掉
+    @Override
+    public void extracted(BigDecimal defaultAmount, ItemBrokerageSequence defaultSequence, List<ItemBrokerageTechnicist> deductionAble) {
+        if (CollectionUtils.isNotEmpty(deductionAble)) {
+            List<ItemBrokerageTechnicistDeduction> deductionDoneList = new ArrayList<>();
+            List<ItemBrokerageTechnicist> xdeductionAble = new ArrayList<>();
+            BigDecimal res = BigDecimal.ZERO;
+            for (ItemBrokerageTechnicist deduction : deductionAble) {
+                if (defaultAmount.compareTo(BigDecimal.ZERO) != 1) {
+                    break;
+                }
+                if (res.compareTo(BigDecimal.ZERO) == -1) {
+                    res = deduction.getResidueAmount().subtract(res.negate());
+                }else {
+                    res = deduction.getResidueAmount().subtract(defaultSequence.getBrokerageAmount());
+                }
+                //可抵扣减去预提的金额  剩余部分
+                //剩下为大于等于0
+                if (res.compareTo(BigDecimal.ZERO) != -1) {
+                    ItemBrokerageTechnicistDeduction deductionDone = ItemBrokerageTechnicistDeduction.builder()
+                            .brokerageSequenceId(defaultSequence.getId())
+                            .brokerageTechnicistId(deduction.getId())
+                            .deductionAmount(defaultAmount)
+                            .build();
+                    deductionDoneList.add(deductionDone);
+                    deduction.setResidueAmount(res);
+                    xdeductionAble.add(deduction);
+                    break;
+                } else {
+                    ItemBrokerageTechnicistDeduction deductionDone = ItemBrokerageTechnicistDeduction.builder()
+                            .brokerageSequenceId(defaultSequence.getId())
+                            .brokerageTechnicistId(deduction.getId())
+                            .deductionAmount(deduction.getResidueAmount())
+                            .build();
+                    deductionDoneList.add(deductionDone);
+                    deduction.setResidueAmount(BigDecimal.ZERO);
+                    xdeductionAble.add(deduction);
+                }
+            }
+            deductionService.saveBatch(deductionDoneList);
+            technicistService.updateBatchById(xdeductionAble);
         }
-        return this.saveBatch(sequences);
     }
 
     /**
@@ -163,16 +293,18 @@ public class ItemBrokerageSequenceServiceImpl extends ServiceImpl<ItemBrokerageS
                 Set<ItemBrokerageSequenceDetail> sequenceDetails = Sets.newHashSet();
                 for (ItemBrokerageDetail x : settleDetails){
                     ItemBrokerageGeneral general = idGeneral.get(x.getGeneralId());
+                    //客户经理预提
                     if (general.getMarketerStatus().equals(BrokerageState.TO_PREDICTING.getCode())
                             && x.getBrokerageMode().equals(BrokerageMode.PERSONAL.getCode())
                             && x.getBrokerageRule().equals(BrokerageRule.LAND_MARKETER_RULE.getCode())) {
                         ItemBrokerageSequenceDetail sequenceDetail = getItemBrokerageSequenceDetail(x);
                         toUpdateItemBrokerageDetails.add(x);
                         sequenceDetails.add(sequenceDetail);
+                        //
                     }else if (general.getMarketerStatus().equals(BrokerageState.NOT_SETTLE.getCode())
                             && x.getBrokerageMode().equals(BrokerageMode.PERSONAL.getCode())
                             && ( x.getBrokerageRule().equals(BrokerageRule.LAND_MARKETER_RULE.getCode()) ||x.getBrokerageRule().equals(BrokerageRule.LAND_SUPERVISOR_RULE.getCode()) )) {
-                        //减去已预提金额 ,这个地方需要再次根据 [结算时间节点] 去重新计算 营销主管和营销经理的 实际提成金额,因为 回款金额等因素可能有变动。
+                        //减去已预提金额 ,这个地方需要再次根据 [结算时间节点] 去重新计算 营销主管或客户经理的 实际提成金额,因为 回款金额等因素可能有变动。
                         //客户经理的实际提成金额则根据预估计算时得出的金额为准
                         ItemBrokerageSequenceDetail sequenceDetail = getItemBrokerageSequenceDetail(x, general);
                         toUpdateItemBrokerageDetails.add(x);
@@ -194,7 +326,7 @@ public class ItemBrokerageSequenceServiceImpl extends ServiceImpl<ItemBrokerageS
                         toUpdateItemBrokerageDetails.add(x);
                     }
                     else if (general.getParticipantStatus().equals(BrokerageState.NOT_SETTLE.getCode()) && x.getBrokerageRule().equals(BrokerageRule.LAND_OTHER_RULE.getCode())) {
-                        ItemBrokerageSequenceDetail sequenceDetail = otherRuleSettle(x);
+                        ItemBrokerageSequenceDetail sequenceDetail = otherRuleSettle(x,general.getItemId());
                         toUpdateItemBrokerageDetails.add(x);
                         sequenceDetails.add(sequenceDetail);
                     }
@@ -204,19 +336,37 @@ public class ItemBrokerageSequenceServiceImpl extends ServiceImpl<ItemBrokerageS
                 Date now = new Date();
                 int year = DateUtils.getYear(now);
                 int month = DateUtils.getMonth(now);
+                Set<Long> marketers = userService.usersByDepartment(MARKET_DEPARTMENT).stream().map(IdNameVO::getId).collect(Collectors.toSet());
                 for (Map.Entry<Long,List<ItemBrokerageSequenceDetail>> userSequence : collect.entrySet()){
                     List<ItemBrokerageSequenceDetail> values = userSequence.getValue();
                     Set<Long> itemSize = values.stream().map(ItemBrokerageSequenceDetail::getGeneralId).collect(Collectors.toSet());
                     BigDecimal userTotalAmount = values.stream().map(ItemBrokerageSequenceDetail::getBrokerageAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
-                    ItemBrokerageSequence sequence = ItemBrokerageSequence.builder().brokerageAmount(userTotalAmount).userId(userSequence.getKey())
-                            .cate(BrokerageBusiness.ITEM_SETTLE.getCode())
-                            .remark(BROKERAGE_SEQUENCE_REMARK.replace("sum",String.valueOf(itemSize.size())))
-                            .embody(BROKERAGE_SEQUENCE_EMBODY.replace(YEARMONTH,year+"-"+(month+1)))
-                            .year(year)
-                            .month(month+1)
-                            .build();
-                    this.save(sequence);
-                    values.stream().forEach(x->{x.setSequenceId(sequence.getId());});
+                    if (marketers.contains(userSequence.getKey())){
+                        //市场人员直接结算
+                        ItemBrokerageSequence sequence = ItemBrokerageSequence.builder().brokerageAmount(userTotalAmount).userId(userSequence.getKey())
+                                .cate(BrokerageBusiness.ITEM_SETTLE.getCode())
+                                .remark(BROKERAGE_SEQUENCE_REMARK.replace("sum",String.valueOf(itemSize.size())))
+                                .embody(BROKERAGE_SEQUENCE_EMBODY.replace(YEARMONTH,year+"-"+month))
+                                .year(year)
+                                .month(month)
+                                .build();
+                        this.save(sequence);
+                        values.stream().forEach(x->{x.setSequenceId(sequence.getId());});
+                    }else {
+                        //技术人员 转移奖金池
+                        ItemBrokerageSequence sequence = ItemBrokerageSequence.builder().brokerageAmount(userTotalAmount).userId(userSequence.getKey())
+                                .cate(BrokerageBusiness.POOL_SETTLE.getCode())
+                                .remark(POOL_SETTLE_REMARK)
+                                .embody(BROKERAGE_POOL_EMBODY.replace(YEARMONTH,year+"-"+month))
+                                .year(year)
+                                .month(month)
+                                .build();
+                        this.save(sequence);
+                        values.stream().forEach(x->{x.setSequenceId(sequence.getId());});
+                        //技术人员提成汇总
+                        doTechnicistBrokerageCollect(userSequence,sequence.getId());
+
+                    }
                     brokerageSequenceDetailService.saveBatch(values);
                 }
                 brokerageDetailService.updateBatchById(toUpdateItemBrokerageDetails);
@@ -250,14 +400,146 @@ public class ItemBrokerageSequenceServiceImpl extends ServiceImpl<ItemBrokerageS
     }
 
     /**
+     * 技术人员的提成在项目维度汇总
+     * @param userSequence
+     */
+    private void doTechnicistBrokerageCollect(Map.Entry<Long, List<ItemBrokerageSequenceDetail>> userSequence,Long sequenceId) {
+        Long userId = userSequence.getKey();
+        List<ItemBrokerageSequenceDetail> sequenceValue = userSequence.getValue();
+        List<ItemBrokerageTechnicist> itemBrokerages = Lists.newArrayList();
+
+
+
+        Map<Long, List<ItemBrokerageSequenceDetail>> collectByItemId = sequenceValue.stream().collect(Collectors.groupingBy(ItemBrokerageSequenceDetail::getItemId));
+        for (Map.Entry<Long,List<ItemBrokerageSequenceDetail>> item : collectByItemId.entrySet()){
+            BigDecimal brokerageTotal = item.getValue().stream().map(ItemBrokerageSequenceDetail::getBrokerageAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+            ItemBrokerageTechnicist itemBrokerage = ItemBrokerageTechnicist.builder()
+                    .itemId(item.getKey())
+                    .userId(userId)
+                    .sequenceId(sequenceId)
+                    .amount(brokerageTotal)
+                    .residueAmount(brokerageTotal)
+                    .build();
+            itemBrokerages.add(itemBrokerage);
+        }
+        technicistService.saveBatch(itemBrokerages);
+        List<ItemBrokerageTechnicist> technicistsBrokerages = technicistService.list(new LambdaQueryWrapper<ItemBrokerageTechnicist>().eq(ItemBrokerageTechnicist::getUserId, userId).gt(ItemBrokerageTechnicist::getResidueAmount,BigDecimal.ZERO));
+        //检查是否存在预提记录,产生真实提成需冲抵技术人员预提记录
+        List<DeductionDTO> deductionDTOS = deductionMapper.notDeductionDefaultSettle(userId);
+
+        //技术人员提成抵扣
+        deduction(technicistsBrokerages, deductionDTOS);
+
+    }
+
+
+    /**
+     * 技术人员的默认预提与项目结算抵扣逻辑
+     * @param itemBrokerages
+     * @param deductionDTOS
+     */
+    @Transactional
+    @Override
+    public void deduction(List<ItemBrokerageTechnicist> itemBrokerages, List<DeductionDTO> deductionDTOS) {
+        BigDecimal res = null;
+        Long sequenceId = null;
+        BigDecimal notDeduAmount = null;
+        int j = 0;
+        List<ItemBrokerageTechnicistDeduction> newDeductions = new ArrayList<>();
+        List<ItemBrokerageTechnicist> updateTechnicists = new ArrayList<>();
+        if (CollectionUtils.isNotEmpty(deductionDTOS)){
+            for (ItemBrokerageTechnicist deductionAble : itemBrokerages){
+                //余数大于等于0
+                if (res!=null && res.compareTo(BigDecimal.ZERO)!=-1){
+                    // 未抵扣的已抵扣完 退出外层循环
+                    break;
+                }
+                else {
+                    //在外循环中一直抵扣
+                    if (res!=null && res.compareTo(BigDecimal.ZERO) == -1){
+                        res = deductionAble.getResidueAmount().subtract(res.negate());
+                        if (res!=null && res.compareTo(BigDecimal.ZERO) == -1){
+                            ItemBrokerageTechnicistDeduction allDeduction = ItemBrokerageTechnicistDeduction.builder()
+                                    .brokerageTechnicistId(deductionAble.getId()).brokerageSequenceId(sequenceId).deductionAmount(deductionAble.getResidueAmount()).build();
+                            deductionAble.setResidueAmount(BigDecimal.ZERO);
+                            newDeductions.add(allDeduction);
+                            updateTechnicists.add(deductionAble);
+                            continue;
+                        }
+                        ItemBrokerageTechnicistDeduction departDeduction = ItemBrokerageTechnicistDeduction.builder()
+                                .brokerageTechnicistId(deductionAble.getId()).brokerageSequenceId(sequenceId).deductionAmount(deductionAble.getResidueAmount().subtract(res)).build();
+                        newDeductions.add(departDeduction);
+                        //减去外循环中已抵扣的一部分,重新设置余额再进入内循环抵扣
+                        deductionAble.setResidueAmount(res);
+                    }
+                    //在外循环中某一笔抵扣完上一笔还有剩余,进入内循环中抵扣
+                    for (int i =j;i<deductionDTOS.size(); i++){
+                        //余数小于0
+                        if (res!=null && res.compareTo(BigDecimal.ZERO) == -1){
+                            res = deductionAble.getResidueAmount().subtract(res.negate());
+                            //余数大于等于0
+                            if (res!=null && res.compareTo(BigDecimal.ZERO)!=-1){
+                                //继续内循环中抵扣 插入
+                                ItemBrokerageTechnicistDeduction allDeduction = ItemBrokerageTechnicistDeduction.builder()
+                                        .brokerageTechnicistId(deductionAble.getId()).brokerageSequenceId(sequenceId).deductionAmount(notDeduAmount).build();
+                                deductionAble.setResidueAmount(res);
+                                newDeductions.add(allDeduction);
+                                updateTechnicists.add(deductionAble);
+                                continue;
+                            }else {
+                                //说明外层循环可抵扣的值不足,调出内层循环
+                                ItemBrokerageTechnicistDeduction departDeduction = ItemBrokerageTechnicistDeduction.builder()
+                                        .brokerageTechnicistId(deductionAble.getId()).brokerageSequenceId(sequenceId).deductionAmount(res.negate()).build();
+                                deductionAble.setResidueAmount(BigDecimal.ZERO);
+                                newDeductions.add(departDeduction);
+                                updateTechnicists.add(deductionAble);
+                                j = i+1;
+                                break;
+                            }
+                        }
+                        else {
+                            sequenceId = deductionDTOS.get(i).getSequenceId();
+                            notDeduAmount = deductionDTOS.get(i).getNotDeduAmount();
+                            res = deductionAble.getResidueAmount().subtract(notDeduAmount);
+                            //余数大于等于0
+                            if (res!=null && res.compareTo(BigDecimal.ZERO)!=-1){
+                                //继续内循环中抵扣 插入 (完全抵扣完)
+                                ItemBrokerageTechnicistDeduction allDeduction = ItemBrokerageTechnicistDeduction.builder()
+                                        .brokerageTechnicistId(deductionAble.getId()).brokerageSequenceId(sequenceId).deductionAmount(notDeduAmount).build();
+                                deductionAble.setResidueAmount(res);
+                                newDeductions.add(allDeduction);
+                                updateTechnicists.add(deductionAble);
+                                continue;
+                            }
+                            else {
+                                //说明外层循环可抵扣的值不足,调出内层循环 (部分抵扣完)
+                                ItemBrokerageTechnicistDeduction departDeduction = ItemBrokerageTechnicistDeduction.builder()
+                                        .brokerageTechnicistId(deductionAble.getId()).brokerageSequenceId(sequenceId).deductionAmount(notDeduAmount.subtract(res.negate())).build();
+                                deductionAble.setResidueAmount(BigDecimal.ZERO);
+                                newDeductions.add(departDeduction);
+                                updateTechnicists.add(deductionAble);
+                                j = i+1;
+                                break;
+                            }
+                        }
+                    }
+                    updateTechnicists.add(deductionAble);
+                }
+            }
+        }
+        deductionService.saveBatch(newDeductions);
+        technicistService.updateBatchById(updateTechnicists);
+    }
+
+    /**
      * 参与人人员结算
      * @param x
      * @return
      */
-    private ItemBrokerageSequenceDetail otherRuleSettle(ItemBrokerageDetail x) {
+    private ItemBrokerageSequenceDetail otherRuleSettle(ItemBrokerageDetail x,Long itemId) {
         ItemBrokerageSequenceDetail sequenceDetail = ItemBrokerageSequenceDetail.builder()
                 .brokerageDetailId(x.getId()).unsettledAmount(BigDecimal.ZERO).userId(x.getUserId())
-                .brokerageCate(BrokerageBusiness.SETTLE.getCode()).brokerageAmount(x.getActualAmount()).generalId(x.getGeneralId()).build();
+                .brokerageCate(BrokerageBusiness.SETTLE.getCode()).brokerageAmount(x.getActualAmount()).generalId(x.getGeneralId()).itemId(itemId).build();
         x.setAdvanceAmount(x.getActualAmount());
         return sequenceDetail;
     }

+ 66 - 0
service/src/main/java/com/dayou/service/impl/ItemBrokerageTechnicistDeductionServiceImpl.java

@@ -0,0 +1,66 @@
+package com.dayou.service.impl;
+
+import com.dayou.entity.ItemBrokerageTechnicistDeduction;
+import com.dayou.mapper.ItemBrokerageTechnicistDeductionMapper;
+import com.dayou.service.IItemBrokerageTechnicistDeductionService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.dayou.utils.ExcelUtil;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.web.multipart.MultipartFile;
+import java.util.List;
+import java.util.ArrayList;
+import org.springframework.transaction.annotation.Transactional;
+import com.dayou.enums.BatchTaskTypeEnum;
+
+/**
+ * <p>
+ * 技术人员提成抵扣记录 服务实现类
+ * </p>
+ *
+ * @author wucl
+ * @since 2023-06-06
+ */
+@Service
+public class ItemBrokerageTechnicistDeductionServiceImpl extends ServiceImpl<ItemBrokerageTechnicistDeductionMapper, ItemBrokerageTechnicistDeduction> implements IItemBrokerageTechnicistDeductionService {
+
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Page<ItemBrokerageTechnicistDeduction> selectPage(Page page,ItemBrokerageTechnicistDeduction itemBrokerageTechnicistDeduction){
+        return this.page(page, new QueryWrapper<ItemBrokerageTechnicistDeduction>(itemBrokerageTechnicistDeduction));
+    }
+
+
+    @Override
+    public ItemBrokerageTechnicistDeduction detail(Long id){
+        return this.getById(id);
+    }
+
+    @Override
+    public Boolean add(ItemBrokerageTechnicistDeduction itemBrokerageTechnicistDeduction){
+        return  this.save(itemBrokerageTechnicistDeduction);
+    }
+
+    @Override
+    public Boolean update(ItemBrokerageTechnicistDeduction itemBrokerageTechnicistDeduction){
+        return  this.updateById(itemBrokerageTechnicistDeduction);
+    }
+
+    @Override
+    public Boolean delete(Long id){
+        //逻辑删除
+        return this.removeById(id);
+    }
+}

+ 66 - 0
service/src/main/java/com/dayou/service/impl/ItemBrokerageTechnicistServiceImpl.java

@@ -0,0 +1,66 @@
+package com.dayou.service.impl;
+
+import com.dayou.entity.ItemBrokerageTechnicist;
+import com.dayou.mapper.ItemBrokerageTechnicistMapper;
+import com.dayou.service.IItemBrokerageTechnicistService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.dayou.utils.ExcelUtil;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.web.multipart.MultipartFile;
+import java.util.List;
+import java.util.ArrayList;
+import org.springframework.transaction.annotation.Transactional;
+import com.dayou.enums.BatchTaskTypeEnum;
+
+/**
+ * <p>
+ * 技术人员项目提成总表 服务实现类
+ * </p>
+ *
+ * @author wucl
+ * @since 2023-06-06
+ */
+@Service
+public class ItemBrokerageTechnicistServiceImpl extends ServiceImpl<ItemBrokerageTechnicistMapper, ItemBrokerageTechnicist> implements IItemBrokerageTechnicistService {
+
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Page<ItemBrokerageTechnicist> selectPage(Page page,ItemBrokerageTechnicist itemBrokerageTechnicist){
+        return this.page(page, new QueryWrapper<ItemBrokerageTechnicist>(itemBrokerageTechnicist));
+    }
+
+
+    @Override
+    public ItemBrokerageTechnicist detail(Long id){
+        return this.getById(id);
+    }
+
+    @Override
+    public Boolean add(ItemBrokerageTechnicist itemBrokerageTechnicist){
+        return  this.save(itemBrokerageTechnicist);
+    }
+
+    @Override
+    public Boolean update(ItemBrokerageTechnicist itemBrokerageTechnicist){
+        return  this.updateById(itemBrokerageTechnicist);
+    }
+
+    @Override
+    public Boolean delete(Long id){
+        //逻辑删除
+        return this.removeById(id);
+    }
+}