package com.brilliance.isc.common.bptbck.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.brilliance.mda.runtime.mda.util.Dates;
import com.brilliance.mda.runtime.mda.util.Decimals;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import com.brilliance.mda.runtime.mda.util.Strings;
import com.brilliance.isc.bo.*;
import com.brilliance.isc.common.bptbck.service.BptbckService;
import com.brilliance.isc.common.cache.pty.PtyCacheService;
import com.brilliance.isc.common.cbsmod.service.CbsmodService;
import com.brilliance.isc.common.cbsmod.service.XrtmodService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.component.BpdToolComponent;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.converter.DtoMapper;
import com.brilliance.isc.common.counter.service.CounterService;
import com.brilliance.isc.common.esb.finance.IFinanceFeign;
import com.brilliance.isc.common.exception.CommonServiceException;
import com.brilliance.isc.common.finmod.service.FinmodService;
import com.brilliance.isc.common.glemod.service.GlemodService;
import com.brilliance.isc.common.transaction.help.TransactionHelpService;
import com.brilliance.isc.common.transaction.vo.BimdataVo;
import com.brilliance.isc.common.transaction.vo.TroStoreObjectVo;
import com.brilliance.isc.common.trnmod.service.TrnmodService;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.common.vo.BizInfoVo;
import com.brilliance.isc.common.wfmmod.service.WfmmodService;
import com.brilliance.isc.esb.model.inner.InnerReq;
import com.brilliance.isc.esb.model.inner.InnerReq6157;
import com.brilliance.isc.esb.model.inner.InnerRes;
import com.brilliance.isc.esb.model.inner.InnerRes6157;
import com.brilliance.isc.mda.dao.BpdMapper;
import com.brilliance.isc.mda.dao.FinmodMapper;
import com.brilliance.isc.mda.dao.TrmMapper;
import com.brilliance.isc.vo.component.bptbck.BptbckQueryVo;
import com.brilliance.isc.vo.component.bptbck.BptbckVo;
import com.brilliance.isc.vo.component.bptbck.BptbckgVo;
import com.brilliance.isc.vo.component.bptbck.Gle4338Vo;
import com.brilliance.isc.vo.model.BpdgrpVo;
import com.brilliance.isc.vo.model.FinmodBizInfoVo;
import com.brilliance.isc.vo.model.FinmodVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
public class BptbckServiceImpl implements BptbckService {

    private static Logger log = LoggerFactory.getLogger(BptbckServiceImpl.class);

    @Autowired
    private BpdMapper bpdMapper;

    @Autowired
    private CbsmodService cbsmodService;

    @Autowired
    private FinmodService finmodService;

    @Autowired
    private XrtmodService xrtmodService;

    @Autowired
    private GlemodService glemodService;

    @Autowired
    private BpdToolComponent bpdToolComponent;

    @Autowired
    private TransactionHelpService transactionHelpService;

    @Autowired
    private TrnmodService trnmodService;

    @Autowired
    private WfmmodService wfmmodService;

    @Autowired
    private CounterService counterService;

    @Autowired
    private FinmodMapper finmodMapper;

    @Autowired(required = false)
    private IFinanceFeign financeFeign;

    @Autowired
    private TrmMapper trmMapper;

    @Autowired
    private PtyCacheService ptyCacheService;

    @Autowired
    private CodetableService codetableService;

