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

import com.brilliance.mda.runtime.mda.CodetableItem;
import com.brilliance.mda.runtime.mda.impl.Argument;
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.bo.model.Tracbs;
import com.brilliance.isc.bo.model.Trdgrp;
import com.brilliance.isc.bo.model.Trtcre;
import com.brilliance.isc.bo.model.Trtp;
import com.brilliance.isc.common.api.trtcre.service.TrtcreApiService;
import com.brilliance.isc.common.api.trtcre.vo.TrtcreQueryVo;
import com.brilliance.isc.common.cache.pty.PtyCacheService;
import com.brilliance.isc.common.component.PtsptaToolComponent;
import com.brilliance.isc.common.component.TrtmodComponent;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.context.SpringEnvContext;
import com.brilliance.isc.common.counter.service.CounterService;
import com.brilliance.isc.common.finmod.service.FinmodService;
import com.brilliance.isc.common.glemod.service.GlemodService;
import com.brilliance.isc.common.liaccv.vo.LiaccvgVo;
import com.brilliance.isc.common.register.trtcre.ITrtcreRegister;
import com.brilliance.isc.common.sysmod.SysmodService;
import com.brilliance.isc.common.transaction.help.TransactionHelpService;
import com.brilliance.isc.common.trnmod.service.TrnmodService;
import com.brilliance.isc.common.trtcre.service.TrtcreService;
import com.brilliance.isc.common.trtcre.service.TrtpService;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.common.wfmmod.service.WfmmodService;
import com.brilliance.isc.mda.dao.*;
import com.brilliance.isc.vo.model.FinancVo;
import com.brilliance.isc.vo.model.FinmodBizInfoVo;
import com.brilliance.isc.vo.model.FinmodVo;
import com.brilliance.isc.vo.model.TrtcreBizInfoVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;

import static com.brilliance.mda.runtime.mda.Constants.*;

@Service
public class TrtcreServiceImpl implements TrtcreService {

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

    @Autowired
    private TrdMapper trdMapper;

    @Autowired
    private SysmodService sysmodService;

    @Autowired
    private TrtMapper trtMapper;

    @Autowired
    private PtsMapper ptsMapper;

    @Autowired
    private OrdMapper ordMapper;

    @Autowired
    private FinmodService finmodService;

    @Autowired
    private PtsptaToolComponent ptsptaToolComponent;

    @Autowired
    private TrtmodComponent trtmodComponent;

    @Autowired
    private FinwarMapper finwarMapper;

    @Autowired
    private GlemodService glemodService;

    @Autowired
    private PtyCacheService ptyCacheService;

    @Autowired
    private TrtpService trtpService;

    @Autowired
    private TrnmodService trnmodService;

    @Autowired
    private CounterService counterService;

    @Autowired
    private WfmmodService wfmmodService;

    @Autowired
    private FinmodMapper finmodMapper;

    @Autowired
    private TransactionHelpService transactionHelpService;

    @Autowired
    private TrtcreApiService trtcreApiService;

    private static List<CodetableItem> fintypList;

    @PostConstruct
    public void initFintypList() {
        fintypList = new ArrayList<>();
        fintypList.add(new CodetableItem("进口信用证押汇", "BRF"));
        fintypList.add(new CodetableItem("汇出汇款押汇（LOA）", "LOA"));
        fintypList.add(new CodetableItem("打包贷款", "PCL"));
        fintypList.add(new CodetableItem("出口贷款", "BEL"));
        fintypList.add(new CodetableItem("进口代收押汇", "BCF"));
        fintypList.add(new CodetableItem("进口汇款贷款", "ICF"));
        fintypList.add(new CodetableItem("汇出汇款押汇（ECF）", "ECF"));
        fintypList.add(new CodetableItem("买方押汇", "DRF"));
    }

    /**
     * 1.删除trd trt数据
     * 2.删除关联pts数据
     * 3.删除finmod
     * @param trn
     */
    @Override
    public void rollbackTrtcreDatas(Trn trn) {
        String objtyp = trn.getObjtyp();
        ITrtcreRegister trtcreRegister = null;
        try {
            trtcreRegister = SpringEnvContext.getBean(objtyp.toLowerCase() + "." + "trtcreRegister");
        } catch (NoSuchBeanDefinitionException e) {
            log.warn("没有找到融资处理注册类, 不涉及融资处理流程");
        }
        if (trtcreRegister == null) {
            return;
        }
        boolean isNeedRepair = trtcreRegister.isNeedRepair(trn);
        if (isNeedRepair) {
            Trd trd = trdMapper.getTrdByParentInrAndType(trn.getObjtyp(), trn.getObjinr());
            if (trd != null) {
                sysmodService.sdbDeleteWithLog(trd);
                Trt trt = trtMapper.getTrtByInr(trd.getInr());
                if (trt != null) {
                    sysmodService.sdbDeleteWithLog(trt);
                }
                List<Pts> ptsList = ptsMapper.getPtsByObjInrTyp(trd.getInr(), "TRD");
                if (ptsList != null && ptsList.size() > 0) {
                    ptsMapper.batchDelete(ptsList);
                }
                finmodMapper.deleteByObjinrAndObjtyp(trd.getInr(), "TRD");
            }
        }
    }

