Răsfoiți Sursa

应收账款-批单

yzc 11 luni în urmă
părinte
comite
4ba2e1bc7f

+ 9 - 0
hx-form/src/main/java/com/fjhx/form/controller/ReportController.java

@@ -1,5 +1,6 @@
 package com.fjhx.form.controller;
 
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.fjhx.form.entity.*;
 import com.fjhx.form.service.ReportService;
@@ -87,4 +88,12 @@ public class ReportController {
         return reportService.receivableCheck(dto);
     }
 
+    /**
+     * 帐龄分析
+     */
+    @PostMapping("/finance/receivableAccounts")
+    List<JSONObject> receivableAccounts(@RequestBody ReceivableAccountsSelectDto dto) {
+        return reportService.getReceivableAccounts(dto);
+    }
+
 }

+ 35 - 0
hx-form/src/main/java/com/fjhx/form/controller/customer/CustomerPayableBalanceController.java

@@ -0,0 +1,35 @@
+package com.fjhx.form.controller.customer;
+
+import com.fjhx.form.entity.customer.dto.CustomerPayableBalanceDto;
+import com.fjhx.form.service.customer.CustomerPayableBalanceService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * <p>
+ * 客户应付余额 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2024-05-11
+ */
+@RestController
+@RequestMapping("/customerPayableBalance")
+public class CustomerPayableBalanceController {
+
+    @Autowired
+    private CustomerPayableBalanceService customerPayableBalanceService;
+
+    /**
+     * 客户应付余额编辑
+     */
+    @PostMapping("/edit")
+    public void edit(@RequestBody CustomerPayableBalanceDto customerPayableBalanceDto) {
+        customerPayableBalanceService.edit(customerPayableBalanceDto);
+    }
+
+}

+ 15 - 0
hx-form/src/main/java/com/fjhx/form/entity/CustomerMonthlyAccounts.java

@@ -0,0 +1,15 @@
+package com.fjhx.form.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+@Getter
+@Setter
+public class CustomerMonthlyAccounts {
+    private Long buyCorporationId;
+    private Integer dataMonth;
+    private BigDecimal truckAmount;
+    private BigDecimal claimMonth;
+}

+ 11 - 0
hx-form/src/main/java/com/fjhx/form/entity/ReceivableAccountsSelectDto.java

@@ -0,0 +1,11 @@
+package com.fjhx.form.entity;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class ReceivableAccountsSelectDto extends BaseSelectDto {
+    private Integer year;
+}

+ 17 - 0
hx-form/src/main/java/com/fjhx/form/entity/customer/dto/CustomerPayableBalanceDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.form.entity.customer.dto;
+
+import com.fjhx.form.entity.customer.po.CustomerPayableBalance;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 客户应付余额新增编辑入参实体
+ *
+ * @author
+ * @since 2024-05-11
+ */
+@Getter
+@Setter
+public class CustomerPayableBalanceDto extends CustomerPayableBalance {
+
+}

+ 17 - 0
hx-form/src/main/java/com/fjhx/form/entity/customer/dto/CustomerPayableBalanceSelectDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.form.entity.customer.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 客户应付余额列表查询入参实体
+ *
+ * @author
+ * @since 2024-05-11
+ */
+@Getter
+@Setter
+public class CustomerPayableBalanceSelectDto extends BaseSelectDto {
+
+}

+ 46 - 0
hx-form/src/main/java/com/fjhx/form/entity/customer/po/CustomerPayableBalance.java

@@ -0,0 +1,46 @@
+package com.fjhx.form.entity.customer.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * <p>
+ * 客户应付余额
+ * </p>
+ *
+ * @author
+ * @since 2024-05-11
+ */
+@Getter
+@Setter
+@TableName("customer_payable_balance")
+public class CustomerPayableBalance extends BasePo {
+
+    /**
+     * 客户id
+     */
+    private Long customerId;
+
+    /**
+     * 日期-yyyy-MM
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM")
+    private Date accountDate;
+
+    /**
+     * 月余额
+     */
+    private BigDecimal balance;
+
+    /**
+     * 月调整
+     */
+    private BigDecimal adjust;
+
+}

+ 17 - 0
hx-form/src/main/java/com/fjhx/form/entity/customer/vo/CustomerPayableBalanceVo.java