    @Override
    public void assertBptbck(BptbckVo bptbckVo) {
        if (StringUtils.isEmpty(bptbckVo.getOldredflg())) {
            getOld(bptbckVo);
            bptbckVo.setOldredflg("X");

            bptbckVo.getWrkbpdgrp().getRec().setOpttyp("1");
            //获取转卖账号下拉列表
            /*String cur = bptbckVo.getWrkbpdgrp().getCbs().getMax().getCur();
            String accs = glemodService.getAvailAcc("SP", cur, "", BigDecimal.ZERO);
            //设置账号动态码表
            Set<String> bmsAccSet = new HashSet<>();
            String[] acts = accs.split("\r\n");
            for (String account : acts) {
                if (StringUtils.isNotEmpty(account.trim())) {
                    bmsAccSet.add(account);
                }
            }
            accs = glemodService.getAvailAcc("AR", cur, "", BigDecimal.ZERO);
            //设置账号动态码表
            acts = accs.split("\r\n");
            for (String account : acts) {
                if (StringUtils.isNotEmpty(account.trim())) {
                    bmsAccSet.add(account);
                }
            }
            bptbckVo.setBmsAccSet(bmsAccSet);*/
        }
        //计算还款类型 opttyp 只考虑到期还款
        /*BpdgrpVo bpdgrpVo = bptbckVo.getWrkbpdgrp();
        if ("0".equals(bpdgrpVo.getRec().getFfttyp())) {
            //转卖还款
            bpdgrpVo.getRec().setOpttyp("2");
        }
        //如果是转卖还款，需要计算转卖信息
        if ("2".equals(bpdgrpVo.getRec().getOpttyp())) {
            if (bpdgrpVo.getRec().getMcdate() == null) {
                bpdgrpVo.getRec().setMcdate(Dates.today());
                this.calcGle4338(bptbckVo);
            } else if (MdaUtils.compareTo(bpdgrpVo.getRec().getMcdate(), Dates.today()) != 0) {
                bpdgrpVo.getRec().setMcdate(Dates.today());
                this.calcGle4338(bptbckVo);
            }
        }*/
    }

    /**
     *   source:bptbck.0001.script
     */
    public void storeAll(BptbckVo bptbckVo) {
        //! store total discount repayment into parent contract, if settlemt is final
        if(!MdaUtils.isEmpty(bptbckVo.getDscbckamt())) {
            Cbe cbe = new Cbe();
            cbe.setExtid("BPDISC");
            cbe.setCbt("UTLAMT");
            cbe.setTrntyp("TRN");
            cbe.setTrninr(transactionHelpService.getTrninr());
            cbe.setDat(Dates.today());
            cbe.setCur(bptbckVo.getDscbckcur());
            cbe.setAmt(bptbckVo.getDscbckamt());
            cbe.setNam("discount paid back");
            cbsmodService.cbsStoreEntry(cbe, DtoMapper.INSTANCE.transfer(bptbckVo.getWrkbpdgrp()).getRec());
        }
        // store repayments in financing contracts (advances or packing credits)
        bptbckVo.getBptbckg().forEach(bptbckgVo -> {
            if (MdaUtils.compareTo(bptbckgVo.getBckamt(),0) != 0) {
                Cbe cbe = new Cbe();
                cbe.setExtid("AMT1");
                cbe.setCbt("UTLAMT");
                cbe.setTrntyp("TRN");
                cbe.setTrninr(transactionHelpService.getTrninr());
                cbe.setDat(Dates.today());
                cbe.setCur(bptbckgVo.getOpncur());
                cbe.setAmt(bptbckgVo.getBckamt());
                cbe.setNam("paid back");
                cbsmodService.cbsStoreEntry(cbe, bptbckVo.getWrkbpdgrp().getRec());
                if(MdaUtils.compareTo(bptbckgVo.getBckamt(), bptbckgVo.getOpnamt()) >= 0) {
                    bptbckVo.getWrkbpdgrp().getRec().setClsdat(Dates.today());
                    trnmodService.trnStoreContract(DtoMapper.INSTANCE.transfer(bptbckVo.getWrkbpdgrp()));
                }
            }
        });
    }

