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

import com.brilliance.mda.runtime.mda.CodetableItem;
import com.brilliance.mda.runtime.mda.IStream;
import com.brilliance.mda.runtime.mda.impl.Argument;
import com.brilliance.mda.runtime.mda.impl.StreamImpl;
import com.brilliance.mda.runtime.mda.util.*;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import com.brilliance.isc.bo.*;
import com.brilliance.isc.common.cache.atpbch.AtpBchCacheService;
import com.brilliance.isc.common.cache.pty.PtyCacheService;
import com.brilliance.isc.common.cbsmod.CbsRange;
import com.brilliance.isc.common.cbsmod.Cbsget;
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.DyncDaoService;
import com.brilliance.isc.common.component.PtsptaToolComponent;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.context.SpringEnvContext;
import com.brilliance.isc.common.converter.DtoMapper;
import com.brilliance.isc.common.counter.service.CounterService;
import com.brilliance.isc.common.exception.CommonServiceException;
import com.brilliance.isc.common.glemod.vo.GlemodVo;
import com.brilliance.isc.common.irtcal.service.IrtcalService;
import com.brilliance.isc.common.liaall.service.LiaallService;
import com.brilliance.isc.common.liaall.vo.*;
import com.brilliance.isc.common.liaallg.service.LiaallgService;
import com.brilliance.isc.common.liaallg.vo.LiaallgVo;
import com.brilliance.isc.common.liaallr.vo.LiaallrVo;
import com.brilliance.isc.common.liaccv.service.LiaccvService;
import com.brilliance.isc.common.liaget.service.LiagetService;
import com.brilliance.isc.common.liaone.service.LiaoneService;
import com.brilliance.isc.common.register.liaall.ILiaallRegister;
import com.brilliance.isc.common.register.liaall.ILiaallRegisterModule;
import com.brilliance.isc.common.setfeg.fee.Setpty;
import com.brilliance.isc.common.setfeg.service.SetfegService;
import com.brilliance.isc.common.setmod.service.SetmodService;
import com.brilliance.isc.common.transaction.help.LiaallSet;
import com.brilliance.isc.common.transaction.help.TransactionHelpService;
import com.brilliance.isc.common.trnmod.service.TrnmodService;
import com.brilliance.isc.common.util.SettleExceptionUtils;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.common.vo.FecVo;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.common.vo.SimpleModuleVo;
import com.brilliance.isc.mda.dao.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

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

/**
 * 表外接口服务
 */
@Service("liaallService")
public class LiaallServiceImpl implements LiaallService {
    private Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private IrtcalService irtcalService;

    @Autowired
    private LiaccvService liaccvService;

    @Autowired
    private LiaoneService liaoneService;

    @Autowired
    private LiaallgService liaallgService;

    @Autowired
    private SetfegService setfegService;

    @Autowired
    private CodetableService codetableService;

    @Autowired
    private SetmodService setmodService;

    @Autowired
    private CounterService counterService;

    @Autowired
    private TrnmodService trnmodService;

    @Autowired
    private TransactionHelpService transactionHelpService;

    @Autowired
    private LiagetService liagetService;

    @Autowired
    private XrtmodService xrtmodService;

    @Autowired
    private CbsRange cbsRange;

    @Autowired
    private Cbsget cbsget;

    @Autowired
    private CbsmodService cbsmodService;

    @Autowired
    private FecMapper fecMapper;

    @Autowired
    private FepMapper fepMapper;

    @Autowired
    private FeeMapper feeMapper;

    @Autowired
    private PtsMapper ptsMapper;

    @Autowired
    private PteMapper pteMapper;

    @Autowired
    private PtyCacheService ptyCacheService;

    @Autowired
    private CbeMapper cbeMapper;

    @Autowired
    private PtsptaToolComponent ptsptaToolComponent;

    @Autowired
    private DyncDaoService dyncDaoService;

    @Autowired
    private AtpBchCacheService atpBchCacheService;

    public boolean isSameObject(String path1, String path2) {
        boolean flag = false;
        SimpleModuleVo simpleModuleVo1 = Utils.toObject(SimpleModuleVo.class, path1);
        SimpleModuleVo simpleModuleVo2 = Utils.toObject(SimpleModuleVo.class, path2);
        if (simpleModuleVo1 != null && simpleModuleVo1.equals(simpleModuleVo2)) {
            flag = true;
        }
        return flag;
    }

    /**
     * source:liaall.0024.script
     */
    public String liaallGetFeecodFucKey(String argBussec, String argCBTPFXlst) {
        //! index of FEECOD in parameter stream for internal use
        //! If setting with Business sector wih LiaallSetFeecodObj is avaialable, take this, otherwise just engagementtype
        //! ArgBussec    :  Busisness sector
        //! ArgCBTPFXlst :  list of engagement types
        String wthBus = NULLSTR;
        String wthOutBus = NULLSTR;
        if (MdaUtils.isEmpty(argCBTPFXlst)) {
            return "";
        } else {
            wthBus = liaallParGet("FEECOD" + "." + argBussec + "D", "COD." + argCBTPFXlst);
            if (!MdaUtils.isEmpty(wthBus)) {
                return "FEECOD" + "." + argBussec + "D";
            } else {
                wthOutBus = liaallParGet("FEECOD", "COD." + argCBTPFXlst);
                if (!MdaUtils.isEmpty(wthOutBus)) {
                    return "FEECOD";
                } else {
                    return "";
                }
            }
        }
        //return  "";
    }

    /**
     * 根据  argFucKey 和 argDtaKey 组合的键，从liallSet中获取对应的KEY ,
     * 如果value 不为空 , 返回value
     * 为空   ,返回""
     **/
    public String liaallParGet(String argFucKey, String argDtaKey) {
        return getLiaallSet().getLiaallStr(argFucKey + TAB + argDtaKey);
    }

    /**
     * 根据  argFucKey 和 argDtaKey 组合的键，从liallSet中获取对应的KEY ,
     * 如果value 不为空 , 返回true
     * 为空   ,返回false
     **/
    public boolean liaallParFound(String argFucKey, String argDtaKey) {
        return getLiaallSet().containLiaallStr(argFucKey + TAB + argDtaKey);
    }

    public void getRelevantDates(LiaallVo liaall, int liaallgIdx, Argument<Date> argbegdat, Argument<Date> argtodat, Argument<String> argWrn) {
        //! get relevant dates for recalculation
        //! (called from  registersettlementLiaZZ )
        int i = liaallgIdx;
        Date begdat = argbegdat.value;
        Date todat = argtodat.value;
        String wrn = argWrn.value;
        Date dat2 = begdat;
        Date lstdat = begdat;
        FecVo wrkFec = liaall.getLiaallg().get(i).getFec();
        // Check if SETDATOLD is in sequence of last settelment dates. If so, use that date
        while (Dates.diff(dat2, liaall.getLiaallg().get(i).getSetdatold()) < 0 && Strings.len(wrkFec.getPertyp()) == 6) {
            lstdat = dat2;
            dat2 = irtcalService.getNextPeriod(begdat, dat2, wrkFec.getPertyp());
        }

        SetRes:
        while (true) {
            if (dat2 == Dates.add(liaall.getLiaallg().get(i).getSetdatold(), 1)) {
                begdat = lstdat;
                break SetRes; //   ####   goto SetRes
            }
            // If not, try to find relevant date from fee pool
            IStream chkStm = new StreamImpl();
            Date fecBegdat = null;
            if (!MdaUtils.isEmpty(wrkFec.getClcdifflg()) && MdaUtils.compareTo(wrkFec.getSettyp(), "A") == 0) {
                begdat = fepMapper.selectMinDat1(liaall.getLiaallg().get(i).getPtegrp().getRec().getInr(), liaall.getLiaallg().get(i).getSetdatold());
            }
            if (MdaUtils.isEmpty(begdat)) {
                todat = NULLDATE;
                wrn = "Recalculation of comission not possible as reference pool entry not found.\\nPlease check manually.";
                break SetRes; //   ####   goto SetRes
            } else {
                todat = Dates.add(liaall.getLiaallg().get(i).getSetdatold(), 0);
            }
            // No recalculation if condition has been changed in settlement period or transaction
            if (!MdaUtils.isEmpty(liaall.getLiaallg().get(i).getFecold())) {
                Streams.streamClear(chkStm);
                Utils.saveData(wrkFec, chkStm, "", "");
                if (MdaUtils.compareTo(MdaUtils.toString(liaall.getLiaallg().get(i).getFecold()), MdaUtils.toString(chkStm)) != 0) {
                    wrn = Strings.getText("Condition for $1 is changed in this transaction.\\nPlease recalculate manually, if necessary", liaall.getLiaallg().get(i).getFeecod());
                    break SetRes; //   ####   goto SetRes
                } else {
                    fecBegdat = fecMapper.selectBegDat(liaall.getLiaallg().get(i).getPtegrp().getRec().getInr(), begdat, todat);
                    if (!MdaUtils.isEmpty(fecBegdat)) {
                        wrn = Strings.getText(("Condition for $1 has been changed in recalculation period.\\nPlease recalculate manually, if necessary"), liaall.getLiaallg().get(i).getFeecod());
                        break SetRes; //   ####   goto SetRes
                    }
                }
            }
            break SetRes;
        }
        //    ####    label SetRes
        argbegdat.value = begdat;
        argtodat.value = todat;
        argWrn.value = wrn;
    }

    @Override
    public BigDecimal getTensetamt() {
        //TODO
        return null;
    }

    public LiaallSet getLiaallSet() {
        return transactionHelpService.getLiaallSet();
    }