@@ -0,0 +1,17 @@
+package com.fjhx.form.entity.customer.vo;
+
+import com.fjhx.form.entity.customer.po.CustomerPayableBalance;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 客户应付余额列表查询返回值实体
+ *
+ * @author
+ * @since 2024-05-11
+ */
+@Getter
+@Setter
+public class CustomerPayableBalanceVo extends CustomerPayableBalance {
+
+}

+ 5 - 0
hx-form/src/main/java/com/fjhx/form/mapper/ReportMapper.java

@@ -24,4 +24,9 @@ public interface ReportMapper {
     List<OrderSummaryBo> orderSummary(@Param("dto") OrderSummarySelectDto dto, @Param("ew") IWrapper<Object> wrapper);
 
     List<ReceivableCheckBo> receivableCheck(@Param("dto") ReceivableCheckSelectDto dto, @Param("ew") IWrapper<Object> wrapper);
+
+    /**
+     * 获取客户某年每月 装车金额,到账金额
+     */
+    List<CustomerMonthlyAccounts> getCustomerMonthlyAccounts(@Param("year") Integer year);
 }

+ 17 - 0
hx-form/src/main/java/com/fjhx/form/mapper/customer/CustomerPayableBalanceMapper.java

@@ -0,0 +1,17 @@
+package com.fjhx.form.mapper.customer;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fjhx.form.entity.customer.po.CustomerPayableBalance;
+
+
+/**
+ * <p>
+ * 客户应付余额 Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2024-05-11
+ */
+public interface CustomerPayableBalanceMapper extends BaseMapper<CustomerPayableBalance> {
+
+}

+ 6 - 0
hx-form/src/main/java/com/fjhx/form/service/ReportService.java

@@ -1,5 +1,6 @@
 package com.fjhx.form.service;
 
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.fjhx.form.entity.*;
 
@@ -41,4 +42,9 @@ public interface ReportService {
      * 应收余额核对
      */
     List<ReceivableCheckBo> receivableCheck(ReceivableCheckSelectDto dto);
+
+    /**
+     * 应收账款-批单
+     */
+    List<JSONObject> getReceivableAccounts(ReceivableAccountsSelectDto dto);
 }

+ 23 - 0
hx-form/src/main/java/com/fjhx/form/service/customer/CustomerPayableBalanceService.java

@@ -0,0 +1,23 @@
+package com.fjhx.form.service.customer;
+
+import com.fjhx.form.entity.customer.dto.CustomerPayableBalanceDto;
+import com.fjhx.form.entity.customer.po.CustomerPayableBalance;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 客户应付余额 服务类
+ * </p>
+ *
+ * @author
+ * @since 2024-05-11
+ */
+public interface CustomerPayableBalanceService extends BaseService<CustomerPayableBalance> {
+
+    /**
+     * 客户应付余额编辑
+     */
+    void edit(CustomerPayableBalanceDto customerPayableBalanceDto);
+
+}

+ 35 - 0
hx-form/src/main/java/com/fjhx/form/service/customer/impl/CustomerPayableBalanceServiceImpl.java

@@ -0,0 +1,35 @@
+package com.fjhx.form.service.customer.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.form.entity.customer.dto.CustomerPayableBalanceDto;
+import com.fjhx.form.entity.customer.po.CustomerPayableBalance;
+import com.fjhx.form.mapper.customer.CustomerPayableBalanceMapper;
+import com.fjhx.form.service.customer.CustomerPayableBalanceService;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * <p>
+ * 客户应付余额 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2024-05-11
+ */
+@Service
+public class CustomerPayableBalanceServiceImpl extends ServiceImpl<CustomerPayableBalanceMapper, CustomerPayableBalance> implements CustomerPayableBalanceService {
+
+    @Override
+    public synchronized void edit(CustomerPayableBalanceDto dto) {
+        CustomerPayableBalance one = getOne(q -> q
+                .eq(CustomerPayableBalance::getCustomerId, dto.getCustomerId())
+                .eq(CustomerPayableBalance::getAccountDate, dto.getAccountDate())
+        );
+        if (ObjectUtil.isNotEmpty(one)) {
+            dto.setId(one.getId());
+        }
+        this.saveOrUpdate(dto);
+    }
+
+}

+ 159 - 1
hx-form/src/main/java/com/fjhx/form/service/impl/ReportServiceImpl.java