    /**
     *  trtcre 融资存盘
     * @param trtcreVo
     */
    @Override
    public void saveTrtcre(Trtcre trtcreVo) {
        //! get reference and store TR if financing is active
        // (has to be executed before MTABUT\\SAV order 500 of transaction)
        if(!MdaUtils.isEmpty(trtcreVo.getCrefinflg())) {
            String ownref = trtcreVo.getTrdgrp().getRec().getOwnref();
            String fintyp = trtcreVo.getTrdgrp().getRec().getFintyp();
            String dflg = Utils.getFieldValue(trtcreVo.getRec(), "dflg", "");
            ownref = trtmodComponent.getref(ownref, fintyp, dflg);
            trtcreVo.getTrdgrp().getRec().setOwnref(ownref);
            // Save Finance Data
            // 借据号使用父交易的REF
            //  \\TRTCRE\\TRTMOD\\FINMOD\\FINCOD = \\TRTCRE\\TRDGRP\\REC\\OWNREF
            //汇出汇款取TR号
            if( MdaUtils.compareTo(SettleContext.getTransName(),"CPTOPN") == 0
                    || MdaUtils.compareTo(SettleContext.getTransName(),"CPTATO") == 0 ) {
                trtcreVo.getFinmod().setFincod(ownref);
            } else {
                trtcreVo.getFinmod().setFincod(trtcreVo.getRec().getOwnref());
            }
            trtcreVo.getTrdgrp().getRec().setFincod(trtcreVo.getFinmod().getFincod());
            trtcreVo.getTrdgrp().getRec().setOvdflg("0");
            trtcreVo.getTrdgrp().getRec().setDinjdm(trtcreVo.getFinmod().getDinjdm());
            trtcreVo.getTrdgrp().getRec().setShuilv(trtcreVo.getFinmod().getShuilv());
            if(MdaUtils.isEmpty(trtcreVo.getTrdgrp().getRec().getJzllgz()) && !MdaUtils.isEmpty(trtcreVo.getFinmod().getDinmod().getJzllgz())) {
                trtcreVo.getTrdgrp().getRec().setJzllgz(trtcreVo.getFinmod().getDinmod().getJzllgz());
            }
            trtcreVo.getTrdgrp().getRec().setOvddat(Dates.add(trtcreVo.getTrdgrp().getRec().getMatdat(), trtcreVo.getFinmod().getGraday()));
            trtcreVo.getTrdgrp().getRec().setActyld(trtcreVo.getTrdgrp().getRec().getActrat());
            Bch bch = SettleContext.getUserSession().getBch();
            Bch wrkbch = SettleContext.getUserSession().getWrkbch();
            //设置业务表的机构信息
            sysmodService.setRecBchInfo(trtcreVo.getTrdgrp().getRec(), bch, wrkbch);
            if (StringUtils.isEmpty(trtcreVo.getTrdgrp().getRec().getPntinr())) {
                trtcreVo.getTrdgrp().getRec().setPntinr(trtcreVo.getRec().getObjinr());
            }
            trtmodComponent.sav(trtcreVo.getTrdgrp());
            cbsSavTrtCre(trtcreVo);
            //组数Finmod
            Finmod finmod = finmodService.saveDataToBlock(trtcreVo.getFinmod());
            trtcreVo.getFinmod().setItftyp("0");
            String fin6153 = finmodService.save6153Data(trtcreVo.getFinmod());
            finmod.setFin6153(fin6153);
            finmod.setInr(counterService.dbCounterFormat("FINMOD"));
            finmod.setObjinr(trtcreVo.getTrdgrp().getRec().getInr());
            finmod.setObjtyp(trtcreVo.getFinmod().getRec().getObjtyp());
            finmod.setOwnref(trtcreVo.getFinmod().getRec().getOwnref());
            finmodMapper.insert(finmod);
            String fkfs = trtcreVo.getRec().getFkfs();
            if (!"2".equals(fkfs)) {
                wfmmodService.wfeAdd ( "CREFIN", "LON", Dates.add(Dates.today(),1), new BigDecimal(21));
            }
            //FINWAR
            this.saveFinwar(trtcreVo);
        }
    }