    public void getOld(BptbckVo bptbckVo) {
        BizInfoVo rec = bptbckVo.getRec();
        String objinr = rec.getObjinr();
        String objtyp = rec.getObjtyp();
        if (StringUtils.isEmpty(objinr) || StringUtils.isEmpty(objtyp)) {
            throw new CommonServiceException("业务主键或者类型为空，无法找到融资数据");
        }
        List<BptbckgVo> bptbckgList = new ArrayList<>();
        List<Bpd> bpdList = bpdMapper.getBpdByPntinrAndPnttyp(objinr, objtyp);
        if (bpdList != null && bpdList.size() > 0) {
            bpdList.forEach(bpd -> {
                log.debug("根据融资数据Bpd[{}]组装Bptbckg", bpd.getInr());
                //查找cbb数据
                Date date = Dates.add(Utils.getMaxDate(), -1);
                Cbb cbb = new Cbb();
                cbsmodService.cbsGetBalance(cbb, "BPD", bpd.getInr(), "OPN", "AMT1", date);
                if (cbb != null && cbb.getAmt().compareTo(BigDecimal.ZERO) > 0) {
                    BptbckgVo bptbckgVo = new BptbckgVo();
                    bptbckgVo.setOwnref(bpd.getOwnref());
                    bptbckgVo.setOpncur(cbb.getCur());
                    bptbckgVo.setOpnamt(cbb.getAmt());
                    bptbckgVo.setObjtyp("BPD");
                    bptbckgVo.setObjinr(bpd.getInr());
                    bptbckgVo.setIntdat(bpd.getIntunt());
                    bptbckgList.add(bptbckgVo);
                    //bpdgrp赋值
                    BpdgrpVo bpdgrpVo = DtoMapper.INSTANCE.transfer(bpdToolComponent.getBpdgrpByInr(bpd.getInr()));
                    bptbckVo.setWrkbpdgrp(bpdgrpVo);
                    //这里需要检核融资状态，移到入口交易
                    FinmodVo finmodVo = finmodService.loadDataFromBlock(bptbckgVo.getObjinr(), bptbckgVo.getObjtyp(), bpd.getFinblk());
                    if (finmodVo != null) {
                        bptbckVo.setWrkfinmod(finmodVo);
                    }
                    bptbckVo.getWrkfinmod().setReptyp("1");
                    if (StringUtils.isEmpty(bptbckVo.getWrkfinmod().getFincod())) {
                        bptbckVo.getWrkfinmod().setFincod(bpd.getFincod());
                    }
                    defaultFinActsN1000(bptbckVo);
                    bptbckVo.setDscbckcur(bptbckgVo.getOpncur());
//                    defaultDscbckcurN100(bptbckVo);
                    ruleFinmodCal(bptbckVo, bptbckgVo);
                    if (StringUtils.isEmpty(bptbckVo.getWrkfinmod().getCbs().getCbb().getCur())) {
                        bptbckVo.getWrkfinmod().getCbs().getCbb().setCur(bpdgrpVo.getCbs().getMax().getCur());
                    }
                    finmodService.defaultCbsCbeCurN1000(bptbckVo.getWrkfinmod());
                    finmodService.defaultTotintN1000(bptbckVo.getWrkfinmod());
                    defaultSetamtN1000(bptbckVo);
                }
            });
        }
        bptbckVo.setBptbckg(bptbckgList);
        defaultDefgrdN1000(bptbckVo);
    }

    //@Rule(target="wrkfinmod.cal",order=500)
    //@Rule(target="wrkfinmod.cal",order=1000)
    //@Rule(target="wrkfinmod.cal",order=1500)
    public void ruleFinmodCal(BptbckVo bptbckVo, BptbckgVo bptbckgVo) {
        if(Strings.pos("ABCDEF", bptbckVo.getWrkbpdgrp().getRec().getOvdflg()) > 0 ) {
            bptbckVo.getWrkfinmod().getCbs().setCalflg("X");
        }
        if(MdaUtils.compareTo(bptbckVo.getSetamt(), 0) > 0 || MdaUtils.compareTo(bptbckVo.getWrkfinmod().getReptyp(), "1") == 0) {
            call6157Data(bptbckVo);
        }
        if(!MdaUtils.isEmpty(bptbckVo.getWrkfinmod().getCbs().getCalflg())) {
            // 解决那些Repair了点计算却不点Apply的Bug
            bptbckgVo.setBckamt(Decimals.sub(Decimals.add(bptbckgVo.getOpnamt(), bptbckVo.getWrkfinmod().getCbs().getCbe().getAmt()), bptbckVo.getWrkfinmod().getCbs().getCbb().getAmt()));
            bptbckgVo.setModified("bckamt");
        } else {
            bptbckgVo.setBckamt(new BigDecimal("0"));
        }
    }