    /**
     * <p>  主要调用流程
     * <pre>
     *       交易中的注册
     *      liaallRegister(liaallVo);
     *
     *      defaultcancel(liaallVo);
     *
     *   </pre>
     *
     * @param liaallVo
     */
    public void assertLIAALL(LiaallVo liaallVo) {
        //! 1. after the initial default of transaction (via post in init)
        //! 2. when the liability panel or an DetailsPanel is entered
        //! 3. if LiaallSetCircular is called when changing amounts or types in liabilities
        //! 4. the settlement-Panel is entered
        //! 5. The selected tenor is changed
        //! 6. The settled amount is changed in settlement
        //! 7. The missing amount is added to a line
        //! 8. at saving of the transaction
        //1.交易包含多个业务品种，需要注册其他业务模型SimpleModule，放在这里实现
        liaallRegisterModule(liaallVo);
        //2.后手交易根据PTE数据和注册信息build Liaallg
        boolean getOldProcess = false;
        if (StringUtils.isEmpty(liaallVo.getOldredflg())) {
            getold(liaallVo);
            liaallVo.setOldredflg("X");
            getOldProcess = true;
        }
        //3.各交易注册
        liaallRegister(liaallVo);
        //4.tenor settle stream处理
        if (getOldProcess) {
            fillTENSTM(liaallVo);
        }
        liaallSetTenorFields(liaallVo);
        // set amount of selected tenor
        //setTensetamt
        // default cancel amounts if necessary
        defaultcancel(liaallVo);
        // parsing parameter stream and handling keywords
        List<LiaallRegisterVo> liaallRegisters = getLiaallSet().getLiaallRegisters();
        //如果其中一条LiaallRegisterVo的金额不等于0，newcbeflg=true
        boolean newcbeflg = false;
        for (LiaallRegisterVo liaallRegisterVo : liaallRegisters) {
            if (liaallRegisterVo.getNewAmt().compareTo(BigDecimal.ZERO) != 0) {
                newcbeflg = true;
                break;
            }
        }
        boolean doExpand = false;
        //编译交易注册的LiaallRegisterVo集合，生成对应的Liaallg
        for (LiaallRegisterVo liaallRegisterVo : liaallRegisters) {
            String dbtrol = liaallRegisterVo.getDbtrol();
            String cur = liaallRegisterVo.getCur();
            BigDecimal amt = liaallRegisterVo.getNewAmt();
            BigDecimal thisamt = amt;
            if (liaallParFound("REDPLN", "CNV")) {
                for (int r = 0; r < liaallVo.getLiaallr().size(); r++) {
                    amt = Decimals.add(amt, liaallVo.getLiaallr().get(r).getAmt());
                }
            }
            String cbtpfx = liaallRegisterVo.getCbtpfx();
            SimpleModuleVo linkModule = liaallRegisterVo.getLinkModule();
            String linkObjModPath = Utils.toJson(linkModule);
            String grpKey = liaallRegisterVo.getGrpKey();
            List<String> rolStm = new ArrayList<>();
            rolStm.add(dbtrol);
            rolStm.addAll(liaallRegisterVo.getOthrol());
            List<String> cdtrolStm = liaallRegisterVo.getCdtrol();
            if (amt.compareTo(BigDecimal.ZERO) != 0 || liaallParFound("ENABLE", "")) {
                for (int g = 0; g < liaallVo.getLiaallg().size(); g++) {
                    LiaallgVo liaallgVo = liaallVo.getLiaallg().get(g);
                    if (grpKey.equals(liaallgVo.getGrpkey())
                            && isSameObject(liaallgVo.getObjmodpath(), linkObjModPath)){
                            //&& !MdaUtils.isEmpty(liaallVo.getRoldsc())) {
                        if (!rolStm.contains(liaallgVo.getRol())) {
                            if (liaallgVo.getOldamt().compareTo(BigDecimal.ZERO) == 0) {
                                liaallgVo.setRol(NULLSTR);
                                liaallgVo.setCdtrol(NULLSTR);
                                liaallgVo.setAmt(new BigDecimal(0));
                                liaallgVo.setOldamt(new BigDecimal(0));
                                liaallgVo.setTenpct(new BigDecimal(0));
                                liaallgVo.getAcplia().getCbe().setCur(NULLSTR);
                            } else {
                                liaallgVo.setAmt(liaallgVo.getOldamt().negate());
                                liaallgVo.setOldflg("R");
                                amt = Decimals.add(amt, liaallgVo.getAmt());
                            }
                        } else {
                            if ("R".equals(liaallgVo.getOldflg())) {
                                liaallgVo.setOldflg("X");
                                liaallgVo.setAmt(BigDecimal.ZERO);
                            }
                            amt = Decimals.sub(amt, liaallgVo.getAmt());
                            liaallgVo.getAcplia().getCbe().setCur(cur);
                        }
                    }
                }
                int fnd = -1;
                boolean allin = false;
                for (int g = 0; g < liaallVo.getLiaallg().size(); g++) {
                    LiaallgVo liaallgVo = liaallVo.getLiaallg().get(g);
                    if (liaallgVo.getAmt().compareTo(BigDecimal.ZERO) == 0 && liaallgVo.getOldamt().compareTo(BigDecimal.ZERO) == 0 && fnd == -1) {
                        fnd = g;
                    }
                    if (StringUtils.isEmpty(liaallgVo.getRol()) && StringUtils.isEmpty(liaallgVo.getOldflg()) && fnd == -1) {
                        fnd = g;
                    }
                    if (grpKey.equals(liaallgVo.getGrpkey()) && isSameObject(liaallgVo.getObjmodpath(), linkObjModPath)
                            && StringUtils.isNotEmpty(liaallgVo.getRol())
                            && rolStm.contains(liaallgVo.getRol())) {
                        if (liaallCBTPFXIsBalance(cbtpfx) || StringUtils.isEmpty(liaallgVo.getOldflg()) || liaallParFound("ENABLE.AMTFLG", "*")) {
                            allin = true;
                            liaallgVo.getAcplia().getCbe().setCur(cur);
                            liaallgVo.setCbtpfxlst(cbtpfx);
                        }
                    }
                }
                if (!allin) {
                    if (amt.compareTo(BigDecimal.ZERO) != 0) {
                        if (fnd == -1) {
                            LiaallgVo liaallgVo = new LiaallgVo();
                            liaallgVo.reset();
                            liaallVo.getLiaallg().add(liaallgVo);
                            fnd = liaallVo.getLiaallg().size() - 1;
                        }
                        liaallVo.getLiaallg().get(fnd).setRol(rolStm.get(0));
                        liaallVo.getLiaallg().get(fnd).setTenpct(new BigDecimal("100"));
                        liaallVo.getLiaallg().get(fnd).getAcplia().getCbe().setCur(cur);
                        liaallVo.getLiaallg().get(fnd).setAmt(Decimals.add(amt, liaallVo.getLiaallg().get(fnd).getAmt()));
                        liaallVo.getLiaallg().get(fnd).setExtid(Strings.getLine(cbtpfx, 1) + "/" + linkModule.getObjtyp());
                        liaallVo.getLiaallg().get(fnd).setObjmodpath(linkObjModPath);
                        liaallVo.getLiaallg().get(fnd).getAcplia().getCbe().setExtid(liaallVo.getLiaallg().get(fnd).getExtid());
                        liaallVo.getLiaallg().get(fnd).setCbtpfxlst(cbtpfx);
                        liaallVo.getLiaallg().get(fnd).setGrpkey(grpKey);
                        liaallVo.getLiaallg().get(fnd).setCbtpfx(Strings.getLine(cbtpfx, 1));
                        liaallVo.getLiaallg().get(fnd).getAcplia().setCbtpfx(Strings.getLine(cbtpfx, 1));
                    }
                }
            } else {
                for (int g = 0; g < liaallVo.getLiaallg().size(); g++) {
                    LiaallgVo liaallgVo = liaallVo.getLiaallg().get(g);
                    if (grpKey.equals(liaallgVo.getGrpkey())
                            && isSameObject(liaallgVo.getObjmodpath(), linkObjModPath)
                            && StringUtils.isNotEmpty(liaallgVo.getRol())
                            && rolStm.contains(liaallgVo.getRol())) {
                        // check if there are auto-booked-out-lines for group
                        boolean revFnd = false;
                        for (int revidx = 0; revidx < liaallVo.getLiaallg().size(); revidx++) {
                            LiaallgVo revLiaallg = liaallVo.getLiaallg().get(revidx);
                            switch (revLiaallg.getOldflg()) {
                                case "C":
                                case "R":
                                    if (grpKey.equals(revLiaallg.getGrpkey())) {
                                        revFnd = true;
                                    }
                                    break;
                            }
                        }
                        // if so, do not clear line
                        if (!revFnd) {
                            liaallgVo.setAmt(BigDecimal.ZERO);
                            liaallgVo.setAmt2(BigDecimal.ZERO);
                            liaallgVo.resetModified("amt");
                            if (liaallgVo.getOldamt().compareTo(BigDecimal.ZERO) == 0) {
                                liaallgVo.setBussec(NULLSTR);
                                liaallgVo.setRol(NULLSTR);
                                liaallgVo.setCdtrol(NULLSTR);
                                liaallgVo.setMatdat(null);
                                liaallgVo.resetModified("matdat");
                                liaallgVo.setCur(NULLSTR);
                                liaallgVo.setAmt(new BigDecimal(0));
                                liaallgVo.setNam(NULLSTR);
                                liaallgVo.setAcc(NULLSTR);
                                liaallgVo.setBussec(NULLSTR);
                                liaallgVo.setObjmodpath(NULLSTR);
                                liaallgVo.setCbtpfx(NULLSTR);
                                liaallgVo.setCbtpfxlst(NULLSTR);
                            }
                        }
                    }
                }
            }
            for (int g = 0; g < liaallVo.getLiaallg().size(); g++) {
                LiaallgVo liaallgVo = liaallVo.getLiaallg().get(g);
                if (liaallgVo.getAmt().compareTo(BigDecimal.ZERO) == 0 || StringUtils.isNotEmpty(liaallgVo.getOldflg())) {
                    //Systems.resetEnabled(this.getLiaallg().getElement(g),"rol");
                    //Systems.resetEnabled(this.getLiaallg().getElement(g),"cdtrol");
                    if (StringUtils.isEmpty(liaallgVo.getOldflg()) && (grpKey.equals(liaallgVo.getGrpkey()) || rolStm.size() < 2)) {
                        liaallgVo.setRol(NULLSTR);
                        liaallgVo.setCdtrol(NULLSTR);
                    }
                } else {
                    if (grpKey.equals(liaallgVo.getGrpkey())
                            && isSameObject(liaallgVo.getObjmodpath(), linkObjModPath)
                            && rolStm.contains(liaallgVo.getRol())) {
                        switch (rolStm.size()) {
                            case 0:
                                liaallgVo.setRol(NULLSTR);
                                //Systems.resetEnabled(this.getLiaallg().getElement(g),"rol");
                                break;
                            case 1:
                                liaallgVo.setRol(rolStm.get(0));
                                //Systems.resetEnabled(this.getLiaallg().getElement(g),"rol");
                                break;
                            default:
                                liaallgVo.setRol(rolStm.get(0));
                                /*Systems.setValues(this.getLiaallg().getElement(g),"rol",rol);
                                if( MdaUtils.isEmpty(this.getLiaallg().getElement(g).getOldflg()) )
                                {
                                    Systems.setEnabled(this.getLiaallg().getElement(g),"rol");
                                }
                                else
                                {
                                    Systems.resetEnabled(this.getLiaallg().getElement(g),"rol");
                                }*/
                        }
                    }
                    if (grpKey.equals(liaallgVo.getGrpkey()) && isSameObject(liaallgVo.getObjmodpath(), linkObjModPath)) {
                        if (cdtrolStm.size() == 0) {
                            liaallgVo.setCdtrol(NULLSTR);
                            //Systems.resetEnabled(this.getLiaallg().getElement(g),"cdtrol");
                        } else {
                            //Systems.setValues(this.getLiaallg().getElement(g),"cdtrol",MdaUtils.toString(cdtval));
                            if (!liaallgVo.isModified("cdtrol")) {
                                liaallgVo.setCdtrol(cdtrolStm.get(0));
                            }
                            /*if( stmCNtCdtRol == 1 )
                            {
                                Systems.resetEnabled(this.getLiaallg().getElement(g),"cdtrol");
                            }
                            else
                            {
                                Systems.setEnabled(this.getLiaallg().getElement(g),"cdtrol");
                            }*/
                        }
                        liaallgVo.setCbtpfxlst(cbtpfx);
                    }
                }
            }
            if ((thisamt.compareTo(BigDecimal.ZERO) != 0 || liaallParFound("ENABLE", "")) && liaallParFound("ALLA", "")) {
                // check, if there is a line for all applicants (if necessary, create it)
                // only if a change amount is set or an old amount is avalable
                if (thisamt.compareTo(BigDecimal.ZERO) != 0) {
                    doExpand = true;
                } else {
                    doExpand = false;
                    for (int g = 0; g < liaallVo.getLiaallg().size(); g++) {
                        if (liaallVo.getLiaallg().get(g).getOldamt().compareTo(BigDecimal.ZERO) != 0
                                && grpKey.equals(liaallVo.getLiaallg().get(g).getGrpkey())) {
                            doExpand = true;
                        }
                    }
                }
                if (doExpand) {
                    for (int rolidx = 0; rolidx < rolStm.size(); rolidx++) {
                        boolean isin = false;
                        int free = -1;
                        for (int grdIdx = 0; grdIdx < liaallVo.getLiaallg().size(); grdIdx++) {
                            LiaallgVo liaallgVo = liaallVo.getLiaallg().get(grdIdx);
                            if (free == -1 && StringUtils.isEmpty(liaallgVo.getRol()) && StringUtils.isEmpty(liaallgVo.getOldflg())) {
                                free = grdIdx;
                            }
                            if (liaallgVo.getRol().equals(rolStm.get(rolidx))
                                    && grpKey.equals(liaallgVo.getGrpkey())) {
                                isin = true;
                            }
                        }
                        if (!isin) {
                            if (free == -1) {
                                LiaallgVo liaallgVo = new LiaallgVo();
                                liaallgVo.reset();
                                liaallVo.getLiaallg().add(liaallgVo);
                                free = liaallVo.getLiaallg().size() - 1;
                            }
                            liaallVo.getLiaallg().get(free).setRol(rolStm.get(rolidx));
                            liaallVo.getLiaallg().get(free).setCbtpfxlst(cbtpfx);
                            liaallVo.getLiaallg().get(free).getAcplia().getCbe().setCur(cur);
                            liaallVo.getLiaallg().get(free).setExtid(Strings.getLine(cbtpfx, 1) + "/" + linkModule.getObjtyp());
                            liaallVo.getLiaallg().get(free).setObjmodpath(linkObjModPath);
                            liaallVo.getLiaallg().get(free).getAcplia().getCbe().setExtid(liaallVo.getLiaallg().get(free).getExtid());
                            liaallVo.getLiaallg().get(free).setCbtpfx(Strings.getLine(cbtpfx, 1));
                            liaallVo.getLiaallg().get(free).getAcplia().setCbtpfx(Strings.getLine(cbtpfx, 1));
                            liaallVo.getLiaallg().get(free).setGrpkey(grpKey);
                            /*Systems.setValues(this.getLiaallg().getElement(free),"rol",rol);
                            if( stmCntRol > 1 )
                            {
                                Systems.setEnabled(this.getLiaallg().getElement(free),"rol");
                            }
                            else
                            {
                                Systems.resetEnabled(this.getLiaallg().getElement(free),"rol");
                            }*/
                            setDefaultPart(liaallVo.getLiaallg().get(free), rolStm.get(0), thisamt, liaallVo);
                        }
                    }
                }
            }
        }
        // check accounts of old entries
        internalCheckOldAccountsAndMov(liaallVo);
        // do distribution
        internalDistrib(liaallVo);
        // do distribution of external amounts
        internalDistribExtamt(liaallVo);
        // get CONCUR from contract amount
        String doccur = "";
        Cbb maxcbb = liaallVo.getCbsMap().get("OPN1");
        if (maxcbb != null) {
            doccur = maxcbb.getCur();
        } else {
            doccur = xrtmodService.sysiso();
        }
        liaallVo.setConcur(doccur);
        // prepare setting of concur by liaallg-entries
        String conCur = "";
        boolean concurVld = true;
        // postprocessing
        IStream cbtPfxstm = new StreamImpl();
        String ptyinr = NULLSTR;
        String ptainr = NULLSTR;
        for (int i = 0; i < liaallVo.getLiaallg().size(); i++) {
            LiaallgVo liaallgVo = liaallVo.getLiaallg().get(i);
            if (StringUtils.isNotEmpty(liaallgVo.getCur())) {
                if (StringUtils.isEmpty(conCur)) {
                    conCur = liaallgVo.getCur();
                } else {
                    if (conCur.equals(liaallgVo.getCur())) {
                        concurVld = false;
                    }
                }
            }

            //liaallg nam属性赋值
            if (StringUtils.isNotEmpty(liaallgVo.getLiaptyinr())) {
                Pty pty = ptyCacheService.getPtyById(liaallgVo.getLiaptyinr());
                if (pty != null) {
                    liaallgVo.setNam(pty.getNam());
                }
            }
            liaallgVo.setDbtrolSet(new ArrayList<>());
            liaallgVo.setCdtrolSet(new ArrayList<>());
            boolean find = false;
            for (CodetableItem role : liaallVo.getRoldsc()) {
                if (liaallgVo.getRol().equals(role.getValue())) {
                    find = true;
                    if (StringUtils.isEmpty(liaallgVo.getNam())) {
                        liaallgVo.setNam(role.getLabel());
                    }
                    break;
                }
            }
            // if role is in settlement role stream, take names from settlement
            if (!find) {
                liaallgVo.getDbtrolSet().add(new CodetableItem(codetableService.getTblLabel(liaallgVo.getRol(), "ROLALL"), liaallgVo.getRol()));
            }
            liaallVo.getRoldsc().forEach(role -> liaallgVo.getDbtrolSet().add(role));
            /*if( MdaUtils.compareTo(this.getLiaallg().getElement(i).getAmt(),0) == 0 || MdaUtils.isEmpty(this.getLiaallg().getElement(i).getCdtrol()) )
            {
                Systems.resetEnabled(this.getLiaallg().getElement(i),"cdtrol");
            }*/
            liaallVo.getRoldsc().forEach(role -> liaallgVo.getCdtrolSet().add(role));
            liaallgVo.getAcplia().getCbe().setAmt(Decimals.sub(liaallgVo.getAmt(), liaallgVo.getExtamt()));
            liaallgVo.getAcplia().getCbe().setAcc(liaallgVo.getAcc());
            liaallgVo.getAcplia().getCbe().setAcc2(liaallgVo.getAcc2());
            liaallgVo.getAcplia().setCbtpfx(liaallgVo.getCbtpfx());
            if (StringUtils.isNotEmpty(liaallgVo.getGrpkey())) {
                String cbtpfxlst = liaallParGet("SETCBTPFX", liaallgVo.getGrpkey());
                if (StringUtils.isNotEmpty(cbtpfxlst)) {
                    liaallgVo.setCbtpfxlst(cbtpfxlst);
                }
            }
            if (StringUtils.isEmpty(liaallgVo.getOldflg()) && liaallgVo.getAmt().compareTo(BigDecimal.ZERO) != 0) {
                Streams.streamSet(cbtPfxstm, liaallgVo.getCbtpfxlst());
                switch (Streams.streamCount(cbtPfxstm)) {
                    case 0:
                        //Systems.resetEnabled(this.getLiaallg().getElement(i),"cbtpfx");
                        break;
                    case 1:
                        //Systems.resetEnabled(this.getLiaallg().getElement(i),"cbtpfx");
                        liaallgVo.setCbtpfx(liaallgVo.getCbtpfxlst());
                        liaallgVo.resetModified("cbtpfx");
                        break;
                    default:
                        //Systems.setEnabled(this.getLiaallg().getElement(i),"cbtpfx");
                        if (Streams.streamSearch(cbtPfxstm, liaallgVo.getCbtpfx()) == 0
                                || !liaallgVo.isModified("cbtpfx")) {
                            liaallgVo.setCbtpfx(Strings.getLine(cbtPfxstm, 1));
                            liaallgVo.resetModified("cbtpfx");
                        }
                }
            }
            if (StringUtils.isNotEmpty(liaallgVo.getObjmodpath())) {
                SimpleModuleVo simpleModuleVo = Utils.toObject(SimpleModuleVo.class, liaallgVo.getObjmodpath());
                if (simpleModuleVo != null) {
                    liaallgVo.setBussec(simpleModuleVo.getObjtyp().substring(0, 2));
                }
            }
            if (StringUtils.isEmpty(liaallgVo.getOldflg())) {
                if (StringUtils.isEmpty(liaallgVo.getCovtyp())) {
                    liaallgVo.setExtid(liaallgVo.getCbtpfx() + "/" + liaallgVo.getBussec());
                } else {
                    liaallgVo.setExtid(liaallgVo.getCbtpfx() + "/" + liaallgVo.getBussec() + "/" + liaallgVo.getCovtyp());
                }
                liaallgVo.getAcplia().getCbe().setExtid(liaallgVo.getExtid());
                // set party from settlement parties for new entries
                ptyinr = "";
                ptainr = "";
                Argument<String> ptyinrBox = new Argument<String>("", ptyinr);
                Argument<String> ptainrBox = new Argument<String>("", ptainr);
                getPtyinrAndPtainr(liaallVo, ptyinrBox, ptainrBox, liaallgVo.getRol());
                ptyinr = ptyinrBox.value;
                ptainr = ptainrBox.value;
                liaallgVo.setLiaptyinr(ptyinr);
            }
            if (!liaallParFound("FeeOnePerMatdat-", liaallgVo.getCbtpfx()) || liaallgVo.getMatdat() == null) {
                liaallgVo.setFeehndidx(0);
            } else {
                if (liaallgVo.getFeehndidx() > 0) {
                    int myrow = liaallgVo.getFeehndidx();
                    if (liaallVo.getLiaallg().get(myrow).getFeehndidx() > 0 || liaallgVo.getMatdat() != liaallVo.getLiaallg().get(myrow).getMatdat()
                            || !liaallgVo.getCbtpfx().equals(liaallVo.getLiaallg().get(myrow).getCbtpfx())) {
                        liaallgVo.setFeehndidx(0);
                    }
                } else {
                    for (int j = 0; j < liaallVo.getLiaallg().size(); j++) {
                        if (i != j && liaallgVo.getMatdat() == liaallVo.getLiaallg().get(j).getMatdat()
                                && liaallgVo.getCbtpfx().equals(liaallVo.getLiaallg().get(j).getCbtpfx())
                                && liaallVo.getLiaallg().get(j).getFeehndidx() == 0) {
                            liaallVo.getLiaallg().get(j).setFeehndidx(i);
                        }
                    }
                }
            }
            //执行Liaallg的default rule
            liaallgService.defaultAmtchgflg(liaallgVo);
            liaallgService.defaultAcpliaLiaptyinr(liaallgVo);
            liaallgService.defaultExtid(liaallgVo);
            liaallgService.defaultNam(liaallgVo);
            liaallgService.defaultPtegrpRecBegdat(liaallgVo);
            liaallgService.defaultPtegrpRecRolpay(liaallVo, liaallgVo);
            liaallgService.defaultPtegrpRecExtid(liaallgVo);
            liaallgService.defaultPtegrpRecSubid(liaallVo, liaallgVo);
            liaallgService.defaultDftfeecod(liaallgVo);
            liaallgService.defaultFeecod(liaallgVo);
            liaallgService.defaultFee(liaallgVo);
            liaallgService.defaultCur(liaallgVo);
            liaallgService.calcValdat(liaallgVo, liaallVo);
            liaallgService.calcMatdat(liaallgVo);
            liaallgService.calcFec(liaallgVo, liaallVo);
            liaoneService.defaultCbeAcc(liaallgVo.getAcplia());
            liaallgService.defaultAcc(liaallgVo);
            liaoneService.defaultActrec(liaallgVo.getAcplia());
            liaoneService.defaultCbeAcc2(liaallgVo.getAcplia());
            liaoneService.defaultCbeXrfCurAmt(liaallgVo.getAcplia());
            liaallgService.defaultAcc2(liaallgVo);
            liaallgService.setLiaallgInfo4Setmod(liaallgVo);
            liaallgService.defaultAcpliaCbeDat(liaallgVo);
            liaallgService.defaultTenday(liaallgVo);
            liaallgService.defaultMatdat(liaallVo, liaallgVo);
            liaallgService.defaultTrntyp(liaallVo, liaallgVo);
        }
        // clear lines without old amount if not amount is changed or amount enabled
        if (!newcbeflg) {
            for (int i = 0; i < liaallVo.getLiaallg().size(); i++) {
                LiaallgVo liaallgVo = liaallVo.getLiaallg().get(i);
                if (liaallgVo.getOldamt().compareTo(BigDecimal.ZERO) == 0 && liaallgVo.getAmt().compareTo(BigDecimal.ZERO) == 0) {
                    if (!enableAmountZero(liaallgVo.getCbtpfx()) || StringUtils.isEmpty(liaallgVo.getCbtpfx())) {
                        liaallgVo.setBussec(NULLSTR);
                        liaallgVo.setRol(NULLSTR);
                        //Systems.resetEnabled(this.getLiaallg().getElement(i),"rol");
                        liaallgVo.setCdtrol(NULLSTR);
                        //Systems.resetEnabled(this.getLiaallg().getElement(i),"cdtrol");
                        liaallgVo.setCur(NULLSTR);
                        liaallgVo.setAmt(new BigDecimal(0));
                        liaallgVo.setNam(NULLSTR);
                        liaallgVo.setAcc(NULLSTR);
                        liaallgVo.setBussec(NULLSTR);
                        liaallgVo.setObjmodpath(NULLSTR);
                        liaallgVo.setCbtpfx(NULLSTR);
                        liaallgVo.setCbtpfxlst(NULLSTR);
                        //cgl for GITCAN
                        liaallgVo.getAcplia().getCbe().setCur(NULLSTR);
                    }
                }
            }
        }
        //清掉金额为0 rol为空 cbtpfx为空的数据
        List<String> removeIds = new ArrayList<>();
        for (int i=0; i<liaallVo.getLiaallg().size(); i++) {
            LiaallgVo liaallgVo = liaallVo.getLiaallg().get(i);
            if (liaallgVo.getAmt().compareTo(BigDecimal.ZERO) == 0
                && liaallgVo.getOldamt().compareTo(BigDecimal.ZERO) == 0){
                //&& StringUtils.isEmpty(liaallgVo.getRol())) {
                removeIds.add(String.valueOf(i));
            }
        }
        if (removeIds.size() > 0) {
            for (int i=removeIds.size()-1; i>=0; i--) {
                liaallVo.getLiaallg().remove(Integer.parseInt(removeIds.get(i)));
            }
        }
        // if contract amounts are not available yet, set CONCUR from currency of booking lines (if not ambigous)
        if (StringUtils.isEmpty(liaallVo.getConcur()) && concurVld) {
            liaallVo.setConcur(conCur);
        }
        fillAcceptLine(liaallVo);
        //由于更改了即远期，且增减额，会出现misamt，老国结采用ADD CURRENT LINE，新国结默认处理到新的line
        this.processMisamt(liaallVo);
    }


    public boolean enableAmountZero(String cbtpfx) {
        //! checks, if amount zero should be enabled for cbtpfx.
        //! for internal use only (but method as to be called by liaallg)
        String amtFlg = liaallParGet("ENABLE.AMTFLG", cbtpfx);
        if (MdaUtils.isEmpty(amtFlg)) {
            amtFlg = liaallParGet("ENABLE.AMTFLG", "*");
        }
        if (MdaUtils.compareTo(amtFlg, "*") == 0) {
            return true;
        } else {
            return false;
        }
    }

    private void defaultcancel(LiaallVo liaallVo) {
        //! internal: all engagement stored for that module have to be booked out
        SimpleModuleVo cancelModule = getLiaallSet().getCancelModule();
        if (cancelModule != null) {
            liaallVo.getLiaallg().forEach(liaallgVo -> {
                if (liaallgVo.getOldamt().compareTo(BigDecimal.ZERO) != 0) {
                    if ("C".equals(liaallgVo.getAmtchgflg())) {
                        liaallgVo.setAmt(BigDecimal.ZERO);
                        liaallgVo.setAmtchgflg("");
                    }
                    if (cancelModule.equals(Utils.toObject(SimpleModuleVo.class, liaallgVo.getObjmodpath()))) {
                        liaallgVo.setAmt(liaallgVo.getOldamt().negate());
                        liaallgVo.setTenpct(new BigDecimal("100"));
                        liaallgVo.setAmtchgflg("C");
                    }
                }
            });
        } else {
            liaallVo.getLiaallg().forEach(liaallgVo -> {
                if ("C".equals(liaallgVo.getAmtchgflg())) {
                    liaallgVo.setAmt(BigDecimal.ZERO);
                    liaallgVo.setAmtchgflg("");
                }
            });
        }
    }

    /**
     * 交易包含多个业务品种，需要注册其他业务模型SimpleModule，放在这里实现
     */
    private void liaallRegisterModule(LiaallVo liaallVo) {
        //按照交易码，获取注册Spring的交易Bean
        String transName = SettleContext.getTransName();
        try {
            ILiaallRegisterModule liaallRegisterModule = SpringEnvContext.getBean(atpBchCacheService.getSdTransNameForRegister().toLowerCase() + "." + "liaallRegisterModule");
            liaallRegisterModule.registerModule(liaallVo);
        } catch (NoSuchBeanDefinitionException e) {
           log.warn("交易 {} 不需要注册其他业务模型SimpleModule", transName);
        }
    }