    @Override
    public void assertTrtcre(Trtcre trtcreVo) {
        String objtyp = trtcreVo.getRec().getObjtyp();
        ITrtcreRegister trtcreRegister = null;
        try {
            trtcreRegister = SpringEnvContext.getBean(objtyp.toLowerCase() + "." + "trtcreRegister");
        } catch (NoSuchBeanDefinitionException e) {
            log.warn("没有找到融资处理注册类, 不涉及融资处理流程");
        }
        if (trtcreRegister == null) {
            return;
        }
        //根据xxxgrp初始化数据
        trtcreRegister.setTRDfieldsfromXXX(trtcreVo);
        //执行init rule
        trtpService.initWbdcre(trtcreVo.getTrtp().getWbdp());
        finmodService.initFinmod(trtcreVo.getFinmod());
        this.assertFinance(trtcreVo.getFinanc(), trtcreVo.getRec());
        //执行当前模型下面的default rule
        this.defaultTrtcreIdtype(trtcreVo);
        this.defaultTrdgrpCbsMaxCurN900(trtcreVo);
        this.defaultTrdgrpRecIssdatN1000(trtcreVo);
        this.defaultTrtpPanstaN1000(trtcreVo);
        this.defaultTrdgrpFipPtsRefN1000(trtcreVo);
        this.defaultAmtPctExtrat(trtcreVo);
        this.defaultTrdgrpRecFintypN1000(trtcreVo);
        this.defaultTrdgrpRecNamN1000(trtcreVo);
        this.defaultBranchesN1000(trtcreVo);
        this.defaultFinCodN1000(trtcreVo);
        this.defaultAccountsN1000(trtcreVo);
        this.defaultTrdgrpRecGuaflgN1000(trtcreVo);
        this.defaultTrdgrpRecTendayN11100(trtcreVo);
        this.defaultTrdgrpRecStagodN1000(trtcreVo);
        this.defaultTrdgrpRecOppaccN1000(trtcreVo);
        this.defaultTrntypN1000(trtcreVo);
        this.defaultOppaccN1000(trtcreVo);
        this.defaultTrdgrpRecInvtypN1000(trtcreVo);
        //执行Trtp模型下的default rule
        Trtp trtpVo = trtcreVo.getTrtp();
        Trdgrp trdgrpVo = trtcreVo.getTrdgrp();
        trtpService.defaultTrdgrpRecOpndatN1000(trdgrpVo);
        trtpService.defaultTrdgrpRecActfindayN1000(trdgrpVo);
        trtpService.defaultTrdgrpRecLprtypN1000(trtpVo, trdgrpVo, trtcreVo.getFinmod());
        trtpService.defaultLabmaxamtN1000(trtpVo, trdgrpVo);
        trtpService.defaultTrdgrpRecStttendatN1000(trtpVo, trdgrpVo);
        trtpService.defaultTrdgrpRecOwnusrN1000(trdgrpVo);
        Cbb maxCbb = trtcreVo.getCbsMap().getOrDefault("max", new Cbb());
        trtpService.defaultTrdgrpCbsMaxCurN12000(trtpVo, maxCbb);
        trtpService.defaultTrdgrpRecGoddspcnN1000(trtcreVo.getCrefinflg(), trtcreVo.getRec(), trdgrpVo);
        trtpService.defaultTrdgrpRecFfaflgN1000(trtpVo, trdgrpVo);
        String cur = trtcreVo.getTrdgrp().getCbs().getMax().getCur();
        String ptyinr = trtcreVo.getTrdgrp().getFip().getPtyinr();
        trtpService.assertWbdcre(trtpVo.getWbdp(), cur, ptyinr);
        //finmod赋值
        fillFinmodVo(trtcreVo);
        //初始化finmod模型
        finmodService.defaultFinmod(trtcreVo.getFinmod());

    }

    /**
     * 获取客户类型
     * @param trtcreVo
     */
    public void defaultTrtcreIdtype(Trtcre trtcreVo) {
        String ptyinr = trtcreVo.getTrdgrp().getFip().getPtyinr();
        Pty pty = ptyCacheService.getPtyById(ptyinr);
        if (pty != null) {
            String idtype = pty.getIdtype();
            trtcreVo.setIdType(idtype);
        }
    }
    /**
     *   source:trtcre.0002.script
     */
    public void defaultTrdgrpCbsMaxCurN900(Trtcre trtcreVo){
        TrtcreBizInfoVo rec = trtcreVo.getRec();
        if (!trtcreVo.getTrdgrp().getCbs().getMax().isModified("cur")) {
            trtcreVo.getTrdgrp().getCbs().getMax().setCur(rec.getDoccur());
        }
    }

    /**
     *   source:trtcre.0003.script
     */
    public void defaultTrdgrpRecIssdatN1000(Trtcre trtcreVo){
        if((!trtcreVo.getTrdgrp().getRec().isModified("issdat")) || trtcreVo.getTrdgrp().getRec().getIssdat() == null) {
            trtcreVo.getTrdgrp().getRec().setIssdat(Dates.today());
        }
    }

    /**
     *   source:trtcre.0009.script
     */
    public void defaultTrtpPanstaN1000(Trtcre trtcreVo){
        if(!MdaUtils.isEmpty(trtcreVo.getCrefinflg())) {
            trtcreVo.getTrtp().setPansta(PanStaEdit);
            trtcreVo.getTrtp().setCrefinflg("X");
        } else {
            trtcreVo.getTrtp().setPansta(PanStaShow);
            trtcreVo.getTrtp().setCrefinflg("");
        }
    }

    /**
     *   source:trtcre.0022.script
     */
    public void defaultTrdgrpFipPtsRefN1000(Trtcre trtcreVo){
        //! Allow user to enter reference of financed party
        //Systems.setEnabled(this.getTrdgrp().getFip().getPts(),"ref");
        //! if not modified default from parent contract
        if(!trtcreVo.getTrdgrp().getFip().getPts().isModified("ref")) {
            PtsptaVo ptsptaVo = null;
            switch(trtcreVo.getTrdgrp().getRec().getPnttyp()) {
                case "LED":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(trtcreVo.getPtsptaList(), "BEN");
                    if (ptsptaVo != null) {
                        trtcreVo.getTrdgrp().getFip().getPts().setRef(ptsptaVo.getRef());
                    }
                    break;
                case "BRD":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(trtcreVo.getPtsptaList(), "APL");
                    if (ptsptaVo != null) {
                        trtcreVo.getTrdgrp().getFip().getPts().setRef(ptsptaVo.getRef());
                    }
                    break;
                case "BCD":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(trtcreVo.getPtsptaList(), "DRE");
                    if (ptsptaVo != null) {
                        trtcreVo.getTrdgrp().getFip().getPts().setRef(ptsptaVo.getRef());
                    }
                    break;
                default:
                    // no defaulting
            }
        }
    }