    /**
     * 调用6157接口
     * @param bptbckVo
     */
    public String call6157Data(BptbckVo bptbckVo) {
        InnerReq6157 req6157 = new InnerReq6157(bptbckVo.getWrkbpdgrp().getRec().getFinact(),
                bptbckVo.getWrkfinmod().getFincod(),
                bptbckVo.getSetact(),
                bptbckVo.getWrkfinmod().getReptyp(),
                bptbckVo.getSetamt() == null ? "0" : bptbckVo.getSetamt().toPlainString(), "0", "6107");
        InnerReq<InnerReq6157> innerReq6157 = new InnerReq<>(req6157);
        String errorMsg = "";
        //调用接口
        try {
            InnerRes<InnerRes6157> innerRes6157 = financeFeign.call6157(innerReq6157);
            if(innerRes6157 == null){
                errorMsg = Strings.getText("调用6157接口失败，返回信息为空");
            }else if("AAAAAAA".equals(innerRes6157.header.code) && innerRes6157.DATA != null) {
                bptbckVo.getWrkfinmod().getCbs().getCbb().setIntamt1(new BigDecimal(innerRes6157.DATA.BWQXLX));
                bptbckVo.getWrkfinmod().getCbs().getCbb().setIntamty1(new BigDecimal(innerRes6157.DATA.BOWIQX));
                bptbckVo.getWrkfinmod().getCbs().getCbb().setIntamt2(new BigDecimal(innerRes6157.DATA.BNQXLX));
                bptbckVo.getWrkfinmod().getCbs().getCbb().setIntamty2(new BigDecimal(innerRes6157.DATA.BONEQX));
                bptbckVo.getWrkfinmod().getCbs().getCbb().setIntamt(new BigDecimal(innerRes6157.DATA.BEJILX));
                bptbckVo.getWrkfinmod().getCbs().getCbb().setAmt(new BigDecimal(innerRes6157.DATA.BENJIN));
                bptbckVo.getWrkfinmod().getCbs().getCbe().setIntamt1(new BigDecimal(innerRes6157.DATA.CHBWQL));
                bptbckVo.getWrkfinmod().getCbs().getCbe().setIntamty1(new BigDecimal(innerRes6157.DATA.CHBWQX));
                bptbckVo.getWrkfinmod().getCbs().getCbe().setIntamt2(new BigDecimal(innerRes6157.DATA.CHBNQL));
                bptbckVo.getWrkfinmod().getCbs().getCbe().setIntamty2(new BigDecimal(innerRes6157.DATA.CHBNQX));
                bptbckVo.getWrkfinmod().getCbs().getCbe().setIntamt(new BigDecimal(innerRes6157.DATA.CHBJLX));
                bptbckVo.getWrkfinmod().getCbs().getCbe().setAmt(new BigDecimal(innerRes6157.DATA.CHDKBJ));
                bptbckVo.getWrkfinmod().getCbs().setCalflg( "X");
            } else {
                errorMsg = Strings.getText("调用6157接口失败，$1", innerRes6157.header != null ? innerRes6157.header.description : "");
            }
        } catch (Exception e) {
            errorMsg = Strings.getText("调用6157接口出现异常，$1", e.getMessage());
        }
        if (StringUtils.isNotEmpty(errorMsg)) {
            bptbckVo.getWrkfinmod().getCbs().getCbe().setIntamt1(new BigDecimal("0"));
            bptbckVo.getWrkfinmod().getCbs().getCbe().setIntamty1(new BigDecimal("0"));
            bptbckVo.getWrkfinmod().getCbs().getCbe().setIntamt2(new BigDecimal("0"));
            bptbckVo.getWrkfinmod().getCbs().getCbe().setIntamty2(new BigDecimal("0"));
            bptbckVo.getWrkfinmod().getCbs().getCbe().setIntamt(new BigDecimal("0"));
            bptbckVo.getWrkfinmod().getCbs().getCbe().setAmt(new BigDecimal("0"));
            bptbckVo.getWrkfinmod().getCbs().setCalflg("");
        }
        return errorMsg;

    }

    /**
     *   source:bptbck.0022.script
     *   @Default(value={"setact","wrkfinmod.accbch"},order=1000)
     */
    public void defaultFinActsN1000(BptbckVo bptbckVo){
        String finAccStream = glemodService.getAvailAcc("BF-TTT", bptbckVo.getWrkbpdgrp().getCbs().getMax().getCur(), "",bptbckVo.getWrkbpdgrp().getCbs().getMax().getAmt());
        String finAct = "";
        if (StringUtils.isNotEmpty(finAccStream)) {
            String[] finAccs = finAccStream.split("[\\r\\n]{1,2}");
            finAct = finAccs[0];
        }
        if(StringUtils.isEmpty(bptbckVo.getWrkfinmod().getAccbch())) {
            bptbckVo.getWrkfinmod().setAccbch(SettleContext.getUserSession().getBch().getBranch());
        }
        bptbckVo.setSetact(bptbckVo.getWrkfinmod().getAccbch() + Strings.mid(finAct,5));
    }