    /**
     * 清空PARSTM 流中的数据，清空 LIAALL缓存
     * 按行遍历Liasetmetstm 流，通过反射 调用每行的方法
     * 为PARSTM赋值
     **/
    private void liaallRegister(LiaallVo liaallVo) {
        //! recreates parameter stream by posting all liaallset-methods
        //! The names of all subs setting parameters for LIAALL have to start with liaallset
        //! CAUTION: As the names are loaded at the beginning of transaction, the transaction has to be reloaded.
        //getLiaallSet().clearLiaall();
        //按照交易码，获取注册Spring的交易Bean
        String transName = SettleContext.getTransName();
        try {
            ILiaallRegister liaallRegister = SpringEnvContext.getBean(atpBchCacheService.getSdTransNameForRegister().toLowerCase() + "." + "liaallSetTransaction");
            liaallRegister.liaallSetTransaction(liaallVo);
        } catch (NoSuchBeanDefinitionException e) {
            throw new CommonServiceException("没有找到交易注册类");
        }
    }

    public void liaallSetFeeOnePerMatdat(String cbtpfx) {
        //! to be called, if teh fee requested by LiaallSetFeecod is to be defaulted only once for each MATDAT, even if there is more than one entry (e.g. for different accounts)
        //! If called the comission suppanel is activated only in one entry per maturity date.
        //! CBTPFX: Prefix for wich commission shall be de defaulted only once
//        liaallParSet( "X", "FeeOnePerMatdat", cbtpfx );
//        liaallParSet( "X", "FeeOnePerMatdat", "" );
        LiaallSet liaallSet = getLiaallSet();
        liaallSet.putLiaallStr("FeeOnePerMatdat" + TAB + cbtpfx, "X");
        liaallSet.putLiaallStr("FeeOnePerMatdat" + TAB, "X");

    }

    /**
     * 根据  argFucKey 和 argDtaKey 组合的键、argValue为值，往LiallSet中放入数据
     **/
    public void liaallParSet(String argValue, String argFucKey, String argDtaKey) {
        LiaallSet liaallSet = getLiaallSet();
        liaallSet.putLiaallStr(argFucKey + TAB + argDtaKey, argValue);
    }

    public void setDefaultPart(LiaallgVo liaallgfee, String mainrole, BigDecimal thisamt, LiaallVo liaallVo) {
        // moves amount from amount of mainrole to new line newidx according to part in original CBTPFX as defined by LiaallSetRefOld
        String cbtPfx = liaallParGet("SETREFOLD", "CBTPFX");
        // no definition by  LiaallSetRefOld => nothing to do
        if (MdaUtils.isEmpty(cbtPfx)) {
            return;
        }
        // CBT of newidx is not the one of  LiaallSetRefOld => nothing to do
        if (MdaUtils.compareTo(liaallgfee.getCbtpfx(), cbtPfx) != 0) {
            return;
        }
        String mod = liaallParGet("SETREFOLD", "MOD");
        String refCbtPfx = liaallParGet("SETREFOLD", "REFCBTPFX");
        String refmod = liaallParGet("SETREFOLD", "REFMOD");
        // Module of newidx is not the one of  LiaallSetRefOld => nothing to do
        if (!isSameObject(liaallgfee.getObjmodpath(), mod)) {
            return;
        }
        // do not move, if amount or percentage has been modified
        if (liaallgfee.isModified("amt") || liaallgfee.isModified("tenpct")) {
            return;
        }
        // line of mainrole
        int mainidx = 0;
        // sum of all old amounts of reference cbt/mod
        BigDecimal oldallamt = new BigDecimal("0");
        // old amount of newdix role in reference cbt/mod
        BigDecimal oldrolamt = new BigDecimal("0");
        // search loop
        int gridcnt = liaallVo.getLiaallg().size();
        for (int i = 0; i < gridcnt; i++) {
            LiaallgVo liaallgvO = liaallVo.getLiaallg().get(i);
            // set line of mainrole
            if (isSameObject(liaallgvO.getObjmodpath(), mod) && MdaUtils.compareTo(liaallgvO.getCbtpfx(), cbtPfx) == 0 &&
                    MdaUtils.compareTo(liaallgvO.getRol(), mainrole) == 0) {
                mainidx = i;
            }
            // add old amounts of reference entries
            if (isSameObject(liaallgvO.getObjmodpath(), refmod) && MdaUtils.compareTo(liaallgvO.getCbtpfx(), refCbtPfx) == 0) {
                oldallamt = Decimals.add(oldallamt, liaallgvO.getOldamt());
                if (MdaUtils.compareTo(liaallgvO.getRol(), liaallgfee.getRol()) == 0) {
                    oldrolamt = Decimals.add(oldrolamt, liaallgvO.getOldamt());
                }
            }
        }
        LiaallgVo liaallgMax = liaallVo.getLiaallg().get(mainidx);
        // do not move, if amount or percentage has been modified
        if (liaallgMax.isModified("amt") || liaallgMax.isModified("tenpct")) {
            return;
        }
        // move amount
        BigDecimal amt = null;
        BigDecimal tenpct = null;
        if (mainidx > 0 && MdaUtils.compareTo(oldallamt, 0) != 0) {
            /**
             * 读取TDPARA.INI 配置文件中的CURRENCY  ，写入XrtmodVO的Currndinf 字段
             * 根据当前列的币种liaallgfee.getCur() ，查找Currndinf （即配置文TDPARA.INI 中的CURRENCY ） 截取末尾的数字作为小数保留位
             *
             * 改造，直接读取TDPARA.INI 配置文件中的CURRENCY ，根据当前列的币种liaallgfee.getCur() 查找对应末尾数字 作为数保留位
             **/
            amt = xrtmodService.amtRnd(Decimals.mul(thisamt, (Decimals.div(oldrolamt, oldallamt))), liaallgfee.getCur());
            tenpct = Numerics.round(Decimals.div(Decimals.mul(amt, 100), thisamt), 3);
            liaallgfee.setAmt(amt);
            liaallgfee.setTenpct(tenpct);
            liaallgMax.setAmt(Decimals.sub(liaallgMax.getAmt(), amt));
            liaallgMax.setTenpct(Decimals.sub(liaallgMax.getTenpct(), tenpct));
        }

    }

    /**
     * 读取TDPARA.INI 配置文件中的CURRENCY ，根据当前列的币种liaallgfee.getCur() 查找对应末尾数字 作为数保留位
     * 每次调用都会重新读取 ，---------------------------------------------------------------------------------待优化
     **/
    public boolean liaallCBTPFXIsBalance(String cbtpfx) {
        //! for internal use only
        //! returns true, if CBTPFX is a balance, which may be changed later
        //! returns false, if it is a usance position for which the only allowed action after creation is to remove it completely
        String usanceCbtpfxLst = "DPU" + CR + "DPZ" + CR + "AKZ";
//        if( Strings.searchBlock(liagetService.trnmodGetUsanceCbtpfxLst(),cbtpfx) > 0 )
        if (Strings.searchBlock(usanceCbtpfxLst, cbtpfx) > 0) {
            return false;
        } else {
            return true;
        }

    }

    public void internalCheckOldAccountsAndMov(LiaallVo liaallVo) {
        //! Check if lines are to be moved to new line because of
        //! a) account is not longer available and HasOldAccountToBeValid is set or
        //! b) move is necessary because of transfer (LiallSetMoveAmounts called for role)
        int gridcnt = liaallVo.getLiaallg().size();
        for (int i = 0; i < gridcnt; i++) {
            LiaallgVo liaallg = liaallVo.getLiaallg().get(i);
            String movTyp = "";
            String newrol = liaallg.getRol();
            String availAcc = "";
            // Check if move is necessary
            // MovTyp = "A" if account is not longer valid
            if (!MdaUtils.isEmpty(liaallg.getAcc()) && liaallgService.hasOldAccountToBeValid(liaallg)) {
                movTyp = "A";
            }
            // MovTyp = "M" if amounts for role have to move because of LiallSetMoveAmounts
            if (StringUtils.isNotEmpty(liaallg.getRol()) && liaallg.getOldamt().compareTo(BigDecimal.ZERO) != 0 && StringUtils.isNotEmpty(liaallg.getCur())) {
                newrol = liaallParGet("MOVAMT", liaallg.getRol());
                if (StringUtils.isNotEmpty(newrol)) {
                    movTyp = "M";
                }
            }
            if (StringUtils.isNotEmpty(movTyp)) {
                switch (liaallg.getOldflg()) {
                    case "X":
                        // old amount loaded. Check if account is still valid create new line if not (only requiered for MovTyp A)
                        if ("A".equals(movTyp)) {
                            availAcc = liaoneService.getAvailAcc(liaallg.getAcplia());
                        }
                        if (!"A".equals(movTyp) || (StringUtils.isNotEmpty(availAcc) && availAcc.indexOf(liaallg.getAcc()) < 0)) {
                            // find free entry
                            int fnd = -1;
                            for (int g = 0; g < gridcnt; g++) {
                                LiaallgVo liaallgGrid = liaallVo.getLiaallg().get(g);
                                if (liaallgGrid.getAmt().compareTo(BigDecimal.ZERO) == 0
                                        && liaallgGrid.getOldamt().compareTo(BigDecimal.ZERO) == 0
                                        && fnd == -1) {
                                    fnd = g;
                                }
                            }
                            if (fnd == -1) {
                                //表示找不到空数据，需要新增一条Liaallg
                                LiaallgVo liaallgVo = new LiaallgVo();
                                liaallgVo.reset();
                                liaallVo.getLiaallg().add(liaallgVo);
                                gridcnt = liaallVo.getLiaallg().size();
                                //fnd始终等于最新新增的数据的下标
                                fnd = gridcnt - 1;
                            }
                            // move information
                            if ("M".equals(movTyp)) {
                                liaallVo.getLiaallg().get(fnd).setRol(newrol);
                            } else {
                                liaallVo.getLiaallg().get(fnd).setRol(liaallg.getRol());
                            }
                            liaallVo.getLiaallg().get(fnd).setCdtrol(liaallg.getCdtrol());
                            // for move use currency from old entry as defaults have not been executed at the time of move
                            // take currency of balance if currency in line has not been defaulted yet
                            // if balance is empty aswell, create dump
                            if ("M".equals(movTyp)) {
                                if (StringUtils.isEmpty(liaallg.getCur())) {
                                    liaallVo.getLiaallg().get(fnd).getAcplia().getCbe().setCur(liaallg.getAcplia().getWrkcbb().getCur());
                                    if (StringUtils.isEmpty(liaallVo.getLiaallg().get(fnd).getAcplia().getCbe().getCur())) {
                                        log.warn(Strings.formatText("LIAALLG( $1 )\\acplia\\wrkcbb\\cur is empty. Move not possible", i));
                                    }
                                } else {
                                    liaallVo.getLiaallg().get(fnd).getAcplia().getCbe().setCur(liaallg.getCur());
                                }
                                liaallVo.getLiaallg().get(fnd).setCur(liaallVo.getLiaallg().get(fnd).getAcplia().getCbe().getCur());
                            } else {
                                liaallVo.getLiaallg().get(fnd).getAcplia().getCbe().setCur(liaallg.getAcplia().getCbe().getCur());
                            }
                            liaallVo.getLiaallg().get(fnd).setAmt(liaallg.getOldamt());
                            liaallVo.getLiaallg().get(fnd).setModified("amt");
                            liaallVo.getLiaallg().get(fnd).setExtid(liaallg.getExtid());
                            liaallVo.getLiaallg().get(fnd).setObjmodpath(liaallg.getObjmodpath());
                            liaallVo.getLiaallg().get(fnd).getAcplia().getCbe().setExtid(liaallg.getAcplia().getCbe().getExtid());
                            liaallVo.getLiaallg().get(fnd).setGrpkey(liaallg.getGrpkey());
                            liaallVo.getLiaallg().get(fnd).setCbtpfx(liaallg.getCbtpfx());
                            liaallVo.getLiaallg().get(fnd).setCbtpfxlst(liaallg.getCbtpfx());
                            // for move use maturity date from old entry as defaults have not been executed at the time of move
                            if ("M".equals(movTyp)) {
                                liaallVo.getLiaallg().get(fnd).setMatdat(liaallg.getPtegrp().getRec().getMatdat());
                            } else {
                                liaallVo.getLiaallg().get(fnd).setMatdat(liaallg.getMatdat());
                            }
                            liaallVo.getLiaallg().get(fnd).getAcplia().setCbtpfx(liaallg.getAcplia().getCbtpfx());
                            liaallVo.getLiaallg().get(fnd).setTenpct(liaallg.getTenpct());
                            liaallg.setAmt(liaallg.getOldamt().negate());
                            // move condition and payed until information
                            liaallVo.getLiaallg().get(fnd).setSetdatold(liaallg.getSetdatold());
                            liaallVo.getLiaallg().get(fnd).setFeecod(liaallg.getFeecod());
                            liaallVo.getLiaallg().get(fnd).setModified("feecod");
                            BeanUtils.copyProperties(liaallg.getFee(), liaallVo.getLiaallg().get(fnd).getFee());
                            BeanUtils.copyProperties(liaallg.getFec(), liaallVo.getLiaallg().get(fnd).getFec());
                            liaallg.setOldflg("C");
                            liaallg.setTenpct(new BigDecimal(0));
                        }
                        break;
                    case "C":
                        switch (movTyp) {
                            case "A":
                                // old amount already moved to other line. If account is valid again in the meantime revert changement
                                availAcc = liaoneService.getAvailAcc(liaallg.getAcplia());
                                if (availAcc.indexOf(liaallg.getAcc()) > -1) {
                                    // find corresponding entry
                                    for (int g = 0; g < gridcnt; g++) {
                                        LiaallgVo liaallgVO = liaallVo.getLiaallg().get(g);
                                        if (MdaUtils.compareTo(liaallg.getGrpkey(), liaallgVO.getGrpkey()) == 0 &&
                                                isSameObject(liaallgVO.getObjmodpath(), liaallg.getObjmodpath()) &&
                                                (MdaUtils.compareTo(liaallg.getRol(), liaallgVO.getRol()) == 0) && g != i) {
                                            liaallg.setAmt(Decimals.add(liaallg.getAmt(), liaallgVO.getAmt()));
                                            liaallg.setTenpct(liaallgVO.getTenpct());
                                            liaallg.setOldflg("X");
                                            liaallgVO.setRol(NULLSTR);
                                            liaallgVO.setGrpkey(NULLSTR);
                                            liaallgVO.setObjmodpath(NULLSTR);
                                            liaallgVO.setAmt(new BigDecimal(0));
                                            liaallgVO.getAcplia().getCbe().setCur(NULLSTR);
                                            liaallgVO.setCur(NULLSTR);
                                            liaallgVO.setCbtpfx(NULLSTR);
                                            liaallgVO.setCbtpfxlst(NULLSTR);
                                        }
                                    }
                                }
                                break;
                            case "M":
                                // nothing to do (dynamic setting of  LiallSetMoveAmounts not supported)
                                break;
                        }
                        // else no action requiered
                        break;
                }
            }
        }

    }

    /**
     * 得到需要结算的liaallg列表pteinr
     * @param liaallVo
     * @return
     */
    public String getTenset(LiaallVo liaallVo) {
        String pteStrs = "";
        if (liaallVo.getTenorSettles() != null && liaallVo.getTenorSettles().size() > 0) {
            for (TenorSettleVo ts : liaallVo.getTenorSettles()) {
                if ("X".equals(ts.getFlag())) {
                    pteStrs += ts.getPteinr() + " ";
                }
            }
        }
        return pteStrs;
    }

    public void internalDistrib(LiaallVo liaallVo) {
        //! Group lines to be handled together and distribute amounts and percentages with InternalDistribLines
        // 0. clear amount and percentage of sight amount (set in InternalDistribLines if necessary)
        liaallVo.setOutpct(BigDecimal.ZERO);
        liaallVo.setOutamt(BigDecimal.ZERO);
        liaallVo.setMisamt(BigDecimal.ZERO);
        liaallVo.setMisidx(0);
        String tenDis = "";
        if (StringUtils.isNotEmpty(getTenset(liaallVo))) {
            tenDis = liaallParGet("TENDISTRIB", "");
        }
        // 1. get groups
        Set<String> grpstm = new HashSet<>();
        for (int i = 0; i < liaallVo.getLiaallg().size(); i++) {
            LiaallgVo liaallgVo = liaallVo.getLiaallg().get(i);
            // check, if line is in tenor  grid
            boolean done = false;
            if (tenorSettleIncludePteinr(liaallVo.getTenorSettles(), liaallgVo.getPtegrp().getRec().getInr())) {
                String tenRedx = liaallParGet("TENAUTREDAMT", "");
                if (StringUtils.isNotEmpty(tenRedx)) {
                    BigDecimal tenRedamt = new BigDecimal(tenRedx);
                    if (tenRedamt.compareTo(BigDecimal.ZERO) > 0) {
                        if (StringUtils.isEmpty(tenDis)) {
                            liaallSetTenorBookAmount(liaallgVo.getPtegrp().getRec().getInr(), liaallgVo, liaallVo);
                            done = true;
                        }
                    }
                } else {
                    if (StringUtils.isEmpty(tenDis)) {
                        liaallSetTenorBookAmount(liaallgVo.getPtegrp().getRec().getInr(), liaallgVo, liaallVo);
                        done = true;
                    }
                }
            } else {
                if (tenorSettleIncludePteinr(liaallVo.getTenorSettles(), liaallgVo.getPtegrp().getRec().getInr())) {
                    done = true;
                    liaallgVo.setAmt(BigDecimal.ZERO);
                }
            }
            if (!done) {
                if (!MdaUtils.isEmpty(liaallgVo.getRol())) {
                    grpstm.add(liaallgService.getGroupKey(liaallgVo, liaallVo));
                }
            }
        }
        // 2. Collect lines for every group and call InternalDistribLines (if amount changes are not forbidden by AMTCHGFLG)
        for (String groupkey : grpstm) {
            List<String> disstm = new ArrayList<>();
            boolean amtChg = true;
            BigDecimal refamt = BigDecimal.ZERO;
            BigDecimal amt = BigDecimal.ZERO;
            BigDecimal amt2 = BigDecimal.ZERO;
            String cur = "";
            int olduse = 0;
            for (int i = 0; i < liaallVo.getLiaallg().size(); i++) {
                LiaallgVo liaallgVo = liaallVo.getLiaallg().get(i);
                if (groupkey.equals(liaallgService.getGroupKey(liaallgVo, liaallVo))) {
                    if (disstm.size() == 0) {
                        amt = getnewamtSumToLine(liaallVo, liaallgVo);
                        String refamtX = liaallParGet("REFAMT.AMT", liaallgVo.getObjmodpath() + "." + liaallgVo.getGrpkey());
                        if (StringUtils.isEmpty(refamtX)) {
                            refamt = amt;
                        } else {
                            refamt = new BigDecimal(refamtX);
                        }
                        String amt2Path = liaallParGet("CBEAMT2.PATH", liaallgVo.getGrpkey());
                        if (StringUtils.isNotEmpty(amt2Path)) {
                            if (isSameObject(liaallgVo.getObjmodpath(), amt2Path)) {
                                String amt2x = liaallParGet("CBEAMT2." + amt2Path, liaallgVo.getGrpkey());
                                if (StringUtils.isNotEmpty(amt2x)) {
                                    amt2 = new BigDecimal(amt2x);
                                }
                            }
                        }
                        cur = liaallgVo.getAcplia().getCbe().getCur();
                        if (liaallCBTPFXIsBalance(liaallgVo.getCbtpfx()) || (liaallParFound("ENABLE.AMTFLG", "*"))) {
                            olduse = 1;
                        }
                    }
                    disstm.add(String.valueOf(i));
                    if (StringUtils.isNotEmpty(liaallgVo.getAmtchgflg())) {
                        amtChg = false;
                    }
                }
            }
            if (amtChg) {
                internalDistribLines(cur, amt, amt2, refamt, disstm, olduse, liaallVo);
            }
        }
    }