    /**
     * @Default(value={"trdgrp.rec.pctfin","oriamt"},order=1000)
     * @defaultExtratN1000
     * @defaultTrdgrpCbsMaxAmtN1000
     * @defaultTrdgrpCbsOpn1AmtN1000
     * @defaultTrdgrpCbsOpn1CurN1000
     */
    public void defaultAmtPctExtrat(Trtcre trtcreVo){
        TrtcreBizInfoVo rec = trtcreVo.getRec();
        trtcreVo.setOricur(rec.getDoccur());
        BigDecimal docamt = rec.getDocamt();
        if(docamt.compareTo(BigDecimal.ZERO) == 0) {
            trtcreVo.getTrdgrp().getRec().setPctfin(BigDecimal.ZERO);
            trtcreVo.getTrdgrp().getRec().resetModified("pctfin");
            trtcreVo.setOriamt(docamt);
        } else {
            List<LiaccvgVo> liaccvg = trtcreVo.getLiaccvg();
            BigDecimal ccvAmt = new BigDecimal("0");
            for (int i=0; i<liaccvg.size(); i++) {
                ccvAmt = Decimals.sub(ccvAmt, liaccvg.get(i).getAcccovamt());
            }
            BigDecimal conAmt = Decimals.sub(Decimals.sub(rec.getDocamt(), rec.getRedamt()), ccvAmt);
            trtcreVo.setOriamt(conAmt);
        }
        //计算pctfin
        if (!trtcreVo.getTrdgrp().getRec().isModified("pctfin") && (trtcreVo.getTrdgrp().getRec().getPctfin() == null || trtcreVo.getTrdgrp().getRec().getPctfin().compareTo(BigDecimal.ZERO) == 0)) {
            trtcreVo.getTrdgrp().getRec().setPctfin(new BigDecimal("100.00"));
        }
        //计算汇率extrat 金额
        String maxcur = trtcreVo.getTrdgrp().getCbs().getMax().getCur();
        if (MdaUtils.compareTo(maxcur, trtcreVo.getOricur()) == 0) {
            trtcreVo.setExtrat(new BigDecimal("1"));
        }
        this.calcAmt(trtcreVo);
        //opn1赋值
        trtcreVo.getTrdgrp().getCbs().getOpn1().setAmt(trtcreVo.getTrdgrp().getCbs().getMax().getAmt());
        trtcreVo.getTrdgrp().getCbs().getOpn1().setCur(trtcreVo.getTrdgrp().getCbs().getMax().getCur());
    }

    private void calcAmt(Trtcre trtcreVo) {
        TrtcreQueryVo trtcreQueryVo = new TrtcreQueryVo();
        if (trtcreVo.isModified("pctoriamt")) {
            trtcreQueryVo.setModifyType("pctamt");
            trtcreQueryVo.setPctoriamt(trtcreVo.getPctoriamt());
        } else{
            trtcreQueryVo.setModifyType("pct");
            trtcreQueryVo.setPctfin(trtcreVo.getTrdgrp().getRec().getPctfin());
        }
        trtcreQueryVo.setOriamt(trtcreVo.getOriamt());
        trtcreQueryVo.setOricur(trtcreVo.getOricur());
        trtcreQueryVo.setTxncur(trtcreVo.getTrdgrp().getCbs().getMax().getCur());
        trtcreQueryVo.setExtrat(trtcreVo.getExtrat());
        trtcreQueryVo = trtcreApiService.calcAmt(trtcreQueryVo);
        if ("pctamt".equals(trtcreQueryVo.getModifyType())) {
            trtcreVo.getTrdgrp().getRec().setPctfin(trtcreQueryVo.getPctfin());
        } else{
            trtcreVo.setPctoriamt(trtcreQueryVo.getPctoriamt());
        }
        trtcreVo.getTrdgrp().getCbs().getMax().setAmt(trtcreQueryVo.getTxnamt());

    }