    /**
     *   source:bptbck.0012.script
     *   @Default(target="dscbckcur",order=100)
     */
    public void defaultDscbckcurN100(BptbckVo bptbckVo){
        String doccur = Utils.getFieldValue(bptbckVo.getRec(), "doccur", "");
        //! If transaction does not overwrite, take settlemnt currecny
        if(!bptbckVo.isModified("dscbckcur") && !MdaUtils.isEmpty(doccur)) {
            bptbckVo.setDscbckcur(doccur);
        }
    }
    /**
     *   source:bptbck.0000.script
     *   @Default(value={"bptbckg","dscbckamt","dscopnamt","pclbckamt"},order=1000)
     */
    public void defaultDefgrdN1000(BptbckVo bptbckVo){
        BizInfoVo rec = bptbckVo.getRec();
        BigDecimal docamt = Utils.getFieldValue(rec, "docamt", BigDecimal.ZERO);
        BigDecimal amt = Decimals.sub(docamt, bptbckVo.getDscnotuseamt());
        if(MdaUtils.compareTo(amt,0) < 0) {
            amt = new BigDecimal("0");
        }
        bptbckVo.setDscbckamt(new BigDecimal("0"));
        bptbckVo.setDscopnamt(new BigDecimal("0"));
        bptbckVo.setPclbckamt(new BigDecimal("0"));
        // DO5DOS.005070 - respect RCVEXTID here (i.e. show and repay only lines matching to RCVEXTID)
        bptbckVo.getBptbckg().forEach(bptbckgVo -> {
            //if( MdaUtils.compareTo(this.getBptbckg().getElement(i).getOpnamt(),0) != 0 && ( Streams.streamSearch(rcvExtId,this.getBptbckg().getElement(i).getWrkbpdgrp().getRec().getLiaextid()) > 0 || MdaUtils.compareTo(this.getRcvextid(),"*ALL*") == 0 || MdaUtils.compareTo(this.getBptbckg().getElement(i).getObjtyp(),"TRD") == 0 ) )
            if (MdaUtils.compareTo(bptbckgVo.getOpnamt(), 0) != 0) {
                if(!MdaUtils.isEmpty(bptbckVo.getWrkbpdgrp().getRec().getIntunt())) {
                    bptbckgVo.setIntamt(xrtmodService.amtRndUnt(Decimals.div(Decimals.mul(Decimals.mul(Dates.diff(Dates.today(), bptbckVo.getWrkbpdgrp().getRec().getIntunt()), bptbckgVo.getBckamt()), bptbckgVo.getIntrat()),36500), bptbckVo.getDscbckcur()));
                } else {
                    bptbckgVo.setIntamt(new BigDecimal(0));
                }
                bptbckVo.setDscbckamt(Decimals.add(bptbckVo.getDscbckamt(), bptbckgVo.getBckamt()));
                bptbckVo.setDscopnamt(Decimals.add(bptbckVo.getDscopnamt(), bptbckgVo.getOpnamt()));
            }
        });
    }

    /**
     *   source:bptbck.0003.script
     *//*
    @Default(target="rcvextid",order=1000)
    public boolean defaultRcvextidN1000(){
        IContext ctx = MdaEnv.getContext();

        IStream res = new StreamImpl();
        Streams.streamClear(res);
        int stmCnt = Streams.streamCount(ctx.absGet(Liaall.class).getTensetstm());
        String line = NULLSTR;
        for(int  i = 1;i <= stmCnt;i++)
        {
            line = Strings.getLine(ctx.absGet(Liaall.class).getTensetstm(),i);
            Streams.streamInsert(res,0,Strings.mid(line,1,Strings.pos(line,TAB) - 1));
        }
        this.setRcvextid( MdaUtils.toString(res));


        return true;
    }*/



