| | |
| | | package com.by4cloud.platformx.business.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.http.HttpUtil; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.by4cloud.platformx.admin.api.entity.SysDept; |
| | | import com.by4cloud.platformx.admin.api.feign.RemoteDeptService; |
| | | import com.by4cloud.platformx.business.dto.AgingQueryDTO; |
| | | import com.by4cloud.platformx.business.dto.PaymentConfirmAddDTO; |
| | | import com.by4cloud.platformx.business.dto.SyncPaymentRecepitDTO; |
| | | import com.by4cloud.platformx.business.entity.*; |
| | | import com.by4cloud.platformx.business.mapper.ContractPaymentScheduleMapper; |
| | | import com.by4cloud.platformx.business.mapper.CurrentOverdueMapper; |
| | | import com.by4cloud.platformx.business.mapper.HistoryOverdueMapper; |
| | | import com.by4cloud.platformx.business.mapper.PaymentConfirmMapper; |
| | | import com.by4cloud.platformx.business.mapper.*; |
| | | import com.by4cloud.platformx.business.service.BusinessCustomerService; |
| | | import com.by4cloud.platformx.business.service.ContractService; |
| | | import com.by4cloud.platformx.business.service.PaymentConfirmService; |
| | | import com.by4cloud.platformx.business.utils.SignHelper; |
| | | import com.by4cloud.platformx.business.vo.AgingAnalysisVo; |
| | | import com.by4cloud.platformx.business.vo.AgingCompanyVo; |
| | | import com.by4cloud.platformx.business.vo.AgingVo; |
| | | import com.by4cloud.platformx.common.core.util.R; |
| | | import com.by4cloud.platformx.common.data.datascope.DataScope; |
| | | import com.by4cloud.platformx.common.security.util.SecurityUtils; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.redis.core.StringRedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.math.RoundingMode; |
| | | import java.security.InvalidKeyException; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.IntStream; |
| | | |
| | | ; |
| | | |
| | | /** |
| | | * 收款确认 |
| | |
| | | * @author syt |
| | | * @date 2026-04-29 11:33:26 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class PaymentConfirmServiceImpl extends ServiceImpl<PaymentConfirmMapper, PaymentConfirm> implements PaymentConfirmService { |
| | |
| | | private final ContractPaymentScheduleMapper contractPaymentScheduleMapper; |
| | | private final CurrentOverdueMapper currentOverdueMapper; |
| | | private final HistoryOverdueMapper historyOverdueMapper; |
| | | private final PaymentSlipMapper paymentSlipMapper; |
| | | private final BipRequestRecordMapper bipRequestRecordMapper; |
| | | private final ContractExecDateMapper contractExecDateMapper; |
| | | private final MeterReadRecordMapper meterReadRecordMapper; |
| | | private final BankStatementMapper bankStatementMapper; |
| | | private final RemoteDeptService remoteDeptService; |
| | | private final StringRedisTemplate redisTemplate; |
| | | |
| | | @Value("${bip.url}") |
| | | private String url; |
| | | |
| | | @Value("${bip.codes}") |
| | | private String codes; |
| | | |
| | | @Value("${bip.appKey}") |
| | | private String appKey; |
| | | |
| | | @Value("${bip.appSecret}") |
| | | private String appSecret; |
| | | |
| | | @Override |
| | | public R add(PaymentConfirmAddDTO addDTO) { |
| | | Contract contract = contractService.getOne(Wrappers.<Contract>lambdaQuery().eq(Contract::getContractNo,addDTO.getContractNo())); |
| | | if(ObjUtil.isNull(contract)){ |
| | | return R.failed("合同查询失败,请检查合同编号"); |
| | | } |
| | | BusinessCustomer customer = businessCustomerService.getOne(Wrappers.<BusinessCustomer>lambdaQuery() |
| | | .eq(StrUtil.isNotBlank(addDTO.getBusGuestName()),BusinessCustomer::getCompanyName,addDTO.getBusGuestName()) |
| | | .eq(StrUtil.isNotBlank(addDTO.getBusGuestId()),BusinessCustomer::getId,addDTO.getBusGuestId())); |
| | | if(ObjUtil.isNull(customer)){ |
| | | return R.failed("客商查询失败,请检查客商"); |
| | | if (StrUtil.isNotBlank(addDTO.getContractNo())) { |
| | | Contract contract = contractService.getOne(Wrappers.<Contract>lambdaQuery().eq(Contract::getContractNo, addDTO.getContractNo())); |
| | | if (ObjUtil.isNull(contract)) { |
| | | return R.failed("合同查询失败,请检查合同编号"); |
| | | } |
| | | BusinessCustomer customer = businessCustomerService.getById(contract.getPartyAId()); |
| | | if (ObjUtil.isNull(customer)) { |
| | | return R.failed("客商查询失败,请检查客商"); |
| | | } |
| | | |
| | | //转入 |
| | | if (StrUtil.equals(addDTO.getInOrOut(), "1")) { |
| | | //保存收款单 |
| | | savePaymentSlip(addDTO,customer,contract); |
| | | //保存收款单 |
| | | savePaymentConfirm(addDTO,contract,customer); |
| | | //处理收款 |
| | | handleSlipToSchedule(addDTO,contract); |
| | | //更新状态 |
| | | updateContractStatus(addDTO,contract); |
| | | } |
| | | //转出 |
| | | if (StrUtil.equals(addDTO.getInOrOut(), "2")) { |
| | | return handleBackSlip(addDTO,contract,customer); |
| | | } |
| | | |
| | | } |
| | | |
| | | PaymentConfirm lastConfirm = baseMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId()) |
| | | return R.ok(); |
| | | } |
| | | |
| | | private R handleBackSlip(PaymentConfirmAddDTO addDTO,Contract contract,BusinessCustomer customer) { |
| | | PaymentConfirm lastConfirm = baseMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId, contract.getId()) |
| | | .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); |
| | | BigDecimal lastTotal = new BigDecimal("0"); |
| | | if(ObjUtil.isNotNull(lastConfirm)){ |
| | | lastTotal = lastConfirm.getTotalAmount(); |
| | | } |
| | | PaymentConfirm entity = new PaymentConfirm(); |
| | | entity.setContractId(contract.getId()); |
| | | entity.setContractName(contract.getContractName()); |
| | | entity.setContractNo(contract.getContractNo()); |
| | | |
| | | //转入 |
| | | if (StrUtil.equals(addDTO.getInOrOut(),"1")){ |
| | | BigDecimal newtotal = addDTO.getTransationAmount().add(lastTotal); |
| | | PaymentConfirm entity = new PaymentConfirm(); |
| | | entity.setContractId(contract.getId()); |
| | | entity.setContractName(contract.getContractName()); |
| | | entity.setContractNo(addDTO.getContractNo()); |
| | | if(ObjUtil.isNotNull(lastConfirm)){ |
| | | entity.setScheduleId(lastConfirm.getScheduleId()); |
| | | entity.setScheduleName(lastConfirm.getScheduleName()); |
| | | entity.setBusGuestId(customer.getId()); |
| | | entity.setBusGuestName(customer.getCompanyName()); |
| | | entity.setBusinessType("退款"); |
| | | entity.setTransationAmount(addDTO.getTransationAmount()); |
| | | BigDecimal newtotal = addDTO.getTransationAmount().multiply(new BigDecimal("-1")).add(lastConfirm.getTotalAmount()); |
| | | if (newtotal.compareTo(new BigDecimal("0")) > 0) { |
| | | entity.setAdvanceAmount(newtotal); |
| | | entity.setTotalAmount(newtotal); |
| | | } else if (newtotal.compareTo(new BigDecimal("0")) == 0) { |
| | | entity.setTotalAmount(newtotal); |
| | | } else { |
| | | return R.failed("当前客户余额为" + lastConfirm.getTotalAmount() + "不足以满足当前发生金额,无法操作"); |
| | | } |
| | | entity.setConfirmTime(new Date()); |
| | | baseMapper.insert(entity); |
| | | contract.setPaidAmount(contract.getPaidAmount().subtract(addDTO.getTransationAmount())); |
| | | contract.setContractStatus(2); |
| | | contractService.updateById(contract); |
| | | return R.ok(); |
| | | } |
| | | |
| | | private void updateContractStatus(PaymentConfirmAddDTO addDTO,Contract contract) { |
| | | |
| | | //非房屋租赁 水电 |
| | | if (!StrUtil.equals(contract.getContractCategory(), "water_house")) { |
| | | //更新合同已付款 |
| | | BigDecimal paid = new BigDecimal("0"); |
| | | if (ObjUtil.isNotNull(contract.getPaidAmount())) { |
| | | paid = contract.getPaidAmount(); |
| | | } |
| | | entity.setBusGuestId(customer.getId()); |
| | | entity.setBusGuestName(customer.getCompanyName()); |
| | | entity.setBusinessType("客户付款"); |
| | | if (newtotal.compareTo(new BigDecimal("0"))>0){ |
| | | entity.setTransationAmount(addDTO.getTransationAmount()); |
| | | entity.setAdvanceAmount(newtotal); |
| | | entity.setTotalAmount(newtotal); |
| | | entity.setConfirmTime(new Date()); |
| | | baseMapper.insert(entity); |
| | | }else if (newtotal.compareTo(new BigDecimal("0"))==0){ |
| | | entity.setTransationAmount(addDTO.getTransationAmount()); |
| | | entity.setTotalAmount(newtotal); |
| | | entity.setConfirmTime(new Date()); |
| | | baseMapper.insert(entity); |
| | | }else { |
| | | entity.setTransationAmount(addDTO.getTransationAmount()); |
| | | entity.setReceivableAmount(newtotal.multiply(new BigDecimal("-1"))); |
| | | entity.setTotalAmount(newtotal); |
| | | entity.setConfirmTime(new Date()); |
| | | baseMapper.insert(entity); |
| | | paid = paid.add(addDTO.getTransationAmount()); |
| | | contract.setPaidAmount(paid); |
| | | if (paid.compareTo(contract.getAmount().subtract(contract.getDropAmount())) >= 0&&contract.getBillingAmout().compareTo(contract.getAmount())==0) { |
| | | contract.setContractStatus(3); |
| | | contract.setPaidAmount(contract.getAmount().subtract(contract.getDropAmount())); |
| | | } |
| | | List<ContractPaymentSchedule> scheduleList = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery() |
| | | .eq(ContractPaymentSchedule::getContractId,contract.getId()).ne(ContractPaymentSchedule::getPaymentStatus,2) |
| | | .orderByAsc(ContractPaymentSchedule::getCreateTime)); |
| | | if (ArrayUtil.isNotEmpty(scheduleList.toArray())){ |
| | | BigDecimal remain = addDTO.getTransationAmount(); |
| | | for (ContractPaymentSchedule schedule:scheduleList) { |
| | | BigDecimal lastRemain = remain; |
| | | remain = remain.subtract(StrUtil.equals(schedule.getPaymentStatus()+"","0")?schedule.getPlannedAmount(): |
| | | schedule.getPlannedAmount().subtract(schedule.getActualAmount())); |
| | | if (remain.compareTo(new BigDecimal("0"))>=0){ |
| | | schedule.setActualAmount(schedule.getPlannedAmount()); |
| | | schedule.setPaymentDate(addDTO.getConfirmTime()); |
| | | schedule.setPaymentStatus(2); |
| | | contractPaymentScheduleMapper.updateById(schedule); |
| | | //查询是否有当前逾期 |
| | | CurrentOverdue currentOverdue = currentOverdueMapper.selectOne(Wrappers.<CurrentOverdue>lambdaQuery().eq(CurrentOverdue::getScheduleId,schedule.getId()) |
| | | .eq(CurrentOverdue::getContractId,schedule.getContractId()).last("limit 1")); |
| | | if (ObjUtil.isNotNull(currentOverdue)){ |
| | | //新增逾期历史 |
| | | HistoryOverdue historyOverdue = BeanUtil.copyProperties(currentOverdue,HistoryOverdue.class,"id"); |
| | | historyOverdue.setPaymentTime(addDTO.getConfirmTime()); |
| | | historyOverdue.setCompId(schedule.getCompId()); |
| | | historyOverdueMapper.insert(historyOverdue); |
| | | //删除当前逾期 |
| | | currentOverdueMapper.deleteById(currentOverdue); |
| | | } |
| | | }else { |
| | | schedule.setActualAmount(StrUtil.equals(schedule.getPaymentStatus()+"","0")?schedule.getPlannedAmount().add(remain): |
| | | schedule.getActualAmount().add(lastRemain)); |
| | | schedule.setPaymentDate(addDTO.getConfirmTime()); |
| | | schedule.setPaymentStatus(1); |
| | | contractPaymentScheduleMapper.updateById(schedule); |
| | | //查询是否有当前逾期 |
| | | CurrentOverdue currentOverdue = currentOverdueMapper.selectOne(Wrappers.<CurrentOverdue>lambdaQuery().eq(CurrentOverdue::getScheduleId,schedule.getId()) |
| | | .eq(CurrentOverdue::getContractId,schedule.getContractId()).last("limit 1")); |
| | | if (ObjUtil.isNotNull(currentOverdue)){ |
| | | //新增逾期历史 |
| | | HistoryOverdue historyOverdue = BeanUtil.copyProperties(currentOverdue,HistoryOverdue.class,"id"); |
| | | historyOverdue.setReceivableAmount(lastRemain); |
| | | historyOverdue.setPaymentTime(addDTO.getConfirmTime()); |
| | | historyOverdue.setCompId(schedule.getCompId()); |
| | | historyOverdueMapper.insert(historyOverdue); |
| | | //查询历史已付逾期金额 |
| | | List<HistoryOverdue> historyOverdueList = historyOverdueMapper.selectList(Wrappers.<HistoryOverdue>lambdaQuery().eq(HistoryOverdue::getScheduleId,currentOverdue.getScheduleId())); |
| | | BigDecimal hisTotal = historyOverdueList.stream().map(item->item.getReceivableAmount()).reduce(BigDecimal.ZERO,BigDecimal::add); |
| | | //更新当前逾期 |
| | | currentOverdue.setReceivableAmount(schedule.getPlannedAmount().subtract(hisTotal)); |
| | | currentOverdueMapper.updateById(currentOverdue); |
| | | } |
| | | break; |
| | | contractService.updateById(contract); |
| | | }else { |
| | | List<ContractExecDate> execDateList = contractExecDateMapper.selectList(Wrappers.<ContractExecDate>lambdaQuery().eq(ContractExecDate::getContractId,contract.getId()) |
| | | .eq(ContractExecDate::getGenFlag,"0")); |
| | | if (CollUtil.isEmpty(execDateList)){ |
| | | //更新合同已付款 |
| | | BigDecimal paid = new BigDecimal("0"); |
| | | if (ObjUtil.isNotNull(contract.getPaidAmount())) { |
| | | paid = contract.getPaidAmount(); |
| | | } |
| | | paid = paid.add(addDTO.getTransationAmount()); |
| | | contract.setPaidAmount(paid); |
| | | if (contract.getBillingAmout().compareTo(contract.getAmount())==0&&paid.compareTo(contract.getAmount().subtract(contract.getDropAmount())) >= 0) { |
| | | contract.setContractStatus(3); |
| | | contract.setPaidAmount(contract.getAmount()); |
| | | } |
| | | contractService.updateById(contract); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void handleSlipToSchedule(PaymentConfirmAddDTO addDTO,Contract contract) { |
| | | //更新付款阶段付款 |
| | | List<ContractPaymentSchedule> scheduleList = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery() |
| | | .eq(ContractPaymentSchedule::getContractId, contract.getId()).ne(ContractPaymentSchedule::getPaymentStatus, 2).ne(ContractPaymentSchedule::getPaymentStatus, 3) |
| | | .orderByAsc(ContractPaymentSchedule::getCreateTime)); |
| | | if (CollUtil.isNotEmpty(scheduleList)) { |
| | | BigDecimal remain = addDTO.getTransationAmount(); |
| | | for (ContractPaymentSchedule schedule : scheduleList) { |
| | | BigDecimal lastRemain = remain; |
| | | remain = remain.subtract(StrUtil.equals(schedule.getPaymentStatus() + "", "0") ? schedule.getPlannedAmount() : |
| | | schedule.getPlannedAmount().subtract(schedule.getActualAmount())); |
| | | if (remain.compareTo(new BigDecimal("0")) >= 0) { |
| | | schedule.setActualAmount(schedule.getPlannedAmount()); |
| | | schedule.setPaymentDate(addDTO.getConfirmTime()); |
| | | schedule.setPaymentStatus(2); |
| | | contractPaymentScheduleMapper.updateById(schedule); |
| | | //查询是否有当前逾期 |
| | | CurrentOverdue currentOverdue = currentOverdueMapper.selectOne(Wrappers.<CurrentOverdue>lambdaQuery().eq(CurrentOverdue::getScheduleId, schedule.getId()) |
| | | .eq(CurrentOverdue::getContractId, schedule.getContractId()).last("limit 1")); |
| | | if (ObjUtil.isNotNull(currentOverdue)) { |
| | | //新增逾期历史 |
| | | HistoryOverdue historyOverdue = BeanUtil.copyProperties(currentOverdue, HistoryOverdue.class, "id"); |
| | | historyOverdue.setPaymentTime(addDTO.getConfirmTime()); |
| | | historyOverdue.setCompId(schedule.getCompId()); |
| | | historyOverdueMapper.insert(historyOverdue); |
| | | //删除当前逾期 |
| | | currentOverdueMapper.deleteById(currentOverdue); |
| | | } |
| | | } else { |
| | | schedule.setActualAmount(StrUtil.equals(schedule.getPaymentStatus() + "", "0") ? schedule.getPlannedAmount().add(remain) : |
| | | schedule.getActualAmount().add(lastRemain)); |
| | | schedule.setPaymentDate(addDTO.getConfirmTime()); |
| | | schedule.setPaymentStatus(1); |
| | | contractPaymentScheduleMapper.updateById(schedule); |
| | | //查询是否有当前逾期 |
| | | CurrentOverdue currentOverdue = currentOverdueMapper.selectOne(Wrappers.<CurrentOverdue>lambdaQuery().eq(CurrentOverdue::getScheduleId, schedule.getId()) |
| | | .eq(CurrentOverdue::getContractId, schedule.getContractId()).last("limit 1")); |
| | | if (ObjUtil.isNotNull(currentOverdue)) { |
| | | //新增逾期历史 |
| | | HistoryOverdue historyOverdue = BeanUtil.copyProperties(currentOverdue, HistoryOverdue.class, "id"); |
| | | historyOverdue.setReceivableAmount(lastRemain); |
| | | historyOverdue.setPaymentTime(addDTO.getConfirmTime()); |
| | | historyOverdue.setCompId(schedule.getCompId()); |
| | | historyOverdueMapper.insert(historyOverdue); |
| | | //更新当前逾期 |
| | | currentOverdue.setReceivableAmount(schedule.getPlannedAmount().subtract(schedule.getActualAmount())); |
| | | currentOverdueMapper.updateById(currentOverdue); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | //转出 |
| | | if (StrUtil.equals(addDTO.getInOrOut(),"2")){ |
| | | PaymentConfirm entity = new PaymentConfirm(); |
| | | entity.setContractId(contract.getId()); |
| | | entity.setContractName(contract.getContractName()); |
| | | entity.setContractNo(addDTO.getContractNo()); |
| | | } |
| | | |
| | | entity.setBusGuestId(customer.getId()); |
| | | entity.setBusGuestName(customer.getCompanyName()); |
| | | entity.setBusinessType(""); |
| | | private void savePaymentConfirm(PaymentConfirmAddDTO addDTO,Contract contract,BusinessCustomer customer) { |
| | | |
| | | PaymentConfirm lastConfirm = baseMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId, contract.getId()) |
| | | .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); |
| | | BigDecimal lastTotal = new BigDecimal("0"); |
| | | if (ObjUtil.isNotNull(lastConfirm)) { |
| | | lastTotal = lastConfirm.getTotalAmount(); |
| | | } |
| | | BigDecimal newtotal = addDTO.getTransationAmount().add(lastTotal); |
| | | PaymentConfirm entity = new PaymentConfirm(); |
| | | entity.setContractId(contract.getId()); |
| | | entity.setContractName(contract.getContractName()); |
| | | entity.setContractNo(addDTO.getContractNo()); |
| | | if (ObjUtil.isNotNull(lastConfirm)) { |
| | | entity.setScheduleId(lastConfirm.getScheduleId()); |
| | | entity.setScheduleName(lastConfirm.getScheduleName()); |
| | | } |
| | | entity.setBusGuestId(customer.getId()); |
| | | entity.setBusGuestName(customer.getCompanyName()); |
| | | entity.setBusinessType("客户付款"); |
| | | if (newtotal.compareTo(new BigDecimal("0")) > 0) { |
| | | entity.setTransationAmount(addDTO.getTransationAmount()); |
| | | BigDecimal newtotal = addDTO.getTransationAmount().multiply(new BigDecimal("-1")).add(lastConfirm.getTotalAmount()); |
| | | if (newtotal.compareTo(new BigDecimal("0"))>0){ |
| | | entity.setAdvanceAmount(newtotal); |
| | | entity.setTotalAmount(newtotal); |
| | | }else if (newtotal.compareTo(new BigDecimal("0"))==0){ |
| | | entity.setTotalAmount(newtotal); |
| | | }else { |
| | | return R.failed("当前客户余额为"+lastConfirm.getTotalAmount()+"不足以满足当前发生金额,无法操作"); |
| | | } |
| | | entity.setAdvanceAmount(newtotal); |
| | | entity.setTotalAmount(newtotal); |
| | | entity.setConfirmTime(new Date()); |
| | | baseMapper.insert(entity); |
| | | } else if (newtotal.compareTo(new BigDecimal("0")) == 0) { |
| | | entity.setTransationAmount(addDTO.getTransationAmount()); |
| | | entity.setTotalAmount(newtotal); |
| | | entity.setConfirmTime(new Date()); |
| | | baseMapper.insert(entity); |
| | | } else { |
| | | entity.setTransationAmount(addDTO.getTransationAmount()); |
| | | entity.setReceivableAmount(newtotal.multiply(new BigDecimal("-1"))); |
| | | entity.setTotalAmount(newtotal); |
| | | entity.setConfirmTime(new Date()); |
| | | baseMapper.insert(entity); |
| | | } |
| | | // 查询所有付款阶段是否都付款完成 |
| | | List<ContractPaymentSchedule> scheduleList = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId,contract.getId())); |
| | | if (ArrayUtil.isNotEmpty(scheduleList.toArray())){ |
| | | if (scheduleList.stream().allMatch(item -> Objects.equals(item.getPaymentStatus(), 2))){ |
| | | contract.setContractStatus(3); |
| | | contractService.updateById(contract); |
| | | }; |
| | | } |
| | | |
| | | private void savePaymentSlip(PaymentConfirmAddDTO addDTO,BusinessCustomer customer,Contract contract) { |
| | | //新增付款单 |
| | | PaymentSlip slip = new PaymentSlip(); |
| | | slip.setBusGuestId(customer.getId()); |
| | | slip.setBusGuestName(customer.getCompanyName()); |
| | | slip.setPayeeCompId(SecurityUtils.getUser().getCompId()); |
| | | slip.setPaymentTime(addDTO.getConfirmTime()); |
| | | slip.setPaymentAmount(addDTO.getTransationAmount()); |
| | | slip.setPayType(addDTO.getPayType()); |
| | | slip.setContractId(contract.getId()); |
| | | paymentSlipMapper.insert(slip); |
| | | } |
| | | |
| | | @Override |
| | | public R syncPaymentRecepit(SyncPaymentRecepitDTO dto) { |
| | | String accessToken = ""; |
| | | if (redisTemplate.hasKey("BIP_TOKEN")) { |
| | | accessToken = (String) redisTemplate.opsForValue().get("BIP_TOKEN"); |
| | | } else { |
| | | accessToken = getAccessToken(accessToken); |
| | | } |
| | | if (StrUtil.isEmpty(accessToken)) { |
| | | return R.failed("获取token失败"); |
| | | } |
| | | String[] bipCodeArr = StrUtil.isNotBlank(dto.getBipCode())?dto.getBipCode().split(","):codes.split(","); |
| | | for (String bipCode : bipCodeArr) { |
| | | //入参 |
| | | JSONObject params = new JSONObject(); |
| | | if (ObjUtil.isNotEmpty(dto.getPageSize())){ |
| | | params.put("pageSize",dto.getPageSize()); |
| | | }else { |
| | | params.put("pageSize",999); |
| | | } |
| | | if (ObjUtil.isNotEmpty(dto.getPageNum())){ |
| | | params.put("pageNum",dto.getPageNum()); |
| | | }else { |
| | | params.put("pageNum",1); |
| | | } |
| | | if (StrUtil.isNotBlank(dto.getStartDate())){ |
| | | params.put("begindate",dto.getStartDate()); |
| | | }else { |
| | | params.put("begindate", DateUtil.formatDate(DateUtil.offsetDay(new Date(), -1))); |
| | | } |
| | | if (StrUtil.isNotBlank(dto.getStartDate())){ |
| | | params.put("enddate", dto.getEndDate()); |
| | | }else { |
| | | params.put("enddate", DateUtil.today()); |
| | | } |
| | | params.put("dc_flag","1");//1 借 2 贷 只查收款 |
| | | //单据状态已审批 |
| | | params.put("accentity_code", bipCode); |
| | | String finalAccessToken = accessToken; |
| | | new Thread(() -> { |
| | | try { |
| | | Thread.sleep(500); |
| | | } catch (InterruptedException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | log.info("银行流水查询 Request:{}", params.toJSONString()); |
| | | String result = HttpUtil.post(url + "/yonbip/ctm/cmp/bankReconciliationQuery?access_token=" + finalAccessToken, params.toJSONString()); |
| | | log.info("银行流水查询 Response:{}", result); |
| | | //保存请求记录 |
| | | saveBipRequestRecord(params, "银行流水查询接口", result); |
| | | JSONObject resultJson = JSONObject.parseObject(result); |
| | | if (resultJson.containsKey("code") && resultJson.getString("code").equals("200")) { |
| | | handleAndSave(bipCode, resultJson); |
| | | } |
| | | |
| | | }).start(); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @Override |
| | | public String getAccessToken(String accessToken) { |
| | | long timestamp = System.currentTimeMillis(); |
| | | Map<String, Object> paramMap = new HashMap<>(); |
| | | paramMap.put("appKey", appKey); |
| | | paramMap.put("timestamp", timestamp); |
| | | String signature = null; |
| | | try { |
| | | signature = SignHelper.sign(paramMap, appSecret); |
| | | } catch (NoSuchAlgorithmException e) { |
| | | throw new RuntimeException(e); |
| | | } catch (UnsupportedEncodingException e) { |
| | | throw new RuntimeException(e); |
| | | } catch (InvalidKeyException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | String getTokenResult = HttpUtil.get(url + "/open-auth/selfAppAuth/getAccessToken?appKey=" + appKey + "×tamp=" + timestamp |
| | | + "&signature=" + signature); |
| | | log.info("Get access_token Response:{}", getTokenResult); |
| | | JSONObject tokenJson = JSONObject.parseObject(getTokenResult); |
| | | if (!tokenJson.containsKey("code") || !tokenJson.getString("code").equals("00000")) { |
| | | log.error("Get access_token ERROR"); |
| | | return ""; |
| | | } |
| | | if (ObjUtil.isNull(tokenJson.get("data")) || ObjUtil.isNull(JSONObject.parseObject(tokenJson.getString("data")))) { |
| | | log.error("access_token value exception"); |
| | | return ""; |
| | | } |
| | | accessToken = JSONObject.parseObject(tokenJson.getString("data")).getString("access_token"); |
| | | log.info("access_token value:{}", accessToken); |
| | | redisTemplate.opsForValue().set("BIP_TOKEN", accessToken, JSONObject.parseObject(tokenJson.getString("data")).getIntValue("expire") - 10, TimeUnit.SECONDS); |
| | | return accessToken; |
| | | } |
| | | |
| | | @Override |
| | | public void saveBipRequestRecord(JSONObject params, String methodName, String result) { |
| | | BipRequestRecord record = new BipRequestRecord(); |
| | | record.setInterfaceName(methodName); |
| | | record.setRequestParams(params.toJSONString()); |
| | | record.setResponseParams(result); |
| | | record.setResponseCode(JSONObject.parseObject(result).getString("code")); |
| | | bipRequestRecordMapper.insert(record); |
| | | } |
| | | |
| | | private void handleAndSave(String bipCode, JSONObject resultJson) { |
| | | R<SysDept> r = remoteDeptService.selectDeptByBipCode(bipCode); |
| | | if (!r.isOk()) { |
| | | log.error("bipcode查询单位失败"); |
| | | return; |
| | | } |
| | | SysDept dept = r.getData(); |
| | | JSONObject dataJson = resultJson.getJSONObject("data"); |
| | | if (ObjUtil.isNull(dataJson)) { |
| | | log.error("返回结果中data解析失败"); |
| | | return; |
| | | } |
| | | JSONArray recordList = dataJson.getJSONArray("recordList"); |
| | | if (CollUtil.isEmpty(recordList)) { |
| | | log.error("返回结果中recordList为空"); |
| | | return; |
| | | } |
| | | log.info("==================开始处理银行流水信息==================="); |
| | | recordList.stream().forEach(obj -> { |
| | | JSONObject record = (JSONObject) obj; |
| | | BusinessCustomer customer = businessCustomerService.getOne(Wrappers.<BusinessCustomer>lambdaQuery() |
| | | .eq(BusinessCustomer::getCompanyName, record.getString("to_acct_name")) |
| | | .eq(BusinessCustomer::getCompId,dept.getDeptId()) |
| | | ); |
| | | //保存付款单 |
| | | Boolean codeFlag = saveBankStatement(customer, record,dept); |
| | | if (!codeFlag) { |
| | | log.error("付款单id:{},付款单已存在"); |
| | | } |
| | | }); |
| | | log.info("==================结束处理银行流水信息==================="); |
| | | } |
| | | |
| | | private Boolean saveBankStatement(BusinessCustomer customer, JSONObject record,SysDept dept) { |
| | | BankStatement bankStatement = new BankStatement(); |
| | | bankStatement.setBankSeqNo(record.getString("bank_seq_no")); |
| | | bankStatement.setReceiveBankAcc(record.getString("bank_seq_no")); |
| | | bankStatement.setReceiveBankAccAcc(record.getString("bankaccount_account")); |
| | | bankStatement.setReceiveBankAccName(record.getString("bankaccount_acctName")); |
| | | bankStatement.setPayBankNo(record.getString("to_acct_no")); |
| | | bankStatement.setPayBankAccName(record.getString("to_acct_name")); |
| | | bankStatement.setTranDate(DateUtil.parseDateTime(record.getString("tran_date"))); |
| | | bankStatement.setTranAmount(record.getBigDecimal("tran_amt")); |
| | | bankStatement.setDcFlag(record.getString("dc_flag")); |
| | | bankStatement.setDataId(record.getLong("id")); |
| | | bankStatement.setDataJson(record.toJSONString()); |
| | | if (ObjUtil.isNotNull(customer)) { |
| | | bankStatement.setBusGuestId(customer.getId()); |
| | | } |
| | | BankStatement statement = bankStatementMapper.selectOne(Wrappers.<BankStatement>lambdaQuery().eq(BankStatement::getDataId,record.getLong("id"))); |
| | | if (ObjUtil.isNotNull(statement)){ |
| | | return false; |
| | | } |
| | | bankStatement.setRemark(record.getString("remark")); |
| | | bankStatement.setCompId(dept.getDeptId()); |
| | | bankStatementMapper.insert(bankStatement); |
| | | return true; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public R queryAllBusinessType() { |
| | | return R.ok(baseMapper.selectList(Wrappers.<PaymentConfirm>lambdaQuery().select(PaymentConfirm::getBusinessType).isNotNull(PaymentConfirm::getBusinessType) |
| | | .groupBy(PaymentConfirm::getBusinessType)).stream().map(PaymentConfirm::getBusinessType).collect(Collectors.toList())); |
| | | } |
| | | |
| | | @Override |
| | | public R queryAging() { |
| | | List<AgingCompanyVo> companys = contractPaymentScheduleMapper.selectAgingCompany(null, DataScope.of("comp_id")); |
| | | if (CollUtil.isEmpty(companys)) { |
| | | return R.failed("暂无账龄"); |
| | | } |
| | | List<AgingAnalysisVo> result = new ArrayList<>(); |
| | | AgingQueryDTO queryDTO = new AgingQueryDTO(); |
| | | List<AgingVo> agingVoList = contractPaymentScheduleMapper.selectAgingTotal(null); |
| | | companys.stream().forEach(company -> { |
| | | BusinessCustomer businessCustomer = businessCustomerService.getById(company.getCompanyId()); |
| | | AgingAnalysisVo agingAnalysisVo = new AgingAnalysisVo(); |
| | | agingAnalysisVo.setCompanyName(businessCustomer.getCompanyName()); |
| | | queryDTO.setCompanyId(company.getCompanyId()); |
| | | List<AgingVo> companyAgingVo = contractPaymentScheduleMapper.selectAgingTotal(queryDTO); |
| | | //补全数据 |
| | | if (CollUtil.isEmpty(companyAgingVo)) { |
| | | companyAgingVo = new ArrayList<>(); |
| | | AgingVo agingVo1 = new AgingVo(1L,"0-30天", new BigDecimal("0"), null); |
| | | AgingVo agingVo2 = new AgingVo(2L,"31-60天", new BigDecimal("0"), null); |
| | | AgingVo agingVo3 = new AgingVo(3L,"61-90天", new BigDecimal("0"), null); |
| | | AgingVo agingVo4 = new AgingVo(4L,"91-180天", new BigDecimal("0"), null); |
| | | AgingVo agingVo5 = new AgingVo(5L,"181-365天", new BigDecimal("0"), null); |
| | | AgingVo agingVo6 = new AgingVo(6L,"1年以上", new BigDecimal("0"), null); |
| | | companyAgingVo.add(agingVo1); |
| | | companyAgingVo.add(agingVo2); |
| | | companyAgingVo.add(agingVo3); |
| | | companyAgingVo.add(agingVo4); |
| | | companyAgingVo.add(agingVo5); |
| | | companyAgingVo.add(agingVo6); |
| | | } else { |
| | | List<String> overdueRanges = companyAgingVo.stream().map(AgingVo::getOverdueRange).collect(Collectors.toList()); |
| | | if (!CollUtil.contains(overdueRanges, "0-30天")) { |
| | | AgingVo agingVo1 = new AgingVo(1L,"0-30天", new BigDecimal("0"), null); |
| | | companyAgingVo.add(agingVo1); |
| | | } |
| | | if (!CollUtil.contains(overdueRanges, "31-60天")) { |
| | | AgingVo agingVo2 = new AgingVo(2L,"31-60天", new BigDecimal("0"), null); |
| | | companyAgingVo.add(agingVo2); |
| | | } |
| | | if (!CollUtil.contains(overdueRanges, "61-90天")) { |
| | | AgingVo agingVo3 = new AgingVo(3L,"61-90天", new BigDecimal("0"), null); |
| | | companyAgingVo.add(agingVo3); |
| | | } |
| | | if (!CollUtil.contains(overdueRanges, "91-180天")) { |
| | | AgingVo agingVo4 = new AgingVo(4L,"91-180天", new BigDecimal("0"), null); |
| | | companyAgingVo.add(agingVo4); |
| | | } |
| | | if (!CollUtil.contains(overdueRanges, "181-365天")) { |
| | | AgingVo agingVo5 = new AgingVo(5L,"181-365天", new BigDecimal("0"), null); |
| | | companyAgingVo.add(agingVo5); |
| | | } |
| | | if (!CollUtil.contains(overdueRanges, "1年以上")) { |
| | | AgingVo agingVo6 = new AgingVo(6L,"1年以上", new BigDecimal("0"), null); |
| | | companyAgingVo.add(agingVo6); |
| | | } |
| | | } |
| | | agingAnalysisVo.setAmount(companyAgingVo.stream().map(AgingVo::getTotalAmount).collect(Collectors.toList())); |
| | | List<AgingVo> finalCompanyAgingVo = companyAgingVo; |
| | | agingAnalysisVo.setPercent(IntStream.range(0, agingVoList.size()) |
| | | .mapToObj(i -> { |
| | | BigDecimal part = finalCompanyAgingVo.get(i).getTotalAmount(); |
| | | BigDecimal total = agingVoList.get(i).getTotalAmount(); |
| | | if (total == null || total.compareTo(BigDecimal.ZERO) == 0) { |
| | | return null; |
| | | } |
| | | return part.divide(total, 4, RoundingMode.HALF_UP) |
| | | .multiply(new BigDecimal("100")) |
| | | .setScale(2, RoundingMode.HALF_UP); |
| | | }) |
| | | .collect(Collectors.toList())); |
| | | result.add(agingAnalysisVo); |
| | | }); |
| | | //合计 |
| | | AgingAnalysisVo agingAnalysisVo = new AgingAnalysisVo(); |
| | | agingAnalysisVo.setCompanyName("合计"); |
| | | agingAnalysisVo.setAmount(agingVoList.stream().map(AgingVo::getTotalAmount).collect(Collectors.toList())); |
| | | List<BigDecimal> percent = IntStream.range(0, agingAnalysisVo.getAmount().size()) |
| | | .mapToObj(i -> { |
| | | |
| | | if (agingAnalysisVo.getAmount().get(i) == null || agingAnalysisVo.getAmount().get(i).compareTo(BigDecimal.ZERO) == 0) { |
| | | return null; |
| | | } else { |
| | | return new BigDecimal("100"); |
| | | } |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | agingAnalysisVo.setPercent(percent); |
| | | result.add(agingAnalysisVo); |
| | | return R.ok(result); |
| | | } |
| | | } |