    /**
     *   source:trtcre.0029.script
     */
    public void defaultTrdgrpRecFintypN1000(Trtcre trtcreVo){
        //! trust receipt or banker`s acceptance are allowed for contracts financing an amount of a payment of contract
        Set<String> fintypSet = new HashSet<>();
        String defaultFintyp = "";
        switch(trtcreVo.getTrdgrp().getRec().getPnttyp()) {
            case "BRD":
                if( MdaUtils.compareTo(SettleContext.getTransName(),"BDTSET") == 0 ) {
                    //国内信用证
                    fintypSet.add("DRF");
                    defaultFintyp = "DRF";
                    //Systems.setValues(this.getTrdgrp().getRec(),"fintyp","DRF");
                } else {
                    fintypSet.add("BRF");
                    defaultFintyp = "BRF";
                    //Systems.setValues(this.getTrdgrp().getRec(),"fintyp","BRF");
                }
                break;
            case "BDD":
                //国内信用证
                fintypSet.add("DRF");
                defaultFintyp = "DRF";
                //Systems.setValues(this.getTrdgrp().getRec(),"fintyp","DRF");
                break;
            case "BCD":
                fintypSet.add("BCF");
                defaultFintyp = "BCF";
                //Systems.setValues(this.getTrdgrp().getRec(),"fintyp","BCF");
                break;
            case "LED":
                fintypSet.add("PCL");
                defaultFintyp = "PCL";
                //Systems.setValues(this.getTrdgrp().getRec(),"fintyp","PCL");
                break;
            case "CPD":
                fintypSet.add("ECF");
                defaultFintyp = "ECF";
                //Systems.setValues(this.getTrdgrp().getRec(),"fintyp","ECF");
                break;
            default:
                fintypSet.add("LOA");
                defaultFintyp = "LOA";
                //Systems.setValues(this.getTrdgrp().getRec(),"fintyp","LOA");
        }
        if(!trtcreVo.getTrdgrp().getRec().isModified("fintyp")) {
            trtcreVo.getTrdgrp().getRec().setFintyp(defaultFintyp);
        }
    }

    /**
     *   source:trtcre.0032.script
     */
    public void defaultTrdgrpRecNamN1000(Trtcre trtcreVo){
        String recNam="";
        if(trtcreVo.getTrdgrp()!=null && trtcreVo.getTrdgrp().getFip()!=null) {
            recNam=trtcreVo.getTrdgrp().getFip().getNam();
        }
        trtcreVo.getTrdgrp().getRec().setNam(recNam);
        /*if (!trtcreVo.getTrdgrp().getRec().isModified("nam")) {
            Optional<CodetableItem> item = fintypList.stream().filter(f -> trtcreVo.getTrdgrp().getRec().getFintyp().equals(f.getValue())).findFirst();
            String fintypName = "";
            if (item.isPresent()) {
                fintypName = item.get().getLabel();
            }
            String nam = fintypName + " " + trtcreVo.getTrdgrp().getCbs().getMax().getCur() + Utils.fmtAmount(trtcreVo.getTrdgrp().getCbs().getMax().getAmt(), trtcreVo.getTrdgrp().getCbs().getMax().getCur()) + " " + "." + trtcreVo.getTrdgrp().getFip().getNam();
            if (nam.length() > 40) {
                nam = nam.substring(0, 40);
            }
            trtcreVo.getTrdgrp().getRec().setNam(nam);
        }*/
    }

    /**
     *   source:trtcre.0036.script
     */
    public void defaultBranchesN1000(Trtcre trtcreVo){
        List<CodetableItem> accbchList = new ArrayList<>();
        List<String> accbchs = new ArrayList<>();
        //业务归属机构
        Bch wrkbch = SettleContext.getUserSession().getWrkbch();
        if (wrkbch != null) {
            accbchList.add(new CodetableItem(wrkbch.getBchname(), wrkbch.getBranch()));
            accbchs.add(wrkbch.getBranch());
        }
        //记账机构  优先放经办机构
        Bch bch = SettleContext.getUserSession().getBch();
        if (bch != null) {
            if (wrkbch != null) {
                if (!wrkbch.getInr().equals(bch.getInr())) {
                    accbchList.add(0, new CodetableItem(bch.getBchname(), bch.getBranch()));
                    accbchs.add(0, bch.getBranch());
                }
            } else {
                accbchList.add(0, new CodetableItem(bch.getBchname(), bch.getBranch()));
                accbchs.add(0, bch.getBranch());
            }
        }
        trtcreVo.getFinmod().setAccbchSet(accbchList);
        if (accbchs.size() > 0) {
            if (StringUtils.isEmpty(trtcreVo.getFinmod().getAccbch())) {
                trtcreVo.getFinmod().setAccbch(accbchs.get(0));
            } else {
                if (!accbchs.contains(trtcreVo.getFinmod().getAccbch())) {
                    trtcreVo.getFinmod().setAccbch(accbchs.get(0));
                }
            }
        } else {
            trtcreVo.getFinmod().setAccbch("");
        }
        // 国结3693自贸区机构下，融资放款交易界面上，“入账机构”栏位需锁定为“3693”，
        // 不允许修改为其他机构号。
        if (bch != null && "X".equals(bch.getZmqflg())) {
            trtcreVo.setZmqflg("X");
            trtcreVo.getFinmod().setAccbch(bch.getBranch());
            trtcreVo.getFinmod().resetEnabled("accbch");
        } else if (wrkbch != null && "X".equals(wrkbch.getZmqflg())){
            trtcreVo.setZmqflg("X");
            Spt spt = SettleContext.getUserSession().getSpt();
            if (spt != null) {
                Ord ord = ordMapper.selectByOrdInr(spt.getOrdinr());
                if (ord != null && "X".equals(ord.getSdhflg())) {
                    trtcreVo.getFinmod().resetEnabled("accbch");
                }
            }
        }
    }