    /**
     *   source:bptbck.0020.script
     *   @Default(target="setamt",order=1000)
     */
    public void defaultSetamtN1000(BptbckVo bptbckVo){
        if( MdaUtils.compareTo(bptbckVo.getWrkfinmod().getReptyp(),"1") == 0 ) {
            if( MdaUtils.compareTo(bptbckVo.getWrkfinmod().getIntprd(),"6") == 0 ) {
                bptbckVo.setSetamt(bptbckVo.getWrkfinmod().getCbs().getCbe().getAmt());
            } else {
                bptbckVo.setSetamt(Decimals.add(Decimals.add(Decimals.add(Decimals.add(Decimals.add(bptbckVo.getWrkfinmod().getCbs().getCbe().getIntamt1(),bptbckVo.getWrkfinmod().getCbs().getCbe().getIntamty1()),bptbckVo.getWrkfinmod().getCbs().getCbe().getIntamt2()),bptbckVo.getWrkfinmod().getCbs().getCbe().getIntamty2()),bptbckVo.getWrkfinmod().getCbs().getCbe().getIntamt()),bptbckVo.getWrkfinmod().getCbs().getCbe().getAmt()));
            }
        }
    }

    /**
     *   source:bptbck.0016.script
     */
    public void process6107Interface(BptbckVo bptbckVo) {
        // 只还一笔
        if (bptbckVo != null && bptbckVo.getBptbckg() != null && bptbckVo.getBptbckg().size() > 0) {
            this.addBimdataExternalModel(bptbckVo);
            for (int i=0; i<bptbckVo.getBptbckg().size(); i++) {
                FinmodBizInfoVo rec = new FinmodBizInfoVo();
                rec.setOvdflg(bptbckVo.getWrkbpdgrp().getRec().getOvdflg());
                rec.setFinact(bptbckVo.getWrkbpdgrp().getRec().getFinact());
                rec.setSetact(bptbckVo.getSetact());
                bptbckVo.getWrkfinmod().setRec(rec);
                String data4338 = "";
                // 如果是转卖还款，则注册4338接口
                if (MdaUtils.compareTo(bptbckVo.getWrkbpdgrp().getRec().getOpttyp(), "2") == 0) {
                    data4338 = this.save4338Data(bptbckVo.getWrkbpdgrp(), bptbckVo.getGle4338List());
                    wfmmodService.wfeAdd("FFT", "FFT", Dates.add(Dates.today(), 1), new BigDecimal(21));
                }
                String data6107 = finmodService.save6107Data(bptbckVo.getWrkfinmod());
                Finmod finmod = finmodMapper.getFinmodByObjinrAndObjtyp(bptbckVo.getWrkbpdgrp().getRec().getInr(), "BPD");
                if (finmod != null) {
                    finmod.setFin6107(data6107);
                    if (StringUtils.isNotEmpty(data4338)) {
                        finmod.setFin4338(data4338);
                    }
                    finmodMapper.updateByPrimaryKey(finmod);
                } else {
                    finmod = finmodService.saveDataToBlock(bptbckVo.getWrkfinmod());
                    finmod.setFin6107(data6107);
                    if (StringUtils.isNotEmpty(data4338)) {
                        finmod.setFin4338(data4338);
                    }
                    finmod.setInr(counterService.dbCounterFormat("FINMOD"));
                    finmod.setObjinr(bptbckVo.getWrkbpdgrp().getRec().getInr());
                    finmod.setObjtyp("BPD");
                    finmod.setOwnref(bptbckVo.getWrkbpdgrp().getRec().getOwnref());
                    finmodMapper.insert(finmod);
                }
                if(MdaUtils.compareTo(bptbckVo.getWrkfinmod().getCbs().getCbb().getAmt(), bptbckVo.getWrkfinmod().getCbs().getCbe().getAmt()) == 0
                        && MdaUtils.compareTo(bptbckVo.getWrkfinmod().getCbs().getCbb().getIntamt(), bptbckVo.getWrkfinmod().getCbs().getCbe().getIntamt()) == 0
                        && MdaUtils.compareTo(bptbckVo.getWrkfinmod().getCbs().getCbb().getIntamty2(), bptbckVo.getWrkfinmod().getCbs().getCbe().getIntamty2()) == 0
                        && MdaUtils.compareTo(bptbckVo.getWrkfinmod().getCbs().getCbb().getIntamt2(),bptbckVo.getWrkfinmod().getCbs().getCbe().getIntamt2()) == 0
                        && MdaUtils.compareTo(bptbckVo.getWrkfinmod().getCbs().getCbb().getIntamty1(),bptbckVo.getWrkfinmod().getCbs().getCbe().getIntamty1()) == 0
                        && MdaUtils.compareTo(bptbckVo.getWrkfinmod().getCbs().getCbb().getIntamt1(),bptbckVo.getWrkfinmod().getCbs().getCbe().getIntamt1()) == 0 ) {
                    int num = Strings.parseInt(bptbckVo.getWrkbpdgrp().getRec().getOvdflg());
                    String newFlg = Strings.mid("ABCDEF", num,1);
                    bptbckVo.getWrkbpdgrp().getRec().setOvdflg(newFlg);
                }
                trnmodService.trnStoreContract(DtoMapper.INSTANCE.transfer(bptbckVo.getWrkbpdgrp()));
                wfmmodService.wfeAdd("SETFIN", "LON", Dates.add(Dates.today(),1), new BigDecimal(21));
            }
        }
    }