@@ -1,30 +1,45 @@
 package com.fjhx.form.service.impl;
 
+import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.common.constant.SourceConstant;
 import com.fjhx.common.utils.Assert;
 import com.fjhx.common.utils.excel.util.ExcelUtil;
+import com.fjhx.customer.entity.customer.po.Customer;
+import com.fjhx.customer.entity.customer.vo.CustomerVo;
+import com.fjhx.customer.service.customer.CustomerService;
 import com.fjhx.form.entity.*;
+import com.fjhx.form.entity.customer.po.CustomerPayableBalance;
 import com.fjhx.form.mapper.ReportMapper;
 import com.fjhx.form.service.ReportService;
+import com.fjhx.form.service.customer.CustomerPayableBalanceService;
 import com.fjhx.item.service.product.ProductInfoService;
 import com.fjhx.mes.entity.report.po.ReportLossesDetails;
 import com.fjhx.mes.service.report.ReportLossesDetailsService;
 import com.ruoyi.common.core.domain.entity.SysDept;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.wrapper.IWrapper;
 import com.ruoyi.common.utils.wrapper.SqlField;
 import com.ruoyi.system.service.ISysDeptService;
+import com.ruoyi.system.service.ISysUserService;
 import com.ruoyi.system.utils.UserUtil;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 import javax.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