    private void internalDistribLines(String argCur, BigDecimal argAmt, BigDecimal argAmt2, BigDecimal argRefAmt, List<String> argLiaallgLines, int argOldUse, LiaallVo liaallVo) {

        //! Distribute Amounts ArgAmt and Argamt2 (Currency Argcur) into lines of LIAALLG
        //! ArgRefAmt: base amount of percentage calculation (usually ArgAmt, but may be set differently by LiaallSetPctRefAmt)
        //! ArgLiaallgLines holds the lines of LIAALLG to be used for distribution
        //! ArgOldUse:
        //!  0: old amounts are not used in distribution, i.e. the percentage is used for ArgAmt only
        //!  1: old amounts are used in distribution, i.e. the percentage is for total amount
        // 1. get sum of old amounts, stored new amounts and percentages for lines with amount modified (MOD...), or not (DFT...) and check if anything has been modified by the user
        BigDecimal modoldamt = new BigDecimal("0");
        BigDecimal modamt = new BigDecimal("0");
        BigDecimal dftoldamt = new BigDecimal("0");
        BigDecimal dftpct = new BigDecimal("0");
        boolean modflg = false;
        boolean modAMtFlg = false;
        String disflg = liaallParGet("NEWDISTRIB", "");
        // make the relevant old amounts available in a stream to be able to reuse the in distribution process
        List<BigDecimal> oldamtstm = new ArrayList<>();
        int grdidx = 0;
        BigDecimal reloldamt = null;
        String oldCbtPfx = NULLSTR;
        String bucCbtPfx = NULLSTR;
        String refTyp = NULLSTR;
        String refCbtPfx = NULLSTR;
        String refmod = NULLSTR;
        for (int stmidx = 0; stmidx < argLiaallgLines.size(); stmidx++) {
            grdidx = Integer.parseInt(argLiaallgLines.get(stmidx));
            LiaallgVo liaallgVo = liaallVo.getLiaallg().get(grdidx);
            // get relevant old amount, usually old amount of line
            reloldamt = liaallgVo.getOldamt();
            // but if reference amount is defined, it is the booking amount of that line
            oldCbtPfx = liaallParGet("SETREFOLD", "CBTPFX");
            bucCbtPfx = liaallParGet("SETREFBUC", "CBTPFX");
            if (!MdaUtils.isEmpty(bucCbtPfx)) {
                refTyp = "SETREFBUC";
            } else {
                if (MdaUtils.isEmpty(oldCbtPfx)) {
                    refTyp = "";
                } else {
                    refTyp = "SETREFOLD";
                }
            }
            if (!MdaUtils.isEmpty(refTyp)) {
                if (MdaUtils.compareTo(liaallParGet(refTyp, "CBTPFX"), liaallgVo.getGrpkey()) == 0 &&
                        isSameObject(liaallParGet(refTyp, "MOD"), liaallgVo.getObjmodpath())) {
                    // search for reference line and set amount and percentage from there
                    refCbtPfx = liaallParGet(refTyp, "REFCBTPFX");
                    refmod = liaallParGet(refTyp, "REFMOD");
                    for (int i = 0; i < liaallVo.getLiaallg().size(); i++) {
                        if (MdaUtils.compareTo(refCbtPfx, liaallVo.getLiaallg().get(i).getGrpkey()) == 0 &&
                                isSameObject(refmod, liaallVo.getLiaallg().get(i).getObjmodpath()) &&
                                MdaUtils.compareTo(liaallgVo.getRol(), liaallVo.getLiaallg().get(i).getRol()) == 0) {
                            if ("SETREFBUC".equals(refTyp)) {
                                reloldamt = liaallVo.getLiaallg().get(i).getAmt();
                            } else {
                                reloldamt = liaallVo.getLiaallg().get(i).getOldamt();
                            }
                        }
                    }
                }
            }
            oldamtstm.add(reloldamt);
            // add amounts /percetage to sum fields
            if (liaallgVo.isModified("amt") || MdaUtils.compareTo(liaallgVo.getOldflg(), "C") == 0 ||
                    MdaUtils.compareTo(liaallgVo.getOldflg(), "R") == 0 || (!liaallgVo.isModified("tenpct") && !MdaUtils.isEmpty(disflg))) {
                modoldamt = Decimals.add(modoldamt, reloldamt);
                modamt = Decimals.add(modamt, liaallgVo.getAmt());
                if (liaallgVo.isModified("amt") || MdaUtils.isEmpty(disflg)) {
                    modflg = true;
                    modAMtFlg = true;
                }
            } else {
                dftoldamt = Decimals.add(dftoldamt, reloldamt);
                dftpct = Decimals.add(dftpct, liaallgVo.getTenpct());
                if (liaallgVo.isModified("tenpct")) {
                    modflg = true;
                }
            }
        }
        // Total percentage of lines with modified amounts
        BigDecimal modPct = null;
        if (MdaUtils.compareTo(Decimals.add(argRefAmt, Decimals.mul(argOldUse, (Decimals.add(modoldamt, dftoldamt)))), 0) != 0) {
            modPct = Numerics.round(Decimals.mul(Decimals.div((Decimals.add(modamt, Decimals.mul(modoldamt, argOldUse))), (Decimals.add(argRefAmt, Decimals.mul(argOldUse, (Decimals.add(modoldamt, dftoldamt)))))), 100), 3);
        } else {
            modPct = new BigDecimal("0");
        }
        // Amount and percentage handled outside
        BigDecimal outAmt = Decimals.sub(argRefAmt, argAmt);
        BigDecimal outPct = null;
        if (MdaUtils.compareTo(argRefAmt, 0) != 0) {
            outPct = Numerics.round(Decimals.div(Decimals.mul(100, (Decimals.sub(argRefAmt, argAmt))), argRefAmt), 3);
        } else {
            outPct = new BigDecimal("0");
        }
        // If amount outside is set, it is the sight amount
        if (MdaUtils.compareTo(outAmt, 0) != 0) {
            liaallVo.setOutamt(outAmt);
            liaallVo.setOutpct(outPct);
        }
        // 2. Handling of intial defaulting (executed as long the user has not changed anything)
        BigDecimal rmdold = null;
        BigDecimal rmdamt = null;
        BigDecimal rmdamt2 = null;
        BigDecimal rmdpct = null;
        if (!modflg) {
            // 2a) If old amounts are not set, first line gets full amount and 100%,
            if (MdaUtils.isEmpty(Decimals.add(dftoldamt, modoldamt))) {
                if (argLiaallgLines.size() > 0) {
                    grdidx = Integer.parseInt(argLiaallgLines.get(0));
                    LiaallgVo liaallgGrd = liaallVo.getLiaallg().get(grdidx);
                    liaallgGrd.setAmt(argAmt);
                    liaallgGrd.setAmt2(argAmt2);
                    liaallgGrd.getAcplia().getCbe().setAmt(liaallgGrd.getAmt());
                    liaallgGrd.setCur(argCur);
                    liaallgGrd.setTenpct(Decimals.sub(100, outPct));
                }
            } else {
                // 2b) else amount and percentage are distributed according to the portions of old amounts
                rmdold = Decimals.add(dftoldamt, modoldamt);
                rmdamt = argAmt;
                rmdamt2 = argAmt2;
                rmdpct = Decimals.sub(100, outPct);
                for (int stmidx = 0; stmidx < argLiaallgLines.size(); stmidx++) {
                    grdidx = Integer.parseInt(argLiaallgLines.get(stmidx));
                    reloldamt = oldamtstm.get(stmidx);
                    LiaallgVo liaallgGrd = liaallVo.getLiaallg().get(grdidx);
                    if (MdaUtils.compareTo(rmdold, liaallgGrd.getOldamt()) == 0) {
                        liaallgGrd.setAmt(rmdamt);
                        liaallgGrd.setAmt2(rmdamt2);
                        liaallgGrd.getAcplia().getCbe().setAmt(liaallgGrd.getAmt());
                        liaallgGrd.setTenpct(rmdpct);
                    } else {
                        if (MdaUtils.compareTo(rmdold, 0) != 0) {
                            liaallgGrd.setAmt(xrtmodService.amtRnd(Decimals.mul(rmdamt, (Decimals.div(reloldamt, rmdold))), argCur));
                            liaallgGrd.setAmt2(xrtmodService.amtRnd(Decimals.mul(rmdamt2, (Decimals.div(reloldamt, rmdold))), argCur));
                            liaallgGrd.getAcplia().getCbe().setAmt(liaallgGrd.getAmt());
                            liaallgGrd.setTenpct(Decimals.mul(Decimals.div(rmdpct, rmdold), reloldamt));
                        } else {
                            liaallgGrd.setAmt(new BigDecimal("0"));
                            liaallgGrd.setAmt2(new BigDecimal("0"));
                            liaallgGrd.getAcplia().getCbe().setAmt(new BigDecimal("0"));
                            liaallgGrd.setTenpct(new BigDecimal("0"));
                        }
                    }
                    rmdold = Decimals.sub(rmdold, reloldamt);
                    rmdamt = Decimals.sub(rmdamt, liaallgGrd.getAmt());
                    rmdamt2 = Decimals.sub(rmdamt2, liaallgGrd.getAmt2());
                    rmdpct = Decimals.sub(rmdpct, liaallgGrd.getTenpct());
                }
            }
        } else { // at least one percentage or amount has been modified by the user
            // 3. Distribute percentage in lines where amount is modified
            if (modAMtFlg) {
                rmdamt = Decimals.add(modamt, Decimals.mul(argOldUse, modoldamt));
                // If total percentage is nearly 100%, add it up to 100 percent
                if (MdaUtils.compareTo(Numerics.abs(Decimals.sub(Decimals.add(Decimals.add(dftpct, modPct), outPct), 100)), 0.005) < 0) {
                    modPct = Decimals.sub(Decimals.sub(100, dftpct), outPct);
                }
                rmdpct = modPct;
                for (int stmidx = 0; stmidx < argLiaallgLines.size(); stmidx++) {
                    reloldamt = oldamtstm.get(stmidx);
                    grdidx = Integer.parseInt(argLiaallgLines.get(stmidx));
                    LiaallgVo liaallgStm = liaallVo.getLiaallg().get(grdidx);
                    if (liaallgStm.isModified("amt") || MdaUtils.compareTo(liaallgStm.getOldflg(), "C") == 0 ||
                            MdaUtils.compareTo(liaallgStm.getOldflg(), "R") == 0 || (!liaallgStm.isModified("tenpct") && !MdaUtils.isEmpty(disflg))) {
                        if (MdaUtils.compareTo(rmdamt, Decimals.add(liaallgStm.getAmt(), Decimals.mul(argOldUse, reloldamt))) == 0) {
                            liaallgStm.setTenpct(rmdpct);
                        } else {
                            if (MdaUtils.compareTo(rmdamt, 0) != 0) {
                                liaallgStm.setTenpct(Decimals.mul(Decimals.div(rmdpct, rmdamt), (Decimals.add(liaallgStm.getAmt(), Decimals.mul(argOldUse, reloldamt)))));
                            } else {
                                liaallgStm.setTenpct(new BigDecimal("0"));
                            }
                        }
                        rmdamt = Decimals.sub(Decimals.sub(rmdamt, liaallgStm.getAmt()), Decimals.mul(argOldUse, reloldamt));
                        rmdpct = Decimals.sub(rmdpct, liaallgStm.getTenpct());
                    }
                }
            }
            // 4. Distribute amounts according to percentage info where amount is not modified
            // If the percentage is nearly 100 in total, the remaining amount is distributed
            if (MdaUtils.compareTo(Numerics.abs(Decimals.sub(Decimals.add(Decimals.add(dftpct, modPct), outPct), 100)), 0.005) < 0) {
                rmdamt = Decimals.add(Decimals.sub(argAmt, modamt), Decimals.mul(argOldUse, (dftoldamt)));
            } else {
                // otherwise just the percentage given by lines where the amount is not modified
                // if old amounts are to be used and no new amount is to be booked, its just the defaulted amount sum (used directly to avoid rounding problems)
                if (MdaUtils.compareTo(argRefAmt, 0) == 0 && MdaUtils.compareTo(argOldUse, 1) == 0) {
                    if (MdaUtils.isEmpty(disflg)) {
                        rmdamt = dftoldamt;
                    } else {
                        rmdamt = Decimals.sub(dftoldamt, modamt);
                    }
                } else {
                    rmdamt = xrtmodService.amtRnd(Decimals.div(Decimals.mul((Decimals.add(argRefAmt, Decimals.mul(argOldUse, (Decimals.add(dftoldamt, modoldamt))))), dftpct), 100), argCur);
                }
            }
            if (!MdaUtils.isEmpty(disflg)) {
                rmdpct = Decimals.sub(Decimals.sub(100, outPct), modPct);
                if (MdaUtils.compareTo(rmdpct, 0) <= 0) {
                    rmdpct = dftpct;
                }
            } else {
                rmdpct = dftpct;
            }
            for (int stmidx = 0; stmidx < argLiaallgLines.size(); stmidx++) {
                reloldamt = oldamtstm.get(stmidx);
                grdidx = Integer.parseInt(argLiaallgLines.get(stmidx));
                LiaallgVo liaallgStm2 = liaallVo.getLiaallg().get(grdidx);
                if (!liaallgStm2.isModified("amt") && MdaUtils.compareTo(liaallgStm2.getOldflg(), "C") != 0 &&
                        MdaUtils.compareTo(liaallgStm2.getOldflg(), "R") != 0 && (liaallgStm2.isModified("tenpct") || MdaUtils.isEmpty(disflg))) {
                    if (MdaUtils.compareTo(rmdpct, liaallgStm2.getTenpct()) == 0) {
                        liaallgStm2.setAmt(Decimals.sub(rmdamt, Decimals.mul(reloldamt, argOldUse)));
                    } else {
                        liaallgStm2.setAmt(Decimals.sub(xrtmodService.amtRnd(Decimals.mul(Decimals.div(rmdamt, rmdpct), liaallgStm2.getTenpct()), argCur), Decimals.mul(reloldamt, argOldUse)));
                    }
                    liaallgStm2.getAcplia().getCbe().setAmt(liaallgStm2.getAmt());
                    rmdamt = Decimals.sub(Decimals.sub(rmdamt, liaallgStm2.getAmt()), Decimals.mul(reloldamt, argOldUse));
                    rmdpct = Decimals.sub(rmdpct, liaallgStm2.getTenpct());
                }
            }
        }
        // Set MISAMT, if not already set and amount has not been fully distributed (replaces old SetMisAmt m)
        String misCur = "";
        if (MdaUtils.compareTo(liaallVo.getMisamt(), 0) == 0) {
            liaallVo.setMisamt(argAmt);
            for (int stmidx = 0; stmidx < argLiaallgLines.size(); stmidx++) {
                grdidx = Integer.parseInt(argLiaallgLines.get(stmidx));
                liaallVo.setMisamt(Decimals.sub(liaallVo.getMisamt(), liaallVo.getLiaallg().get(grdidx).getAmt()));
                liaallVo.setMisidx(grdidx);
                misCur = liaallVo.getLiaallg().get(grdidx).getCur();
            }
            if (MdaUtils.compareTo(liaallVo.getMisamt(), 0) == 0) {
                liaallVo.setMisidx(0);
            } else {
                liaallVo.setConcur(misCur);
            }
        }
    }

    private void liaallSetTenorBookAmount(String argPteInr, LiaallgVo liaallgVO, LiaallVo liaallVo) {
        // Set default booking amount (is oldamt, if this is a settlemnt of tenor and this tenor is in tenors settled)
        BigDecimal tenRedamt = null;
        String tenRedx = NULLSTR;
        if (tenorSettleIncludePteinr(liaallVo.getTenorSettles(), argPteInr) && liaallParFound("TENCBT", "CBTPFX")) {
            // partial payment support
            tenRedamt = liaallVo.getDocamt();
            tenRedx = liaallParGet("TENAUTREDAMT", "");
            if (!MdaUtils.isEmpty(tenRedx)) {
                tenRedamt = new BigDecimal(tenRedx);
            }
            if (MdaUtils.compareTo(liaallgVO.getOldamt(), tenRedamt) < 0) {
                liaallgVO.setAmt(liaallgVO.getOldamt().negate());
            } else {
                liaallgVO.setAmt(tenRedamt.negate());
            }
        } else {
            liaallgVO.setAmt(new BigDecimal(0));
        }
    }

    public void internalDistribExtamt(LiaallVo liaallVo) {
        //! Distribute external amount changes
        // 1. Clear all EXTAMTs and add CBTPFX with old amounts to types to be distributed (if no distribution amount is set)
        List<LiaallExtAmtInfo> liaallExtAmtInfos = getLiaallSet().getLiaallExtAmtInfos();
        int initSize = liaallExtAmtInfos.size();
        for (int i = 0; i < liaallVo.getLiaallg().size(); i++) {
            LiaallgVo liaallgVo = liaallVo.getLiaallg().get(i);
            liaallgVo.setExtamt(BigDecimal.ZERO);
            //如果其他模型或者交易没有注册LiaallExtAmtInfo,则根据liaallg列表创建
            if (initSize == 0 && liaallgVo.getExtoldamt().compareTo(BigDecimal.ZERO) != 0) {
                boolean existFlag = false;
                for (LiaallExtAmtInfo tmp : liaallExtAmtInfos) {
                    if ("Internal".equals(tmp.getSource()) && liaallgVo.getCbtpfx().equals(tmp.getCbtpfx())) {
                        existFlag = true;
                        break;
                    }
                }
                //如果source和cbtpfx不相同,则新建一条数据LiaallExtAmtInfo
                if (!existFlag) {
                    LiaallExtAmtInfo liaallExtAmtInfo = new LiaallExtAmtInfo();
                    liaallExtAmtInfo.setSource("Internal");
                    liaallExtAmtInfo.setCbtpfx(liaallgVo.getCbtpfx());
                    liaallExtAmtInfo.setCur(liaallVo.getConcur());
                    liaallExtAmtInfo.setExtAmt(BigDecimal.ZERO);
                    liaallExtAmtInfos.add(liaallExtAmtInfo);
                }
            }
        }
        //遍历liaallExtAmtInfos更新liaallg的extamt
        liaallExtAmtInfos.forEach(liaallExtAmtInfo -> {
            //get Amount information for this entry
            String cur = liaallExtAmtInfo.getCur();
            BigDecimal disAmt = liaallExtAmtInfo.getExtAmt();
            String cbtpfx = liaallExtAmtInfo.getCbtpfx();
            BigDecimal refamt = BigDecimal.ZERO;
            List<String> disStm = new ArrayList<>();
            //get matching lines and sum up reference amount
            for (int i = 0; i < liaallVo.getLiaallg().size(); i++) {
                LiaallgVo liaallgVo = liaallVo.getLiaallg().get(i);
                if (cbtpfx.equals(liaallgVo.getCbtpfx())) {
                    refamt = Decimals.add(Decimals.add(refamt, liaallgVo.getAmt()), liaallgVo.getOldamt());
                    disAmt = Decimals.add(disAmt, liaallgVo.getExtoldamt());
                    disStm.add(String.valueOf(i));
                }
            }
            for (int i = 0; i < disStm.size(); i++) {
                int liaallGidx = Integer.parseInt(disStm.get(i));
                LiaallgVo liaallgGidx = liaallVo.getLiaallg().get(liaallGidx);
                if (i == disStm.size() - 1) {
                    //如果是最后一条，为防止误差，extamt=disamt-extoldamt
                    liaallgGidx.setExtamt(Decimals.sub(disAmt, liaallgGidx.getExtoldamt()));
                } else {
                    if (refamt.compareTo(BigDecimal.ZERO) != 0) {
                        if (!liaallgGidx.isModified("extamt")) {
                            liaallgGidx.setExtamt(Decimals.sub(xrtmodService.amtRnd(Decimals.div(Decimals.mul(disAmt,
                                    (Decimals.add(liaallgGidx.getAmt(), liaallgGidx.getOldamt()))), refamt), cur), liaallgGidx.getExtoldamt()));
                        }
                        refamt = Decimals.sub(Decimals.sub(refamt, liaallgGidx.getAmt()), liaallgGidx.getOldamt());
                        disAmt = Decimals.sub(Decimals.sub(disAmt, liaallgGidx.getExtamt()), liaallgGidx.getExtoldamt());
                    }
                }
            }
        });
        // 7. Set Total fields for display and set visible if set
        liaallVo.setExttotamt(BigDecimal.ZERO);
        liaallVo.setExttotoldamt(BigDecimal.ZERO);
        for (int i = 0; i < liaallVo.getLiaallg().size(); i++) {
            LiaallgVo liaallgVo = liaallVo.getLiaallg().get(i);
            liaallVo.setExttotamt(Decimals.add(liaallVo.getExttotamt(), liaallgVo.getExtamt()));
            liaallVo.setExttotoldamt(Decimals.add(liaallVo.getExttotoldamt(), liaallgVo.getExtoldamt()));
        }
    }