    /**
     *   source:trtcre.0037.script
     */
    public void defaultFinCodN1000(Trtcre trtcreVo){
        // 借据号使用父交易的REF
        //  TRTCRE\\TRTMOD\\FINMOD\\FINCOD = TRTCRE\\TRDGRP\\REC\\OWNREF
        //汇出汇款取TR号
        if(MdaUtils.compareTo(SettleContext.getTransName(),"CPTOPN") == 0 || MdaUtils.compareTo(SettleContext.getTransName(),"CPTATO") == 0) {
            trtcreVo.getFinmod().setFincod(trtcreVo.getTrdgrp().getRec().getOwnref());
        } else {
            trtcreVo.getFinmod().setFincod(trtcreVo.getRec().getOwnref());
        }
        trtcreVo.getTrdgrp().getRec().setFincod(trtcreVo.getFinmod().getFincod());
    }

    /**
     *   source:trtcre.0041.script
     */
    public void defaultAccountsN1000(Trtcre trtcreVo){
        String ptyinr = trtcreVo.getTrdgrp().getFip().getPtyinr();
        String cur = trtcreVo.getTrdgrp().getCbs().getMax().getCur();
        BigDecimal amt = trtcreVo.getTrdgrp().getCbs().getMax().getAmt();
        Set<String> act1Set = new HashSet<>();
        Set<String> intactSet = new HashSet<>();
        if (StringUtils.isNotEmpty(ptyinr) && StringUtils.isNotEmpty(cur)) {
            String actVal = glemodService.getAvailAcc("LO", cur, ptyinr, amt);
            if (StringUtils.isNotEmpty(actVal)) {
                Arrays.stream(actVal.split("[\\r\\n]{1,2}")).forEach(account -> {
                    act1Set.add(account);
                    intactSet.add(account);
                });
            }
        }
        trtcreVo.getFinmod().setAct1Set(act1Set);
        trtcreVo.getFinmod().setIntactSet(act1Set);
    }

    /**
     *   source:trtcre.0046.script
     */
    public void defaultTrdgrpRecGuaflgN1000(Trtcre trtcreVo){
        if(!trtcreVo.getTrdgrp().getRec().isModified("guaflg")) {
            trtcreVo.getTrdgrp().getRec().setGuaflg("0");
        }
    }

    /**
     *   source:trtcre.0063.script
     */
    public void defaultTrdgrpRecTendayN11100(Trtcre trtcreVo){
        trtcreVo.getTrdgrp().getRec().setTenday(Dates.diff(trtcreVo.getTrdgrp().getRec().getMatdat(), trtcreVo.getTrdgrp().getRec().getStttendat()));
    }

    /**
     *   source:trtcre.0065.script
     */
    public void defaultTrdgrpRecStagodN1000(Trtcre trtcreVo){
        if(MdaUtils.isEmpty(trtcreVo.getCrefinflg())) {
            trtcreVo.getTrdgrp().getRec().setStagod(NULLSTR);
            trtcreVo.getTrdgrp().getRec().resetModified("stagod");
        } else {
            switch(trtcreVo.getTrdgrp().getRec().getPnttyp()) {
                case "BRD":
                case "BCD":
                case "CPD":
                    if(!trtcreVo.getTrdgrp().getRec().isModified("stagod")) {
                        trtcreVo.getTrdgrp().getRec().setStagod(trtcreVo.getRec().getStagod());
                    }
                    break;
                default:
            }
        }
    }

    /**
     *   source:trtcre.0066.script
     *   TODO visiable 前端实现(后端返回zmqflg)
     */
    public void defaultTrdgrpRecOppaccN1000(Trtcre trtcreVo){
        //--zmqzmq-----
        /*if( MdaUtils.compareTo(Platform.getzmqflg(),"X") == 0 || MdaUtils.compareTo(ctx.absGet(Sysmod.class).getBch().getZmqflg(),"X") == 0 )
        {
            Systems.setVisible(this.getTrdgrp().getRec(),"oppacc");
        }
        else
        {
            Systems.resetVisible(this.getTrdgrp().getRec(),"oppacc");
        }*/
        //---zmqzmq---
        if(!trtcreVo.getTrdgrp().getRec().isModified("oppacc")) {
            if(!MdaUtils.isEmpty(trtcreVo.getFinmod().getAct1())) {
                trtcreVo.getTrdgrp().getRec().setOppacc(trtcreVo.getFinmod().getAct1());
            }
        }
    }

    /**
     *   source:trtcre.0069.script
     *   TODO visiable 前端实现(后端返回zmqflg)
     */
    public void defaultTrntypN1000(Trtcre trtcreVo){
        if ("X".equals(trtcreVo.getZmqflg())) {
            trtcreVo.setTrntyp("交易性质");
        }
        //--zmqzmq-----
        /*if( MdaUtils.compareTo(Platform.getzmqflg(),"X") == 0 || MdaUtils.compareTo(ctx.absGet(Sysmod.class).getBch().getZmqflg(),"X") == 0 )
        {
            Systems.setVisible(this,"trntyp");
            this.setTrntyp(  "交易性质");
        }
        else
        {
            Systems.resetVisible(this,"trntyp");
        }*/
    }