    private void calcGle4338(BptbckVo bptbckVo) {
        BpdgrpVo bpdgrpVo = bptbckVo.getWrkbpdgrp();
        FinmodVo finmodVo = bptbckVo.getWrkfinmod();
        BptbckQueryVo bptbckQueryVo = new BptbckQueryVo();
        bptbckQueryVo.setCur(bpdgrpVo.getCbs().getMax().getCur());
        bptbckQueryVo.setAmt(bpdgrpVo.getCbs().getMax().getAmt());
        bptbckQueryVo.setMatdat(bpdgrpVo.getRec().getMatdat());
        bptbckQueryVo.setMcdate(bpdgrpVo.getRec().getMcdate());
        bptbckQueryVo.setTolrat(bpdgrpVo.getRec().getTolrat());
        bptbckQueryVo.setShuilv(bpdgrpVo.getRec().getShuilv());
        bptbckQueryVo.setAccbch(finmodVo.getAccbch());
        bptbckQueryVo.setFintyp(bpdgrpVo.getRec().getFintyp());
        List<Gle4338Vo> gle4338List = this.calcGle4338(bptbckQueryVo);
        bptbckVo.setGle4338List(gle4338List);
    }

    /**
     * 转卖还款计算递延信息
     * @param bptbckQueryVo
     */
    public List<Gle4338Vo> calcGle4338(BptbckQueryVo bptbckQueryVo) {
        List<Gle4338Vo> gle4338List = new ArrayList<>();
        String cur = bptbckQueryVo.getCur();
        BigDecimal amt = bptbckQueryVo.getAmt();
        BigDecimal tolrat = bptbckQueryVo.getTolrat();
        String fintyp = bptbckQueryVo.getFintyp();
        int days = Dates.diff(bptbckQueryVo.getMatdat(), bptbckQueryVo.getMcdate());
        if (days <= 0) {
            return gle4338List;
        }
        // 利息
        BigDecimal allint = Decimals.div(Decimals.div(Decimals.mul(Decimals.mul(amt, new BigDecimal(days)), tolrat), new BigDecimal("100")), new BigDecimal("360"));;
        allint = xrtmodService.amtRnd(allint, cur);
        // 增值税率
        BigDecimal shulv = Decimals.div(bptbckQueryVo.getShuilv(), new BigDecimal("100"));
        // 利息收入
        BigDecimal czhint = Decimals.div(allint, (new BigDecimal("1").add(shulv)));
        czhint = xrtmodService.amtRnd(czhint, cur);
        // 增值税
        BigDecimal czhzzs = allint.subtract(czhint);
        String accbch = bptbckQueryVo.getAccbch();
        Gle4338Vo gle1 = new Gle4338Vo();
        gle1.setDbtcdt("C");
        String finAcc1 = glemodService.getAvailAcc("AR-TT3", cur, "", allint);
        String acc1 = accbch + Strings.mid(finAcc1, 5);
        gle1.setAct(acc1);
        gle1.setCur(cur);
        gle1.setAmt(allint);
        Trm trm = trmMapper.seletByTrmtyp("AR-TT3");
        if (trm != null) {
            gle1.setTrmtyp(trm.getTrmcod());
            gle1.setTrmtypName(trm.getNam());
        }
        gle4338List.add(gle1);

        Gle4338Vo gle2 = new Gle4338Vo();
        gle2.setDbtcdt("D");
        String finAcc2 = "";
        Trm trm2 = null;
        if ("F".equals(fintyp)) {
            finAcc2 = glemodService.getAvailAcc("IN-BI1", cur, "", czhint);
            trm2 = trmMapper.seletByTrmtyp("IN-BI1");
        } else if ("G".equals(fintyp)) {
            finAcc2 = glemodService.getAvailAcc("IN-BI2", cur, "", czhint);
            trm2 = trmMapper.seletByTrmtyp("IN-BI2");
        }
        String acc2 = accbch + Strings.mid(finAcc2, 5);
        gle2.setAct(acc2);
        gle2.setCur(cur);
        gle2.setAmt(czhint);
        if (trm2 != null) {
            gle2.setTrmtyp(trm2.getTrmcod());
            gle2.setTrmtypName(trm2.getNam());
        }
        gle4338List.add(gle2);

        Gle4338Vo gle3 = new Gle4338Vo();
        gle3.setDbtcdt("D");
        String finAcc3 = glemodService.getAvailAcc("PL-TA1", cur, "", czhzzs);
        String acc3 = accbch + Strings.mid(finAcc3, 5);
        gle3.setAct(acc3);
        gle3.setCur(cur);
        gle3.setAmt(czhzzs);
        Trm trm3 = trmMapper.seletByTrmtyp("PL-TA1");
        if (trm3 != null) {
            gle3.setTrmtyp(trm3.getTrmcod());
            gle3.setTrmtypName(trm3.getNam());
        }
        gle4338List.add(gle3);

        return gle4338List;
    }