    public void getPtyinrAndPtainr(LiaallVo liaall, Argument<String> argPtyinr, Argument<String> argPtainr, String argRole) {
        //String argRole = liaallgVO.getRol();
        PtsptaVo ptspta = ptsptaToolComponent.getPtsFromListByRol(liaall.getPtsList(), argRole);
        if (ptspta != null && StringUtils.isNotEmpty(ptspta.getPtyinr())) {
            argPtyinr.value = ptspta.getPtyinr();
            argPtainr.value = ptspta.getPtainr();
        } else {
            Setpty setpty = setfegService.getFeeSet().getSetpty(argRole);
            if (setpty != null) {
                argPtyinr.value = setpty.getPtyInr();
                argPtainr.value = setpty.getPtaInr();
            }
        }
    }

    public BigDecimal getnewamtSumToLine(LiaallVo liaallVo, LiaallgVo liaallgVo) {
        //! retrieves total amount of new amount
        //! setmod\\docamt, if selected tenor is really settled.
        //! ELse Liaallgetfullamount (the defined amount for that line)
        //! internal only
        String tenCbtVal = NULLSTR;
        BigDecimal tenRedamt = null;
        String tenRedx = NULLSTR;
        boolean cbtok = false;
        if (!MdaUtils.isEmpty(liaallgVo.getOldflg())) {
            tenCbtVal = liaallParGet("TENCBT", "CBTPFX");
            tenRedamt = liaallVo.getDocamt();
            tenRedx = liaallParGet("TENAUTREDAMT", "");
            if (!MdaUtils.isEmpty(tenRedx)) {
                tenRedamt = new BigDecimal(tenRedx);
            }
            if (!MdaUtils.isEmpty(tenCbtVal) && isSameObject(getLiaallSet().getLiaallStr("GRPRECPATH"), liaallgVo.getObjmodpath())
                    //&& MdaUtils.compareTo(setmodVo.getDspflg(),"CG")== 0   //setmodVo.getDspflg()  固定为CG
                    && MdaUtils.compareTo(tenRedamt, 0) > 0) {
                if (MdaUtils.compareTo(tenCbtVal, "<all>") == 0) {
                    tenCbtVal = NULLSTR;
                }
                cbtok = true;
                if (MdaUtils.compareTo(tenCbtVal, "*ALL*MATCBT*") == 0) {
                    if (MdaUtils.compareTo(liaallgVo.getCbtpfx(), liaallGetCurrentTenorCBTPFX(liaallVo)) != 0) {
                        cbtok = false;
                    }
                }
                if (liaallParFound("TENDISTRIB", "")) {
                    return tenRedamt.negate();
                }
                if (liaallgVo.getMatdat() == liaallVo.getTensetmatdat() && cbtok && !MdaUtils.isEmpty(liaallVo.getTensetmatdat())) {
                    if (MdaUtils.compareTo(Strings.mid(tenCbtVal, 1, 1), "-") != 0) {
                        return tenRedamt.negate();
                    } else {
                        if (Strings.searchBlock(tenCbtVal, liaallgVo.getCbtpfx()) == 0) {
                            return tenRedamt.negate();
                        }
                    }
                }
            }
        }
        return liaAllGetFullamount(liaallVo, liaallgVo);

    }

    public BigDecimal getOldamtSumToLine(LiaallVo liaallVo,LiaallgVo liaallgVo){
        BigDecimal res = new BigDecimal("0");
        int gridcnt = liaallVo.getLiaallg().size();
        for(int i=0; i<gridcnt; i++) {
            if(MdaUtils.compareTo(liaallVo.getLiaallg().get(i).getCbtpfx(),liaallgVo.getCbtpfx()) == 0
                    && isSameObject( liaallVo.getLiaallg().get(i).getObjmodpath(), liaallgVo.getObjmodpath() )
                    && liaallVo.getLiaallg().get(i).getMatdat() == liaallgVo.getMatdat()
                    && MdaUtils.compareTo(Strings.mid(liaallVo.getLiaallg().get(i).getRol(),1,2),Strings.mid(liaallgVo.getRol(),1,2)) == 0 ) {
                res = Decimals.add(res,liaallVo.getLiaallg().get(i).getOldamt());
            }
        }
        return  res;
    }

    public String liaallGetCurrentTenorCBTPFX(LiaallVo liaallVo) {
        int gridcnt = liaallVo.getLiaallg().size();
        for (int i = 0; i < gridcnt; i++) {
            if (MdaUtils.compareTo(liaallVo.getLiaallg().get(i).getPtegrp().getRec().getInr(), liaallVo.getTenset()) == 0) {
                return liaallVo.getLiaallg().get(i).getCbtpfx();
            }
        }
        return "INT";
    }

    private BigDecimal liaAllGetFullamount(LiaallVo liaallVo, LiaallgVo liaallgVo) {
        //! returns total amount defined tor that type
        //! should be used internal only
        List<LiaallRegisterVo> liaallRegisters = getLiaallSet().getLiaallRegisters();
        String argGrpKey = liaallgVo.getGrpkey();
        String objmodpath = liaallgVo.getObjmodpath();
        String role = liaallgVo.getRol();
        BigDecimal res = BigDecimal.ZERO;
        int findIdx = -1;
        for (int i = 0; i < liaallRegisters.size(); i++) {
            LiaallRegisterVo liaallRegisterVo = liaallRegisters.get(i);
            if (3 == liaallRegisterVo.getRolepart()
                    && role.equals(liaallRegisterVo.getDbtrol())
                    && argGrpKey.equals(liaallRegisterVo.getGrpKey())
                    && Utils.toObject(SimpleModuleVo.class, objmodpath).equals(liaallRegisterVo.getLinkModule())) {
                findIdx = i;
                break;
            }
        }
        if (findIdx == -1) {
            for (int i = 0; i < liaallRegisters.size(); i++) {
                LiaallRegisterVo liaallRegisterVo = liaallRegisters.get(i);
                if (argGrpKey.equals(liaallRegisterVo.getGrpKey())
                        && Utils.toObject(SimpleModuleVo.class, objmodpath).equals(liaallRegisterVo.getLinkModule())) {
                    findIdx = i;
                    break;
                }
            }
        }
        if (findIdx > -1) {
            res = liaallRegisters.get(findIdx).getNewAmt();
            if (liaallParFound("REDPLN", "CNV")) {
                for (int r = 0; r < liaallVo.getLiaallr().size(); r++) {
                    res = Decimals.add(res, liaallVo.getLiaallr().get(r).getAmt());
                }
            }
        }
        return res;
    }

    public void liaallSetShowDetailsIfOld() {
        liaallParSet("X", "SHWOLD", "");
    }

    public void liaallSetCoverChangeAmount(String role, String currency, BigDecimal amt, SimpleModuleVo linkModule) {
        liaallParSet(Utils.toJson(linkModule), "CCV", "MOD");
        liaallParSet(currency, "CCV", "CUR");
        liaallParSet(MdaUtils.toString(amt), "CCV", "AMT");
        liaallParSet(role, "CCV", "ROL");
    }

    @Override
    public void liaallSetAllRolesHaveAmount() {
        liaallParSet("X", "ALLAMT", "");
        liaallParSet("X", "ALLA", "");
    }


    public void liaallSetCbeAmount(String role, int rolepart, String currency, BigDecimal argamt, String cbtpfx, SimpleModuleVo linkModule) {
        liaallSetCbeAmountDbtCdt(role, rolepart, "", currency, argamt, cbtpfx, "", linkModule);
    }

    public void liaallSetCoverReserveAmount(String role, String currency, BigDecimal amt, SimpleModuleVo linkModule) {
        liaallParSet(Utils.toJson(linkModule), "CCVRES", "MOD");
        liaallParSet(currency, "CCVRES", "CUR");
        liaallParSet(MdaUtils.toString(amt), "CCVRES", "AMT");
        liaallParSet(role, "CCVRES", "ROL");

    }

    public void liaallSetCbeAmountDbtCdt(String dbtrol, int rolepart, String cdtrol, String currency, BigDecimal argamt,
                                         String cbtpfx, String argGrpKey, SimpleModuleVo linkModule) {
        //! defines the amount a liability has to be changed (inbooking: positive; outbooking negative)
        //! Dbtrol: Role the liability should be assigned to. Has to be a contract party
        //! rolepart: usually 3, (or 2) but if there should be a selection (e.g. for multi applicants) the length of the prefix can be defined
        //! CdtRol : Role the amount will be credited (if necessary for account defaulting)
        //! currency and amount: amount to be booked
        //! CBTPFX: The Liability type. See codetable LIAALLG:CBTPFX for supported types. You may use a list of types (separated by CR) if the user should be able to select between those
        //! mod: contract module group (e.g. BCDGRP, GIDGRP)
        //! ArgGrpkey : Group key to be used to group items together
        //!             If not set for a single CBTPFX CBTPFX is used as groupkey, in case of a list "TNR" for tenor handling is used
        LiaallSet liaallSet = getLiaallSet();
        LiaallRegisterVo liaallRegisterVo = new LiaallRegisterVo();
        liaallRegisterVo.setDbtrol(dbtrol);
        liaallRegisterVo.setCur(currency);
        liaallRegisterVo.setNewAmt(argamt);
        liaallRegisterVo.setCbtpfx(cbtpfx);
        liaallRegisterVo.setLinkModule(linkModule);
        liaallRegisterVo.setRolepart(rolepart);
        String grpKey = argGrpKey;
        if (StringUtils.isEmpty(grpKey)) {
            if (Strings.pos(cbtpfx, CR) == 0) {
                grpKey = cbtpfx;
            } else {
                grpKey = "TNR";
            }
        }
        liaallRegisterVo.setGrpKey(grpKey);
        if (StringUtils.isNotEmpty(cdtrol)) {
            liaallRegisterVo.getCdtrol().add(cdtrol);
        }
        //如果dbtrol,grpkey,linkModule一样,则可以把金额相加，cdtrol角色积累，然后删掉之前的liaallRegisterVo
        List<String> removeIds = new ArrayList<>();
        for (int i = 0; i < liaallSet.getLiaallRegisters().size(); i++) {
            LiaallRegisterVo tmpLiaallRegisterVo = liaallSet.getLiaallRegisters().get(i);
            if (dbtrol.equals(tmpLiaallRegisterVo.getDbtrol())
                    && grpKey.equals(tmpLiaallRegisterVo.getGrpKey())
                    && linkModule.equals(tmpLiaallRegisterVo.getLinkModule())) {
                liaallRegisterVo.setNewAmt(liaallRegisterVo.getNewAmt().add(tmpLiaallRegisterVo.getNewAmt()));
                liaallRegisterVo.getCdtrol().addAll(tmpLiaallRegisterVo.getCdtrol());
                removeIds.add(String.valueOf(i));
            }
        }
        if (removeIds.size() > 0) {
            for (int index = removeIds.size() - 1; index >= 0; index--) {
                liaallSet.getLiaallRegisters().remove(Integer.parseInt(removeIds.get(index)));
            }
        }
        if (rolepart < 3) {
            List<PtsptaVo> ptsptas = liaallSet.getPtsptas();
            for (PtsptaVo ptsptaVo : ptsptas) {
                String setRole = ptsptaVo.getRol();
                if (StringUtils.isEmpty(setRole)) {
                    continue;
                }
                if (("GI".equals(SettleContext.getUserSession().getAtp().getBus()) || "NI".equals(SettleContext.getUserSession().getAtp().getBus()))
                        && ("APC".equals(setRole) || "APR".equals(setRole))) {
                    continue;
                } else {
                    if (!setRole.equals(dbtrol) && setRole.substring(0, rolepart).equals(dbtrol.substring(0, rolepart))) {
                        liaallRegisterVo.getOthrol().add(setRole);
                    }
                }
            }
        }
        liaallSet.getLiaallRegisters().add(liaallRegisterVo);
    }

    /**
     * source:liaall.0138.script
     */
    public void createGLEFromLIA(GlemodVo glemod) {
        // save transaction accounting entries
        List<LiaallgVo> liaallgVos = glemod.getLiaallg();
        if (liaallgVos != null && liaallgVos.size() > 0) {
            for (int i = 0; i < liaallgVos.size(); i++) {
                LiaallgVo liaallg = liaallgVos.get(i);
                if (StringUtils.isNotEmpty(liaallg.getAcc())) {
                    liaoneService.glesavlia(glemod, liaallg);
                }
            }
        }
    }

    /**
     * source:liaall.0020.script
     */
    public void storeAll(LiaallVo liaall) {
        //! stores all liability information incl. Feecodes.
        //! to be called in cbssav in all transactions using LIAALL
        // try to store assignments 找不到函数方法实现
       /* Modules.invokeExpress(this,"\\LIAAOPP.Storeall",-1);
        int ignore = ctx.getErrorCode();
        // try to store syndications
        Modules.invokeExpress(this,"\\LIASYNP.Storeall",-1);
        ignore = ctx.getErrorCode();*/
        // now engagements
        int gridcnt = liaall.getLiaallg().size();
        String newTyp = NULLSTR;
        int factor = 0;
        IStream chkStm = new StreamImpl();
        for (int i = 0; i < gridcnt; i++) {
            LiaallgVo liaallg = liaall.getLiaallg().get(i);
            if (!MdaUtils.isEmpty(liaallg.getObjmodpath())) {
                // store PTx-contracts and main CBS entry
                newTyp = liaallParGet("BUCTYP.NEW", liaallg.getCbtpfxlst());
                if (MdaUtils.isEmpty(newTyp)) {
                    storeCon(liaall, i, liaallg.getObjmodpath(), 1, liaallg.getCbtpfx());
                } else {
                    factor = Strings.parseInt(liaallParGet("BUCTYP.FACTOR", liaallg.getCbtpfxlst()));
                    storeCon(liaall, i, liaallg.getObjmodpath(), factor, newTyp);
                    // store entry to second contract if transfer of an amount
                    /*newmodidx = Streams.streamSearch(liaall.getParstm(),"NEWMOD-" + liaallg.getCbtpfx());
                    if( newmodidx > 0 ) {
                        storeCon(liaall, i, Strings.getLine(this.getParstm(),newmodidx + 1), Strings.parseInt(Strings.getLine(this.getParstm(),newmodidx + 2)), Strings.getLine(this.getParstm(),newmodidx + 3) );
                    }*/
                }
                if (StringUtils.isNotEmpty(liaallg.getPtegrp().getRec().getInr())) {
                    // store Fee condition
                    if (!MdaUtils.isEmpty(liaallg.getFee().getInr())) {
                        liaallg.getFec().setBegdat(liaallg.getPtegrp().getRec().getBegdat());
                        if (MdaUtils.isEmpty(liaallg.getFec().getBegdat())) {
                            liaallg.getFec().setBegdat(Dates.today());
                        }
                        Streams.streamClear(chkStm);
                        Utils.saveData(liaallg.getFec(), chkStm, "", "");
                        if (MdaUtils.compareTo(MdaUtils.toString(liaallg.getFecold()), MdaUtils.toString(chkStm)) != 0) {
                            cbsRange.sdbRngInsert(DtoMapper.INSTANCE.transfer(liaallg.getFec()));
                        }
                        //this.getLiaallg().getElement(i).getFecinf().codSaveTxt();
                    }
                }
            }
            // show Details panel in TRNREL if user was able to access it
            /*if( ! Systems.isEnabled(this.getLiaallg().getElement(i),"det") )
            {
                MdaUtilsEx.setPanelOption(this.getLiaallg().getElement(i).getDetp(),"VISIBLE","0");
            }
            else
            {
                // set subpanel visible/invisible and set correct label texts, even if panel has never been activ in transaction
                this.getLiaallg().getElement(i).getFecp1().recalcFecp1();
                MdaUtilsEx.setPanelOption(this.getLiaallg().getElement(i).getDetp(),"VISIBLE","2");
            }*/
        }
        // store reductions
        String id;
        Argument<String> idBox = new Argument<String>();
        String type;
        Argument<String> typeBox = new Argument<String>();
        String cur;
        Argument<String> curBox = new Argument<String>();
        BigDecimal amt;
        Argument<BigDecimal> amtBox = new Argument<BigDecimal>();
        getReductionInfo(idBox, typeBox, curBox, amtBox);

        id = idBox.value;
        type = typeBox.value;
        cur = curBox.value;
        amt = amtBox.value;
        if (!MdaUtils.isEmpty(id)) {
            SimpleModuleVo linkModule = SimpleModuleVo.buildModule(liaall.getRec());
            gridcnt = liaall.getLiaallr().size();
            for (int i = 0; i < gridcnt; i++) {
                LiaallrVo liaallr = liaall.getLiaallr().get(i);
                if (MdaUtils.compareTo(liaallr.getAmt(), 0) != 0) {
                    trnmodService.cbsTrnStore("REDAMT", Utils.fmtDate(liaallr.getMatdat(), "dd/MM/yyyy"), Dates.today(), liaallr.getCur(), liaallr.getAmt(), "", linkModule, transactionHelpService.getTrninr());
                }
            }
        }

    }