    /**
     *   source:trtcre.0070.script
     *   TODO visiable 前端实现(后端返回zmqflg)
     */
    public void defaultOppaccN1000(Trtcre trtcreVo){
        if ("X".equals(trtcreVo.getZmqflg())) {
            trtcreVo.setOppacc("对方账号");
        }
        //--zmqzmq-----
        /*if( MdaUtils.compareTo(Platform.getzmqflg(),"X") == 0 || MdaUtils.compareTo(ctx.absGet(Sysmod.class).getBch().getZmqflg(),"X") == 0 )
        {
            Systems.setVisible(this,"oppacc");
            this.setOppacc(  "对方账号");
        }
        else
        {
            Systems.resetVisible(this,"oppacc");
        }*/
    }

    /**
     *   source:trtcre.0073.script
     */
    public void defaultTrdgrpRecInvtypN1000(Trtcre trtcreVo){
        //2019 5月 EAST改造
        String frame = SettleContext.getDirectTransName();
        String invtyp = trtcreVo.getRec().getInvtyp();
        if(!trtcreVo.getTrdgrp().getRec().isModified("invtyp")) {
            if(!MdaUtils.isEmpty(trtcreVo.getCrefinflg())) {
                if(!MdaUtils.isEmpty(invtyp) && ( MdaUtils.compareTo(frame,"BRTSET") == 0 || MdaUtils.compareTo(frame,"BDTSET") == 0)) {
                    trtcreVo.getTrdgrp().getRec().setInvtyp( invtyp);
                } else {
                    if(!MdaUtils.isEmpty(invtyp) && MdaUtils.compareTo(frame,"BCTSET") == 0) {
                        trtcreVo.getTrdgrp().getRec().setInvtyp(invtyp);
                    }
                }
            } else {
                trtcreVo.getTrdgrp().getRec().setInvtyp(NULLSTR);
            }
        }
    }

    @Override
    public void assertFinance(FinancVo financVo, TrtcreBizInfoVo rec) {
        String transName = SettleContext.getDirectTransName();
        if ("CPTOPN".equals(transName) || "CPTATO".equals(transName)) {
            if (StringUtils.isEmpty(financVo.getRzkx1())
                    && StringUtils.isEmpty(financVo.getRzkx2())
                    && StringUtils.isEmpty(financVo.getRzkx3())) {
                if (!financVo.isModified("rzkx4")) {
                    financVo.setRzkx4("X");
                }
                if (!financVo.isModified("ref4")) {
                    financVo.setRef4(rec.getOwnref());
                }
            }
        }
        if ("BRTSET".equals(transName)) {
            if (StringUtils.isEmpty(financVo.getRzkx1())
                    && StringUtils.isEmpty(financVo.getRzkx3())
                    && StringUtils.isEmpty(financVo.getRzkx4())) {
                if (!financVo.isModified("rzkx2")) {
                    financVo.setRzkx2("X");
                }
                if (!financVo.isModified("ref2")) {
                    financVo.setRef2(rec.getPntref());
                }
            }
        }
        if ("BCTSET".equals(transName)) {
            if (StringUtils.isEmpty(financVo.getRzkx1())
                    && StringUtils.isEmpty(financVo.getRzkx2())
                    && StringUtils.isEmpty(financVo.getRzkx4())) {
                if (!financVo.isModified("rzkx3")) {
                    financVo.setRzkx3("X");
                }
                if (!financVo.isModified("ref3")) {
                    financVo.setRef3(rec.getOwnref());
                }
            }
        }
        if ("BDTSET".equals(transName)) {
            if (StringUtils.isEmpty(financVo.getRzkx1())) {
                if (!financVo.isModified("rzkx5")) {
                    financVo.setRzkx5("X");
                }
                if (!financVo.isModified("ref5")) {
                    financVo.setRef5(rec.getPntref());
                }
            }
        }
    }

    /**
     *   source:trtcre.0064.script
     */
    public void favoriteRate(String ptyinr, String oricur, String maxcur, BigDecimal midRat,Argument<BigDecimal> rate) {
        String buyTyp = "";
        BigDecimal buyRat = BigDecimal.ZERO;
        String selTyp = "";
        BigDecimal selRat = BigDecimal.ZERO;
        Pty pty = ptyCacheService.getPtyById(ptyinr);
        if (pty != null) {
            buyTyp = pty.getBuytyp();
            buyRat = pty.getBuyrat();
            selTyp = pty.getSeltyp();
            selRat = pty.getSelrat();
        }
        if(MdaUtils.compareTo(oricur, "CNY") == 0 && MdaUtils.compareTo(maxcur, "CNY") != 0) {
            // 买价B
            if(MdaUtils.compareTo(buyTyp,"1") == 0) {
                //日元从小数点后6位开始优惠
                if( MdaUtils.compareTo(maxcur, "JPY") == 0 ) {
                    rate.value = Decimals.add(rate.value,Decimals.div(buyRat,1000000));
                } else {
                    rate.value = Decimals.add(rate.value,Decimals.div(buyRat,10000));
                }
            }
            if(MdaUtils.compareTo(buyTyp,"2") == 0) {
                rate.value = Decimals.add(rate.value,Decimals.div(Decimals.mul(( Decimals.sub(midRat,rate.value) ),buyRat),100));
            }
        } else {
            if(MdaUtils.compareTo(oricur, "CNY") != 0 && MdaUtils.compareTo(maxcur, "CNY") == 0) {
                // 卖价S
                if(MdaUtils.compareTo(selTyp,"1") == 0) {
                    //日元从小数点后6位开始优惠
                    if(MdaUtils.compareTo(oricur, "JPY") == 0) {
                        rate.value = Decimals.sub(rate.value,Decimals.div(selRat,1000000));
                    } else {
                        rate.value = Decimals.sub(rate.value,Decimals.div(selRat,10000));
                    }
                }
                if(MdaUtils.compareTo(selTyp,"2") == 0) {
                    rate.value = Decimals.sub(rate.value,Decimals.div(Decimals.mul(( Decimals.sub(rate.value,midRat) ),selRat),100));
                }
            }
        }

    }