@@ -35,12 +50,20 @@ public class ReportServiceImpl implements ReportService {
     private final ProductInfoService productInfoService;
     private final ISysDeptService deptService;
 
+    private final CustomerPayableBalanceService customerPayableBalanceService;
+
+    private final CustomerService customerService;
+    private final ISysUserService userService;
+
     @Autowired
-    public ReportServiceImpl(ReportMapper reportMapper, ReportLossesDetailsService reportLossesDetailsService, ProductInfoService productInfoService, ISysDeptService sysDeptService) {
+    public ReportServiceImpl(ReportMapper reportMapper, ReportLossesDetailsService reportLossesDetailsService, ProductInfoService productInfoService, ISysDeptService sysDeptService, CustomerPayableBalanceService customerPayableBalanceService, CustomerService customerService, ISysUserService userService) {
         this.reportMapper = reportMapper;
         this.reportLossesDetailsService = reportLossesDetailsService;
         this.productInfoService = productInfoService;
         this.deptService = sysDeptService;
+        this.customerPayableBalanceService = customerPayableBalanceService;
+        this.customerService = customerService;
+        this.userService = userService;
     }
 
     @Override
@@ -296,4 +319,139 @@ public class ReportServiceImpl implements ReportService {
         list.add(sumBo);
         return list;
     }
+
+    @Override
+    public List<JSONObject> getReceivableAccounts(ReceivableAccountsSelectDto dto) {
+        Integer year = dto.getYear();
+        Assert.notEmpty(year, "年份不能为空");
+
+        //获取一年里有交易的客户信息
+        List<CustomerMonthlyAccounts> customerMonthlyAccounts = reportMapper.getCustomerMonthlyAccounts(year);
+        Map<Long, List<CustomerMonthlyAccounts>> monthlyAccountsMap = customerMonthlyAccounts
+                .stream().collect(Collectors.groupingBy(CustomerMonthlyAccounts::getBuyCorporationId));
+        //获取年初额度
+        Map<Long, CustomerPayableBalance> lastPayableBalanceMap = customerPayableBalanceService.mapKEntity(
+                CustomerPayableBalance::getCustomerId,
+                q -> q.eq(CustomerPayableBalance::getAccountDate, StrUtil.format("{}-12", year - 1))
+        );
+
+        //获取今年的调整信息
+        Map<Long, List<CustomerPayableBalance>> payableBalanceListMap = customerPayableBalanceService.mapKGroup(
+                CustomerPayableBalance::getCustomerId,
+                q -> q.apply("YEAR(account_date) = {0}", year)
+        );
+        List<Long> customerIds = customerMonthlyAccounts.stream().map(CustomerMonthlyAccounts::getBuyCorporationId).distinct().collect(Collectors.toList());
+        List<CustomerVo> customerList = new ArrayList<>();
+        if (ObjectUtil.isNotEmpty(customerIds)) {
+            customerList = customerService.getList(IWrapper.<CustomerVo>getWrapper().in("c", Customer::getId, customerIds));
+            //赋值业务员信息
+            UserUtil.assignmentNickName(customerList, CustomerVo::getUserId, CustomerVo::setUserName);
+        }
+        Map<Long, CustomerVo> customerMap = customerList.stream().collect(Collectors.toMap(CustomerVo::getId, Function.identity()));
+
+        List<JSONObject> outList = new ArrayList<>();
+        for (Long customerId : customerIds) {
+            //获取年初信息
+            BigDecimal yearBeginBalance = BigDecimal.ZERO;
+            CustomerPayableBalance customerPayableBalance = lastPayableBalanceMap.get(customerId);
+            if (ObjectUtil.isNotNull(customerPayableBalance)) {
+                yearBeginBalance = customerPayableBalance.getBalance();
+            }
+
+            //获取每月信息
+            List<CustomerMonthlyAccounts> monthlyAccountsList = monthlyAccountsMap.getOrDefault(customerId, new ArrayList<>());
+            Map<Integer, CustomerMonthlyAccounts> itemMonthlyAccountsMap = monthlyAccountsList
+                    .stream().collect(Collectors.toMap(CustomerMonthlyAccounts::getDataMonth, Function.identity()));
+
+            //获取调整信息
+            List<CustomerPayableBalance> payableBalanceList = payableBalanceListMap.getOrDefault(customerId, new ArrayList<>());
+            Map<Date, CustomerPayableBalance> payableBalanceMap = payableBalanceList
+                    .stream().collect(Collectors.toMap(CustomerPayableBalance::getAccountDate, Function.identity()));
+
+            //上月余额
+            BigDecimal lastBalanceAmount = yearBeginBalance;
+
+            CustomerVo customer = customerMap.getOrDefault(customerId, new CustomerVo());
+
+            JSONObject dataJson = new JSONObject();
+            dataJson.put("customerId", customerId);
+            dataJson.put("customerName", customer.getName());
+            dataJson.put("customerShortName", customer.getShortName());
+            dataJson.put("saleUserName", customer.getUserName());
+            dataJson.put("yearBeginBalance", yearBeginBalance);
+            for (int i = 1; i <= 12; i++) {
+                //获取应收 已收
+                BigDecimal receivableAmount = BigDecimal.ZERO;
+                BigDecimal receivedAmount = BigDecimal.ZERO;
+                CustomerMonthlyAccounts customerMonthlyAccounts1 = itemMonthlyAccountsMap.get(i);
+                if (ObjectUtil.isNotEmpty(customerMonthlyAccounts1)) {
+                    receivableAmount = customerMonthlyAccounts1.getTruckAmount();
+                    //调整为负数
+                    receivedAmount = BigDecimal.ZERO.subtract(customerMonthlyAccounts1.getClaimMonth());
+                }
+
+                //获取调整
+                BigDecimal adjustAmount = BigDecimal.ZERO;
+                CustomerPayableBalance customerPayableBalance1 = payableBalanceMap
+                        .get(DateUtil.parse(StrUtil.format("{}-{}", year, i), "yyyy-MM"));
+                if (ObjectUtil.isNotEmpty(customerPayableBalance1)) {
+                    adjustAmount = customerPayableBalance1.getAdjust();
+                }
+
+                //计算余额
+                BigDecimal balanceAmount = lastBalanceAmount.add(receivableAmount).add(receivedAmount).add(adjustAmount);
+
+                //赋值上月余额
+                lastBalanceAmount = balanceAmount;
+
+
+                JSONObject itemJson = new JSONObject();
+                itemJson.put("receivableAmount", receivableAmount);
+                itemJson.put("receivedAmount", receivedAmount);
+                itemJson.put("adjustAmount", adjustAmount);
+                itemJson.put("balanceAmount", balanceAmount);
+                dataJson.put("" + i, itemJson);
+            }
+            outList.add(dataJson);
+        }
+
+        return outList;
+    }
+
+    /**
+     * 每月1日0点1分 赋值客户上月应付余额
+     */
+//    @PostConstruct
+    @Scheduled(cron = "0 1 0 1 * ?")
+    public void autoSaveReceivableAccountsEnding() {
+        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
+        SecurityUtils.setTenantId("000000");
+
+        ReceivableAccountsSelectDto dto = new ReceivableAccountsSelectDto();
+        DateTime lastMonth = DateUtil.offsetMonth(new Date(), -1);
+        dto.setYear(DateUtil.year(lastMonth));
+        List<JSONObject> receivableAccounts = getReceivableAccounts(dto);
+        for (JSONObject receivableAccount : receivableAccounts) {
+            int month = DateUtil.month(lastMonth) + 1;
+            JSONObject item = receivableAccount.getJSONObject("" + month);
+            Long customerId = receivableAccount.getLong("customerId");
+
+            DateTime parse = DateUtil.parse(StrUtil.format("{}-{}", dto.getYear(), month), "yyyy-MM");
+
+            CustomerPayableBalance customerPayableBalance = customerPayableBalanceService.getOne(q -> q
+                    .eq(CustomerPayableBalance::getCustomerId, customerId)
+                    .eq(CustomerPayableBalance::getAccountDate, parse)
+            );
+            if (ObjectUtil.isEmpty(customerPayableBalance)) {
+                customerPayableBalance = new CustomerPayableBalance();
+                customerPayableBalance.setCustomerId(customerId);
+                customerPayableBalance.setAccountDate(parse);
+            }
+            customerPayableBalance.setBalance(item.getBigDecimal("balanceAmount"));
+            customerPayableBalanceService.saveOrUpdate(customerPayableBalance);
+        }
+
+        SecurityUtils.clearTenantId();
+        DynamicDataSourceContextHolder.clear();
+    }
 }

+ 44 - 1
hx-form/src/main/resources/mapper/ReportMapper.xml

@@ -5,7 +5,7 @@
     <select id="productionReport" resultType="com.fjhx.form.entity.ProductionReportBo">
         SELECT pod.id,
                pod.company_id                                                     AS factoryId,
-               po.`code`                                                      AS orderCode,
+               po.`code`                                                          AS orderCode,
                pod.product_id,
                pod.quantity,
                po.delivery_period,
@@ -175,4 +175,47 @@
                        HAVING receivable_amount != 0) c1 ON c1.buy_corporation_id = cu.id
             ${ew.customSqlSegment}
     </select>
