platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/BankStatementServiceImpl.java
@@ -1,28 +1,41 @@
package com.by4cloud.platformx.business.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
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.JSON;
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.BankStatementUpdateDTO;
import com.by4cloud.platformx.business.dto.PaymentConfirmAddDTO;
import com.by4cloud.platformx.business.entity.BankStatement;
import com.by4cloud.platformx.business.entity.BusinessCustomer;
import com.by4cloud.platformx.business.entity.Contract;
import com.by4cloud.platformx.business.entity.*;
import com.by4cloud.platformx.business.mapper.BankStatementItemMapper;
import com.by4cloud.platformx.business.mapper.BankStatementMapper;
import com.by4cloud.platformx.business.mapper.BusinessCustomerMapper;
import com.by4cloud.platformx.business.mapper.ContractMapper;
import com.by4cloud.platformx.business.service.BankStatementService;
import com.by4cloud.platformx.business.service.PaymentConfirmService;
import com.by4cloud.platformx.business.vo.StatementContractVo;
import com.by4cloud.platformx.common.core.util.R;
import com.by4cloud.platformx.common.security.util.SecurityUtils;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 银行流水
 *
@@ -38,96 +51,421 @@
   private final ContractMapper contractMapper;
   private final BusinessCustomerMapper businessCustomerMapper;
   private final StringRedisTemplate redisTemplate;
   private final RemoteDeptService remoteDeptService;
   private final BankStatementItemMapper bankStatementItemMapper;
   @Value("${bip.url}")
   private String url;
   @Value("${bip.flag}")
   private Boolean bipFlag;
   @Override
   public R edit(BankStatementUpdateDTO updateDTO) {
      BankStatement statement = baseMapper.selectById(updateDTO.getId());
      Contract contract = contractMapper.selectById(updateDTO.getContractId());
      if (ObjUtil.isNull(contract)){
         return R.failed("合同查询失败");
      if (CollUtil.isEmpty(updateDTO.getContractCollectionList())){
         return R.failed("请选择收款合同后在提交");
      }
      PaymentConfirmAddDTO addDTO = new PaymentConfirmAddDTO();
      addDTO.setBusGuestId(statement.getBusGuestId()+"");
      addDTO.setConfirmTime(statement.getTranDate());
      addDTO.setContractNo(contract.getContractNo());
      addDTO.setInOrOut("1");
      addDTO.setTransationAmount(statement.getTranAmount());
      R r = paymentConfirmService.add(addDTO);
      if (!r.isOk()){
         return r;
      BigDecimal toPaidTotal = updateDTO.getContractCollectionList().stream() .map(StatementContractDTO::getToPaidAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
      if (toPaidTotal.compareTo(statement.getTranAmount().subtract(statement.getConfirmAmount()))>0){
         return R.failed("确认收款总额不能超过交易流水金额");
      }
      statement.setContractId(updateDTO.getContractId());
      baseMapper.updateById(statement);
      //bip推送
      pushSaveCollection(statement);
      if (bipFlag) {
         R r = pushSaveCollection(statement, updateDTO.getContractCollectionList());
         if (!r.isOk()){
            return r;
         }
      }
      statement.setConfirmAmount(statement.getConfirmAmount().add(toPaidTotal));
      baseMapper.updateById(statement);
      updateDTO.getContractCollectionList().stream().forEach(statementContractDTO -> {
         BankStatementItem item = new BankStatementItem();
         item.setStatetId(statement.getId());
         item.setBankSeqNo(statement.getBankSeqNo());
         item.setConfirmAmount(statementContractDTO.getToPaidAmount());
         item.setContractId(statementContractDTO.getId());
         bankStatementItemMapper.insert(item);
         Contract contract = contractMapper.selectById(statementContractDTO.getId());
         PaymentConfirmAddDTO addDTO = new PaymentConfirmAddDTO();
         addDTO.setBusGuestId(statement.getBusGuestId()+"");
         addDTO.setConfirmTime(statement.getTranDate());
         addDTO.setContractNo(contract.getContractNo());
         addDTO.setInOrOut("1");
         addDTO.setTransationAmount(statementContractDTO.getToPaidAmount());
         addDTO.setBankSeqNo(statement.getBankSeqNo());
         paymentConfirmService.add(addDTO);
      });
      return R.ok();
   }
   private void pushSaveCollection(BankStatement statement) {
   private R pushSaveCollection(BankStatement statement, List<StatementContractDTO> contractDTOList) {
      String accessToken = "";
      if (redisTemplate.hasKey("BIP_TOKEN")) {
         accessToken = (String) redisTemplate.opsForValue().get("BIP_TOKEN");
      } else {
         paymentConfirmService.getAccessToken(accessToken);
         accessToken = paymentConfirmService.getAccessToken(accessToken);
      }
      if (StrUtil.isEmpty(accessToken)) {
         log.error("bip accessToken 获取异常");
         return;
         return R.failed("bip accessToken 获取异常");
      }
      String finalAccessToken = accessToken;
      JSONObject params = genRequestParam(statement);
      BusinessCustomer customer = businessCustomerMapper.selectById(statement.getBusGuestId());
      if (ObjUtil.isNull(customer)||StrUtil.isEmpty(customer.getBipCode())){
         log.error("查询客户信息异常");
         return R.failed("查询客户信息异常");
      }
      R<SysDept> r = remoteDeptService.getById(SecurityUtils.getUser().getCompId());
      log.info("查询单位信息:{}",JSONObject.toJSONString(r.getData()));
      if (!r.isOk()){
         log.error("查询单位信息异常");
         return R.failed("查询单位信息异常");
      }
      SysDept dept = r.getData();
      JSONObject params = genRequestParam(statement,dept,customer,contractDTOList);
      log.info("收款单集成 Request:{}", params.toJSONString());
      String result = HttpUtil.post(url + "/yonbip/EFI/receivable/save?access_token=" + finalAccessToken, params.toJSONString());
      String result = HttpUtil.post(url + "/yonbip/EFI/collection/saveandsubmit?access_token=" + finalAccessToken, params.toJSONString());
      log.info("收款单集成 Response:{}", result);
      JSONObject resultJson = JSONObject.parseObject(result);
      if (!resultJson.getString("code").equals("200")) {
         return R.failed(resultJson.getString("message"));
      }
      return R.ok();
   }
   private JSONObject genRequestParam(BankStatement statement) {
      BusinessCustomer customer = businessCustomerMapper.selectById(statement.getBusGuestId());
      Contract contract = contractMapper.selectById(statement.getContractId());
      JSONObject req = new JSONObject();
   private JSONObject genRequestParam(BankStatement statement,SysDept dept,BusinessCustomer customer,List<StatementContractDTO> contractDTOList) {
      JSONObject jsonObject = new JSONObject();
      JSONObject data = new JSONObject();
      JSONObject freeCh = new JSONObject();
      freeCh.put("YSYF57","MJHYXGLXT");
      data.put("freeChId",freeCh);
      data.put("extVouchCode",statement.getBankSeqNo());
      data.put("billDate",statement.getTranDate());
      data.put("billDate",DateUtil.format(statement.getTranDate(), DatePattern.NORM_DATETIME_FORMAT));
      data.put("exchangeRate","1");//汇率
      data.put("exchangeRateDate",DateUtil.now());//汇率时间
      data.put("objectType","1");
      data.put("customerCode",customer.getCreditCode());
      data.put("exchangeRate",1);
      data.put("exchangeRateDate", DateUtil.now());
      data.put("contractNo",contract.getContractNo());
      JSONArray bodyItems = new JSONArray();
      JSONObject bodyItem = new JSONObject();
      bodyItem.put("srcBillType","38");
      bodyItem.put("srcBillNo",statement.getBankSeqNo());
      JSONObject freeChItem = new JSONObject();
      freeChItem.put("YSZJX01A","业务资金预算项目");
      freeChItem.put("YSZJX05","");
      freeChItem.put("YSZJX11","2146820445301112836");
      freeChItem.put("zzbkfl","");
      bodyItem.put("freeChId",freeChItem);
      bodyItems.add(bodyItem);
      data.put("bodyItem",bodyItems);
      data.put("customerCode",customer.getBipCode());//客户编码
      data.put("financeOrgCode",dept.getBipCode());//开票组织编码
      data.put("orgCode",dept.getBipCode());//业务组织编码
      data.put("bustypeCode","ar_colsale");// TODO 交易类型编码 暂估默认ZGYSFP,装备默认ZBYXGLXT暂时不能用
      data.put("oriCurrencyCode","CNY");//币种
      data.put("srcBillType","38");
      data.put("srcBillNo",statement.getBankSeqNo());
      data.put("_status","Insert");
      data.put("oriTaxIncludedAmount",statement.getTranAmount());
      JSONArray bodyItem = new JSONArray();
      for (StatementContractDTO statementContractDTO:contractDTOList) {
         Contract contract = contractMapper.selectById(statementContractDTO.getId());
         JSONObject item = new JSONObject();
         item.put("oriTaxIncludedAmount", statementContractDTO.getToPaidAmount());
         item.put("contractNo", contract.getContractNo());
         item.put("quickTypeCode", "1");
         item.put("_status", "Insert");
         bodyItem.add(item);
      }
      data.put("bodyItem",bodyItem);
      jsonObject.put("data",data);
      return  jsonObject;
   }
      req.put("data",data);
      return req;
   @Override
   public R getHistoryById(Long id) {
      MPJLambdaWrapper<BankStatementItem> wrapper = new MPJLambdaWrapper<BankStatementItem>()
            .selectAll(BankStatementItem.class)
            .select(Contract::getContractNo)
            .select(Contract::getPartyA)
            .select(Contract::getAmount)
            .leftJoin(Contract.class,Contract::getId,BankStatementItem::getContractId)
            .eq(BankStatementItem::getCompId,SecurityUtils.getUser().getCompId())
            .orderByDesc(BankStatementItem::getCreateTime);
      return R.ok(bankStatementItemMapper.selectJoinList(StatementContractVo.class, wrapper));
   }
   @Override
   public R delHistoryById(Long id) {
      BankStatementItem statement = bankStatementItemMapper.selectById(id);
      BankStatement bankStatement = baseMapper.selectById(statement.getStatetId());
      Contract contract = contractMapper.selectById(statement.getContractId());
      if (ObjUtil.isNull(contract)){
         return R.failed("合同信息异常");
      }
      BusinessCustomer customer = businessCustomerMapper.selectById(contract.getPartyAId());
      if (ObjUtil.isNull(customer)){
         return R.failed("客户信息信息异常");
      }
      R<SysDept> r = remoteDeptService.getById(contract.getPartyBId());
      if (!r.isOk()){
         return r;
      }
      //bip推送
      if (bipFlag) {
         String accessToken = "";
         if (redisTemplate.hasKey("BIP_TOKEN")) {
            accessToken = (String) redisTemplate.opsForValue().get("BIP_TOKEN");
         } else {
            accessToken = paymentConfirmService.getAccessToken(accessToken);
         }
         if (StrUtil.isEmpty(accessToken)) {
            log.error("bip accessToken 获取异常");
            return R.failed("bip accessToken 获取异常");
         }
         String finalAccessToken = accessToken;
         JSONObject request = genRefundParam(bankStatement,statement, contract, customer, r.getData());
         log.info("收款退款单-退款单一历史确认请求入参:{}", request.toJSONString());
         String result = HttpUtil.post(url + "/yonbip/EFI/arRefund/saveandsubmit?access_token=" + finalAccessToken, request.toJSONString());
         log.info("收款退款单-退款单一历史确认请求回参:{}", result);
         JSONObject resultJson = JSONObject.parseObject(result);
         if (!resultJson.getString("code").equals("200")) {
            return R.failed(resultJson.getString("message"));
         }
      }
      bankStatementItemMapper.deleteById(id);
      bankStatement.setConfirmAmount(bankStatement.getConfirmAmount().subtract(statement.getConfirmAmount()));
      baseMapper.updateById(bankStatement);
      return R.ok();
   }
   private JSONObject genRefundParam(BankStatement bankStatement,BankStatementItem statement, Contract contract,BusinessCustomer customer, SysDept dept) {
      JSONObject jsonObject = new JSONObject();
      JSONObject data = new JSONObject();
      data.put("billDate",DateUtil.now());
      data.put("exchangeRate","1");//汇率
      data.put("exchangeRateDate",DateUtil.now());//汇率时间
      data.put("objectType","1");
      data.put("customerCode",customer.getBipCode());//客户编码
      data.put("financeOrgCode",dept.getBipCode());//开票组织编码
      data.put("orgCode",dept.getBipCode());//业务组织编码
      data.put("bustypeCode","ar_refsale");//交易类型编码 暂估默认ZGYSFP,销售默认MJHYXGLXT
      data.put("oriCurrencyCode","CNY");//币种
      data.put("srcBillType","38");
      data.put("srcBillNo",bankStatement.getBankSeqNo());
      data.put("_status","Insert");
      JSONArray bodyItem = new JSONArray();
      JSONObject item = new JSONObject();
      item.put("oriTaxIncludedAmount", statement.getConfirmAmount());
      item.put("contractNo", contract.getContractNo());
      item.put("quickTypeCode", "1");
      item.put("_status", "Insert");
      bodyItem.add(item);
      data.put("bodyItem",bodyItem);
      jsonObject.put("data",data);
      return  jsonObject;
   }
   @Override
   public R backBal(Long id) {
      BankStatement bankStatement = baseMapper.selectById(id);
      BusinessCustomer customer = businessCustomerMapper.selectById(bankStatement.getBusGuestId());
      if (ObjUtil.isNull(customer)||StrUtil.isEmpty(customer.getBipCode())){
         log.error("查询客户信息异常");
         return R.failed("查询客户信息异常");
      }
      R<SysDept> r = remoteDeptService.getById(SecurityUtils.getUser().getCompId());
      if (!r.isOk()){
         log.error("查询单位信息异常");
         return R.failed("查询单位信息异常");
      }
      SysDept dept = r.getData();
      List<BankStatementItem> items = bankStatementItemMapper.selectList(Wrappers.<BankStatementItem>lambdaQuery()
            .eq(BankStatementItem::getStatetId,id));
      if (bipFlag){
         String accessToken = "";
         if (redisTemplate.hasKey("BIP_TOKEN")) {
            accessToken = (String) redisTemplate.opsForValue().get("BIP_TOKEN");
         } else {
            accessToken = paymentConfirmService.getAccessToken(accessToken);
         }
         if (StrUtil.isEmpty(accessToken)) {
            log.error("bip accessToken 获取异常");
            return R.failed("bip accessToken 获取异常");
         }
         String finalAccessToken = accessToken;
         JSONObject request = genBackBalParam(bankStatement,customer,dept,items);
         log.info("收款退款单-退款余额请求入参:{}", request.toJSONString());
         String result = HttpUtil.post(url + "/yonbip/EFI/arRefund/saveandsubmit?access_token=" + finalAccessToken, request.toJSONString());
         log.info("收款退款单-退款余额请求回参:{}", result);
         JSONObject resultJson = JSONObject.parseObject(result);
         if (!resultJson.getString("code").equals("200")) {
            return R.failed(resultJson.getString("message"));
         }
      }
      bankStatement.setTranAmount(bankStatement.getConfirmAmount());
      baseMapper.updateById(bankStatement);
      return R.ok();
   }
   private JSONObject genBackBalParam(BankStatement bankStatement, BusinessCustomer customer, SysDept dept, List<BankStatementItem> items) {
      JSONObject jsonObject = new JSONObject();
      JSONObject data = new JSONObject();
      data.put("billDate",DateUtil.now());
      data.put("exchangeRate","1");//汇率
      data.put("exchangeRateDate",DateUtil.now());//汇率时间
      data.put("objectType","1");
      data.put("customerCode",customer.getBipCode());//客户编码
      data.put("financeOrgCode",dept.getBipCode());//开票组织编码
      data.put("orgCode",dept.getBipCode());//业务组织编码
      data.put("bustypeCode","ar_refsale");//交易类型编码 暂估默认ZGYSFP,销售默认MJHYXGLXT
      data.put("oriCurrencyCode","CNY");//币种
      data.put("srcBillType","38");
      data.put("srcBillNo",bankStatement.getBankSeqNo());
      data.put("_status","Insert");
      JSONArray bodyItem = new JSONArray();
      JSONObject item = new JSONObject();
      item.put("oriTaxIncludedAmount", bankStatement.getTranAmount().subtract(bankStatement.getConfirmAmount()));
      item.put("quickTypeCode", "1");
      item.put("_status", "Insert");
      bodyItem.add(item);
      data.put("bodyItem",bodyItem);
      jsonObject.put("data",data);
      return  jsonObject;
   }
   @Override
   public R backAll(Long id) {
      BankStatement bankStatement = baseMapper.selectById(id);
      BusinessCustomer customer = businessCustomerMapper.selectById(bankStatement.getBusGuestId());
      if (ObjUtil.isNull(customer)||StrUtil.isEmpty(customer.getBipCode())){
         log.error("查询客户信息异常");
         return R.failed("查询客户信息异常");
      }
      R<SysDept> r = remoteDeptService.getById(SecurityUtils.getUser().getCompId());
      if (!r.isOk()){
         log.error("查询单位信息异常");
         return R.failed("查询单位信息异常");
      }
      SysDept dept = r.getData();
      List<BankStatementItem> items = bankStatementItemMapper.selectList(Wrappers.<BankStatementItem>lambdaQuery()
            .eq(BankStatementItem::getStatetId,id));
      if (bipFlag){
         String accessToken = "";
         if (redisTemplate.hasKey("BIP_TOKEN")) {
            accessToken = (String) redisTemplate.opsForValue().get("BIP_TOKEN");
         } else {
            accessToken = paymentConfirmService.getAccessToken(accessToken);
         }
         if (StrUtil.isEmpty(accessToken)) {
            log.error("bip accessToken 获取异常");
            return R.failed("bip accessToken 获取异常");
         }
         String finalAccessToken = accessToken;
         JSONObject request = genBackAllParam(bankStatement,customer,dept,items);
         log.info("收款退款单-退款所有请求入参:{}", request.toJSONString());
         String result = HttpUtil.post(url + "/yonbip/EFI/arRefund/saveandsubmit?access_token=" + finalAccessToken, request.toJSONString());
         log.info("收款退款单-退款所有请求回参:{}", result);
         JSONObject resultJson = JSONObject.parseObject(result);
         if (!resultJson.getString("code").equals("200")) {
            return R.failed(resultJson.getString("message"));
         }
      }
      bankStatement.setConfirmAmount(new BigDecimal("0"));
      baseMapper.updateById(bankStatement);
      return R.ok();
   }
   private JSONObject genBackAllParam(BankStatement bankStatement, BusinessCustomer customer, SysDept dept, List<BankStatementItem> items) {
      JSONObject jsonObject = new JSONObject();
      JSONObject data = new JSONObject();
      data.put("billDate",DateUtil.now());
      data.put("exchangeRate","1");//汇率
      data.put("exchangeRateDate",DateUtil.now());//汇率时间
      data.put("objectType","1");
      data.put("customerCode",customer.getBipCode());//客户编码
      data.put("financeOrgCode",dept.getBipCode());//开票组织编码
      data.put("orgCode",dept.getBipCode());//业务组织编码
      data.put("bustypeCode","ar_refsale");//交易类型编码 暂估默认ZGYSFP,销售默认MJHYXGLXT
      data.put("oriCurrencyCode","CNY");//币种
      data.put("srcBillType","38");
      data.put("srcBillNo",bankStatement.getBankSeqNo());
      data.put("_status","Insert");
      JSONArray bodyItem = new JSONArray();
      JSONObject item = new JSONObject();
      item.put("oriTaxIncludedAmount", bankStatement.getTranAmount());
      item.put("quickTypeCode", "1");
      item.put("_status", "Insert");
      bodyItem.add(item);
      data.put("bodyItem",bodyItem);
      jsonObject.put("data",data);
      return  jsonObject;
   }
   @Override
   public R backHis(Long id) {
      BankStatement bankStatement = baseMapper.selectById(id);
      BusinessCustomer customer = businessCustomerMapper.selectById(bankStatement.getBusGuestId());
      if (ObjUtil.isNull(customer)||StrUtil.isEmpty(customer.getBipCode())){
         log.error("查询客户信息异常");
         return R.failed("查询客户信息异常");
      }
      R<SysDept> r = remoteDeptService.getById(SecurityUtils.getUser().getCompId());
      if (!r.isOk()){
         log.error("查询单位信息异常");
         return R.failed("查询单位信息异常");
      }
      SysDept dept = r.getData();
      List<BankStatementItem> items = bankStatementItemMapper.selectList(Wrappers.<BankStatementItem>lambdaQuery()
            .eq(BankStatementItem::getStatetId,id));
      if (bipFlag){
         String accessToken = "";
         if (redisTemplate.hasKey("BIP_TOKEN")) {
            accessToken = (String) redisTemplate.opsForValue().get("BIP_TOKEN");
         } else {
            accessToken = paymentConfirmService.getAccessToken(accessToken);
         }
         if (StrUtil.isEmpty(accessToken)) {
            log.error("bip accessToken 获取异常");
            return R.failed("bip accessToken 获取异常");
         }
         String finalAccessToken = accessToken;
         JSONObject request = genBackHisParam(bankStatement,customer,dept,items);
         log.info("收款退款单-退款历史确认请求入参:{}", request.toJSONString());
         String result = HttpUtil.post(url + "/yonbip/EFI/arRefund/saveandsubmit?access_token=" + finalAccessToken, request.toJSONString());
         log.info("收款退款单-退款历史确认请求回参:{}", result);
         JSONObject resultJson = JSONObject.parseObject(result);
         if (!resultJson.getString("code").equals("200")) {
            return R.failed(resultJson.getString("message"));
         }
      }
      bankStatement.setConfirmAmount(new BigDecimal("0"));
      baseMapper.updateById(bankStatement);
      bankStatementItemMapper.deleteByIds(items.stream().map(item->item.getId()).collect(Collectors.toList()));
      return R.ok();
   }
   private JSONObject genBackHisParam(BankStatement bankStatement, BusinessCustomer customer, SysDept dept,List<BankStatementItem> items) {
      JSONObject jsonObject = new JSONObject();
      JSONObject data = new JSONObject();
      data.put("billDate",DateUtil.now());
      data.put("exchangeRate","1");//汇率
      data.put("exchangeRateDate",DateUtil.now());//汇率时间
      data.put("objectType","1");
      data.put("customerCode",customer.getBipCode());//客户编码
      data.put("financeOrgCode",dept.getBipCode());//开票组织编码
      data.put("orgCode",dept.getBipCode());//业务组织编码
      data.put("bustypeCode","ar_refsale");//交易类型编码 暂估默认ZGYSFP,销售默认MJHYXGLXT
      data.put("oriCurrencyCode","CNY");//币种
      data.put("srcBillType","38");
      data.put("srcBillNo",bankStatement.getBankSeqNo());
      data.put("_status","Insert");
      JSONArray bodyItem = new JSONArray();
      for (BankStatementItem statementItem:items) {
         Contract contract = contractMapper.selectById(statementItem.getContractId());
         JSONObject item = new JSONObject();
         item.put("oriTaxIncludedAmount", statementItem.getConfirmAmount());
         item.put("contractNo", contract.getContractNo());
         item.put("quickTypeCode", "1");
         item.put("_status", "Insert");
         bodyItem.add(item);
      }
      data.put("bodyItem",bodyItem);
      jsonObject.put("data",data);
      return  jsonObject;
   }
}