    /**
     * source:liaall.0015.script
     */
    public void storeCon(LiaallVo liaall, int idx, String objmodpath, int factor, String cbtpfx) {
        //! internal: stores contract information (PTS,PTE,CBS) for one line
        LiaallgVo liaallg = liaall.getLiaallg().get(idx);
        // DBLock( $grpmod )
        // find PTS
        if (!storePteAndCbs(cbtpfx)) {
            return;
        }
        SimpleModuleVo linkModule = Utils.toObject(SimpleModuleVo.class, objmodpath);
        String objinr = linkModule.getObjinr();
        String objtyp = linkModule.getObjtyp();
        if (StringUtils.isEmpty(objinr) || StringUtils.isEmpty(objtyp)) {
            throw new CommonServiceException("linkModule ObjInr或者objtyp 不能为空");
        }
        Map<String, Object> maps = dyncDaoService.dyncReadByInr(objtyp, objinr);
        // for old entries reference is the role in old PTS, else ROL in grid
        String refrol = NULLSTR;
        if (MdaUtils.isEmpty(liaallg.getOldamt())) {
            refrol = liaallg.getRol();
        } else {
            refrol = liaallg.getPtegrp().getPts().getRol();
        }
        // no old PTS is loaded or for existing OAP, reference role is the role of entry entered by user
        if (MdaUtils.isEmpty(refrol) || MdaUtils.compareTo(liaallg.getRol(), "OAP") == 0 && ptsptaToolComponent.ptsIsRolSet(getLiaallSet().getPtsptas(), "OAP")) {
            refrol = liaallg.getRol();
        }
        if (MdaUtils.isEmpty(refrol)) {
            if (!MdaUtils.isEmpty(liaallg.getAmt())) {
                SettleExceptionUtils.sysDump(Strings.formatText("Role not set in Engagement line $1, with booking amount of $2 $3 to be stored", idx, liaallg.getCur(), Utils.fmtAmount(liaallg.getAmt(), "EN")));
            }
        }
        // do not use LiaallSetPtsPtaForRol-assignmet as OAP is now a role in contract to allow reoports for last old applicant later
        // otherwise check if PTSPTA (and PTS inside)  is available in contract for role
        String ownref = NULLSTR;
        String ptyinr = NULLSTR;
        String ptainr = NULLSTR;
        String ptsinr = NULLSTR;
//        Pts pts = ptsMapper.getPtsByObjInrTypAndRole(objinr, objtyp, refrol, liaallg.getLiaptyinr());
        Pts pts = ptsMapper.getPtsByObjInrTypAndRole(objinr, objtyp, refrol, "");
        if (pts == null || StringUtils.isEmpty(pts.getInr())) {
            pts = new Pts();
            pts.setObjtyp(objtyp);
            pts.setObjinr(objinr);
            pts.setRol(liaallg.getRol());
            // DO5DOS.006132 set OWNREF like SavPtsptaForContract
            ownref = (String) maps.get("ownref");
            pts.setOwnref(ownref + "\\" + pts.getRol());

            Argument<String> pathBox = new Argument<String>("", pts.getPtyinr());
            Argument<String> pathBox1 = new Argument<String>("", pts.getPtainr());
            getPtyinrAndPtainr(liaall, pathBox, pathBox1, pts.getRol());

            pts.setPtyinr(pathBox.value);
            pts.setPtainr(pathBox1.value);
            pts.setInr(counterService.dbCounterFormat("PTS"));
            // DO5DOS.004628 - no log for PTS
            //Platform.sdbInsert(this.getWrkpts());
            ptsMapper.insert(pts);
            // DO5DOS.006132 store in BIM to ensure deletion on rollback
           // pts.setObjtyp(NULLSTR);
            //TODO trnmodService.troStoreInBimForUndo( pts, "" );
            //pts.setObjtyp(objtyp);
        }
        ptsinr = pts.getInr();
        ptainr = pts.getPtainr();
        ptyinr = pts.getPtyinr();
        // do not save the record if PTS not correct
        //if( MdaUtils.isEmpty(pts.getInr()) || MdaUtils.isEmpty(pts.getObjinr()) ) {
        if (StringUtils.isEmpty(ptsinr)) {
            if (MdaUtils.isEmpty(liaallg.getAmt())) {
                // no action
                return;
            } else {
                SettleExceptionUtils.sysDump(Strings.formatText("Contract not set in Engagement line $1, with booking amount of $2 $3 to be stored", idx, liaallg.getCur(), Utils.fmtAmount(liaallg.getAmt(), "EN")));
            }
        }
        // store PTE
        Pte pte = null;
        if (MdaUtils.isEmpty(liaallg.getPtegrp().getRec().getInr())) {
            pte = pteMapper.getPteByObjtypAndObjinrAndSubidAndExtid("PTS", pts.getInr(), liaallg.getPtegrp().getRec().getSubid(), liaallg.getPtegrp().getRec().getExtid());
        } else {
            pte = pteMapper.selectByInr(liaallg.getPtegrp().getRec().getInr());
        }
        if (pte == null) {
            //liaallg.getPtegrp().getRec().setInr("");
            liaallgService.defaultPtegrpRecExtid(liaallg);
            liaallgService.defaultPtegrpRecSubid(liaall, liaallg);
        } else {
            liaallg.getPtegrp().getRec().setInr(pte.getInr());
        }
        liaallg.getPtegrp().getRec().setObjinr(ptsinr);
        liaallg.getPtegrp().getRec().setObjtyp("PTS");
        liaallg.getPtegrp().getRec().setLiaptainr(ptainr);
        liaallg.getPtegrp().getRec().setLiaptyinr(ptyinr);
        liaallg.getPtegrp().getRec().setGrpkey(liaallg.getGrpkey());
        liaallg.getPtegrp().getRec().setFeeinr(liaallg.getFee().getInr());
        if (MdaUtils.isEmpty(liaallg.getCdtrol())) {
            liaallg.getPtegrp().getRec().setCdtptsinr(NULLSTR);
        } else {
            PtsptaVo ptspta = ptsptaToolComponent.getPtsFromListByRol(getLiaallSet().getPtsptas(), liaallg.getCdtrol());
            if (ptspta != null) {
                liaallg.getPtegrp().getRec().setCdtptsinr(ptspta.getPtsinr());
            }
        }
        boolean matChg = false;
        if (MdaUtils.compareTo(liaallg.getPtegrp().getRec().getMatdat(), liaallg.getMatdat()) == 0) {
            matChg = false;
        } else {
            matChg = true;
            liaallg.getPtegrp().getRec().setMatdat(liaallg.getMatdat());
        }
        // check, if amount set to zero -> set clsdat in PTE
        if (MdaUtils.compareTo(liaallg.getOldamt(), 0) != 0 && (MdaUtils.compareTo(Decimals.add(liaallg.getOldamt(), liaallg.getAmt()), 0) == 0)) {
            liaallg.getPtegrp().getRec().setClsdat(Dates.today());
        } else {
            liaallg.getPtegrp().getRec().setClsdat(null);
        }
        // set name of PTE-record (to be stored in Limit request)
        String connam = liaallg.getBussec();
        String conref = (String) maps.get("ownref");
        connam += " " + conref;
        liaallg.getPtegrp().getRec().setNam(connam + ":" + pts.getRol() + "/" + cbtpfx);
        liaallg.getPtegrp().getRec().setOwnref(pts.getOwnref());
        liaallg.getPtegrp().getRec().setCbtpfx(cbtpfx);
        //---------------
        liaallg.getPtegrp().getRec().setTenday(liaallg.getTenday());
        //--------------
        trnmodService.trnStoreContract(liaallg.getPtegrp());
        liaallg.getPtegrp().setPts(pts);
        if (MdaUtils.compareTo(liaallg.getPtegrp().getPts().getPtyinr(), liaallg.getPtegrp().getPty().getInr()) != 0) {
            Pty pty = ptyCacheService.getPtyById(pts.getPtyinr());
            liaallg.getPtegrp().setPty(pty);
        }
        // store CBS-entry
        String oldpfx = NULLSTR;
        if (MdaUtils.compareTo(factor, 0) != 0 && (MdaUtils.compareTo(liaallg.getAcplia().getCbe().getAmt(), 0) != 0 || matChg)) {
            oldpfx = liaallg.getAcplia().getCbtpfx();
            liaallg.getAcplia().setCbtpfx(cbtpfx);
            liaallg.getAcplia().getCbe().setOptdat(liaallg.getPtegrp().getRec().getMatdat());
            liaallg.getAcplia().getCbe().setAmt(Decimals.mul(liaallg.getAcplia().getCbe().getAmt(), factor));
            liaallg.getAcplia().getCbe().setAcc(liaallg.getAcc());
            liaoneService.cbsstore(liaallg, liaallg.getPtegrp().getRec(), transactionHelpService.getTrninr());
            liaallg.getAcplia().getCbe().setAmt(Decimals.div(liaallg.getAcplia().getCbe().getAmt(), factor));
            liaallg.getAcplia().setCbtpfx(oldpfx);
        }
        // If additional amount part changes, store this info
        if (!MdaUtils.isEmpty(liaallg.getAmt2())) {
            trnmodService.cbsTrnStore("LIAIN", "AMT2", Dates.today(), liaallg.getCur(), liaallg.getAmt2(), "Additional Amount", liaallg.getPtegrp().getRec(), transactionHelpService.getTrninr());
        }
        // If external amount part changes, store this info
        if (!MdaUtils.isEmpty(liaallg.getExtamt())) {
            trnmodService.cbsTrnStore("LIAIN", "EXTAMT", Dates.today(), liaallg.getCur(), liaallg.getExtamt(), "External Amount", liaallg.getPtegrp().getRec(), transactionHelpService.getTrninr());
        }

    }

    /**
     * source:liaall.0064.script
     */
    public boolean storePteAndCbs(String cbtpfx) {
        //! returns true if type is to be stored in PTE and CBS
        //! only SET (used to define amounts for settlement only) is not stored
        switch (cbtpfx) {
            case "SET":
                return false;
            default:
                return true;
        }
    }

    /**
     * source:liaall.0029.script
     */
    public void getReductionInfo(Argument<String> cbtPFXlst, Argument<String> type, Argument<String> cur, Argument<BigDecimal> amt) {
        //! Retrieves information set by LiaallsetReductionInfo
        //! Do not use from outside. Is method to allow LIAALLR to access it.
        String modpath = liaallParGet("REDPLN", "MOD");
        if (!MdaUtils.isEmpty(modpath)) {
            cbtPFXlst.value = liaallParGet("REDPLN", "CBTPFX");
            type.value = liaallParGet("REDPLN", "TYPE");
            cur.value = liaallParGet("REDPLN", "CUR");
            amt.value = new BigDecimal(liaallParGet("REDPLN", "AMT"));
        } else {
            cbtPFXlst.value = "";
            type.value = "";
            cur.value = "";
            amt.value = new BigDecimal("0");
        }

    }

