소스 검색

个贷模板认领实收款

wucl 1 년 전
부모
커밋
3a409a21b0

+ 3 - 3
biz-base/src/main/java/com/dayou/controller/FinanceClaimController.java

@@ -110,9 +110,9 @@ public class FinanceClaimController extends BaseController {
      * @param file
      * @return
      */
-    @PostMapping("/personal/temp/upload")
-    public RestResponse<Boolean> personalClaimByTemplate(MultipartFile file){
-        Boolean ret = financeClaimService.personalClaimByTemplate(file);
+    @PostMapping("/personal/temp/upload/{financeFundId}")
+    public RestResponse<Boolean> personalClaimByTemplate(@RequestPart("file") MultipartFile file,@PathVariable("financeFundId") Long financeFundId){
+        Boolean ret = financeClaimService.personalClaimByTemplate(file,financeFundId);
         return RestResponse.data(ret);
     }
 }

+ 22 - 13
common/src/main/java/com/dayou/utils/ExcelUtil.java

@@ -167,15 +167,15 @@ public class ExcelUtil {
         Field[] fields = clazz.getDeclaredFields();
         T t = clazz.newInstance();
 
-        for (int i = 0; i < fields.length; i++) {
-            Cell cell = row.getCell(i);
-            if (getCellValue(cell) != null) {
-                break;
-            }
-            if (i == fields.length - 1) {
-                ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "存在空行,请检查表格尾部是否有曾经存在数据的空白行,请删除这些空白行");
-            }
-        }
+//        for (int i = 0; i < fields.length; i++) {
+//            Cell cell = row.getCell(i);
+//            if (getCellValue(cell) != null) {
+//                break;
+//            }
+//            if (i == fields.length - 1) {
+//                ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "存在空行,请检查表格尾部是否有曾经存在数据的空白行,请删除这些空白行");
+//            }
+//        }
 
         int index = 0;
         for (Field field : fields) {
@@ -192,7 +192,8 @@ public class ExcelUtil {
                 }
 
                 if (getCellValue(cell) == null && notNull) {
-                    ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "第" + (index + 1) + "列:不能为空");
+                    //ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "第" + (index + 1) + "列:不能为空");
+                    return null;
                 }
 
                 if (CellType.ERROR.equals(cell.getCellType())) {
@@ -202,7 +203,8 @@ public class ExcelUtil {
 
                 //处理空cell情况
                 if (notNull && getCellValue(cell) == null) {
-                    ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "第" + (index + 1) + "列不能为空");
+                    //ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "第" + (index + 1) + "列不能为空");
+                    return null;
                 }
 
                 if(field.getType().equals(String.class) && !cell.getCellType().equals(CellType.STRING)){
@@ -459,7 +461,7 @@ public class ExcelUtil {
 
     }
 
-    public static <T> List<T> importExcel(Class<T> clazz, MultipartFile file, int startRow) {
+    public static <T> List<T> importExcel(Class<T> clazz,ImportListener<T> importListener, MultipartFile file, int startRow) {
         List<T> result = new LinkedList<>();
         List<BatchImportResult.FailResult> failResults = new LinkedList<>();
         try {
@@ -486,7 +488,14 @@ public class ExcelUtil {
                 Row row = sheet.getRow(i);
                 try {
                     if (row != null) {
-                        result.add(ExcelUtil.convertRow2Model(row, clazz));
+                        T t = ExcelUtil.convertRow2Model(row, clazz);
+                        if (t==null){
+                            continue;
+                        }
+                        Boolean ret = importListener.handleOneRecord(t);
+                        if (ret){
+                            result.add(t);
+                        }
                     }
                 } catch (Throwable e) {
                     String reason = getReasonByException(e);

+ 2 - 0
dao/src/main/java/com/dayou/mapper/FinanceClaimMapper.java

@@ -21,4 +21,6 @@ public interface FinanceClaimMapper extends CustomBaseMapper<FinanceClaim> {
     List<FinanceClaimVO> getList(@Param("realFundId") Long  realFundId);
 
     BigDecimal getTotalClaimAmountByProductionFundId(@Param("productionFundId") Long productionFundId);
+
+    BigDecimal residueAmount(@Param("financeFundId") Long financeFundId);
 }

+ 2 - 0
dao/src/main/java/com/dayou/mapper/OrderFundMapper.java

@@ -17,4 +17,6 @@ import java.math.BigDecimal;
 public interface OrderFundMapper extends CustomBaseMapper<OrderFund> {
 
     void updateRealAmount(@Param("id") Long id, @Param("thisTimeAmount") BigDecimal thisTimeAmount);
+
+    void updateRealAmountByOrderId(@Param("orderId") String orderId, @Param("thisTimeAmount") BigDecimal thisTimeAmount);
 }

+ 8 - 0
dao/src/main/resources/mapper/FinanceClaimMapper.xml

@@ -50,4 +50,12 @@
     <select id="getTotalClaimAmountByProductionFundId" parameterType="java.lang.Long" resultType="java.math.BigDecimal">
         select ifnull(sum(claim_amount),0) from finance_claim where production_fund_id = #{productionFundId} and deleted = 0
     </select>
+
+    <select id="residueAmount" parameterType="java.lang.Long" resultType="java.math.BigDecimal">
+        SELECT amount -( SELECT IFNULL( sum( claim_amount ), 0 ) FROM `finance_claim` WHERE deleted = 0 AND real_fund_id = #{financeFundId} ) AS residueAmount
+        FROM
+            finance_real_fund
+        WHERE
+            id = #{financeFundId} and deleted = 0
+    </select>
 </mapper>

+ 4 - 0
dao/src/main/resources/mapper/OrderFundMapper.xml

@@ -27,4 +27,8 @@
     <update id="updateRealAmount">
         update order_fund set real_amount = (ifnull(real_amount,0) + #{thisTimeAmount}) where id = #{id}
     </update>
+
+    <update id="updateRealAmountByOrderId">
+        update order_fund set real_amount = (ifnull(real_amount,0) + #{thisTimeAmount}) where order_id = #{orderId} and deleted = 0
+    </update>
 </mapper>

+ 26 - 0
domain/src/main/java/com/dayou/dto/PersonalClaimDTO.java

@@ -0,0 +1,26 @@
+package com.dayou.dto;
+
+import com.dayou.annotation.ImportCell;
+import lombok.Data;
+import org.hibernate.validator.constraints.NotEmpty;
+
+import java.math.BigDecimal;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2024/4/10
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class PersonalClaimDTO {
+
+    @ImportCell(notNull = true)
+    @NotEmpty(message = "项目编号为空")
+    private String orderId;
+
+    @ImportCell(notNull = true)
+    @NotEmpty(message = "认领金额为空")
+    private BigDecimal amount;
+}

+ 9 - 1
service/src/main/java/com/dayou/service/IFinanceClaimService.java

@@ -1,4 +1,5 @@
 package com.dayou.service;
+import com.dayou.dto.PersonalClaimDTO;
 import com.dayou.entity.FinanceClaim;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -26,13 +27,20 @@ public interface IFinanceClaimService extends IService<FinanceClaim> {
 
         Boolean add(FinanceClaim financeClaim);
 
+        Boolean doClaim(FinanceClaim financeClaim);
+
         Boolean update(FinanceClaim financeClaim);
 
+        Boolean doClaimUpdate(FinanceClaim financeClaim);
+
         Boolean delete(Long id);
 
     List<FinanceClaimVO> getList(Long realFundId);
 
         BigDecimal getTotalClaimAmountByProductionFundId(Long id);
 
-    Boolean personalClaimByTemplate(MultipartFile file);
+    Boolean personalClaimByTemplate(MultipartFile file,Long financeFundId);
+
+    Boolean doClaimByTemplateDTO(List<PersonalClaimDTO> personalClaimDTOS, Long financeFundId, BigDecimal residueAmount);
+    BigDecimal residueAmount(Long financeFundId);
 }

+ 1 - 0
service/src/main/java/com/dayou/service/IMajorProductionService.java

@@ -64,6 +64,7 @@ public interface IMajorProductionService extends IService<MajorProduction> {
 
     List<OrderReportDTO> getOrderReport(List<OrderReportDTO> claimOrders);
 
+    Boolean doAllotRealAmount(List<OrderReportDTO> claimOrders);
     Boolean allotRealAmount(List<OrderReportDTO> claimOrders);
 
     Page<TaskTodoVO> todoSaveFilePage(Page page, TaskTodoVO todoVO,String keyword);

+ 124 - 6
service/src/main/java/com/dayou/service/impl/FinanceClaimServiceImpl.java

@@ -1,21 +1,35 @@
 package com.dayou.service.impl;
 
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.dayou.common.BaseEntity;
+import com.dayou.dto.PersonalClaimDTO;
 import com.dayou.entity.FinanceClaim;
+import com.dayou.entity.FinanceRealFund;
+import com.dayou.entity.OrderFund;
+import com.dayou.entity.Personal;
+import com.dayou.enums.MainBusinessEnum;
 import com.dayou.exception.ErrorCode;
 import com.dayou.mapper.FinanceClaimMapper;
-import com.dayou.service.IFinanceClaimService;
+import com.dayou.mapper.OrderFundMapper;
+import com.dayou.service.*;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.dayou.service.IFinanceRealFundService;
-import com.dayou.service.IProductionFundService;
+import com.dayou.utils.ExcelUtil;
 import com.dayou.utils.LoginContext;
 import com.dayou.vo.FinanceClaimVO;
+import org.springframework.aop.framework.AopContext;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -39,6 +53,18 @@ public class FinanceClaimServiceImpl extends ServiceImpl<FinanceClaimMapper, Fin
     @Autowired
     private IProductionFundService productionFundService;
 
+    @Autowired
+    private IPersonalService personalService;
+
+    @Autowired
+    private IOrderFundService orderFundService;
+
+    @Autowired
+    private OrderFundMapper orderFundMapper;
+
+    @Autowired
+    private IFinanceClaimService financeClaimService;
+
     @Override
     @SuppressWarnings("unchecked")
     public Page<FinanceClaim> selectPage(Page page,FinanceClaim financeClaim){
@@ -56,10 +82,11 @@ public class FinanceClaimServiceImpl extends ServiceImpl<FinanceClaimMapper, Fin
 
     @Override
     public synchronized Boolean add(FinanceClaim financeClaim){
-       return doClaim(financeClaim);
+       return financeClaimService.doClaim(financeClaim);
     }
 
     @Transactional
+    @Override
     public Boolean doClaim(FinanceClaim financeClaim){
         BigDecimal notClaimAmount = financeRealFundService.getNotClaimAmount(financeClaim.getRealFundId());
         if (financeClaim.getClaimAmount().compareTo(notClaimAmount)<=0){
@@ -76,9 +103,10 @@ public class FinanceClaimServiceImpl extends ServiceImpl<FinanceClaimMapper, Fin
 
     @Override
     public synchronized Boolean update(FinanceClaim financeClaim){
-        return doClaimUpdate(financeClaim);
+        return financeClaimService.doClaimUpdate(financeClaim);
     }
 
+    @Override
     @Transactional
     public Boolean doClaimUpdate(FinanceClaim financeClaim){
         FinanceClaim xFinanceClaim = this.getById(financeClaim.getId());
@@ -117,12 +145,102 @@ public class FinanceClaimServiceImpl extends ServiceImpl<FinanceClaimMapper, Fin
         BigDecimal totalClaimAmount =  financeClaimMapper.getTotalClaimAmountByProductionFundId(id);
         return totalClaimAmount;
     }
+    @Override
+    public synchronized Boolean personalClaimByTemplate(MultipartFile file,Long financeFundId) {
+        //检查这笔实收款剩余金额
+        BigDecimal residueAmount = checkFinanceFound(financeFundId);
+        List<PersonalClaimDTO> personalClaimDTOS = ExcelUtil.importExcel(PersonalClaimDTO.class,
+                personalClaimDTO->{
+                    String orderId = personalClaimDTO.getOrderId();
+                    BigDecimal amount = personalClaimDTO.getAmount();
+                    if (StrUtil.isNotBlank(orderId)){
+                        checkOrderId(orderId);
+                    }
+                    if (amount!=null){
+                        checkAmount(orderId,amount);
+                    }
+                    return true;
+                },file, 1);
+        return financeClaimService.doClaimByTemplateDTO(personalClaimDTOS,financeFundId,residueAmount);
+    }
 
     @Override
-    public Boolean personalClaimByTemplate(MultipartFile file) {
+    public synchronized BigDecimal residueAmount(Long financeFundId) {
+        return financeClaimMapper.residueAmount(financeFundId);
+    }
+
+    private BigDecimal checkFinanceFound(Long financeFundId) {
+        BigDecimal residueAmount = residueAmount(financeFundId);
+        if (residueAmount==null){
+            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"未查询到此笔实收款");
+        }
+        if (residueAmount.compareTo(BigDecimal.ZERO)<=0){
+            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"该笔实收款余额为0,无法再次认领");
+        }
+        return residueAmount;
+
+    }
+
+    @Transactional
+    @Override
+    public  Boolean doClaimByTemplateDTO(List<PersonalClaimDTO> personalClaimDTOS,Long financeFundId,BigDecimal residueAmount) {
+        if (CollectionUtil.isEmpty(personalClaimDTOS)){
+            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"未解析到模板数据,请检查模板。");
+        }
+        BigDecimal thisTimeClaimTotalAmount = personalClaimDTOS.stream().collect(Collectors.mapping(PersonalClaimDTO::getAmount,
+                Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)));
+
+        if (thisTimeClaimTotalAmount.compareTo(residueAmount)>0){
+            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"模板认领总金额大于实收款剩余金额,请检查。");
+        }
+        personalClaimDTOS.stream().forEach(x->{
+            //检查该订单是否创建应收款记录
+            OrderFund orderFund = orderFundService.getOne(new LambdaQueryWrapper<OrderFund>().eq(OrderFund::getOrderId, x.getOrderId()).eq(BaseEntity::getDeleted, Boolean.FALSE));
+            if (orderFund==null){
+                Personal personal = personalService.getOne(new LambdaQueryWrapper<Personal>().select(BaseEntity::getId, Personal::getLocation).eq(Personal::getOrderId, x.getOrderId()).eq(BaseEntity::getDeleted, Boolean.FALSE));
+                if (personal!=null){
+                    orderFund = new OrderFund();
+                    orderFund.setOrderId(x.getOrderId());
+                    orderFund.setBusinessType(MainBusinessEnum.PERSONAL_BUSINESS.name());
+                    orderFund.setBusinessId(personal.getId());
+                    orderFund.setOrderName(personal.getLocation());
+                    orderFundService.save(orderFund);
+                }
+            }
+            FinanceClaim financeClaim = new FinanceClaim();
+            financeClaim.setRealFundId(financeFundId);
+            financeClaim.setOrderFundId(orderFund.getId());
+            financeClaim.setClaimId(LoginContext.getCurrentUserId());
+            financeClaim.setClaimDatetime(LocalDateTime.now());
+            financeClaim.setClaimAmount(x.getAmount());
+            this.save(financeClaim);
+        });
+
+        //更新订单认领总金额
+        Map<String, BigDecimal> orderIdGroup = personalClaimDTOS.stream()
+                .collect(Collectors.groupingBy(PersonalClaimDTO::getOrderId,
+                        Collectors.mapping(PersonalClaimDTO::getAmount, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
+
+        for(Map.Entry<String,BigDecimal> orderAmount :orderIdGroup.entrySet()){
+            orderFundMapper.updateRealAmountByOrderId(orderAmount.getKey(),orderAmount.getValue());
+        }
 
         return Boolean.TRUE;
     }
 
+    private void checkAmount(String orderId,BigDecimal amount) {
+        if (amount.compareTo(BigDecimal.ZERO)<0){
+            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"个贷项目编号["+orderId+"]认领金额不能为负数");
+        }
+    }
+
+    private void checkOrderId(String orderId) {
+        int count = personalService.count(new LambdaQueryWrapper<Personal>().eq(Personal::getOrderId, orderId).eq(BaseEntity::getDeleted, Boolean.FALSE));
+        if (count!=1){
+            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"个贷项目编号["+orderId+"]不存在或有多个");
+        }
+    }
+
+
 
 }

+ 6 - 3
service/src/main/java/com/dayou/service/impl/ItemBrokerageGeneralServiceImpl.java

@@ -104,6 +104,9 @@ public class ItemBrokerageGeneralServiceImpl extends ServiceImpl<ItemBrokerageGe
     @Autowired
     private IUserService userService;
 
+    @Autowired
+    private IItemBrokerageGeneralService itemBrokerageGeneralService;
+
 
     @Override
     @SuppressWarnings("unchecked")
@@ -217,7 +220,7 @@ public class ItemBrokerageGeneralServiceImpl extends ServiceImpl<ItemBrokerageGe
             brokerageDetailBO.setAheadAmount(BigDecimal.ZERO);
             brokerageDetailBO.setMarketerStatus(BrokerageState.NOT_PAYMENT.getCode());
             brokerageDetailBO.setUserId(item.getUserId());
-            this.doCreateBrokerageGeneralAndDetail(brokerageDetailBO);
+            itemBrokerageGeneralService.doCreateBrokerageGeneralAndDetail(brokerageDetailBO);
         }else {
             log.info("未设置合同金额,创建提成总表和客户经理提成记录终止。itemId[{}]",id);
         }
@@ -361,7 +364,7 @@ public class ItemBrokerageGeneralServiceImpl extends ServiceImpl<ItemBrokerageGe
         this.updateById(general);
         //如果项目已经被评价 需重新评价
         itemEvaluateMapper.delete(new LambdaQueryWrapper<ItemEvaluate>().eq(ItemEvaluate::getItemId,itemStageVO.getItemId()));
-        addParticipatorBrokerage(itemStageVO,itemStageVO.getId());
+        itemBrokerageGeneralService.addParticipatorBrokerage(itemStageVO,itemStageVO.getId());
     }
 
     @Transactional
@@ -672,7 +675,7 @@ public class ItemBrokerageGeneralServiceImpl extends ServiceImpl<ItemBrokerageGe
         ItemBrokerageGeneral general = brokerageGeneralMapper.getByItemId(itemStageVO.getItemId());
         if (general == null){
             addMarketerBrokerage(itemStageVO.getItemId());
-            addParticipatorBrokerage(itemStageVO,itemStageVO.getId());
+            itemBrokerageGeneralService.addParticipatorBrokerage(itemStageVO,itemStageVO.getId());
             log.info("更新项目信息时创建了相关的提成记录");
             return;
         }

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

@@ -106,6 +106,9 @@ public class ItemBrokerageSequenceServiceImpl extends ServiceImpl<ItemBrokerageS
     @Autowired
     private IBrokerageMarketerSettledService brokerageMarketerSettledService;
 
+    @Autowired
+    private IItemBrokerageSequenceService itemBrokerageSequenceService;
+
     @Override
     @SuppressWarnings("unchecked")
     public Page<BrokerageSequenceVO> selectPage(Page page, BrokerageSequenceVO itemBrokerageSequence){
@@ -492,7 +495,7 @@ public class ItemBrokerageSequenceServiceImpl extends ServiceImpl<ItemBrokerageS
         List<DeductionDTO> deductionDTOS = deductionMapper.notDeductionDefaultSettle(userId);
 
         //技术人员提成抵扣
-        deduction(technicistsBrokerages, deductionDTOS);
+        itemBrokerageSequenceService.deduction(technicistsBrokerages, deductionDTOS);
 
     }
 

+ 9 - 1
service/src/main/java/com/dayou/service/impl/MajorProductionServiceImpl.java

@@ -98,6 +98,9 @@ public class MajorProductionServiceImpl extends ServiceImpl<MajorProductionMappe
     @Autowired
     private IBusinessFileService businessFileService;
 
+    @Autowired
+    private IMajorProductionService majorProductionService;
+
 
     @Override
     @SuppressWarnings("unchecked")
@@ -364,9 +367,14 @@ public class MajorProductionServiceImpl extends ServiceImpl<MajorProductionMappe
         return claimOrders;
     }
 
-    @Transactional
     @Override
     public synchronized Boolean allotRealAmount(List<OrderReportDTO> claimOrders) {
+        return majorProductionService.doAllotRealAmount(claimOrders);
+    }
+
+    @Override
+    @Transactional
+    public Boolean doAllotRealAmount(List<OrderReportDTO> claimOrders){
         if (CollectionUtil.isNotEmpty(claimOrders)){
             //先校验各订单此次认领金额之和是否大于这笔实收款的剩余金额
             Long financeFundId = claimOrders.get(0).getFinanceFundId();

+ 6 - 3
service/src/main/java/com/dayou/service/impl/MajorTargetServiceImpl.java

@@ -39,6 +39,9 @@ public class MajorTargetServiceImpl extends ServiceImpl<MajorTargetMapper, Major
     @Autowired
     private MajorTargetMapper majorTargetMapper;
 
+    @Autowired
+    private IMajorTargetService majorTargetService;
+
     @Override
     public List<MajorTarget> getList(MajorTarget majorTarget){
         return this.list(new LambdaQueryWrapper<MajorTarget>().eq(MajorTarget::getMajorId,majorTarget.getMajorId())
@@ -86,13 +89,13 @@ public class MajorTargetServiceImpl extends ServiceImpl<MajorTargetMapper, Major
     public synchronized String takeNumber(TakeNumberDTO takeNumberDTO) {
         ProductionEnum productionType = takeNumberDTO.getProductionType();
         if (productionType.equals(ProductionEnum.STATEMENT)){
-            return majorTakeStatementNo(takeNumberDTO);
+            return majorTargetService.majorTakeStatementNo(takeNumberDTO);
         }
         if (productionType.equals(ProductionEnum.REPORT)){
-            return majorTakeReportNo(takeNumberDTO);
+            return majorTargetService.majorTakeReportNo(takeNumberDTO);
         }
         if (productionType.equals(ProductionEnum.LETTER)){
-            return  majorTakeLetterNo(takeNumberDTO);
+            return  majorTargetService.majorTakeLetterNo(takeNumberDTO);
         }
         return null;
     }