    public String save4338Data(BpdgrpVo bpdgrpVo, List<Gle4338Vo> gle4338List) {
        Map<String, Object> maps = new LinkedHashMap<>();
        Pty pty = ptyCacheService.getPtyById(bpdgrpVo.getFia().getPtyinr());
        maps.put("kehhao", pty.getExtkey()); // 客户号
        maps.put("bchinr", SettleContext.getUserSession().getBch().getInr()); // 业务所属机构INR
        maps.put("jiejuh", bpdgrpVo.getRec().getFincod()); // 借据号
        if (!MdaUtils.isEmpty(bpdgrpVo.getCbs().getOpn1().getCur())) {
            maps.put("huobdh", codetableService.getTblLabel(bpdgrpVo.getCbs().getOpn1().getCur(), "CURKEY")); // 货币代号
        } else {
            maps.put("huobdh", bpdgrpVo.getCbs().getOpn1().getCur()); // 货币代号
        }
        maps.put("zhanch", bpdgrpVo.getRec().getYwacct()); // 业务账号
        if (gle4338List != null && gle4338List.size() > 0) {
            for (Gle4338Vo gle4338Vo : gle4338List) {
                if ("2149".equals(gle4338Vo.getTrmtyp()) && "C".equals(gle4338Vo.getDbtcdt())) {
                    maps.put("jioyje", gle4338Vo.getAmt().negate()); // 交易金额
                    maps.put("lxsrzh", gle4338Vo.getAct()); // 贷方账号
                } else if ("2061".equals(gle4338Vo.getTrmtyp()) && "D".equals(gle4338Vo.getDbtcdt())) {
                    maps.put("lxzczh", gle4338Vo.getAct()); // 借方账号
                } else if ("2732".equals(gle4338Vo.getTrmtyp()) && "D".equals(gle4338Vo.getDbtcdt())) {
                    maps.put("tiozje", gle4338Vo.getAmt()); // 增值税金额
                    maps.put("duifzh", gle4338Vo.getAct()); // 增值税账号
                }
            }
        }
        maps.put("kousbl", bpdgrpVo.getRec().getShuilv().divide(new BigDecimal("100"))); // 增值税税率
        return JSONObject.toJSONString(maps);
    }

    /**
     * 存盘之前需要存储bimdata额外模型
     * finmod bpd，适用于回滚逻辑
     * @param bptbckVo
     */
    private void addBimdataExternalModel(BptbckVo bptbckVo) {
        BimdataVo bimdataVo = transactionHelpService.getTransactionStoreSet().getBimdataVo();
        if (bimdataVo != null) {
            Bpd bpd = bpdMapper.getBpdByInr(bptbckVo.getWrkbpdgrp().getRec().getInr());
            if (bpd != null) {
                bimdataVo.addModel(new TroStoreObjectVo(bpd));
            }
            Finmod finmod = finmodMapper.getFinmodByObjinrAndObjtyp(bptbckVo.getWrkbpdgrp().getRec().getInr(), "BPD");
            if (finmod != null) {
                bimdataVo.addModel(new TroStoreObjectVo(finmod));
            }
        }
    }
}