    @Override
    public boolean tenorSettleIncludePteinr(List<TenorSettleVo> tenorSettles, String pteinr) {
        if (StringUtils.isEmpty(pteinr)) {
            return false;
        }
        boolean flag = false;
        if (tenorSettles != null && tenorSettles.size() > 0) {
            for (int i = 0; i < tenorSettles.size(); i++) {
                if (pteinr.equals(tenorSettles.get(i).getPteinr())
                        && "X".equals(tenorSettles.get(i).getFlag())) {
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }

    /**
     * source:liaall.0028.script
     */
    public void liaallReductionPlan(String cbtpfx, String path, String type, String cur, BigDecimal amt) {
        //! activates the grids for reduction plan (guarantees only)
        //!
        //! supported types (or combinations)
        //! S  Show grid
        //! F  use in fee calculation
        //! C  Covert due entries to extid
        //!
        //! Diaries will be created automatically
        String oldmod = liaallParGet("REDPLN", "MOD");
        if (MdaUtils.isEmpty(oldmod)) {
            liaallParSet(cbtpfx, "REDPLN", "CBTPFX");
            liaallParSet(path, "REDPLN", "MOD");
            liaallParSet(type, "REDPLN", "TYPE");
            liaallParSet(cur, "REDPLN", "CUR");
            liaallParSet(MdaUtils.toString(amt), "REDPLN", "AMT");
        } else {
            SettleExceptionUtils.sysDump("LIAALL supports one reduction plan only");
        }
        if (Strings.pos(type, "C") > 0) {
            liaallParSet(type, "REDPLN", "CNV");
        }
    }

    @Override
    public void liaallSetCancel(SimpleModuleVo cancelModule, String cbtpfx) {
        //! all liabilities for the passed module are to be cancelled.
        //! this is easier as to set all amounts in xxTCAN one by one.
        getLiaallSet().setCancelModule(cancelModule);
        liaallSetDisable(cbtpfx);
    }

    @Override
    public void liaallSetFeecod(String feecod, String addcovflg, String cbtpfx, Date tilDat) {

        //! sets the feecode for the comission code.
        //! If called the comission suppanel is activated.
        //! Feecod: The default feecod to be used.
        //! addcovflg: If set, the coverflag is added to the feecod to allow different rates depending in the type of cover
        //! expdat: Date the contract expires. This is used as final date for comission calculation.
        //! use for guarantees only
        //! The default for the begin date of calculation is the creation date of contract.
        //! If another date should be used, call  LiaallSetFeeBegdat
        //! If commission shall be caclulated for each tenor till its maturity call LiaallSetCalcTilMatDat
        liaallParSet(feecod, "FEECOD", "COD." + cbtpfx);
        liaallParSet(addcovflg, "FEECOD", "ADDCOVFLG." + cbtpfx);
        liaallParSet(Formats.format(tilDat, "dd/MM/yyyy"), "FEECOD", "EXPDAT." + cbtpfx);
    }

    /**
     * source:liaall.0021.script
     */
    public void liaallSetDisable(String cbtpfx) {
        //! to be called, if the user should not be able to change the defaulted amounts.
        liaallParSet("X", "DISABLE", cbtpfx);

    }

    public void liaallSetInccod(String feecod, String cbtpfx) {
        //取得上下文
//        IContext ctx = MdaEnv.getContext();
//        ctx.setErrorCode(NO_ERROR);
        //! sets a different feecode for increment commission.
        //! currently for guarantees only
        liaallParSet(feecod, "FEEINCCOD", cbtpfx);

    }

    public void liaallSetAllowChanges(String cbtpfx, String matflg, String amtflg) {
        //! to be called in extension transactions.
        //! CBTPFX "*" sets it for all types
        //! matflg allowing the following for the maturity date:
        //! + allow extension
        //! * allow all other dates
        //! empty: Don´t allow to change maturity dates (default)
        //! amtflg
        //! * allow moving of amounts, even if no amount is to be booked.
        liaallParSet("X", "ENABLE", "");
        liaallParSet(matflg, "ENABLE.MATFLG", cbtpfx);
        liaallParSet(amtflg, "ENABLE.AMTFLG", cbtpfx);

    }

    public void liaallSetAdditionalContract(String objinr, String objtyp) {
        List<SimpleModuleVo> simpleModuleVos = Utils.toListObject(SimpleModuleVo.class, liaallParGet("ADDMODULE", "ALL"));
        if (simpleModuleVos == null || simpleModuleVos.size() == 0) {
            //第一次存模型对象
            simpleModuleVos = new ArrayList<>();
            simpleModuleVos.add(new SimpleModuleVo(objinr, objtyp));
            liaallParSet(Utils.toJson(simpleModuleVos), "ADDMODULE", "ALL");
        } else {
            boolean existFlag = false;
            for (SimpleModuleVo simpleModuleVo : simpleModuleVos) {
                if (objinr.equals(simpleModuleVo.getObjinr())
                        && objtyp.equals(simpleModuleVo.getObjtyp())) {
                    existFlag = true;
                    break;
                }
            }
            //如果已经存在相同的模型对象，没必要存储
            if (!existFlag) {
                simpleModuleVos.add(new SimpleModuleVo(objinr, objtyp));
                liaallParSet(Utils.toJson(simpleModuleVos), "ADDMODULE", "ALL");
            }
        }
    }

    /**
     * source:liaall.0033.script
     */
    public BigDecimal liaallGetOldamtSum(LiaallVo liaallVo, String cbtpfx, String modpath) {
        //取得上下文
//        IContext ctx = MdaEnv.getContext();
//        ctx.setErrorCode(NO_ERROR);
        //! retrieves total amount of old balances for cbtpfx
        //! maybe useful for defaults that depends on old balance
        BigDecimal res = new BigDecimal("0");
//        int gridcnt = Grids.gridCount(this.getLiaallg());
        if (liaallVo.getLiaallg() == null) {
            return res;
        } else {
            int gridcnt = liaallVo.getLiaallg().size();
            for (int i = 0; i < gridcnt; i++) {
                if (cbtpfx.equals(liaallVo.getLiaallg().get(i).getCbtpfx()) && modpath.equals(liaallVo.getLiaallg().get(i).getObjmodpath())) {
                    res = Decimals.add(res, liaallVo.getLiaallg().get(i).getOldamt());
                    break;
                }
            }
        }
        return res;
    }

    /**
     * source:liaall.0042.script
     */
    public BigDecimal liaallGetNewamtSum(LiaallVo liaallVo, String argGrpKey) {
        //! retrieves total amount of changes for ArgGrpKey
        //! should only be used if the recoding of the amount for
        //! LiaallSetCbeAmount is too complicated.
        BigDecimal res = new BigDecimal("0");
//        int gridcnt = Grids.gridCount(LiaallVo.getLiaallg());
        if (MdaUtils.isEmpty(liaallVo.getLiaallg())) {
            return res;
        } else {
            int gridcnt = liaallVo.getLiaallg().size();
            for (int i = 0; i < gridcnt; i++) {
                if (argGrpKey.equals(liaallVo.getLiaallg().get(i).getGrpkey())) {
                    res = Decimals.add(res, liaallVo.getLiaallg().get(i).getAmt());
                    break;
                }
            }
        }
        return res;
    }


    @Override
    public IStream getDecstm(String decamtstm) {

        IStream decstm = new StreamImpl();
        StringBuilder str = new StringBuilder("");
        str.append("0 1 \"\" 30").append(CR);
        str.append("1 2 \"\" 102").append(CR);
        str.append("2 3 \"\" 37").append(CR);
        str.append("3 4 \"\" 111 ").append(tdDataTypeNumeric).append(" ").append(tdViewTypeAmount);
        str.append(":1 2 5").append(CR);
        str.append("4 5 \"\" 104 ").append(tdDataTypeDate).append(" ").append(tdViewTypeDate).append(CR);
        str.append("7 6 \"\" 50 ").append(CR);
        str.append("P COLORED TRUE").append(CR);
        str.append("P VERTLINES TRUE").append(CR);
        str.append("P HORZLINES TRUE").append(CR);

        Streams.streamSet(decstm, str.toString());

        IStream tmpstr = new StreamImpl();
        Streams.streamClear(tmpstr);
        Streams.streamSet(tmpstr, decamtstm);

        IStream finstr = new StreamImpl();
        Streams.streamClear(finstr);

        for (int i = 1; i <= Streams.streamCount(tmpstr); i++) {
            String line = i <= tmpstr.countLines() && i > 0 ? tmpstr.getLine(i) : "";
            String flg = line.length() > 0 ? line.substring(line.length() - 1) : "";
            if (!"D".equals(flg)) {
                Streams.streamDelete(tmpstr, i);
                i = i - 1;
            } else {
                String arg1 = line.length() > 0 ? line.substring(0, StringUtils.pos(line, TAB) - 1) : NULLSTR;
                String argoth = line.length() > 0 ? line.substring(StringUtils.pos(line, TAB) + 1) : NULLSTR;
                int pos = StringUtils.pos(arg1, ";");
                String amecnt = pos > 0 ? arg1.substring(0, pos - 1) : arg1;
                String insertline = amecnt + TAB + argoth;
                Streams.streamInsert(finstr, 0, insertline);
            }
        }
        Streams.streamSet(decstm, finstr);
        return decstm;
    }

    @Override
    public void liaallSetSelectTenorCBTPFX(String cbtPFXlst) {
        if (MdaUtils.isEmpty(cbtPFXlst)) {
            liaallParSet("<all>", "TENCBT", "CBTPFX");
        } else {
            liaallParSet(cbtPFXlst, "TENCBT", "CBTPFX");
        }
    }

    /**
     *   source:liaall.0049.script
     */
    public void liaallSetFinaningTenor(String cbtpfxlst, SimpleModuleVo linkModule) {
        //! defines, that this is the financing transaction fo a tenor.
        //! If used, the field TENSET may be on the transaction  panel to allow selection of tenor be reduced by the amount settled.
        //
        //! CBTLST is a list of tenor types seperated by CR, eg "ACP"+ Cr + "DFP".
        //! an empty CBTLST accepts all tenor types
        //!
        //! currently only to be used by BP-Transactions
        liaallParSet(cbtpfxlst, "TENFIN", "CBTPFX");
        liaallParSet(Utils.toJson(linkModule), "TENFIN", "MOD" );
    }

    @Override
    public void liaallSetDefaultMaturity(String cbtpfx, SimpleModuleVo linkModule, Date matdat) {
        if (matdat != null) {
            liaallParSet(Formats.format(matdat, "dd/MM/yyyy"), "DFTMATDAT", cbtpfx + "." + Utils.toJson(linkModule));
            liaallParSet("X", "DFTMATDAT", "");
        }
    }

    @Override
    public void liaallSetValdat(Date argValdat, String argGrpkey) {
        liaallParSet(Utils.fmtDate(argValdat, "dd/MM/yyyy"), "VALDAT", argGrpkey);
    }

    /**
     * source:liaall.0000.script
     */
    public void getold(LiaallVo liaallVo) {
        //! get old liability amounts of necessary contracts
        //! GRP is loaded automatically
        //! other contracts as specified in LiaallSetAdditionalContract
        //! clear coverage info
        //! clear old amounts in grid and amounts if new entry and amount not changed manually
        liaallVo.getLiaallg().forEach(liaallgVo -> liaallgVo.setOldamt(new BigDecimal("0")));
        // call init before loading old lines for LIAAOPP or LIASYNP (if available)
        // read old data for main contract
        getOldForContract(liaallVo, SimpleModuleVo.buildModule(liaallVo.getRec().getObjinr(), liaallVo.getRec().getObjtyp()));
        // read old data for additional contracts 交易注册的时候会注入 liaallSetAdditionalContract
        List<SimpleModuleVo> simpleModuleList = Utils.toListObject(SimpleModuleVo.class, liaallParGet("ADDMODULE", "ALL"));
        if (simpleModuleList != null && simpleModuleList.size() > 0) {
            simpleModuleList.forEach(simpleModuleVo -> getOldForContract(liaallVo, simpleModuleVo));
        }
        int oldMaxSubid = getOldMaxSub(liaallVo);
        this.liaallParSet(String.valueOf(oldMaxSubid), "LIAALLMAXOLDSUBID", "");
        // now set default for final acceptance if necessary. 内部实现直接return了
        /*if( Streams.streamSearch(liaallVo.getParstm(),"ACPTRN-") > 0 ) {
            defaultacceptance();
        }*/

    }

    /**
     * source:liaall.0045.script
     */
    public void getOldForContract(LiaallVo liaallVo, SimpleModuleVo simpleModuleVo) {
        //! internal:gets old amounts for module mod (sub function of getold)
        // if module has no INR there are no old amounts
        String objInr = simpleModuleVo.getObjinr();
        String objTyp = simpleModuleVo.getObjtyp();
        log.info("getOldForContractf方法入参：liaallvo:{}objInr:{}objTyp:{}", liaallVo, objInr, objTyp);
        if (StringUtils.isEmpty(objInr)) {
            return;
        }
        // get reduction amounts
        String id;
        Argument<String> idBox = new Argument<String>();
        String type;
        Argument<String> typeBox = new Argument<String>();
        String cur;
        Argument<String> curBox = new Argument<String>();
        BigDecimal amt;
        Argument<BigDecimal> amtBox = new Argument<BigDecimal>();
        getReductionInfo(idBox, typeBox, curBox, amtBox);

        id = idBox.value;
        type = typeBox.value;
        cur = curBox.value;
        amt = amtBox.value;

        if (StringUtils.isNotEmpty(id)) {
            List<String> extidList = cbsget.cbsGetUnbalancedExtIds(objTyp, objInr, "REDSUM");
            int liaallrSize = liaallVo.getLiaallr().size();
            int extidSize = extidList.size();
            if (liaallrSize < extidSize) {
                for (int i = liaallrSize; i <= extidSize; i++) {
                    liaallVo.getLiaallr().add(new LiaallrVo());
                }
            }
            for (int i = 0; i < extidSize; i++) {
                String extid = extidList.get(i);
                //此段逻辑来自与Liaall的defaultLiaallrN1000
                liaallVo.getLiaallr().get(i).setCur(cur);
                liaallVo.getLiaallr().get(i).setAmt(amt);
                liaallVo.getLiaallr().get(i).setMatdat(Strings.parseDate(extid));
                //查找cbb数据
                Date date = Dates.add(Utils.getMaxDate(), -1);
                Cbb cbb = new Cbb();
                log.info("cbsGetBalance方法入参：cbb:{} objTyp:{} objInr:{} cbcArg:{} extid:{} date:{}", cbb, objTyp, objInr, "REDSUM", extid, date);
                cbsmodService.cbsGetBalance(cbb, objTyp, objInr, "REDSUM", extid, date);
                log.info("执行完cbsGetBalance方法cbb:{}", cbb);
                liaallVo.getLiaallr().get(i).setOldamt(cbb.getAmt());
                if (Dates.diff(liaallVo.getLiaallr().get(i).getMatdat(), Dates.today()) < 0) {
                    liaallVo.getLiaallr().get(i).setAmt(cbb.getAmt().negate());
                }
                //此段逻辑来自于Liaallr的newamt的default rule
                liaallVo.getLiaallr().get(i).setNewamt(liaallVo.getLiaallr().get(i).getOldamt().add(liaallVo.getLiaallr().get(i).getAmt()));
            }
            //Grids.gridSort(this.getLiaallr(),"MATDAT","A"); 根据matdat升序排序
            List<LiaallrVo> liaallrs = liaallVo.getLiaallr().stream()
                    .sorted(Comparator.comparing(liaallrVo -> liaallrVo.getMatdat()))
                    .collect(Collectors.toList());
            liaallVo.setLiaallr(liaallrs);
        }
        // read applicants and engagements
        List<Pts> ptsList = ptsMapper.getPtsByObjInrTyp(objInr, objTyp);
        log.info("pts集合:{}", ptsList);
        ptsList.forEach(pts -> {
            List<Pte> pteList = pteMapper.getPteByObjtypAndObjinr("PTS", pts.getInr());
            log.info("pts相关联的pte集合:{}", pteList);
            pteList.forEach(pte -> {
                String cbtpfx = pte.getCbtpfx();
                if ("AOP".equals(cbtpfx)) {
                    //找不到对应的实现
                    //Modules.invokeExpress(this,"\\LIAAOPP.MovePteToLiaAopG( " + recpath + " )",-1);
                } else if ("".equals(cbtpfx)) {
                    //找不到对应的实现
                    //Modules.invokeExpress(this,"\\LIASYNP.MovePteToLiaSynG( " + recpath + " )",-1);
                } else {
                    movePteToLiaallg(liaallVo, pts, pte, simpleModuleVo);
                }
            });
        });
        // check cash cover
        // store maximum sub-Id already used by old PTEs 此处逻辑在save存盘中实现了
    }

    /**
     * source:liaall.0103.script
     */
    public void movePteToLiaallg(LiaallVo liaallVo, Pts pts, Pte pte, SimpleModuleVo simpleModuleVo) {
        log.info("movePteToLiaallg入参：liaallVo：{},pts:{},pte:{},simpleModuleVo：{}", liaallVo, pts, pte, simpleModuleVo);
        // read applicants and engagements
        String useold = liaallParGet("UseEmpCbbAmt", "");
        String objTyp = "PTE";
        String objInr = pte.getInr();
        //查找cbb数据
        Date date = Dates.add(Utils.getMaxDate(), -1);
        Cbb cbb = new Cbb();
        log.info("cbsGetBalance入参：cbb:{},objTyp:{},objInr:{},cbcArg:{},extId:{},date:{}", cbb, objTyp, objInr, "LIASUM", "AMT1", date);
        cbsmodService.cbsGetBalance(cbb, objTyp, objInr, "LIASUM", "AMT1", date);
        log.info("执行完cbsGetBalance方法后的cbb:{}", cbb);
        int gridcnt = 0;
        Date refFecDat = null;
        IStream sptfec = new StreamImpl();
        boolean sptFecModified = false;
        IStream dbfec = new StreamImpl();
        String modulePath = Utils.toJson(simpleModuleVo);
        log.info("MdaUtils.compareTo(cbb.getAmt(), 0) != 0结果：{},!MdaUtils.isEmpty(useold) && MdaUtils.compareTo(Strings.mid(pts.getRol(), 1, 2), \"OA\") != 0)结果：{}", MdaUtils.compareTo(cbb.getAmt(), 0) != 0, !MdaUtils.isEmpty(useold) && MdaUtils.compareTo(Strings.mid(pts.getRol(), 1, 2), "OA") != 0);
        if (MdaUtils.compareTo(cbb.getAmt(), 0) != 0
                || (!MdaUtils.isEmpty(useold) && MdaUtils.compareTo(Strings.mid(pts.getRol(), 1, 2), "OA") != 0)) {
            int free = -1;
            /*gridcnt = liaallVo.getLiaallg().size();
            for (int i = 0; i < gridcnt; i++) {
                //通过liaallg去匹配Pte数据，如果没有匹配的 就新增一条liaallg数据
                LiaallgVo liaallgVo = liaallVo.getLiaallg().get(i);
                if (liaallgVo.getCbtpfx().equals(pte.getCbtpfx())
                        && isSameObject(liaallgVo.getObjmodpath(), modulePath)
                        && (liaallgVo.getRol().equals(checkrole(liaallVo, pts.getRol(), pts.getPtyinr())))) {
                    free = i;
                } else if (liaallgVo.getPtegrp().getRec().getInr().equals(pte.getInr())) {
                    free = i;
                } else if (liaallgVo.getOldamt().compareTo(BigDecimal.ZERO) == 0) {
                    //if there is an empty line for that role and contract, reuse it
                    free = i;
                }
            }*/
            if (free == -1) {
                //如果没有找到 则会新增一条记录，然后通过PTE构造Liaallg
                LiaallgVo liaallgVo = new LiaallgVo();
                liaallgVo.reset();
                liaallVo.getLiaallg().add(liaallgVo);
                //free 始终等于最后一条
                free = liaallVo.getLiaallg().size() - 1;
            }
            liaallVo.getLiaallg().get(free).getPtegrp().setRec(pte);
            liaallVo.getLiaallg().get(free).getPtegrp().setPts(pts);
            //ctx.absGet(Trnmod.class).troLockExistingOrNewConSilent ( this.getLiaallg().getElement(free).getPtegrp());
            liaallVo.getLiaallg().get(free).setSetdatold(pte.getSetdat());
            liaallVo.getLiaallg().get(free).setExtid(pte.getExtid());
            liaallVo.getLiaallg().get(free).setCur(cbb.getCur());
            liaallVo.getLiaallg().get(free).setOldamt(cbb.getAmt());
            liaallVo.getLiaallg().get(free).setObjmodpath(modulePath);
            liaallVo.getLiaallg().get(free).setBussec(simpleModuleVo.getObjtyp().substring(0, 2));
            liaallVo.getLiaallg().get(free).getAcplia().setCbtpfx(pte.getCbtpfx());
            liaallVo.getLiaallg().get(free).setCbtpfx(pte.getCbtpfx());
            liaallVo.getLiaallg().get(free).setCbtpfxlst(pte.getCbtpfx());
            //liaallVo.getLiaallg().get(free).getAcplia().setCbtpfx(pte.getCbtpfx());
            boolean setGrpFnd = liaallParFound("SETGRPKEY", Strings.mid(liaallVo.getRec().getObjtyp(), 1, 2) + "." + pte.getCbtpfx());
            if (setGrpFnd) {
                String setGrpKey = liaallParGet("SETGRPKEY", Strings.mid(liaallVo.getRec().getObjtyp(), 1, 2) + "." + pte.getCbtpfx());
                if (MdaUtils.isEmpty(setGrpKey)) {
                    liaallVo.getLiaallg().get(free).setGrpkey(liaallVo.getLiaallg().get(free).getPtegrp().getRec().getGrpkey());
                    if (MdaUtils.isEmpty(liaallVo.getLiaallg().get(free).getGrpkey())) {
                        liaallVo.getLiaallg().get(free).setGrpkey(pte.getCbtpfx());
                    }
                } else {
                    liaallVo.getLiaallg().get(free).setGrpkey(setGrpKey);
                }
            } else {
                liaallVo.getLiaallg().get(free).setGrpkey(pte.getCbtpfx());
            }
            if (MdaUtils.isEmpty(pte.getCdtptsinr())) {
                liaallVo.getLiaallg().get(free).setCdtrol(NULLSTR);
            } else {
                Pts tmpPts = new Pts();
                tmpPts.setInr(pte.getCdtptsinr());
                tmpPts = ptsMapper.selectByPrimaryKey(tmpPts);
                if (tmpPts != null) {
                    //liaallVo.getLiaallg().get(free).setCdtrol(Dynamic.getTextOfInrTable( "PTS", this.getWrkpte().getCdtptsinr(), "ROL" ));
                    liaallVo.getLiaallg().get(free).setCdtrol(tmpPts.getRol());
                }
            }
            liaallVo.getLiaallg().get(free).setLiaptyinr(pts.getPtyinr());
            liaallVo.getLiaallg().get(free).getAcplia().setLiaptyinr(pts.getPtyinr());
            liaallVo.getLiaallg().get(free).setRol(checkrole(liaallVo, pts.getRol(), liaallVo.getLiaallg().get(free).getLiaptyinr()));
            //Systems.resetEnabled(this.getLiaallg().getElement(free),"rol");
            liaallVo.getLiaallg().get(free).getFec().setObjinr(pte.getInr());
            liaallVo.getLiaallg().get(free).getFec().setFeeinr(pte.getFeeinr());
            liaallVo.getLiaallg().get(free).getFec().setObjtyp("PTE");
            liaallVo.getLiaallg().get(free).getFec().setFeepri("6");
            // ( leave OLDFLG unchanged if an old row with nonempty OLDFLG is used)
            if (MdaUtils.isEmpty(liaallVo.getLiaallg().get(free).getOldflg())) {
                liaallVo.getLiaallg().get(free).setOldflg("X");
            }
            // if begin date of settlement is in the future, take that date as reference date of condition, as it is stored for that date
            if (Dates.diff(pte.getBegdat(), Dates.today()) > 0) {
                refFecDat = pte.getBegdat();
            } else {
                refFecDat = Dates.today();
            }
            //存储初始的fec序列化到sptfec
            Utils.saveData(liaallVo.getLiaallg().get(free).getFec(), sptfec, "", "");
            if (liaallVo.getLiaallg().get(free).isModified("fec")) {
                sptFecModified = true;
            } else {
                sptFecModified = false;
            }
            Fec fec = DtoMapper.INSTANCE.transfer(liaallVo.getLiaallg().get(free).getFec());
            cbsRange.sdbRngRead(fec, refFecDat);
            if (StringUtils.isEmpty(fec.getInr())) {
                //没有找到fec
                MdaUtils.clear(liaallVo.getLiaallg().get(free).getFecold());
            } else {
                // DO5DOS 004183 /DO5BAC 230: take condition from original transaction if
                // - an SPT is loaded and
                // - condition has been modified in original transaction and
                // - condition in database is equal to condition before starting old transaction
                // as contract is stored in fecold with INR marked as modified, set it to modified for compare
                //20230513 chengzhuoshen重写该逻辑，仅供参考
                //1.fec赋值给liaallg
                liaallVo.getLiaallg().get(free).setFec(DtoMapper.INSTANCE.transfer(fec));
                //2.查询到的fec序列化赋值给dbfec Stream
                Utils.saveData(fec, dbfec, "", "");
                //3.如果数据库的值和fecold一样，并且fec已经改变了，则fec不变(多次操作)
                if (sptFecModified) {
                    if (dbfec.equals(liaallVo.getLiaallg().get(free).getFecold())) {
                        Utils.loadData(liaallVo.getLiaallg().get(free).getFec().getClass(), sptfec, "");
                    }
                }
                //4.将从dbfec给到fecold Stream
                Streams.streamSet(liaallVo.getLiaallg().get(free).getFecold(), dbfec);
                //5.更新fee和feecod
                Fee fee = new Fee();
                fee.setInr(liaallVo.getLiaallg().get(free).getFec().getFeeinr());
                fee = feeMapper.selectByPrimaryKey(fee);
                liaallVo.getLiaallg().get(free).setFee(fee);
                liaallVo.getLiaallg().get(free).setFeecod(fee.getCod());
            }
            cbsmodService.cbsGetBalance(cbb, objTyp, objInr, "LIASUM", "AMT2", date);
            liaallVo.getLiaallg().get(free).setOldamt2(cbb.getAmt());
            cbsmodService.cbsGetBalance(cbb, objTyp, objInr, "LIASUM", "EXTAMT", date);
            liaallVo.getLiaallg().get(free).setExtoldamt(cbb.getAmt());
            liaallVo.getLiaallg().get(free).setOldamt(Decimals.add(liaallVo.getLiaallg().get(free).getOldamt(), cbb.getAmt()));
            // to ensure that old account is available at first call of assertliaall
            //Modules.postDefaultRule(this.getLiaallg().getElement(free),"acplia.wrkcbb",true);
            liaoneService.defaultWrkcbb(liaallVo.getLiaallg().get(free).getAcplia(), objTyp, objInr);
            liaoneService.defaultWrkcbe(liaallVo.getLiaallg().get(free).getAcplia());
            //没找到acplia.cbe的defaultRule
//            Modules.postDefaultRule(this.getLiaallg().getElement(free),"acplia.cbe",true);
            //Modules.postDefaultRule(this.getLiaallg().getElement(free),"acc",true);
            Cbe cbe = new Cbe();
            cbe.setInr(liaallVo.getLiaallg().get(free).getAcplia().getWrkcbb().getCbeinr());
            liaallVo.getLiaallg().get(free).getAcplia().setCbe(cbeMapper.selectByPrimaryKey(cbe));
            liaallVo.getLiaallg().get(free).getAcplia().getCbe().setExtid(pte.getExtid());
            if (!MdaUtils.isEmpty(liaallVo.getLiaallg().get(free).getAcplia().getWrkcbb().getCur())) {
                liaallVo.getLiaallg().get(free).getAcplia().getCbe().setCur(liaallVo.getLiaallg().get(free).getAcplia().getWrkcbb().getCur());
            }
            if (!MdaUtils.isEmpty(pte.getMatdat())) {
                liaallVo.getLiaallg().get(free).getAcplia().getCbe().setOptdat(pte.getMatdat());
            }

            liaallVo.getLiaallg().get(free).setAcc(liaallVo.getLiaallg().get(free).getAcplia().getCbe().getAcc());
            liaallVo.getLiaallg().get(free).setAcc2(liaallVo.getLiaallg().get(free).getAcplia().getCbe().getAcc2());
            log.info("liaallVo.getLiaallg().get(free)的值为：{}", liaallVo.getLiaallg().get(free));
        }
    }

    /**
     * source:liaall.0058.script
     */
    public String checkrole(LiaallVo liaallVo, String rolecode, String ptyinr) {
        //! only for internal use
        //! checks, if role is still matching with PTYINR.
        //! If not, the rolecode is of that party is replaced by the one, matching this role (if available)
        // 1. If oldrol code is set by  LiaallSetPtsptaForRol, take the old one
        String oldRol = liaallParGet("OLDROL", rolecode);
        if (!MdaUtils.isEmpty(oldRol)) {
            return oldRol;
        }
        // 2. If PTYINR still matching with ptyinr of rolecode, nothing to do
        String vptyinr = "";
        String ptainr = "";
        Argument<String> vptyinrBox = new Argument<String>("", vptyinr);
        Argument<String> ptainrBox = new Argument<String>("", ptainr);
        getPtyinrAndPtainr(liaallVo, vptyinrBox, ptainrBox, rolecode);
        vptyinr = vptyinrBox.value;
        ptainr = ptainrBox.value;
        if (MdaUtils.compareTo(vptyinr, ptyinr) == 0 && (!MdaUtils.isEmpty(vptyinr))) {
            return rolecode;
        }
        /*// 3. Otherwise, check if PTYINR is available in other role
        Caches.cacheRead(ctx.absGet(Setmod.class).getSetpty(),"SETPTYINR");
        if( ctx.getErrorCode() != tdCacheNotFound )
        {
            ctx.reraise();
            return  ctx.absGet(Setmod.class).getSetpty().getRol();
        }*/
        // 4. if not found, return old code
        return rolecode;

    }

    /**
     * source:liaall.0088.script
     */
    public void liaallSetCbeAmountDivAvlAvsInt(LiaallVo liaallVo, SimpleModuleVo linkModule, String cur, BigDecimal amt) {
        //! Set amount cur/amt for module mod according to the portions of INT, AVL and AVS
        //! used for L/C confirmation amounts
        // set CBTPFX to be distributed
        List<String> cbtLst = Arrays.asList("INT", "AVL", "AVS");
        String cbtpfxlst = "INT" + CR + "AVL" + CR + "AVS";
        // set role to be used
        // left as PARSTM as rule to set the role has been removed from product
        String rol = "ISS";
        String avlavsintrol = getLiaallSet().getAvlavsintrol();
        if (StringUtils.isNotEmpty(avlavsintrol)) {
            rol = avlavsintrol;
        }
        // set role to be used
        String seq = liaallParGet("AVLAVSINTSEQ", "");
        // get total old amount
        BigDecimal oldAllAmt = BigDecimal.ZERO;
        for (String cbtpfx : cbtLst) {
            oldAllAmt = Decimals.add(oldAllAmt, liagetService.trnmodGetTenorAmount(linkModule, cbtpfx));
        }
        if (StringUtils.isNotEmpty(liaallVo.getAvxgrpkey())) {
            // if AVXGRPKEY is set, move all amounts to that group
            for (String cbtpfx : cbtLst) {
                liaallSetGrpKey(linkModule.getObjtyp().substring(0, 2), cbtpfx, liaallVo.getAvxgrpkey());
            }
        }
        // if total amount or more is to be reverted or old total amount is zero, book out everything
        if (MdaUtils.compareTo(amt.negate(), oldAllAmt) >= 0 || MdaUtils.compareTo(oldAllAmt, 0) == 0) {
            if (StringUtils.isEmpty(liaallVo.getAvxgrpkey())) {
                for (String cbtpfx : cbtLst) {
                    liaallSetCbeAmount(rol, 3, cur, liagetService.trnmodGetTenorAmount(linkModule, cbtpfx).negate(), cbtpfx, linkModule);
                }
            } else {
                liaallSetCbeAmountDbtCdt(rol, 3, "", cur, oldAllAmt.negate(), cbtpfxlst, liaallVo.getAvxgrpkey(), linkModule);
                liaallSetAllowExchange(cbtpfxlst, linkModule);
            }
        } else {
            // otherwise, if AVXGRPKEY is empty, distribute amount according to portions of old amount
            if (StringUtils.isEmpty(liaallVo.getAvxgrpkey())) {
                BigDecimal remaining = amt;
                for (String cbtpfx : cbtLst) {
                    BigDecimal oldThisamt = liagetService.trnmodGetTenorAmount(linkModule, cbtpfx);
                    BigDecimal part = BigDecimal.ZERO;
                    if (MdaUtils.compareTo(oldThisamt, oldAllAmt) == 0) {
                        part = remaining;
                    } else {
                        if (StringUtils.isEmpty(seq) || amt.compareTo(BigDecimal.ZERO) > 0) {
                            part = xrtmodService.amtRnd(Decimals.mul(remaining, (Decimals.div(oldThisamt, oldAllAmt))), cur);
                        } else {
                            if (MdaUtils.compareTo(oldThisamt, remaining.negate()) > 0) {
                                part = remaining;
                            } else {
                                part = oldThisamt.negate();
                            }
                        }
                    }
                    liaallSetCbeAmount(rol, 3, cur, part, cbtpfx, linkModule);
                    remaining = Decimals.sub(remaining, part);
                    oldAllAmt = Decimals.sub(oldAllAmt, oldThisamt);
                }
            } else {
                // if AVXGRPKEY is set, book amount to that group
                liaallSetCbeAmountDbtCdt(rol, 3, "", cur, amt, cbtpfxlst, liaallVo.getAvxgrpkey(), linkModule);
                // allow exchange
                liaallSetAllowExchange(cbtpfxlst, linkModule);
            }
        }
    }

    /**
     * source:liaall.0071.script
     */
    public void liaallSetAllowExchange(String cbtpfx, SimpleModuleVo linkModule) {
        //! Allows interchange of amounts between lines of module mod
        //! CBTPFX is a list of liability types which may be exchanged.
        //! mod: contract module group (e.g. BCDGRP, GIDGRP)
        liaallParSet(cbtpfx, "ALWEXC", Utils.toJson(linkModule));
    }

    /**
     * source:liaall.0100.script
     */
    public void liaallSetGrpKey(String argBussec, String argCBTPFX, String argGrpKey) {
        //! Changes standard setting of Grpkey (use CBTPFX for old and new entries) on loading of old engagemnent
        //! ArgBussec Business sector (e.g. BE)
        //! ArgCBTPFX CBTPFX as used in LiaallSetCbeAmount
        //!
        //! ArgGrpkey  GRPKEY to be used for CBTPFX
        //!            If empty value is passed, the old value read from PTE is used for old entries, CBTPFX for new entries
        liaallParSet(argGrpKey, "SETGRPKEY", argBussec + "." + argCBTPFX);
    }

    public void liaallSetRefBuc(String objmodPath, String cbtpfx, String refmodPath, String refCBTPFX) {
        //! The defaulting of this entries for mod /CBTPFX shall use the booking amounts of refmod/refcbtpfx
        //! This is used in guarantees to default the amounts of the GI-Booking from the internal claim
        liaallParSet(cbtpfx, "SETREFBUC", "CBTPFX");
        liaallParSet(objmodPath, "SETREFBUC", "MOD");
        liaallParSet(refCBTPFX, "SETREFBUC", "REFCBTPFX");
        liaallParSet(refmodPath, "SETREFBUC", "REFMOD");
    }

    public void liaallSetRefOld(String objmodPath, String cbtpfx, String refmodPath, String refCBTPFX) {
        liaallParSet(cbtpfx, "SETREFOLD", "CBTPFX");
        liaallParSet(objmodPath, "SETREFOLD", "MOD");
        liaallParSet(refCBTPFX, "SETREFOLD", "REFCBTPFX");
        liaallParSet(refmodPath, "SETREFOLD", "REFMOD");
    }

    public void liaallSetTransferToSettlement(String argGrpKey, BigDecimal factor) {
        //! transfer the changes to settlement. If used, LIAALL tranfers the bookings of that Extid to SETDOC\\DOCAMT of the assigned roles (see GITSET for an examlpe).
        //! use factor -1 to debit or +1 to credit the outbooking to the said roles.
        //! If CDTROL is set in lines, the amount is booked to that role in reverse direction
        //! Currently this is used for guarantees and assignments
        liaallParSet(MdaUtils.toString(factor), "SETMOD", argGrpKey);
        liaallParSet(MdaUtils.toString(factor), "SETMOD", "");
    }

    public void liaallSetAllRolesAvailable() {
        //! call this procedure to ensure that all roles are available, but they do not have to have  hold an amount
        liaallParSet("X", "ALLAVB", "");
        liaallParSet("X", "ALLA", "");
    }

    /**
     * 处理midamt
     * @param liaallVo
     */
    public void processMisamt(LiaallVo liaallVo) {
        if (liaallVo.getMisamt().compareTo(BigDecimal.ZERO) != 0) {
            SimpleModuleVo objmod = SimpleModuleVo.buildModule(liaallVo.getRec());
            String objmodpath = Utils.toJson(objmod);
            if (liaallVo.getLiaallg().size() == 1) {
                liaallVo.getLiaallg().get(0).setAmt(liaallVo.getLiaallg().get(0).getAmt().add(liaallVo.getMisamt()));
            } else {
                for (int i=0; i<liaallVo.getLiaallg().size(); i++) {
                    if (objmodpath.equals(liaallVo.getLiaallg().get(i).getObjmodpath())
                            && liaallVo.getLiaallg().get(i).getOldamt().compareTo(BigDecimal.ZERO) == 0) {
                        liaallVo.getLiaallg().get(i).setAmt(liaallVo.getLiaallg().get(i).getAmt().add(liaallVo.getMisamt()));
                        break;
                    }
                }
            }
            liaallVo.setMisamt(BigDecimal.ZERO);
        }
    }
    /**
     * 承兑列表
     * @param liaallVo
     */
    public void fillAcceptLine(LiaallVo liaallVo) {
        String acceptFlag = liaallParGet("ACCEPTFLAG", "");
        List<AcceptLineVo> acceptLines = new ArrayList<>();
        if ("AKZ".equals(acceptFlag)) {
            //AKZ表示承兑
            liaallVo.getLiaallg().forEach(liaallgVo -> {
                if ("AKZ".equals(liaallgVo.getCbtpfx())) {
                    AcceptLineVo acceptLine = new AcceptLineVo();
                    acceptLine.setTrntyp(liaallgVo.getTrntyp());
                    acceptLine.setCbtpfx(liaallgVo.getCbtpfx());
                    acceptLine.setMatdat(liaallgVo.getMatdat());
                    acceptLine.setCur(liaallgVo.getCur());
                    acceptLine.setAmt(liaallgVo.getAmt());
                    acceptLine.setOldamt(liaallgVo.getOldamt());
                    acceptLine.setAcc(liaallgVo.getAcc());
                    acceptLine.setPteinr(liaallgVo.getPtegrp().getRec().getInr());
                    if (StringUtils.isEmpty(liaallgVo.getPtegrp().getRec().getInr())) {
                        acceptLine.setMatdatDisable("");
                    } else {
                        acceptLine.setMatdatDisable("X");
                    }
                    if (liaallgVo.getModifySet().contains("matdat")) {
                        acceptLine.getModifySet().add("matdat");
                    }
                    if (liaallgVo.getMarkSet().contains("matdat")) {
                        acceptLine.getMarkSet().add("matdat");
                    }
                    if (liaallgVo.getMarkSetX().contains("matdat")) {
                        acceptLine.getMarkSetX().add("matdat");
                    }
                    acceptLines.add(0, acceptLine);
                }
            });
        } else if ("ALL".equals(acceptFlag)) {
            //ALL表示展期
            liaallVo.getLiaallg().forEach(liaallgVo -> {
                if ("AKZ".equals(liaallgVo.getCbtpfx())) {
                    AcceptLineVo acceptLine = new AcceptLineVo();
                    acceptLine.setTrntyp(liaallgVo.getTrntyp());
                    acceptLine.setCbtpfx(liaallgVo.getCbtpfx());
                    acceptLine.setMatdat(liaallgVo.getMatdat());
                    acceptLine.setCur(liaallgVo.getCur());
                    acceptLine.setAmt(liaallgVo.getAmt());
                    acceptLine.setOldamt(liaallgVo.getOldamt());
                    acceptLine.setAcc(liaallgVo.getAcc());
                    acceptLine.setPteinr(liaallgVo.getPtegrp().getRec().getInr());
                    if (liaallgVo.getModifySet().contains("matdat")) {
                        acceptLine.getModifySet().add("matdat");
                    }
                    if (liaallgVo.getMarkSet().contains("matdat")) {
                        acceptLine.getMarkSet().add("matdat");
                    }
                    if (liaallgVo.getMarkSetX().contains("matdat")) {
                        acceptLine.getMarkSetX().add("matdat");
                    }
                    acceptLines.add(acceptLine);
                }
            });
        }
        liaallVo.setAcceptLines(acceptLines);
    }
    /**
     *   source:liaall.0137.script
     */
    public void fillTENSTM(LiaallVo liaallVo) {
        //关于Systems.isVisible(this,"tenstm") 需要交易注册通知表外组件
        String tenstmVisible = liaallParGet("VISIBLE", "TENSTM");
        if ("X".equals(tenstmVisible)) {
            SimpleModuleVo objmod = SimpleModuleVo.buildModule(liaallVo.getRec());
            String objmodpath = Utils.toJson(objmod);
            String lst = liaallParGet( "TENCBT", "CBTPFX" );
            if (StringUtils.isEmpty(lst)) {
                lst = liaallParGet( "TENFIN", "CBTPFX" );
                if( ! MdaUtils.isEmpty(lst) ) {
                    objmodpath = liaallParGet( "TENFIN", "MOD" );
                } else {
                    lst = "DPU" + CR + "DPZ" + CR + "AKZ";
                }
            }
            if ("<all>".equals(lst)) {
                lst = "";
            }
            List<TenorSettleVo> tenorSettles = new ArrayList<>();
            List<LiaallgVo> liaallgs = liaallVo.getLiaallg();
            for (int i = 0; i < liaallgs.size(); i++) {
                LiaallgVo liaallgVo = liaallgs.get(i);
                if((Strings.searchBlock(lst, liaallgVo.getCbtpfx()) > 0 || MdaUtils.isEmpty(lst))
                        && isSameObject(liaallgVo.getObjmodpath(), objmodpath)) {
                    Date matdat = liaallgVo.getMatdat();
                    if (matdat == null) {
                        matdat = liaallgVo.getPtegrp().getRec().getMatdat();
                    }
                    TenorSettleVo tenorSettle = new TenorSettleVo();
                    //tenorSettle.setFlag("X");
                    tenorSettle.setPteinr(liaallgVo.getPtegrp().getRec().getInr());
                    tenorSettle.setCbtpfx(liaallgVo.getCbtpfx());
                    tenorSettle.setRol(liaallgVo.getRol());
                    tenorSettle.setCdtrol(liaallgVo.getCdtrol());
                    tenorSettle.setCur(liaallgVo.getCur());
                    tenorSettle.setOldamt(liaallgVo.getOldamt());
                    tenorSettle.setMatdat(matdat);
                    tenorSettles.add(tenorSettle);
                }
            }
            //默认勾选第一条
            if (tenorSettles.size() > 0) {
                tenorSettles.get(0).setFlag("X");
            }
            liaallVo.setTenorSettles(tenorSettles);
        }
    }

    /**
     *   source:liaall.0035.script
     */
    public void liaallSetTenorFields(LiaallVo liaallVo) {
        //! internal function to set workfields for tenor handling
        BigDecimal tensetamt = BigDecimal.ZERO;
        Date tensetmatdat = null;
        List<TenorSettleVo> tenorSettles = liaallVo.getTenorSettles();
        if (tenorSettles != null && tenorSettles.size() > 0) {
            for (int i = 0; i < tenorSettles.size(); i++) {
                TenorSettleVo tenorSettleVo = tenorSettles.get(i);
                if ("X".equalsIgnoreCase(tenorSettleVo.getFlag())) {
                    if(Dates.diff(tenorSettleVo.getMatdat(), tensetmatdat) < 0 || tensetmatdat == null) {
                        tensetmatdat = tenorSettleVo.getMatdat();
                    }
                    tensetamt = tensetamt.add(tenorSettleVo.getOldamt());
                }
            }
        }
        liaallVo.setTensetamt(tensetamt);
        liaallVo.setTensetmatdat(tensetmatdat);
        String pteinr = getTenset(liaallVo);
        if (StringUtils.isNotEmpty(pteinr)) {
            String[] pteinrs = pteinr.split(" ", -1);
            liaallVo.setTenset(pteinrs[0]);
        }
    }

    /**
     *   source:liaall.0089.script
     */
    public void liaallSetMatinf(LiaallVo liaallVo, SimpleModuleVo simpleModuleVo, Argument<Date> argMatdat, Argument<String> argMatTxtFlg) {
        //! Set maturity information in contract (usually xxD\\Matdat und xxD\\MatTxtFlg)
        //! If no tenor is set, ArgMatDat is not changed and Argmatxtflg is reset.
        //! If excatly one tenor is set, ArgMatDat is set to that date and Argmatxtflg is reset.
        //! If more than one tenor is set, ArgMatDat is not changed and Argmatxtflg is set.
        //! A tenor is defined as set, if it has an amount and is not booked out completely in current transaction
        // init registers
        int cnt = 0;
        Date dat = NULLDATE;
        String tenId = "";
        String path = Utils.toJson(simpleModuleVo);
        String thisId = NULLSTR;
        // scan LIAALLG
        for (int i=0; i<liaallVo.getLiaallg().size(); i++) {
            LiaallgVo liaallgVo = liaallVo.getLiaallg().get(i);
            if(isSameObject(liaallgVo.getObjmodpath(), path) && MdaUtils.compareTo(Decimals.add(liaallgVo.getAmt(), liaallgVo.getOldamt()),0) != 0){
                dat = liaallgVo.getMatdat();
                thisId = liaallgService.getTnrId(liaallVo, liaallgVo);
                if( MdaUtils.compareTo(tenId,thisId) != 0 ) {
                    tenId = thisId;
                    cnt = cnt + 1;
                }
            }
        }
        // set result
        switch(cnt) {
            case 0:
                MdaUtils.clear(argMatTxtFlg);
                break;
            case 1:
                MdaUtils.clear(argMatTxtFlg);
                argMatdat.value = dat;
                break;
            default:
                argMatTxtFlg.value = "X";
        }
    }

    @Override
    public void updateLiaallgObjmodpath(List<LiaallgVo> liaallgs, String cbtpfx, SimpleModuleVo linkModule) {
        liaallgs.forEach(liaallgVo -> {
            if ("ALL".equals(cbtpfx) || cbtpfx.equals(liaallgVo.getCbtpfx())) {
                SimpleModuleVo curLinkModule = Utils.toObject(SimpleModuleVo.class, liaallgVo.getObjmodpath());
                if (curLinkModule != null && curLinkModule.getObjtyp().equals(linkModule.getObjtyp())) {
                    liaallgVo.setObjmodpath(Utils.toJson(linkModule));
                }
            }
        });
    }

    @Override
    public void liaallSetTenorAutoRedMaxamt(BigDecimal argAmt) {
        liaallParSet(MdaUtils.toString(argAmt), "TENAUTREDAMT", "");
    }

    /**
     *   source:liaall.0081.script
     */
    @Override
    public void liaallSetPctRefAmt(String currency,BigDecimal argamt,String cbtpfx, SimpleModuleVo linkModule) {
        //! defines the reference amount for percentage calclulation, if 100% shall be different from total of amounts to be booked
        //! currency and amount: reference amount
        //! CBTPFX: The Liability type. See codetable LIAALLG:CBTPFX for supported types. You may use a list of types (separated by CR) if the user should be able to select between those
        //! mod: contract module group (e.g. BCDGRP, GIDGRP)
        String path = Utils.toJson(linkModule);
        // Insert into PARSTM
        liaallParSet( currency, "REFAMT.CUR", path + "." + cbtpfx );
        liaallParSet( MdaUtils.toString(argamt), "REFAMT.AMT", path + "." + cbtpfx );

    }
    /**
     *   source:liaall.0082.script
     */
    @Override
    public void liaallSetAllowMoveSight(String argDir,String cbtpfx, SimpleModuleVo linkModule) {
        //! Allows to move the amount not yet assigned to SETDOC\\DOCAMT
        //! If called, an additional button "Move to Sight" will be available for the amount not yet assigned.
        //! ArgDir: Direction. If "-" the amount not assigned is subtracted from, otherwise it is added to SETDOC\\DOCAMT
        //! CBTPFX: The Liability type. See codetable LIAALLG:CBTPFX for supported types. You may use a list of types (separated by CR) if the user should be able to select between those
        //! mod: contract module group (e.g. BCDGRP, GIDGRP)
        String path = Utils.toJson(linkModule);
        // Insert into PARSTM
        liaallParSet( argDir, "MOVSIG." + path, cbtpfx );
        liaallParSet( argDir, "MOVSIG", "ANY" );

    }

    /**
     *   source:liaall.0095.script
     */
    @Override
    public void liaallSetAmount2(String argCur, BigDecimal argamt, SimpleModuleVo linkModule, String argGrpKey) {
        //! defines the amount additional amount change (inbooking: positive; outbooking negative)
        //! ArgCur and ArgAmt: amount to be booked as additional amount
        //! mod: contract module group (e.g. BCDGRP, GIDGRP)
        //! ArgGrpkey : Group key as used in  LiaallSetCbeAmountDbtCdt for the main booking
        String path = Utils.toJson(linkModule);
        liaallParSet( MdaUtils.toString(argamt), "CBEAMT2." + path, argGrpKey );
        liaallParSet( path, "CBEAMT2.PATH", argGrpKey );
    }

    /**
     *   source:liaallg.0056.script
     */
    public int getOldMaxSub(LiaallVo liaall) {
        List<LiaallgVo> liaallgList = liaall.getLiaallg().parallelStream()
                .filter(liaallg -> StringUtils.isNotEmpty(liaallg.getPtegrp().getRec().getSubid()) && StringUtils.isNotEmpty(liaallg.getOldflg()))
                .sorted(Comparator.comparingInt(o -> Integer.parseInt(o.getPtegrp().getRec().getSubid())))
                .collect(Collectors.toList());
        if (liaallgList != null && liaallgList.size() > 0) {
            return Integer.parseInt(liaallgList.get(liaallgList.size()-1).getPtegrp().getRec().getSubid());
        }
        return 0;
    }
}