    /**
     *   source:trtcre.0026.script
     */
    public void cbsSavTrtCre(Trtcre trtcreVo) {
        if(!MdaUtils.isEmpty(trtcreVo.getCrefinflg()) ) {
            Optional<CodetableItem> item = fintypList.stream().filter(f -> trtcreVo.getTrdgrp().getRec().getFintyp().equals(f.getValue())).findFirst();
            String fintypName = "";
            if (item.isPresent()) {
                fintypName = item.get().getLabel();
            }
            trnmodService.cbsTrnStore("MAXAMT","AMT1",Dates.today(), trtcreVo.getTrdgrp().getCbs().getMax().getCur(), trtcreVo.getTrdgrp().getCbs().getMax().getAmt(), Strings.getText("$1 opening", fintypName), trtcreVo.getTrdgrp().getRec(), transactionHelpService.getTrninr());
        }

    }

    private void saveFinwar(Trtcre trtcreVo) {
        Date stttendat = trtcreVo.getTrdgrp().getRec().getStttendat();
        Date matdat = trtcreVo.getTrdgrp().getRec().getMatdat();
        int unt = 0;
        if (stttendat != null && matdat != null) {
            //计算是否超过半年
            unt = Utils.calcUnt(stttendat, matdat, "CALMON");
        }
        if (unt > 6) {
            //期限超过半年 插入FINWAR表
            Finwar finwar = new Finwar();
            finwar.setInr(counterService.dbCounterFormat("FINWAR"));
            finwar.setOwnref(trtcreVo.getTrdgrp().getRec().getOwnref());
            finwar.setObjtyp("TRN");
            finwar.setObjinr(transactionHelpService.getTrninr());
            finwar.setWartxt("融资期限超半年，请确认是否完成超权限审批");
            finwar.setVer("0001");
            finwarMapper.insert(finwar);
        }
    }

    /**
     * 封装finmodVo
     * @param trtcreVo
     * @return
     */
    private void fillFinmodVo(Trtcre trtcreVo) {
        FinmodVo finmodVo = trtcreVo.getFinmod();
        //bizinfo
        FinmodBizInfoVo rec = finmodVo.getRec();
        rec.setCrefinflg(trtcreVo.getCrefinflg());
        rec.setObjtyp("TRD");
        rec.setObjinr(trtcreVo.getTrdgrp().getRec().getInr());
        rec.setOwnref(trtcreVo.getTrdgrp().getRec().getOwnref());
        rec.setOpndat(trtcreVo.getTrdgrp().getRec().getOpndat());
        rec.setMatdat(trtcreVo.getTrdgrp().getRec().getMatdat());
        rec.setJzllgz(trtcreVo.getTrdgrp().getRec().getJzllgz());
        rec.setFintyp(trtcreVo.getTrdgrp().getRec().getFintyp());
        rec.setStttendat(trtcreVo.getTrdgrp().getRec().getStttendat());
        rec.setIntrat(trtcreVo.getTrdgrp().getRec().getIntrat());
        rec.setActrat(trtcreVo.getTrdgrp().getRec().getActrat());
        rec.setLprtyp(trtcreVo.getTrdgrp().getRec().getLprtyp());
        rec.setOvdflg(trtcreVo.getTrdgrp().getRec().getOvdflg());
        rec.setFinact(trtcreVo.getTrdgrp().getRec().getFinact());
        //cbb
        Map<String, Cbb> cbsMap = finmodVo.getCbsMap();
        Tracbs tracbs = trtcreVo.getTrdgrp().getCbs();
        cbsMap.put("MAX", tracbs.getMax());
        cbsMap.put("MAX2", tracbs.getMax2());
        cbsMap.put("OPN1", tracbs.getOpn1());
        cbsMap.put("INTCLC", tracbs.getIntclc());
        cbsMap.put("INTSET", tracbs.getIntset());
        cbsMap.put("INTCPL", tracbs.getIntcpl());
        cbsMap.put("INTACR", tracbs.getIntacr());
        //ptspta
        List<PtsptaVo> ptsptaList = new ArrayList<>();
        Field[] fields = trtcreVo.getTrdgrp().getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (PtsptaVo.class.equals(field.getType())) {
                PtsptaVo ptspta = Utils.getFieldValue(trtcreVo.getTrdgrp(), field.getName());
                if (ptsptaToolComponent.ptsIsRolSet(ptspta)) {
                    ptsptaToolComponent.fillPtsptaAllProperties(ptspta);
                    ptsptaList.add(ptspta);
                }
            }
        }
        finmodVo.setPtsptaList(ptsptaList);
    }
}