+    <select id="getCustomerMonthlyAccounts" resultType="com.fjhx.form.entity.CustomerMonthlyAccounts">
+        SELECT t1.buy_corporation_id,
+               t1.data_month,
+               ifnull(sum(t1.truck_amount), 0) as truck_amount,
+               ifnull(sum(t1.claim_month), 0)  as claim_month
+        FROM (SELECT t1.buy_corporation_id,
+                     t1.truck_month       AS data_month,
+                     sum(t1.truck_amount) AS truck_amount,
+                     NULL                 AS claim_month
+              FROM (SELECT c.buy_corporation_id, MONTH ( coi.truck_date ) AS truck_month, sum ( cor.truck_quantity * cor.price ) AS truck_amount
+                    FROM
+                        contract_outbound_records cor
+                        JOIN contract_outbound_info coi
+                    ON cor.record_id = coi.id
+                        JOIN contract c ON coi.contract_id = c.id
+                    WHERE
+                        YEAR ( coi.truck_date )= #{year}
+                    GROUP BY
+                        coi.id) t1
+              GROUP BY t1.buy_corporation_id,
+                       t1.truck_month
+              UNION ALL
+              SELECT t1.buy_corporation_id,
+                     t1.claim_month AS data_month,
+                     NULL           AS truck_amount,
+                     sum(t1.claim_amount)
+              FROM (SELECT c.buy_corporation_id,
+                           sum(cc.money) AS claim_amount, MONTH ( arw.transaction_time ) AS claim_month
+                    FROM
+                        contract c
+                        JOIN claim_contract cc
+                    ON cc.contract_id = c.id
+                        JOIN claim cl ON cc.claim_id = cl.id
+                        JOIN account_running_water arw ON cl.business_id = arw.id
+                    WHERE
+                        YEAR ( arw.transaction_time )= #{year}
+                    GROUP BY
+                        cl.id) t1
+              GROUP BY t1.buy_corporation_id,
+                       t1.claim_month) t1
+        GROUP BY t1.buy_corporation_id,
+                 t1.data_month
+    </select>
 </mapper>

+ 4 - 0
hx-form/src/main/resources/mapper/customer/CustomerPayableBalanceMapper.xml

@@ -0,0 +1,4 @@
+<?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.form.mapper.customer.CustomerPayableBalanceMapper">
+</mapper>