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

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 com.brilliance.isc.bo.Cur;
import com.brilliance.isc.bo.Ptyrat;
import com.brilliance.isc.bo.Xrt;
import com.brilliance.isc.bo.Zmqxrt;
import com.brilliance.isc.common.cbsmod.service.XrtmodService;
import com.brilliance.isc.common.exception.CommonServiceException;
import com.brilliance.isc.common.setfeg.fee.Setpty;
import com.brilliance.isc.common.setfeg.fee.Wrksum;
import com.brilliance.isc.common.setfeg.service.SetfegService;
import com.brilliance.isc.common.setglg.service.SetglgService;
import com.brilliance.isc.common.setglg.vo.MessageDetailVo;
import com.brilliance.isc.common.setglg.vo.SetglgVo;
import com.brilliance.isc.common.setgll.service.SetgllService;
import com.brilliance.isc.common.setgll.vo.SetgllVo;
import com.brilliance.isc.common.setmod.service.SetmodService;
import com.brilliance.isc.common.setmod.vo.PtsFeeDetailVo;
import com.brilliance.isc.common.setmod.vo.SetmodVo;
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.mda.dao.XrtMapper;
import com.brilliance.isc.mda.dao.ZmqxrtMapper;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.*;

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

@Service("setglgService")
public class SetglgServiceImpl implements SetglgService {

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

    @Autowired
    private SetfegService setfegService;

    @Autowired
    private SetgllService setgllService;

    @Autowired
    private SetmodService setmodService;

    @Autowired
    private XrtmodService xrtmodService;

    @Autowired
    private XrtMapper xrtMapper;

    @Autowired
    private ZmqxrtMapper zmqxrtMapper;

    private static Set<String> fixDspFlgSet = null;

    @PostConstruct
    public void initFixDspFlgSet() {
        fixDspFlgSet = new HashSet<>();
        fixDspFlgSet.add("A"); //固定账号 固定科目 账号灰显
        fixDspFlgSet.add("D"); //固定账号 固定科目 账号不灰显
        fixDspFlgSet.add("J"); //结售汇
    }

    @Override
    public String calcMac(SetmodVo setmod) {
        // created from all MACs of SETGLL
        IStream stm = new StreamImpl();
        SetglgVo setglg = setmod.getSetglg();
        Streams.streamSet(stm, setglg.getSetglgamtcon());
        int count = setglg.getSetgll().size();
        if (count > 0) {
            for (int i = 0; i < count; i++) {
                Streams.streamInsert(stm, 0, setglg.getSetgll().get(i).getMac());
                //客户A然后删掉再选客户A，再选客户B，会导致账务不发生变化
                for (PtsFeeDetailVo ptsFeeDetail : setmod.getPtydet()) {
                    if (ptsFeeDetail.getRol().equals(setglg.getSetgll().get(i).getRol())) {
                        Streams.streamInsert(stm, 0, ptsFeeDetail.getPtyinr());
                        Streams.streamInsert(stm, 0, ptsFeeDetail.getDftcur());
                        Streams.streamInsert(stm, 0, ptsFeeDetail.getDftdsp());
                        Streams.streamInsert(stm, 0, ptsFeeDetail.getDftact());
                        Streams.streamInsert(stm, 0, ptsFeeDetail.getDftfeecur());
                        Streams.streamInsert(stm, 0, ptsFeeDetail.getGlggrpflg());
                    }
                }
            }
        }
        Streams.streamInsert(stm, 0, setmod.getDoccur() + MdaUtils.toString(Numerics.round(setmod.getDocamt(), 2)) + MdaUtils.toString(Numerics.round(setmod.getSetamt(), 2)) + MdaUtils.toString(Numerics.round(setmod.getOthdocamt(), 2)));
        Streams.streamInsert(stm, 0, setmod.getRoldsc());
        String mac = Systems.macGen(stm, 0);
        setmod.getSetglg().setMac(mac);
        return mac;
    }

    @Override
    public String calcMaceog(SetmodVo setmod) throws CommonServiceException {
        // created from all CPRMACs and booking amounts of SETGLL (thus end processing is done if ccompression info changes)
        IStream stm = new StreamImpl();
        Streams.streamClear(stm);
        SetglgVo setglg = setmod.getSetglg();
        //int count = Grids.gridCount(this.getSetgll());
        int count = setglg.getSetgll().size();
        if (count > 0) {
            for (int i = 0; i < count; i++) {
                Streams.streamInsert(stm, 0, setglg.getSetgll().get(i).getCprmac() + MdaUtils.toString(Numerics.round(setglg.getSetgll().get(i).getAccamt(), 2)) + MdaUtils.toString(Numerics.round(setglg.getSetgll().get(i).getAcccpramt(), 2)));
            }
        }
        String maceog = Systems.macGen(stm, 0);
        setglg.setMaceog(maceog);
        return maceog;
    }

    @Override
    public Set<String> getFixDspflagSet() {
        return fixDspFlgSet;
    }

    /**
     * source:setglg.0039.script
     */
    @Override
    public boolean defaultSetgllN3000() {
/*WD 暂时不需要
        boolean flag = false;
        flag = getFFAActFlg();
        if (flag) {
            Dynamic.sysWarningSet(SYSWRNTypeWarning, "交易正在使用外币贷款专户,请确认", "ACTFFATYP");
        } else {
            Dynamic.sysWarningSet(SYSWRNTypeWarning, "", "ACTFFATYP");
        }
*/
        return true;
    }

    /**
     * source:setglg.0000.script
     */
    @Override
    public void recalcSetglgBog(SetmodVo setmod) throws CommonServiceException {
        SetglgVo setglg = setmod.getSetglg();
        // Collect amounts
        internalWrkSumCollect(setglg);
        // distribue to booking grid
        internalGlgDistrib(setglg, setmod);
        setglg.setTotamt(new BigDecimal("0"));
        int gridcnt = setglg.getSetgll().size();
        for (int i = 0; i < gridcnt; i++) {
            setglg.setTotamt(Decimals.add(setglg.getTotamt(), Numerics.abs(setglg.getSetgll().get(i).getAmt())));
        }
        String mac = calcMac(setmod);
        setglg.setMacold(mac);
        //报文面涵取费用账务数据的时候会使用
        setmod.setWrksumMap(setfegService.getFeeSet().getWrksumMap());
    }

    /**
     * source:setglg.0001.script
     */
    @Override
    @JsonIgnore
    public void setKeyAmtForRol(SetglgVo setglg, String argrol) {
        //! set relevant settled amount for role ROL to SETGLG\\KEYCUR and KEYAMT
        setglg.setKeycur("");
        setglg.setKeyamt(0);
        int gridcnt = setglg.getSetgll().size();
        for (int i = 0; i < gridcnt; i++) {
            if (MdaUtils.compareTo(argrol, setglg.getSetgll().get(i).getRol()) == 0) {
                // if first row found, set currency amount
                if (MdaUtils.isEmpty(setglg.getKeycur())) {
                    setglg.setKeycur(setglg.getSetgll().get(i).getAcccur());
                    //TODO 处理字段类型不匹配
                    setglg.setKeyamt(Strings.parseInt(setglg.getSetgll().get(i).getAccamt()));
                } else {
                    // if old amount set and same currency, add it
                    if (MdaUtils.compareTo(setglg.getKeycur(), setglg.getSetgll().get(i).getAcccur()) == 0) {
                        //TODO 处理字段类型不匹配
                        setglg.setKeyamt(Decimals.add(setglg.getKeyamt(), setglg.getSetgll().get(i).getAccamt()).intValue());
                    } else {
                        // otherwise return nothing
                        setglg.setKeycur(NULLSTR);
                        setglg.setKeyamt(0);
                        return;
                    }
                }
            }
        }
        setglg.setKeyamt(Numerics.abs(setglg.getKeyamt()));
    }

    /**
     * source:setglg.0002.script
     */
    @Override
    @JsonIgnore
    public void getSettlementRowsForRole(SetglgVo setglg, String rol, Argument<Integer> argSETFEG, Argument<Integer> argSETFOG, Argument<Integer> argTRN) {
        //! Returns Rows in SETGLG for ROL, in which AMounts for SETFEG, SETFEG and TRN are settled.
        //! If no or more than one Row contain amounts 0 in the relevant argument is returned
        argSETFEG.value = 0;
        argSETFOG.value = 0;
        argTRN.value = 0;
        // if ROL is empty , return 0
        if (MdaUtils.isEmpty(rol)) {
            return;
        }
        // Identify Row that holds SETFEG entries
        // search for lines for ROL and count them
        int fegrow = 0;
        int fegcnt = 0;
        int fogrow = 0;
        int fogcnt = 0;
        int trnrow = 0;
        int trncnt = 0;
        int gridcnt = setglg.getSetgll().size();
        int cidx = 0;
        for (int i = 0; i < gridcnt; i++) {
            if (MdaUtils.compareTo(setglg.getSetgll().get(i).getRol(), rol) == 0 && MdaUtils.compareTo(setglg.getSetgll().get(i).getAcccpramt(), 0) != 0) {
                if (!setmodService.isInternalDsp(setglg.getSetgll().get(i).getDsp())) {
                    for (int c = 1; c <= Streams.streamCount(setglg.getSetgll().get(i).getCprlinlst()); c++) {
                        cidx = Strings.parseInt(Strings.getLine(setglg.getSetgll().get(i).getCprlinlst(), c));
                        if (Streams.streamSearch(setglg.getSetgll().get(cidx).getAmtidsstm(), "*SETFEG") > 0) {
                            fegrow = i;
                            fegcnt = fegcnt + 1;
                        }
                        if (Streams.streamSearch(setglg.getSetgll().get(cidx).getAmtidsstm(), "*SETFOG") > 0) {
                            fogrow = i;
                            fogcnt = fogcnt + 1;
                        }
                        if (Streams.streamSearch(setglg.getSetgll().get(cidx).getAmtidsstm(), "TRN") > 0) {
                            trnrow = i;
                            trncnt = trncnt + 1;
                        }
                    }
                }
            }
        }
        // return row of ROL if and only if one line is available
        if (fegcnt == 1) {
            argSETFEG.value = fegrow;
        }
        if (fogcnt == 1) {
            argSETFOG.value = fogrow;
        }
        if (trncnt == 1) {
            argTRN.value = trnrow;
        }
    }

    /**
     * source:setglg.0003.script
     */
    @Override
    public void internalGllAdjust(SetglgVo setglg, Wrksum wrksum, SetmodVo setmod, BigDecimal argamt, String argcur, String srcmod, int srcidx) {
        //! adjusts rows of SETGLG to amount Argamt and a line in SETGLG or WRKSUM
        //
        //
        // Argamt: Amount for combination
        // Argcur: currency
        // srcmod: Reference module (WRKSUM or SETGLL)
        // srcidx: Index in reference module if SETGLL (ignored for WRKSUM; WRKSUM has to be set outside)
        //
        // set registers from srcmod:
        String r = NULLSTR;
        String d = NULLSTR;
        String fcdinr = NULLSTR;
        String acccur = NULLSTR;
        BigDecimal accamt = null;
        String dsp = NULLSTR;
        String dspflg = NULLSTR;
        String gllGrp = NULLSTR;
        IStream amtIDsStm = new StreamImpl();
        String act = NULLSTR;
        Date valdat = null;
        BigDecimal dcbrat = null;
        BigDecimal scbrat = null;
        Set<String> disableSet = null;
        if (MdaUtils.compareTo(srcmod, "WRKSUM") == 0) {
            r = wrksum.getRol();
            d = wrksum.getFlg();
            fcdinr = wrksum.getFcdinr();
            acccur = wrksum.getAcccur();
            accamt = wrksum.getAccamt();
            dsp = wrksum.getDsp();
            dspflg = wrksum.getDspflg();
            gllGrp = wrksum.getGllgrp();
            Streams.streamSet(amtIDsStm, wrksum.getAmtidsstm());
            act = wrksum.getAct();
            valdat = wrksum.getValdat();
            dcbrat = wrksum.getDcbextrat();
            scbrat = wrksum.getScbextrat();
            disableSet = wrksum.getDisableSet();
        } else {
            r = setglg.getSetgll().get(srcidx).getRol();
            d = setglg.getSetgll().get(srcidx).getFlg();
            fcdinr = setglg.getSetgll().get(srcidx).getFcdinr();
            acccur = setglg.getSetgll().get(srcidx).getAcccur();
            accamt = setglg.getSetgll().get(srcidx).getAccamt();
            dsp = setglg.getSetgll().get(srcidx).getDsp();
            dspflg = setglg.getSetgll().get(srcidx).getDspflg();
            gllGrp = setglg.getSetgll().get(srcidx).getGllgrp();
            Streams.streamSet(amtIDsStm, setglg.getSetgll().get(srcidx).getAmtidsstm());
            act = setglg.getSetgll().get(srcidx).getAct();
            valdat = setglg.getSetgll().get(srcidx).getValdat();
            dcbrat = setglg.getSetgll().get(srcidx).getDcbextrat();
            scbrat = setglg.getSetgll().get(srcidx).getScbextrat();
        }
        // Start
        int n = -1;
        int f = -1;
        BigDecimal b = argamt;
        int free = -1;
        int gridcnt = setglg.getSetgll().size();
        // ####### 改写 LABEL与GOTO   ####    label lopfee
        while (true) {
            f = f + 1;
            if (f >= gridcnt) {
                break; // ####### 改写 LABEL与GOTO  ####   goto lopend
            }
            if (MdaUtils.isEmpty(setglg.getSetgll().get(f).getRol())) {
                if (free < 0) {
                    free = f;
                }
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(r, setglg.getSetgll().get(f).getRol()) != 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(argcur, setglg.getSetgll().get(f).getCur()) != 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(d, setglg.getSetgll().get(f).getFlg()) != 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(gllGrp, setglg.getSetgll().get(f).getGllgrp()) != 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(fcdinr, setglg.getSetgll().get(f).getFcdinr()) != 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(act, setglg.getSetgll().get(f).getAct()) != 0 && MdaUtils.compareTo(dspflg, "A") == 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(dspflg, "D") == 0 && MdaUtils.compareTo(setglg.getSetgll().get(f).getDspflg(), "D") != 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(dspflg, "D") != 0 && MdaUtils.compareTo(setglg.getSetgll().get(f).getDspflg(), "D") == 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(dspflg, "A") == 0 && MdaUtils.compareTo(setglg.getSetgll().get(f).getDspflg(), "A") != 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(dspflg, "A") != 0 && MdaUtils.compareTo(setglg.getSetgll().get(f).getDspflg(), "A") == 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(dspflg, "C") == 0 && MdaUtils.compareTo(setglg.getSetgll().get(f).getDspflg(), "C") != 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(dspflg, "C") != 0 && MdaUtils.compareTo(setglg.getSetgll().get(f).getDspflg(), "C") == 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(dspflg, "F") == 0 && MdaUtils.compareTo(setglg.getSetgll().get(f).getDspflg(), "F") != 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(dspflg, "F") != 0 && MdaUtils.compareTo(setglg.getSetgll().get(f).getDspflg(), "F") == 0) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            // don`t mix debits and credits (if not allowed by SetDebCreAlw)
            if (Numerics.sgn(setglg.getSetgll().get(f).getAmt()) * Numerics.sgn(argamt) < 0 && MdaUtils.isEmpty(setmod.getDebcrealwflg())) {
                continue; // ####### 改写 LABEL与GOTO  ####   goto lopfee
            }
            if (MdaUtils.compareTo(setglg.getSetgll().get(f).getModflg(), "-") == 0) {
                if (n == -1) {
                    n = f;
                    setglg.getSetgll().get(f).setAmt(new BigDecimal("0"));
                    setglg.getSetgll().get(f).resetModified("amt");
                    setglg.getSetgll().get(f).setDonflg("x");
                } else {
                    SetgllVo setgllVo = new SetgllVo();
                    setgllVo.reset();
                    BeanUtils.copyProperties(setglg.getSetgll().get(f), setgllVo);
                    setglg.getSetgll().get(f).setMacold("<Recalc>");
                }
            } else {
                b = Decimals.sub(b, setglg.getSetgll().get(f).getAmt());
                setglg.getSetgll().get(f).setDonflg("x");
                internalSetValdat(setglg, f, valdat);
            }
            // ####### 改写 LABEL与GOTO  ####   goto lopfee
        }
        // ####### 改写 LABEL与GOTO   ####    label lopend
        if (MdaUtils.compareTo(b, 0) == 0 && (MdaUtils.isEmpty(amtIDsStm) || MdaUtils.isEmpty(setglg.getCreemplinflg()))) {
            return;
            // ####### 改写 LABEL与GOTO  ####   goto subend
        }
        if (n < 0) {
            if (free < 0) {
                SetgllVo setgllVo = new SetgllVo();
                setgllVo.reset();
                setglg.getSetgll().add(setgllVo);
                n = setglg.getSetgll().size() - 1;
            } else {
                n = free;
            }
            setglg.getSetgll().get(n).setModflg("-");
            setglg.getSetgll().get(n).setRol(r);
        }
        f = n;
        setglg.getSetgll().get(f).setAmt(b);
        setglg.getSetgll().get(f).setCur(argcur);
        setglg.getSetgll().get(f).setDonflg("x");
        if (MdaUtils.compareTo(srcmod, "WRKSUM") == 0) {
            // set converted amount, if set by transaction
            setglg.getSetgll().get(f).setAccamt(accamt);
            // if so, this setting is fix
            if (!MdaUtils.isEmpty(accamt)) {
                setglg.getSetgll().get(f).setAccamtfix("T");
            }
        }
        setglg.getSetgll().get(f).setCur(argcur);
        setglg.getSetgll().get(f).setFcdinr(fcdinr);
        if (!MdaUtils.isEmpty(fcdinr)) {
            setglg.getSetgll().get(f).setDcbextrat(dcbrat);
            setglg.getSetgll().get(f).setScbextrat(scbrat);
        }
        // If currency or even account is disabled by SetglgAddAmount (argument ArgDsp), always settle in original currency (DO5DOS 4224)
        String dFTACTcur = NULLSTR;
        int ptydetRow = 0;
        String ptydetAcccur = NULLSTR;
        IStream dftAccCurGrp = new StreamImpl();
        IStream dftAccCur = new StreamImpl();
        int grpLin = 0;
        int allLin = 0;
        String newcurdft = NULLSTR;
        if (MdaUtils.compareTo(dspflg, "C") == 0 || MdaUtils.compareTo(dspflg, "A") == 0) {
            setglg.getSetgll().get(f).resetModified("acccur");
            setglg.getSetgll().get(f).setAcccur(setglg.getSetgll().get(f).getCur());
        } else {
            if ((!setglg.getSetgll().get(f).isModified("acccur") && MdaUtils.isEmpty(setglg.getSetgll().get(f).getExtsetflg()) && MdaUtils.isEmpty(setglg.getSetgll().get(f).getGlpinr())) || "J".equals(setglg.getSetgll().get(f).getDspflg())) {
                // determine default account currency
                dFTACTcur = setglg.getSetgll().get(f).getAcccur();
                // if account currency is set on Details panel, use it
                ptydetRow = setmodService.getPtyDetRow(setglg.getSetgll().get(f).getRol(), setmod);
                if (ptydetRow > 0) {
                    ptydetAcccur = setmod.getPtydet().get(ptydetRow).getDftcur();
                } else {
                    ptydetAcccur = "";
                }
                if (!MdaUtils.isEmpty(ptydetAcccur)) {
                    dFTACTcur = ptydetAcccur;
                } else {
                    // if currency for role is defined by SetDftAcccur, use that one
                    Setpty setpty = setfegService.getFeeSet().getSetpty(setglg.getSetgll().get(f).getRol());
                    if (setpty != null) {
                        if (!MdaUtils.isEmpty(setpty.getDftacccur())) {
                            if (MdaUtils.isEmpty(setpty.getDftacccurgrp())) {
                                dFTACTcur = Strings.getLine(setpty.getDftacccur(), 1);
                            } else {
                                Streams.streamSet(dftAccCurGrp, setpty.getDftacccurgrp());
                                Streams.streamSet(dftAccCur, setpty.getDftacccur());
                                grpLin = Streams.streamSearch(dftAccCurGrp, gllGrp);
                                if (grpLin > 0) {
                                    dFTACTcur = Strings.getLine(dftAccCur, grpLin);
                                } else {
                                    allLin = Streams.streamSearch(dftAccCurGrp, "*");
                                    if (allLin > 0) {
                                        dFTACTcur = Strings.getLine(dftAccCur, allLin);
                                    } else {
                                        dFTACTcur = setmod.getDoccur();
                                    }
                                }
                            }
                        }
                    }
                }
                // if set by transaction, use that one
                if (!MdaUtils.isEmpty(acccur)) {
                    dFTACTcur = acccur;
                }
                if (MdaUtils.isEmpty(dFTACTcur)) {
                    // if there is a default connection stored for role, use it
                    if (ptydetRow > 0) {
                        if (!MdaUtils.isEmpty(setmod.getPtydet().get(ptydetRow).getDftcur())) {
                            dFTACTcur = setmod.getPtydet().get(ptydetRow).getDftcur();
                        }
                    }
                    // if still empty, do not convert
                    if (MdaUtils.isEmpty(setglg.getSetgll().get(n).getAcccur())) {
                        dFTACTcur = setglg.getSetgll().get(n).getCur();
                    }
                }
                if (!setglg.getSetgll().get(f).isModified("acccur")) {
                    setglg.getSetgll().get(f).setAcccur(dFTACTcur);
                } else {
                    // use default currency, if it is not an old currency of the currency set (to avoid dead loop with default acccur of sumtab)
                    newcurdft = xrtmodService.getCurNewCur(dFTACTcur);
                    if (MdaUtils.compareTo(newcurdft, setglg.getSetgll().get(f).getAcccur()) != 0) {
                        setglg.getSetgll().get(f).setAcccur(dFTACTcur);
                    }
                }
            }
        }
        if (!setglg.getSetgll().get(n).isModified("dsp") || MdaUtils.compareTo(dsp, "BRF") == 0) {
            if (!MdaUtils.isEmpty(dsp)) {
                setglg.getSetgll().get(n).setDsp(dsp);
                setglg.getSetgll().get(n).setExtsetflg("D");
            }
        }
        if (MdaUtils.compareTo(dsp, "BRF") != 0 && MdaUtils.compareTo(setglg.getSetgll().get(n).getDsp(), "BRF") == 0) {
            setglg.getSetgll().get(n).setDsp(dsp);
        }
        if (!setglg.getSetgll().get(n).isModified("act")) {
            if (!MdaUtils.isEmpty(act)) {
                setglg.getSetgll().get(n).setAct(act);
                setglg.getSetgll().get(n).setExtsetflg("A");
            }
        }
        internalSetValdat(setglg, n, valdat);
        setglg.getSetgll().get(f).setFlg(d);
        setglg.getSetgll().get(f).setDspflg(dspflg);
        setglg.getSetgll().get(f).setGllgrp(gllGrp);
        int stmCnt = Streams.streamCount(amtIDsStm);
        for (int i = 1; i <= stmCnt; i++) {
            if (Streams.streamSearch(setglg.getSetgll().get(f).getAmtidsstm(), Strings.getLine(amtIDsStm, i)) == 0) {
                Streams.streamInsert(setglg.getSetgll().get(f).getAmtidsstm(), 0, Strings.getLine(amtIDsStm, i));
            }
        }
        setglg.getSetgll().get(f).resetModified("amt");
        if (disableSet != null) {
            for (String field : disableSet) {
                setglg.getSetgll().get(f).setDisable(field);
            }
        }
        // ####### 改写 LABEL与GOTO   ####    label subend
    }

    /**
     * source:setglg.0004.script
     */
    @Override
    public void internalGlgDistrib(SetglgVo setglg, SetmodVo setmod) {
        String relevant = "";
        // determine SetSumMax
        int setSumMax = 0;
        int gridcnt = setglg.getSetgll().size();
        for (int i = 0; i < gridcnt; i++) {
            if (setglg.getSetgll().get(i).getSetxxxrow() >= setSumMax) {
                setSumMax = setglg.getSetgll().get(i).getSetxxxrow() + 1;
            }
            if (!MdaUtils.isEmpty(setglg.getSetgll().get(i).getRol())) {
                relevant = relevant + setglg.getSetgll().get(i).getRol() + setglg.getSetgll().get(i).getDsp() + CR;
            }
            setglg.getSetgll().get(i).setValdattrn(null);
            MdaUtils.clear(setglg.getSetgll().get(i).getAmtidsstm());
        }
        // Delete Done-Flag
        int i = 0;
        String trnset = "";
        // ####### 改写 LABEL与GOTO   ####    label lop1
        while (true) {
            if (i >= gridcnt) {
                break; // ####### 改写 LABEL与GOTO  ####   goto don1
            }
            setglg.getSetgll().get(i).setDonflg(" ");
            setglg.getSetgll().get(i).setAccamtfix(" ");
            if (setglg.getSetgll().get(i).isModified("amt")) {
                setglg.getSetgll().get(i).setModflg("a");
            }
            if (setglg.getSetgll().get(i).isModified("accamt")) {
                setglg.getSetgll().get(i).setModflg("b");
            }
            if (MdaUtils.isEmpty(setglg.getSetgll().get(i).getSetxxxrow())) {
                setSumMax = setSumMax + 1;
                setglg.getSetgll().get(i).setSetxxxrow(setSumMax);
            }
            i = i + 1;
            // ####### 改写 LABEL与GOTO  ####   goto lop1
        }
        // ####### 改写 LABEL与GOTO   ####    label don1
        // Check all lines of Workgrid and add, if necessary
        for (int f = 0; f < gridcnt; f++) {
            setglg.getSetgll().get(f).resetModified("amt");
            setglg.getSetgll().get(f).resetModified("accamt");
            setgllService.cnvAmtAccamt(setglg.getSetgll().get(f));
        }
        int w = 0;
        // ####### 改写 LABEL与GOTO   ####    label lopwrk
        while (true) {
            w = w + 1;
            if (w > Streams.streamCount(setglg.getWrksumcon())) {
                break; // ####### 改写 LABEL与GOTO  ####   goto donwrk
            }
            Wrksum wrksum = setfegService.getFeeSet().getWrksum("SETGLG" + TAB + Strings.getLine(setglg.getWrksumcon(), w));
            if (wrksum != null) {
                internalGllAdjust(setglg, wrksum, setmod, wrksum.getAmt(), wrksum.getCur(), "WRKSUM", w - 1);
            }
            // ####### 改写 LABEL与GOTO  ####   goto lopwrk
        }
        //此处逻辑是将没有link上的Setgll条目删掉
        List<String> removeIds = new ArrayList<>();
        gridcnt = setglg.getSetgll().size();
        for (int f = 0; f < gridcnt; f++) {
            if (" ".equals(setglg.getSetgll().get(f).getDonflg())) {
                if ("-".equals(setglg.getSetgll().get(f).getModflg())
                        && StringUtils.isEmpty(setglg.getSetgll().get(f).getGlpinr())) {
                    removeIds.add(String.valueOf(f));
                } else {
                    internalGllAdjust(setglg, null, setmod, BigDecimal.ZERO, setglg.getSetgll().get(f).getCur(), "SETGLL", f);
                }
            }
        }
        if (removeIds.size() > 0) {
            for (int index = removeIds.size() - 1; index >= 0; index--) {
                setglg.getSetgll().remove(Integer.parseInt(removeIds.get(index)));
            }
            //重新取setgll的size
            gridcnt = setglg.getSetgll().size();
        }
        // ####### 改写 LABEL与GOTO   ####    label donfee2
        for (int f = 0; f < gridcnt; f++) {
            if (MdaUtils.compareTo(setglg.getSetgll().get(f).getAccamtfix(), "T") != 0) {
                setglg.getSetgll().get(f).resetModified("amt");
                setglg.getSetgll().get(f).resetModified("accamt");
                setgllService.cnvAmtAccamt(setglg.getSetgll().get(f));
            }
        }
        int lastset = -1;
        for (i = 0; i < gridcnt; i++) {
            if (MdaUtils.compareTo(setglg.getSetgll().get(i).getAmt(), 0) != 0) {
                lastset = i;
            }
        }
        i = 0;
        while ((i <= lastset)) {
            if (MdaUtils.compareTo(setglg.getSetgll().get(i).getAmt(), 0) == 0 && MdaUtils.isEmpty(setglg.getSetgll().get(i).getGlpinr())) {
                if (lastset > i) {
                    for (int tar = i; tar <= lastset - 1; tar++) {
                        //Datas.setModuleContent(setglg.getSetgll().get(tar), setglg.getSetgll().get(1 + tar));
                        BeanUtils.copyProperties(setglg.getSetgll().get(1 + tar), setglg.getSetgll().get(tar));
                        setglg.getSetgll().get(tar).setMacold("<Recalc>");
                    }
                    //MdaUtils.clear(setglg.getSetgll().get(lastset));
                    SetgllVo setgllVo = new SetgllVo();
                    setgllVo.reset();
                    BeanUtils.copyProperties(setglg.getSetgll().get(lastset), setgllVo);
                    lastset = lastset - 1;
                }
            }
            i = i + 1;
        }
        int gc = gridcnt;
        if (lastset < gridcnt) {
            //   GridDeleteRow ( SETGLL , $lastset + 1 , $gc - $lastset  )
        }
        String newrelevant = "";
        for (i = 0; i < gridcnt; i++) {
            if (MdaUtils.compareTo(setglg.getSetgll().get(i).getDsp(), "BRF") == 0) {
/*
                Systems.setValues(setglg.getSetgll().get(i), "dsp", "BRF");
*/
            } else {
                setgllService.defdsp(setglg.getSetgll().get(i), setmod);
            }
//            setgllService.setcurandval(setglg.getSetgll().get(i));
            setgllService.defActSub(setglg.getSetgll().get(i), setmod);
            if (!MdaUtils.isEmpty(setglg.getSetgll().get(i).getRol())) {
                newrelevant = newrelevant + setglg.getSetgll().get(i).getRol() + setglg.getSetgll().get(i).getDsp() + CR;
            }
        }
        IStream chkflgstm = new StreamImpl();
        Streams.streamClear(chkflgstm);
        Streams.streamSort(chkflgstm, true);
        boolean found = false;
        // if there are debits and credits to same role in settlement allow debits and credits to same party (needed for cash cover and repayment of financing)
        // ( do the check only, if DEBCREALWFLG is not set
        int stmCnt = 0;
        String line = NULLSTR;
        int tabpos = 0;
        String modid = NULLSTR;
        boolean errorfound = false;
        if (MdaUtils.isEmpty(setmod.getDebcrealwflg())) {
            stmCnt = Streams.streamCount(setglg.getSetglgamtcon());
            for (i = 1; i <= stmCnt; i++) {
                line = Strings.getLine(setglg.getSetglgamtcon(), i);
                tabpos = Strings.pos(line, TAB);
                modid = Strings.mid(line, 1, tabpos - 1);
                // do not check amounts internally set by modules of SETMOD
                if (MdaUtils.compareTo(Strings.mid(modid, 1, 4), "*SET") != 0) {
                    line = Strings.mid(line, tabpos + 1);
                    line = Strings.mid(line, 1, Strings.pos(line, CR) - 1);
                    Wrksum wrksum = setfegService.getFeeSet().getWrksum(modid + TAB + line);
                    // Don`t check entries not yet in cache
                    if (wrksum != null) {
                        // if disposition of entry is set, mixes have to be allowed (as there may be charges settled in addition)
                        if (!MdaUtils.isEmpty(wrksum.getDsp())) {
                            found = true;
                        }
                        if (MdaUtils.compareTo(wrksum.getAmt(), 0) < 0) {
                            if (Streams.streamSearch(chkflgstm, wrksum.getGllgrp() + wrksum.getRol() + wrksum.getCur() + "C") == 0) {
                                Streams.streamInsert(chkflgstm, 0, wrksum.getGllgrp() + wrksum.getRol() + wrksum.getCur() + "C");
                            }
                            if (Streams.streamSearch(chkflgstm, wrksum.getGllgrp() + wrksum.getRol() + wrksum.getCur() + "D") > 0) {
                                found = true;
                            }
                        } else {
                            if (MdaUtils.compareTo(wrksum.getAmt(), 0) > 0) {
                                if (Streams.streamSearch(chkflgstm, wrksum.getGllgrp() + wrksum.getRol() + wrksum.getCur() + "D") == 0) {
                                    Streams.streamInsert(chkflgstm, 0, wrksum.getGllgrp() + wrksum.getRol() + wrksum.getCur() + "D");
                                }
                                if (Streams.streamSearch(chkflgstm, wrksum.getGllgrp() + wrksum.getRol() + wrksum.getCur() + "C") > 0) {
                                    found = true;
                                }
                            }
                        }
                    }
                }
            }
            if (!found) {
                // if mixed debits and credits are defined, check, if there are Credits and debits for same role & currency
                // if so, redefault complete settlement
                Streams.streamClear(chkflgstm);
                Streams.streamSort(chkflgstm, true);
                errorfound = false;
                for (i = 0; i < gridcnt; i++) {
                    if (MdaUtils.compareTo(setglg.getSetgll().get(i).getAmt(), 0) < 0) {
                        if (Streams.streamSearch(chkflgstm, setglg.getSetgll().get(i).getGllgrp() + TAB + setglg.getSetgll().get(i).getRol() + TAB + setglg.getSetgll().get(i).getCur() + TAB + "C") == 0) {
                            Streams.streamInsert(chkflgstm, 0, setglg.getSetgll().get(i).getGllgrp() + TAB + setglg.getSetgll().get(i).getRol() + TAB + setglg.getSetgll().get(i).getCur() + TAB + "C");
                        }
                        if (Streams.streamSearch(chkflgstm, setglg.getSetgll().get(i).getGllgrp() + TAB + setglg.getSetgll().get(i).getRol() + TAB + setglg.getSetgll().get(i).getCur() + TAB + "D") > 0) {
                            errorfound = true;
                        }
                    } else {
                        if (MdaUtils.compareTo(setglg.getSetgll().get(i).getAmt(), 0) > 0) {
                            if (Streams.streamSearch(chkflgstm, setglg.getSetgll().get(i).getGllgrp() + TAB + setglg.getSetgll().get(i).getRol() + TAB + setglg.getSetgll().get(i).getCur() + TAB + "D") == 0) {
                                Streams.streamInsert(chkflgstm, 0, setglg.getSetgll().get(i).getGllgrp() + TAB + setglg.getSetgll().get(i).getRol() + TAB + setglg.getSetgll().get(i).getCur() + TAB + "D");
                            }
                            if (Streams.streamSearch(chkflgstm, setglg.getSetgll().get(i).getGllgrp() + TAB + setglg.getSetgll().get(i).getRol() + TAB + setglg.getSetgll().get(i).getCur() + TAB + "C") > 0) {
                                errorfound = true;
                            }
                        }
                    }
                }
                if (errorfound) {
                    for (i = gridcnt - 1; i >= 0; i--) {
                        setglg.getSetgll().remove(i);
                    }
                    setglg.setRecalcSetglg(true);
                }
            }
        }
    }

    /**
     * source:setglg.0005.script
     */
    @Override
    @JsonIgnore
    public BigDecimal getSettledAmount(SetglgVo setglg, String rol) {
        BigDecimal res = new BigDecimal("0");
        int gridcnt = setglg.getSetgll().size();
        if (gridcnt > 0) {
            for (int i = 0; i < gridcnt; i++) {
                if (MdaUtils.compareTo(setglg.getSetgll().get(i).getRol(), rol) == 0) {
                    res = Decimals.add(res, setglg.getSetgll().get(i).getAmt());
                }
            }
        }
        return res;
    }

    /**
     * source:setglg.0006.script
     */
    @Override
    @JsonIgnore
    public BigDecimal getSetAmtSysByRolTypDsp(SetglgVo setglg, String rol, String flg, String dsp) {
        //argument blank = all
        //multiples separated by commas
        BigDecimal res = new BigDecimal("0");
        int gridcnt = setglg.getSetgll().size();
        boolean fnd = false;
        if (gridcnt > 0) {
            for (int i = 0; i < gridcnt; i++) {
                fnd = true;
                if (!(Strings.pos(rol, setglg.getSetgll().get(i).getRol()) > 0 || MdaUtils.isEmpty(rol))) {
                    fnd = false;
                }
                if (!(Strings.pos(flg, setglg.getSetgll().get(i).getFlg()) > 0 || MdaUtils.isEmpty(flg))) {
                    fnd = false;
                }
                if (!(Strings.pos(dsp, setglg.getSetgll().get(i).getDsp()) > 0 || MdaUtils.isEmpty(dsp))) {
                    fnd = false;
                }
                if (fnd) {
                    res = Decimals.add(res, setglg.getSetgll().get(i).getXrfamt());
                }
            }
        }
        return res;
    }

    /**
     * source:setglg.0007.script
     */
    @Override
    @JsonIgnore
    public int getSumtabRowForRole(SetglgVo setglg, String rol) {
        //! returns row in SETGLL with compressed amount for role ROL if it is exactly one row.
        //! If no ore more than one row is available for that role,  0 is returned
        // if empty, return 0
        if (MdaUtils.isEmpty(rol)) {
            return -1;
        }
        // serach for lines for ROL and count them
        int row = -1;
        int cnt = 0;
        int gridcnt = setglg.getSetgll().size();
        for (int i = 0; i < gridcnt; i++) {
            if (MdaUtils.compareTo(setglg.getSetgll().get(i).getRol(), rol) == 0 && MdaUtils.compareTo(setglg.getSetgll().get(i).getAcccpramt(), 0) != 0) {
                if (!setmodService.isInternalDsp(setglg.getSetgll().get(i).getDsp())) {
                    row = i;
                    cnt = cnt + 1;
                }
            }
        }
        // return row of ROL if and only if one line is available
        if (cnt == 1) {
            return row;
        } else {
            return -1;
        }
    }

    /**
     * source:setglg.0011.script
     */
    @Override
    public void internalWrkSumCollect(SetglgVo setglg) {
        // ex default WRKSUM
        MdaUtils.clear(setglg.getWrksumcon());
        // collect amounts set from other modules
        int stmCnt = Streams.streamCount(setglg.getSetglgamtcon());
        String line = NULLSTR;
        int tabpos = 0;
        String modid = NULLSTR;
        BigDecimal amt = null;
        Date val = null;
        String payrol = NULLSTR;
        int gllGrpidx = 0;
        String gllGrplin = NULLSTR;
        String gllGrp = NULLSTR;
        int modidx = 0;
        int amtpos = 0;
        BigDecimal wrkamt = null;
        for (int d = 1; d <= stmCnt; d++) {
            line = Strings.getLine(setglg.getSetglgamtcon(), d);
            tabpos = Strings.pos(line, TAB);
            modid = Strings.mid(line, 1, tabpos - 1);
            line = Strings.mid(line, tabpos + 1);
            line = Strings.mid(line, 1, Strings.pos(line, CR) - 1);
            Wrksum wrksum = setfegService.getFeeSet().getWrksum(modid + TAB + line);
            if (wrksum != null) {
                amt = wrksum.getAmt();
                val = wrksum.getValdat();
                if (MdaUtils.compareTo(wrksum.getAmt(), 0) != 0 || (MdaUtils.isEmpty(setglg.getCreemplinflg()))) {
                    // redirect if other role is set for amounts to settle by SetPtyGllPty
                    payrol = setmodService.getGllRol(wrksum.getRol());
                    // add line to GLLSEPSTM, if acutal line is not in yet
                    gllGrpidx = Streams.streamSearch(setglg.getGllgrpstm(), payrol + TAB + modid + TAB);
                    if (gllGrpidx == 0) {
                        Streams.streamInsert(setglg.getGllgrpstm(), 0, payrol + TAB + modid + TAB + getGllGrpFlg(setglg, payrol, modid));
                        gllGrpidx = Streams.streamCount(setglg.getGllgrpstm());
                    }
                    gllGrplin = Strings.getLine(setglg.getGllgrpstm(), gllGrpidx);
                    wrksum.setGllgrp(Strings.mid(gllGrplin, Strings.len(gllGrplin)));
                    if (MdaUtils.compareTo(wrksum.getGllgrp(), TAB) == 0) {
                        wrksum.setGllgrp(NULLSTR);
                    }
                    gllGrp = wrksum.getGllgrp();
                    Wrksum setglgWrksum = internalWrksumGetByKey(wrksum.getCur(), payrol, wrksum.getGllgrp(), wrksum.getDsp(), wrksum.getFcdinr(), wrksum.getDspflg(), wrksum.getAct());
                    if (MdaUtils.isEmpty(setglgWrksum.getRol())) {
                        //wrksum = setfegService.getFeeSet().getWrksum(modid + TAB + line);
                        BeanUtils.copyProperties(wrksum, setglgWrksum);
                        setglgWrksum.setRol(payrol);
                    } else {
                        setglgWrksum.setAmt(Decimals.add(setglgWrksum.getAmt(), amt));
                        setglgWrksum.setAmt2(setglgWrksum.getAmt());
                        if (!MdaUtils.isEmpty(val)) {
                            setglgWrksum.setValdat(val);
                        }
                    }
                    // do not set VALDAT here. VALDAT only set, if transaction wants it by setting it in SETAMT
                    // Only if empty, VALDAT is set by Chksumtab using adjustments defined in DBICUR
                    //    WRKSUM\\VALDAT = Today
                    if (MdaUtils.isEmpty(setglgWrksum.getFlg())) {
                        setglgWrksum.setFlg("D");
                    }
                    setglgWrksum.setGllgrp(gllGrp);
                    modidx = Streams.streamSearch(setglgWrksum.getAmtidsstm(), modid + TAB);
                    if (modidx == 0 && MdaUtils.compareTo(amt, 0) != 0) {
                        Streams.streamInsert(setglgWrksum.getAmtidsstm(), 0, modid + TAB + setglgWrksum.getCur() + TAB + MdaUtils.toString(amt) + TAB);
                    } else {
                        line = Strings.getLine(setglgWrksum.getAmtidsstm(), modidx);
                        amtpos = Strings.pos(line, setglgWrksum.getCur() + TAB) + 4;
                        tabpos = Strings.pos(Strings.mid(line, amtpos, 30), TAB);
                        wrkamt = Decimals.add(Strings.parseInt(Strings.mid(line, amtpos, tabpos - 1)), amt);
                        Streams.streamSetLine(setglgWrksum.getAmtidsstm(), modidx, modid + TAB + setglgWrksum.getCur() + TAB + MdaUtils.toString(wrkamt) + TAB);
                    }
                    internalWrksumSet(setglg, setglgWrksum);
                }
            }
        }
        // final adjustments
        // StreamCount must be used in loop, because WRKCOMCON may be changed in InternalWrkumSet
        for (int i = 1; i <= Streams.streamCount(setglg.getWrksumcon()); i++) {
            Wrksum wrksum = setfegService.getFeeSet().getWrksum("SETGLG" + TAB + Strings.getLine(setglg.getWrksumcon(), i));
            if (wrksum != null) {
                // clear lines with empty amounts and credit lines if not final settlement (only debits are advised)
                if (MdaUtils.compareTo(wrksum.getAmt(), 0) == 0 || (MdaUtils.compareTo(wrksum.getAmt(), 0) < 0 || MdaUtils.compareTo(wrksum.getRol(), "OWN") == 0)) {
                    wrksum = new Wrksum();
                    internalWrksumSet(setglg, wrksum);
                }
            }
        }
    }

    /**
     * source:setglg.0012.script
     */
    @Override
    public Wrksum internalWrksumGetByKey(String argCur, String argRol, String argGllGrp, String argDsp, String argFcDinr, String argDspFlg, String argact) {
        Wrksum setglgWrksum = setfegService.getFeeSet().getWrksum("SETGLG" + TAB + argCur + TAB + argRol + TAB + argGllGrp + TAB + argDsp + argDspFlg + TAB + argFcDinr + TAB + argact);
        if (setglgWrksum == null) {
            setglgWrksum = new Wrksum();
        } else {
            if (MdaUtils.compareTo(setglgWrksum.getFlg(), "R") == 0) {
                setglgWrksum = new Wrksum();
            }
        }
        return setglgWrksum;

    }

    /**
     * source:setglg.0013.script
     */
    @Override
    public void internalWrksumSet(SetglgVo setglg, Wrksum wrksum) {
        String wrksumconKey = wrksum.getCur() + TAB + wrksum.getRol() + TAB + wrksum.getGllgrp() + TAB + wrksum.getDsp() + wrksum.getDspflg() + TAB + wrksum.getFcdinr() + TAB + wrksum.getAct();
        if (MdaUtils.compareTo(wrksum.getFlg(), "R") == 0) {
            wrksumconKey = wrksumconKey + TAB + MdaUtils.toString(Streams.streamCount(setglg.getWrksumcon()));
        }
        //金额为0 从wrksum中移除
        if (wrksum.getAmt().compareTo(BigDecimal.ZERO) == 0) {
            log.info("Wrksum 合并之后金额为0, 从wrksumMap中去掉这条记录,key{}", wrksumconKey);
            setfegService.getFeeSet().clearWrksum(wrksumconKey);
            return;
        }
        if (Streams.streamSearch(setglg.getWrksumcon(), wrksumconKey) == 0) {
            Streams.streamInsert(setglg.getWrksumcon(), 0, wrksumconKey);
        }
        setfegService.getFeeSet().putWrksum("SETGLG" + TAB + wrksumconKey, wrksum);
    }

    /**
     * source:setglg.0014.script
     */
/*
    @Override
    public void internalWrksumGetByIdx(SetglgVo setglg, int argIdx) {
        //! Gets WRKSUM of line ArgIdx in WRKSUMCON
        String lin = NULLSTR;
        if (argIdx < 1 || argIdx > Streams.streamCount(setglg.getWrksumcon())) {
            MdaUtils.clear(setglg.getWrksum());
        } else {
            lin = Strings.getLine(setglg.getWrksumcon(), argIdx);
            Caches.cacheRead(setglg.getWrksum(), "SETGLG", lin);
            if (setglg.getWrksum() == null) {
                MdaUtils.clear(setglg.getWrksum());
            }
        }
    }
*/

    /**
     * source:setglg.0015.script
     */
    @Override
    @JsonIgnore
    public String setglgAddAmount(SetglgVo setglg, String argId, String argRol, String argCur, BigDecimal argAmt, String argAmttyp, String argDsp, String argDspFlg, String argAct, String argFcdInr) {
        //! Add Amount Argamt to amounts to be settled to ArgRol
        //! ArgId: Id of Caller. All amounts of an ArgId can be removed using SetglgClrAmount
        //! ArgRol : Role for which amount is to be added
        //! ArgCur/ArgAmt: Amount to be added. If the amount is < 0 it is credited, if > 0 it is debitied.
        //!                Calls with amount zero are allowed
        //! The following parameters are optional:
        //! ArgAmtTyp    : Type of amount (has to be a key of codetable SETSUMW:DOCAMTTYP )
        //! ArgDsp       : Default disposition
        //! ArgDspflg    : Controls, which fields may be chancge by user
        //!                Default (empty): Disposition, Currency and Account modifiable
        //!                F: Disposition disabled; Currency and Account modifiable
        //!                C:Disposition and Currency disabled; Account modifiable
        //!                A:Disposition, Currency and Account disabled
        //! ArgAct       : Default Account
        //! ArgFcdInr    : INR of forward contract to be used
        //!
        //! Function returns key allowing setting additional information with SetglgAddAmtFld<xxx> -Functions
        String cacKey = argCur + TAB + argRol + TAB + argAmttyp + TAB + argDsp + argDspFlg + TAB + argAct + argFcdInr;
        Wrksum wrksum = setfegService.getFeeSet().getWrksum(argId + TAB + cacKey);
        if (wrksum == null) {
            wrksum = new Wrksum();
        }
        wrksum.setAmt(Decimals.add(wrksum.getAmt(), argAmt));
        wrksum.setAmt2(Decimals.add(wrksum.getAmt2(), argAmt));
        wrksum.setCur(argCur);
        wrksum.setRol(argRol);
        wrksum.setDsp(argDsp);
        wrksum.setDspflg(argDspFlg);
        wrksum.setAct(argAct);
        wrksum.setFcdinr(argFcdInr);
        wrksum.setDocamttyp(argAmttyp);
        // Set flag, if not called from settlement (fees)
        if (MdaUtils.compareTo(Strings.mid(argId, 1, 4), "*SET") != 0) {
            // If Argdspflg is set, set Flag to "R"
            if (MdaUtils.isEmpty(argDspFlg)) {
                wrksum.setFlg("D");
            } else {
                wrksum.setFlg("R");
            }
        }
        /**
         if IsEmpty( WRKSUM\\VALDAT ) and Pos( DSPFLG, "G" ) > 0 then
         WRKSUM\\VALDAT = Today
         endif
         **/
        internalSetAmountCache(setglg, wrksum, argId, cacKey);
        return cacKey;
    }

    /**
     * source:setglg.0016.script
     */
    @Override
    @JsonIgnore
    public void setglgClrAmount(SetglgVo setglg, String argId) {
        //! Clear Amounts for Id ArgId to allow complete redefaulting with following calls of SetglgAddAmount
        // remove Cache entries for Argid
        setfegService.getFeeSet().clearWrksum(argId);
        // remove entries from control stream
        String sea = argId + TAB;
        int row = 0;
        do {
            row = Streams.streamSearch(setglg.getSetglgamtcon(), sea);
            if (row > 0) {
                Streams.streamDelete(setglg.getSetglgamtcon(), row);
            }
        } while (!(row == 0));
    }

    /**
     * source:setglg.0017.script
     */
    @Override
    public void internalSetAmountCache(SetglgVo setglg, Wrksum wrksum, String argId, String argCacheKey) {
        String stmKey = argId + TAB + argCacheKey;
        setfegService.getFeeSet().putWrksum(stmKey, wrksum);
        IStream wrksumstm = new StreamImpl();
        Streams.streamClear(wrksumstm);
        Utils.saveData(wrksum, wrksumstm, "", "");
        String mac = Systems.macGen(wrksumstm, 0);
        int lin = Streams.streamSearch(setglg.getSetglgamtcon(), stmKey);
        if (lin == 0) {
            Streams.streamInsert(setglg.getSetglgamtcon(), 0, stmKey + CR + mac);
        } else {
            Streams.streamSetLine(setglg.getSetglgamtcon(), lin, stmKey + CR + mac);
        }
    }

    /**
     * source:setglg.0018.script
     */
    @Override
    public void setglgAddAmtFldAccCur(SetglgVo setglg, String argID, String argKey, String argAccCur) {
        //! Set account currency and disposition of an amount booked
        //!
        //! ArgId:     Id of Caller. All amounts of an ArgId can be removed using SetglgClrAmount
        //! ArgKey:    Key returned by SetglgAddAmount when registering the amount
        //! ArgAccCur : Currency to be defaulted as account currency
        Wrksum wrksum = setfegService.getFeeSet().getWrksum(argID + TAB + argKey);
        if (wrksum == null) {
            wrksum = new Wrksum();
        }
        wrksum.setAcccur(argAccCur);
        internalSetAmountCache(setglg, wrksum, argID, argKey);
    }

    @Override
    public void setglgAddAmtFldAccCurAmt(SetglgVo setglg, String argID, String argKey, String argAccCur, BigDecimal argAccAmt) {
        //! Set account currency and disposition of an amount booked
        //!
        //! ArgId:     Id of Caller. All amounts of an ArgId can be removed using SetglgClrAmount
        //! ArgKey:    Key returned by SetglgAddAmount when registering the amount
        //! ArgAccCur : Currency to be defaulted as account currency
        Wrksum wrksum = setfegService.getFeeSet().getWrksum(argID + TAB + argKey);
        if (wrksum == null) {
            wrksum = new Wrksum();
        }
        wrksum.setAcccur(argAccCur);
        wrksum.setAccamt(argAccAmt);
        internalSetAmountCache(setglg, wrksum, argID, argKey);
    }

    /**
     * source:setglg.0019.script
     */
    @Override
    public void setglgAddAmtFldValDat(SetglgVo setglg, String argId, String argKey, Date argValdat) {
        //! Set value Date of an amount booked
        //!
        //! ArgCallMod: Id of Caller. All amounts of an ArgId can be removed using SetglgClrAmount
        //! ArgKey: Key returned by SetglgAddAmount when registering the amount
        //! ArgValDat : Value Date
        Wrksum wrksum = setfegService.getFeeSet().getWrksum(argId + TAB + argKey);
        if (wrksum == null) {
            wrksum = new Wrksum();
        }
        wrksum.setValdat(argValdat);
        internalSetAmountCache(setglg, wrksum, argId, argKey);
    }

    /**
     * source:setglg.0020.script
     */
    public void setglgAddAmtFldExtRat(SetglgVo setglg, String argId, String argKey, BigDecimal argScbExtRat, BigDecimal argDcbExtRat) {
        //! Set rates for amount booked (used for forward contracts by LIACCV only)
        //!
        //! ArgCallMod: Id of Caller. All amounts of an ArgId can be removed using SetglgClrAmount
        //! ArgKey: Key returned by SetglgAddAmount when registering the amount
        //! ArgScbExtRat : ScbExtRat to be used
        //! ArgDcbExtRat : DcbExtRat to be used
        Wrksum wrksum = setfegService.getFeeSet().getWrksum(argId + TAB + argKey);
        if (wrksum == null) {
            wrksum = new Wrksum();
        }
        wrksum.setDcbextrat(argDcbExtRat);
        wrksum.setScbextrat(argScbExtRat);
        internalSetAmountCache(setglg, wrksum, argId, argKey);
    }

    @Override
    public void setglgAddAmtFldDisabled(SetglgVo setglg, String argId, String argKey, String... fields) {
        if (fields == null) {
            return;
        }
        Wrksum wrksum = setfegService.getFeeSet().getWrksum(argId + TAB + argKey);
        if (wrksum == null) {
            wrksum = new Wrksum();
        }
        for (String field : fields) {
            wrksum.setDisable(field);
        }
        internalSetAmountCache(setglg, wrksum, argId, argKey);
    }

    /**
     * source:setglg.0022.script
     */
    public void recalcSetglgEog(SetmodVo setmod) throws CommonServiceException {
        SetglgVo setglg = setmod.getSetglg();
        // Format : MAC+TAB+ Str(line)
        IStream ctlStm = new StreamImpl();
        Streams.streamClear(ctlStm);
        List<MessageDetailVo> msgDets = new ArrayList<>();
        //int gridcnt = Grids.gridCount(this.getSetgll());
        int gridcnt = setglg.getSetgll().size();
        int ctlIdx = 0;
        String ctllin = NULLSTR;
        int oldlin = 0;
        for (int i = 0; i < gridcnt; i++) {
            if (MdaUtils.isEmpty(setglg.getSetgll().get(i).getAccamt())) {
                setglg.getSetgll().get(i).setAcccpramt(new BigDecimal(0));
            } else {
                ctlIdx = Streams.streamSearch(ctlStm, setglg.getSetgll().get(i).getCprmac() + TAB);
                if (ctlIdx == 0) {
                    setglg.getSetgll().get(i).setAcccpramt(setglg.getSetgll().get(i).getAccamt());
                    Streams.streamInsert(ctlStm, 0, setglg.getSetgll().get(i).getCprmac() + TAB + MdaUtils.toString(i));
                    Streams.streamClear(setglg.getSetgll().get(i).getCprlinlst());
                    Streams.streamInsert(setglg.getSetgll().get(i).getCprlinlst(), 0, MdaUtils.toString(i));
                } else {
                    ctllin = Strings.getLine(ctlStm, ctlIdx);
                    oldlin = Strings.parseInt(Strings.mid(ctllin, Strings.pos(ctllin, TAB) + 1));
                    setglg.getSetgll().get(i).setAcccpramt(new BigDecimal(0));
                    // the old line gets amount of this line, if same direction or amount in old line is greater or equal amount of this line
                    if (Numerics.sgn(setglg.getSetgll().get(oldlin).getAcccpramt()) == Numerics.sgn(setglg.getSetgll().get(i).getAccamt()) || MdaUtils.compareTo(Numerics.abs(setglg.getSetgll().get(oldlin).getAcccpramt()), Numerics.abs(setglg.getSetgll().get(i).getAccamt())) >= 0) {
                        setglg.getSetgll().get(oldlin).setAcccpramt(Decimals.add(setglg.getSetgll().get(oldlin).getAcccpramt(), setglg.getSetgll().get(i).getAccamt()));
                        Streams.streamClear(setglg.getSetgll().get(i).getCprlinlst());
                        Streams.streamInsert(setglg.getSetgll().get(i).getCprlinlst(), 0, MdaUtils.toString(i));
                    } else {
                        // otherwise this line is the new line for the compressed amount
                        setglg.getSetgll().get(i).setAcccpramt(Decimals.add(setglg.getSetgll().get(oldlin).getAcccpramt(), setglg.getSetgll().get(i).getAccamt()));
                        Streams.streamSetLine(ctlStm, ctlIdx, setglg.getSetgll().get(i).getCprmac() + TAB + MdaUtils.toString(i));
                        Streams.streamSet(setglg.getSetgll().get(i).getCprlinlst(), setglg.getSetgll().get(oldlin).getCprlinlst());
                        Streams.streamInsert(setglg.getSetgll().get(i).getCprlinlst(), 0, MdaUtils.toString(i));
                        setglg.getSetgll().get(oldlin).setAcccpramt(new BigDecimal("0"));
                        Streams.streamClear(setglg.getSetgll().get(oldlin).getCprlinlst());
                    }
                }
            }
            //报文对象赋值
            if ("103".equals(setglg.getSetgll().get(i).getSftmt())) {
                MessageDetailVo messageDetail = new MessageDetailVo();
                messageDetail.setIdx(i);
                messageDetail.setType("103");
                messageDetail.setTitle(Strings.getText("客户汇款(MT103 $1 $2 $3)", setglg.getSetgll().get(i).getRol(), setglg.getSetgll().get(i).getAcccur(), xrtmodService.amtRnd(setglg.getSetgll().get(i).getFmtaccamt(), setglg.getSetgll().get(i).getAcccur())));
                msgDets.add(messageDetail);
            }
            if ("202".equals(setglg.getSetgll().get(i).getSftmt())) {
                MessageDetailVo messageDetail = new MessageDetailVo();
                messageDetail.setIdx(i);
                messageDetail.setType("202");
                messageDetail.setTitle(Strings.getText("头寸调拨(MT202 $1 $2 $3)", setglg.getSetgll().get(i).getRol(), setglg.getSetgll().get(i).getAcccur(), xrtmodService.amtRnd(setglg.getSetgll().get(i).getFmtaccamt(), setglg.getSetgll().get(i).getAcccur())));
                msgDets.add(messageDetail);
            }
            if ("CIU".equals(setglg.getSetgll().get(i).getSftmt())) {
                MessageDetailVo messageDetail = new MessageDetailVo();
                messageDetail.setIdx(i);
                messageDetail.setType("CIU");
                messageDetail.setTitle(Strings.getText("人民币跨境支付(CIPS111 $1 $2 $3)", setglg.getSetgll().get(i).getRol(), setglg.getSetgll().get(i).getAcccur(), xrtmodService.amtRnd(setglg.getSetgll().get(i).getFmtaccamt(), setglg.getSetgll().get(i).getAcccur())));
                msgDets.add(messageDetail);
            }
            if ("CIV".equals(setglg.getSetgll().get(i).getSftmt())) {
                MessageDetailVo messageDetail = new MessageDetailVo();
                messageDetail.setIdx(i);
                messageDetail.setType("CIV");
                messageDetail.setTitle(Strings.getText("人民币跨境支付(CIPS112 $1 $2 $3)", setglg.getSetgll().get(i).getRol(), setglg.getSetgll().get(i).getAcccur(), xrtmodService.amtRnd(setglg.getSetgll().get(i).getFmtaccamt(), setglg.getSetgll().get(i).getAcccur())));
                msgDets.add(messageDetail);
            }
            if ("400".equals(setglg.getSetgll().get(i).getSftmt())) {
                MessageDetailVo messageDetail = new MessageDetailVo();
                messageDetail.setIdx(i);
                messageDetail.setType("400");
                messageDetail.setTitle(Strings.getText("付款通知(MT400 $1 $2 $3)", setglg.getSetgll().get(i).getRol(), setglg.getSetgll().get(i).getAcccur(), xrtmodService.amtRnd(setglg.getSetgll().get(i).getFmtaccamt(), setglg.getSetgll().get(i).getAcccur())));
                msgDets.add(messageDetail);
                if (StringUtils.isEmpty(setglg.getSetgll().get(i).getDirindflg())) {
                    messageDetail = new MessageDetailVo();
                    messageDetail.setIdx(i);
                    messageDetail.setType("202");
                    messageDetail.setTitle(Strings.getText("头寸调拨(MT202 $1 $2 $3)", setglg.getSetgll().get(i).getRol(), setglg.getSetgll().get(i).getAcccur(), xrtmodService.amtRnd(setglg.getSetgll().get(i).getFmtaccamt(), setglg.getSetgll().get(i).getAcccur())));
                    msgDets.add(messageDetail);
                }
            }
            if ("756".equals(setglg.getSetgll().get(i).getSftmt())) {
                MessageDetailVo messageDetail = new MessageDetailVo();
                messageDetail.setIdx(i);
                messageDetail.setType("756");
                messageDetail.setTitle(Strings.getText("通知付款(MT756 $1 $2 $3)", setglg.getSetgll().get(i).getRol(), setglg.getSetgll().get(i).getAcccur(), xrtmodService.amtRnd(setglg.getSetgll().get(i).getFmtaccamt(), setglg.getSetgll().get(i).getAcccur())));
                msgDets.add(messageDetail);
                if (StringUtils.isEmpty(setglg.getSetgll().get(i).getDirindflg())) {
                    messageDetail = new MessageDetailVo();
                    messageDetail.setIdx(i);
                    messageDetail.setType("202");
                    messageDetail.setTitle(Strings.getText("头寸调拨(MT202 $1 $2 $3)", setglg.getSetgll().get(i).getRol(), setglg.getSetgll().get(i).getAcccur(), xrtmodService.amtRnd(setglg.getSetgll().get(i).getFmtaccamt(), setglg.getSetgll().get(i).getAcccur())));
                    msgDets.add(messageDetail);
                }
            }
            if ("111".equals(setglg.getSetgll().get(i).getSftmt())) {
                MessageDetailVo messageDetail = new MessageDetailVo();
                messageDetail.setIdx(i);
                messageDetail.setType("111");
                messageDetail.setTitle(Strings.getText("境内跨行贷记(FXPS111 $1 $2 $3)", setglg.getSetgll().get(i).getRol(), setglg.getSetgll().get(i).getAcccur(), xrtmodService.amtRnd(setglg.getSetgll().get(i).getFmtaccamt(), setglg.getSetgll().get(i).getAcccur())));
                msgDets.add(messageDetail);
            }
            if ("112".equals(setglg.getSetgll().get(i).getSftmt())) {
                MessageDetailVo messageDetail = new MessageDetailVo();
                messageDetail.setIdx(i);
                messageDetail.setType("112");
                messageDetail.setTitle(Strings.getText("银行间资金调拨(FXPS112 $1 $2 $3)", setglg.getSetgll().get(i).getRol(), setglg.getSetgll().get(i).getAcccur(), xrtmodService.amtRnd(setglg.getSetgll().get(i).getFmtaccamt(), setglg.getSetgll().get(i).getAcccur())));
                msgDets.add(messageDetail);
            }
            //对方账号缺少
            if (setglg.getSetgll().get(i).isOppaccLoseFlag()) {
                setglg.getSetgll().get(i).setOppacc(getOppacc(setglg.getSetgll(), setglg.getSetgll().get(i).getDebcdtflg()));
                setglg.getSetgll().get(i).setOppaccLoseFlag(false);
            }
        }
        setmod.getSetglg().setAvlMsgDetial(msgDets);
        String maceog = calcMaceog(setmod);
        setmod.getSetglg().setMaceogold(maceog);
    }

    /**
     * 获取对方账号方法
     * @param setgllVos
     * @param debcdtflg
     * @return
     */
    private String getOppacc(List<SetgllVo> setgllVos, String debcdtflg) {
        String oppacc = "";
        if(MdaUtils.compareTo(debcdtflg, "C") == 0) {
            for (int i=0; i<setgllVos.size(); i++) {
                if ("D".equalsIgnoreCase(setgllVos.get(i).getDebcdtflg())) {
                    oppacc = setgllVos.get(i).getAct();
                }
            }
        }
        if(MdaUtils.compareTo(debcdtflg, "D") == 0) {
            for (int i=0; i<setgllVos.size(); i++) {
                if ("C".equalsIgnoreCase(setgllVos.get(i).getDebcdtflg())) {
                    oppacc = setgllVos.get(i).getAct();
                }
            }
        }
        return oppacc;
    }

    /**
     * source:setglg.0024.script
     */
    @Override
    public void internalGetGlp(SetglgVo setglg, SetmodVo setmod) {
        //! Get GLP to SEP\\INR and set into SETGLL-entries
        //! For internal use only
        // get INRs for GLPs linked to SEP\\INR
    }


    /**
     * source:setglg.0026.script
     */
    @Override
    public void internalSetValdat(SetglgVo setglg, int argLin, Date argValdat) {
        //! Set value date in SETGLL-Line
        //! (used internally by InternalGllAdjust)
        if (!MdaUtils.isEmpty(argValdat)) {
            setglg.getSetgll().get(argLin).setValdattrn(argValdat);
        }
        if (!setglg.getSetgll().get(argLin).isModified("valdat")) {
            if (!MdaUtils.isEmpty(setglg.getAllvaldat()) || MdaUtils.compareTo(setglg.getAllvaldatflg(), "N") == 0) {
                setglg.getSetgll().get(argLin).setValdat(setglg.getAllvaldat());
            } else {
                if ((MdaUtils.isEmpty(setglg.getSetgll().get(argLin).getGlpinr()) || MdaUtils.isEmpty(setglg.getSetgll().get(argLin).getValdat()))) {
                    if (!MdaUtils.isEmpty(setglg.getSetgll().get(argLin).getValdattrn())) {
                        setglg.getSetgll().get(argLin).setValdat(setglg.getSetgll().get(argLin).getValdattrn());
                    } else {
                        Cur wrkCur = xrtmodService.getCurByCode(setglg.getSetgll().get(argLin).getAcccur());
                        if (MdaUtils.isEmpty(argValdat)) {
                            Date val = Dates.today();
                            //liuwenqing要求只有pac才根据假期和usr表中维护的标准
                            if (MdaUtils.compareTo(setglg.getSetgll().get(argLin).getDsp(), "PAC") == 0) {
                                if (MdaUtils.compareTo(setglg.getSetgll().get(argLin).getAmt(), 0) < 0) {
                                    setglg.getSetgll().get(argLin).setValdat(setmodService.addDays(setglg.getSetgll().get(argLin).getAcccur(), val, wrkCur.getCdtday(), true));
                                } else {
                                    setglg.getSetgll().get(argLin).setValdat(setmodService.addDays(setglg.getSetgll().get(argLin).getAcccur(), val, wrkCur.getDbtday(), true));
                                }
                            } else {
                                setglg.getSetgll().get(argLin).setValdat(val);
                            }
                        } else {
                            setglg.getSetgll().get(argLin).setValdat(argValdat);
                        }
                    }
                }
            }
        }
    }

    /**
     * source:setglg.0027.script
     */
    @Override
    @JsonIgnore
    public String getGllGrpFlg(SetglgVo setglg, String argrol, String argid) {
        //! Get default group flag (as defined with SetDefaultGlgGrp)
        // default is no (empty) group code
        String res = "";
        // If entry for all roles exists, take it
        int allidx = Streams.streamSearch(setglg.getGllgrpdftstm(), "*" + TAB + argid + TAB);
        String alllin = NULLSTR;
        if (allidx > 0) {
            alllin = Strings.getLine(setglg.getGllgrpdftstm(), allidx);
            res = Strings.mid(alllin, Strings.len(alllin), 1);
        }
        // If entry for specified roles exists, even overwrite the definition for all
        int oldidx = Streams.streamSearch(setglg.getGllgrpdftstm(), argrol + TAB + argid + TAB);
        String oldlin = NULLSTR;
        if (oldidx > 0) {
            oldlin = Strings.getLine(setglg.getGllgrpdftstm(), oldidx);
            res = Strings.mid(oldlin, Strings.len(oldlin), 1);
        }
        return res;
    }

    /**
     * source:setglg.0028.script
     */
    @Override
    public void setDefaultGlgGrp(SetglgVo setglg, String argrol, String argId, String argGllGrp) {
        //! Sets default group for defaulting in SETGLL
        //! ArgRol   : Role for which setting should be valid (use * for all roles)
        //! ArgId    : ID for which setting should be valid (as used in SetglgAddAmount)
        //! ArgGllGrp: One digit group code.
        //!            Entries for each group code are totalled up in settlement.
        if (Strings.len(argGllGrp) > 1) {
            SettleExceptionUtils.sysDump("Error in call of SetDefaultGlgGrp : Group code " + argGllGrp + " has more than one digit");
        }
        boolean changed = false;
        String newLin = argrol + TAB + argId + TAB + argGllGrp;
        int oldidx = Streams.streamSearch(setglg.getGllgrpdftstm(), argrol + TAB + argId);
        String oldlin = NULLSTR;
        if (oldidx == 0) {
            changed = true;
            Streams.streamInsert(setglg.getGllgrpdftstm(), 0, newLin);
        } else {
            oldlin = Strings.getLine(setglg.getGllgrpdftstm(), oldidx);
            if (MdaUtils.compareTo(oldlin, newLin) != 0) {
                changed = true;
                Streams.streamSetLine(setglg.getGllgrpdftstm(), oldidx, newLin);
            }
        }
        // On changes GLLGRPSTM has to be reset as the defaulting may change.
        // If there has been manually changes, just a warning is set.
        if (changed) {
            if (!setglg.isModified("gllgrpstm")) {
                setglg.setGllgrpstm(new StreamImpl());
            } else {
                log.warn("Splitting of settlement lines has been defined manually.\nRedefaulting has been stopped.");
            }
        }
    }

    /**
     * source:setglg.0029.script
     */
    @Override
    @JsonIgnore
    public int getNumberOfSettledRowsForRole(SetglgVo setglg, String rol) {
        //! Calculates the number of rows in 3.grid of settlement for the given role
        // Argument rol contains the role of the receiver
        int fnd = 0;
        int gllcnt = setglg.getSetgll().size();
        for (int i = 0; i < gllcnt; i++) {
            if (MdaUtils.compareTo(setglg.getSetgll().get(i).getRol(), rol) == 0) {
                if (MdaUtils.compareTo(setglg.getSetgll().get(i).getAcccpramt(), 0) != 0) {
                    fnd = fnd + 1;
                }
            }
        }
        return fnd;
    }

    /**
     * source:setglg.0030.script
     */
    @Override
    @JsonIgnore
    public BigDecimal getFinAmtSys(SetglgVo setglg, String rol) {
        //! get amount financed in system currency
        BigDecimal res = new BigDecimal("0");
        int gridcnt = setglg.getSetgll().size();
        if (gridcnt > 0) {
            for (int i = 0; i < gridcnt; i++) {
                if (MdaUtils.compareTo(setglg.getSetgll().get(i).getRol(), rol) == 0 && MdaUtils.compareTo(setglg.getSetgll().get(i).getFlg(), "F") != 0) {
                    switch (setglg.getSetgll().get(i).getDsp()) {
                        case "TRF":
                        case "BAT":
                        case "BRF":
                            res = Decimals.add(res, setglg.getSetgll().get(i).getXrfamt());
                            break;
                    }
                }
            }
        }
        return res;
    }

    /**
     * source:setglg.0031.script
     */
    @Override
    @JsonIgnore
    public boolean isexternaldsp(String dsp) {
        return false;
        //去掉PAY的控制
        // 去掉这个判断
       /* if (true) return false;
        if (MdaUtils.compareTo(dsp, "BAT") == 0 || MdaUtils.compareTo(dsp, "TRF") == 0) {
            //if Dsp = "BAT" or Dsp = "TRF" or Dsp = "PAY" then
            return true;
        } else {
            return false;
        }*/
    }

    /**
     * source:setglg.0032.script
     */
/*
    @Override
    @TDMethod
    public void registerdocuments(SetglgVo setglg) {
        int gridcnt = setglg.getSetgll().size();
        for (int i = 0; i < gridcnt; i++) {
            setgllService.registerDocument(setglg.getSetgll().get(i));
        }
    }
*/

    /**
     * source:setglg.0033.script
     */
    @Override
    public String getCprAdd(SetglgVo setglgVo, SetgllVo setgllVo) {
        //! Returns addon for correspondence for amount if line ArgGllIdx compresses amount
        StringBuilder res = new StringBuilder();
        String sgnstr;
        if (Streams.streamCount(setgllVo.getCprlinlst()) > 1) {
            res = new StringBuilder(Strings.getText(" ( $1 $2", setgllVo.getAcccur(), Utils.fmtAmount(setgllVo.getFmtaccamt(), setgllVo.getAcccur())));
            if (MdaUtils.compareTo(setgllVo.getAcccpramt(), 0) < 0) {
                sgnstr = "+ -";
            } else {
                sgnstr = "- +";
            }
            List<SetgllVo> setgllVoList = setglgVo.getSetgll();
            for (SetgllVo otherSetgllVo : setgllVoList) {
                if (MdaUtils.compareTo(otherSetgllVo.getCprmac(), setgllVo.getCprmac()) == 0 && setgllVoList.indexOf(otherSetgllVo) != setgllVoList.indexOf(setgllVo)) {
                    res.append(Strings.getText(" $1 $2 $3", Strings.mid(sgnstr, Numerics.sgn(otherSetgllVo.getAccamt()) + 2, 1), otherSetgllVo.getAcccur(), Utils.fmtAmount(otherSetgllVo.getFmtaccamt(), otherSetgllVo.getAcccur())));
                }
            }
            res.append(" ) ");
        }
        return res.toString();
    }

    /**
     * source:setglg.0034.script
     */
    @Override
    public void getRateXrtWithResRatesZZZ(Ptyrat ptyrat, String argCur, String basCur, boolean ininFlg, String typ, Date value, Argument<BigDecimal> rat, Argument<BigDecimal> sqrRat, Argument<BigDecimal> resRat, Argument<BigDecimal> rebRat) {
        //! Routine to get rates for a passed currency
        //!
        //! ArgCur: Currency rate to be retrieved for
        //! BasCur: Base rate currency
        //! IninFlg: To be set, if IN/IN conversion (to be retrieved using XrtCheckInIn)
        //! Typ: Rate type (Rate type has to be one of the keys defined in Codetable XRTMOD:RATTYP)
        //! Value: Date for which the rates are to be read
        //!
        //! Rat: The rate requested
        //! SqrRat: Squaring rate used in some booking systems
        //! ResRat: Reference selling rate
        //! RebRat: Reference buying rate
        //!
        //! Corresponding functions: GetRateXrt
        BigDecimal vrat = new BigDecimal("1");
        BigDecimal sqrrat = new BigDecimal("1");
        String newcur = NULLSTR;
        String currency = NULLSTR;
        if (MdaUtils.compareTo(argCur, basCur) == 0) {
            rat.value = new BigDecimal("1");
            sqrRat.value = new BigDecimal("1");
            resRat.value = new BigDecimal("1");
            rebRat.value = new BigDecimal("1");
        } else {
            Cur wrkCur = new Cur();
            Xrt wrkXrt = new Xrt();
            newcur = xrtmodService.getCurNewCur(argCur);
            if (ininFlg || MdaUtils.compareTo(basCur, newcur) == 0) {
                vrat = xrtmodService.getCurGlbRat(argCur);
                sqrrat = vrat;
            } else {
                if (MdaUtils.isEmpty(newcur)) {
                    currency = argCur;
                } else {
                    currency = newcur;
                }

                xrtmodService.getXrt(currency, value, wrkCur, wrkXrt);
                //  Note for supporter:
                //   The rate types supported in the following case has to be availabe in codetable XRTMOD:RATTYP.
                //   Thus make sure to update that embedded codetable if you add or remove the support of rate types.
                switch (typ) {
                    //--------汇率优惠方式和点数使用新表ptyrat----
                    //--------以下统一将取优惠方式和点数的模块\\TRNMOD\\PTSMOD\\PTY\\改为\\TRNMOD\\PTSMOD\\PTYRAT\\
                    case "S":
                        if (ptyrat != null && MdaUtils.compareTo(Strings.trim(ptyrat.getSeltyp()), "1") == 0) {
                            //日圆从小数点后6位开始优惠
                            if (MdaUtils.compareTo(currency, "JPY") == 0) {
                                vrat = Decimals.sub(wrkXrt.getSelrat(), Decimals.div(ptyrat.getSelrat(), 1000000));
                                sqrrat = Decimals.sub(vrat, Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                            } else {
                                //港币按点差优惠的计算方法是1bp=小数点后第4位
                                //刘文青需求
                                //  if $currency = "HKD" then
                                //   $rat = \\CBSMOD\\XRTMOD\\XRT\\SELRAT - \\TRNMOD\\PTSMOD\\PTY\\SELRAT / 100000
                                //  $sqrrat = $rat - \\CBSMOD\\XRTMOD\\CUR\\SQRMAR * \\CBSMOD\\XRTMOD\\XRTRATDIR
                                //  else
                                vrat = Decimals.sub(wrkXrt.getSelrat(), Decimals.div(ptyrat.getSelrat(), 10000));
                                sqrrat = Decimals.sub(vrat, Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                                //  endif
                            }
                        } else if (ptyrat != null && MdaUtils.compareTo(Strings.trim(ptyrat.getSeltyp()), "2") == 0) {
                            vrat = Decimals.sub(wrkXrt.getSelrat(), Decimals.div(Decimals.mul((Decimals.sub(wrkXrt.getSelrat(), wrkXrt.getMidrat())), ptyrat.getSelrat()), 100));
                            sqrrat = Decimals.sub(Decimals.sub(wrkXrt.getSelrat(), Decimals.div(Decimals.mul((Decimals.sub(wrkXrt.getSelrat(), wrkXrt.getMidrat())), ptyrat.getSelrat()), 100)), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        } else {
                            vrat = wrkXrt.getSelrat();
                            sqrrat = Decimals.sub(wrkXrt.getSelrat(), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        }
                        break;
                    case "B":
                        if (ptyrat != null && MdaUtils.compareTo(Strings.trim(ptyrat.getBuytyp()), "1") == 0) {
                            //日圆从小数点后6位开始优惠
                            if (MdaUtils.compareTo(currency, "JPY") == 0) {
                                vrat = Decimals.add(wrkXrt.getBuyrat(), Decimals.div(ptyrat.getBuyrat(), 1000000));
                                sqrrat = Decimals.add(vrat, Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                            } else {
                                //港币按点差优惠的计算方法是1bp=小数点后第4位
                                //刘文青需求
                                //  if $currency = "HKD" then
                                //    $rat = \\CBSMOD\\XRTMOD\\XRT\\BUYRAT + \\TRNMOD\\PTSMOD\\PTY\\BUYRAT / 100000
                                //    $sqrrat = $rat + \\CBSMOD\\XRTMOD\\CUR\\SQRMAR * \\CBSMOD\\XRTMOD\\XRTRATDIR
                                //  else
                                vrat = Decimals.add(wrkXrt.getBuyrat(), Decimals.div(ptyrat.getBuyrat(), 10000));
                                sqrrat = Decimals.add(vrat, Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                                //  endif
                            }
                        } else if (ptyrat != null && MdaUtils.compareTo(Strings.trim(ptyrat.getBuytyp()), "2") == 0) {
                            vrat = Decimals.add(wrkXrt.getBuyrat(), Decimals.div(Decimals.mul((Decimals.sub(wrkXrt.getMidrat(), wrkXrt.getBuyrat())), ptyrat.getBuyrat()), 100));
                            sqrrat = Decimals.add(Decimals.add(wrkXrt.getBuyrat(), Decimals.div(Decimals.mul((Decimals.sub(wrkXrt.getMidrat(), wrkXrt.getBuyrat())), ptyrat.getBuyrat()), 100)), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        } else {
                            vrat = wrkXrt.getBuyrat();
                            sqrrat = Decimals.add(wrkXrt.getBuyrat(), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        }
                        break;
                    case "T":
                        vrat = wrkXrt.getTtrrat();
                        sqrrat = Decimals.add(wrkXrt.getTtrrat(), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        break;
                    case "O":
                        vrat = wrkXrt.getOdrrat();
                        sqrrat = Decimals.add(wrkXrt.getOdrrat(), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        break;
                    case "M":
                        vrat = wrkXrt.getMidrat();
                        sqrrat = wrkXrt.getMidrat();
                        break;
                    case "A":
                        vrat = wrkXrt.getBuy1rat();
                        sqrrat = Decimals.add(wrkXrt.getBuy1rat(), Decimals.mul(Decimals.div(wrkCur.getSqrmar(), 2), xrtmodService.getXrtratdir()));
                        break;
                    case "H":
                        vrat = wrkXrt.getSel1rat();
                        sqrrat = Decimals.sub(wrkXrt.getSel1rat(), Decimals.mul(Decimals.div(wrkCur.getSqrmar(), 2), xrtmodService.getXrtratdir()));
                        break;
                    case "G":
                        vrat = xrtmodService.getCurGlbRat(argCur);
                        sqrrat = vrat;
                        break;
                    default:
                        /**
                         SysDump( "XRTMOD.GetRateXrtWithResRates called with unknown exchangerate typ. Typ = '" + Typ + "'" )
                         **/
                        SettleExceptionUtils.sysDump("SETGLG.GetRateXrtWithResRatesZZZ called with unknown exchangerate typ. Typ = '" + typ + "'");
                }
            }
            rat.value = Numerics.round(vrat, 6);
            sqrRat.value = Numerics.round(sqrrat, 6);
            resRat.value = wrkXrt.getResrat();
            rebRat.value = wrkXrt.getRebrat();
        }
    }

    /**
     * source:setglg.0035.script
     */
    @Override
    public boolean checkXrtChg(SetglgVo setglg) {
        //检核交易中间价是否发生变化
        //如变化给出提示是否继续
        boolean prompt = false;
        String buycur = "";
        BigDecimal buyrat = new BigDecimal("0.000000");
        String selcur = "";
        String fromcur = "";
        BigDecimal selrat = new BigDecimal("0.000000");
        BigDecimal midrat = new BigDecimal("0.000000");
        BigDecimal buymidrat = new BigDecimal("0.000000");
        BigDecimal selmidrat = new BigDecimal("0.000000");
        BigDecimal newmidrat = new BigDecimal("0.000000");
        BigDecimal buymidratchage = new BigDecimal("0.000000");
        BigDecimal buymidratbefore = new BigDecimal("0.000000");
        BigDecimal selmidratchage = new BigDecimal("0.000000");
        BigDecimal selmidratbefore = new BigDecimal("0.000000");
        int buytyp = 0;
        int seltyp = 0;
        boolean boolVar = false;
        int cnt = setglg.getSetgll().size();
        String whmtyp = NULLSTR;
        String datSql = NULLSTR;
        String getxrtsql = NULLSTR;
        int error = 0;
        if (cnt > 0) {
            for (int idx = 0; idx < cnt; idx++) {
                whmtyp = "";
                if (((MdaUtils.compareTo(setglg.getSetgll().get(idx).getAcccur(), xrtmodService.sysiso()) == 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getCur(), xrtmodService.sysiso()) != 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getAmt(), 0) < 0) || (MdaUtils.compareTo(setglg.getSetgll().get(idx).getAcccur(), xrtmodService.sysiso()) != 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getCur(), xrtmodService.sysiso()) == 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getAmt(), 0) > 0))) {
                    whmtyp = "3";
                } else {
                    if (((MdaUtils.compareTo(setglg.getSetgll().get(idx).getAcccur(), xrtmodService.sysiso()) == 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getCur(), xrtmodService.sysiso()) != 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getAmt(), 0) > 0) || (MdaUtils.compareTo(setglg.getSetgll().get(idx).getAcccur(), xrtmodService.sysiso()) != 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getCur(), xrtmodService.sysiso()) == 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getAmt(), 0) < 0))) {
                        whmtyp = "5";
                    }
                }
                //光大要求一笔业务中出现多次结售汇时只提示一次
                //光大业务中不会发生一笔业务中出现多币种的结售汇
                if (MdaUtils.compareTo(whmtyp, "") != 0) {
                    if (MdaUtils.compareTo(setglg.getSetgll().get(idx).getAcccur(), xrtmodService.sysiso()) != 0) {
                        fromcur = setglg.getSetgll().get(idx).getAcccur();
                    } else {
                        if (MdaUtils.compareTo(setglg.getSetgll().get(idx).getCur(), xrtmodService.sysiso()) != 0) {
                            fromcur = setglg.getSetgll().get(idx).getCur();
                        }
                    }
                    Xrt wrkXrt = xrtMapper.selectByCurWithDatRng(fromcur, Dates.today());
                    if (MdaUtils.compareTo(whmtyp, "3") == 0 && MdaUtils.compareTo(wrkXrt.getMidrat(), setglg.getSetgll().get(idx).getMidrat()) != 0) {
                        buycur = fromcur;
                        buymidratchage = wrkXrt.getBuyrat();
                        buymidratbefore = setglg.getSetgll().get(idx).getRat();
                        buytyp = 1;
                    } else {
                        if (MdaUtils.compareTo(whmtyp, "5") == 0 && MdaUtils.compareTo(wrkXrt.getMidrat(), setglg.getSetgll().get(idx).getMidrat()) != 0) {
                            selcur = fromcur;
                            selmidratchage = wrkXrt.getSelrat();
                            selmidratbefore = setglg.getSetgll().get(idx).getRat();
                            seltyp = 1;
                        }
                    }
                }
            }
        }
        if (buytyp == 1) {
            prompt = true;
            if (prompt) {
                boolVar = false;
            } else {
                return true;
            }
        }
        if (seltyp == 1) {
            prompt = true;
            if (prompt) {
                boolVar = false;
            } else {
                return true;
            }
        }
        // ####### 改写 LABEL与GOTO   ####    label done
        return false;
    }

    /**
     * source:setglg.0036.script
     */
    @Override
    public void getRateXrtWithResRatesZZZ_ZMQ(Ptyrat ptyrat, String argCur, String basCur, boolean ininFlg, String typ, Date value, Argument<BigDecimal> rat, Argument<BigDecimal> sqrRat, Argument<BigDecimal> resRat, Argument<BigDecimal> rebRat) {
        //! Routine to get rates for a passed currency
        //!
        //! ArgCur: Currency rate to be retrieved for
        //! BasCur: Base rate currency
        //! IninFlg: To be set, if IN/IN conversion (to be retrieved using XrtCheckInIn)
        //! Typ: Rate type (Rate type has to be one of the keys defined in Codetable XRTMOD:RATTYP)
        //! Value: Date for which the rates are to be read
        //!
        //! Rat: The rate requested
        //! SqrRat: Squaring rate used in some booking systems
        //! ResRat: Reference selling rate
        //! RebRat: Reference buying rate
        //!
        //! Corresponding functions: GetRateXrt
        //--zmqzmq--
        BigDecimal vrat = new BigDecimal("1");
        BigDecimal sqrrat = new BigDecimal("1");
        String newcur = NULLSTR;
        String currency = NULLSTR;
        if (MdaUtils.compareTo(argCur, basCur) == 0) {
            rat.value = new BigDecimal("1");
            sqrRat.value = new BigDecimal("1");
            resRat.value = new BigDecimal("1");
            rebRat.value = new BigDecimal("1");
        } else {
            Cur wrkCur = new Cur();
            Zmqxrt wrkZmqxrt = new Zmqxrt();
            newcur = xrtmodService.getCurNewCur(argCur);
            if (ininFlg || MdaUtils.compareTo(basCur, newcur) == 0) {
                vrat = xrtmodService.getCurGlbRat(argCur);
                sqrrat = vrat;
            } else {
                if (MdaUtils.isEmpty(newcur)) {
                    currency = argCur;
                } else {
                    currency = newcur;
                }
                xrtmodService.getzmqXrt(currency, value, wrkCur, wrkZmqxrt);
                //  Note for supporter:
                //   The rate types supported in the following case has to be availabe in codetable XRTMOD:RATTYP.
                //   Thus make sure to update that embedded codetable if you add or remove the support of rate types.
                switch (typ) {
                    //--------汇率优惠方式和点数使用新表ptyrat----
                    //--------以下统一将取优惠方式和点数的模块\\TRNMOD\\PTSMOD\\PTY\\改为\\TRNMOD\\PTSMOD\\PTYRAT\\
                    case "S":
                        if (ptyrat != null && MdaUtils.compareTo(Strings.trim(ptyrat.getSeltyp()), "1") == 0) {
                            //日圆从小数点后6位开始优惠
                            if (MdaUtils.compareTo(currency, "JPY") == 0) {
                                vrat = Decimals.sub(wrkZmqxrt.getSelrat(), Decimals.div(ptyrat.getSelrat(), 1000000));
                                sqrrat = Decimals.sub(vrat, Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                            } else {
                                //港币按点差优惠的计算方法是1bp=小数点后第4位
                                //刘文青需求
                                //  if $currency = "HKD" then
                                //   $rat = \\CBSMOD\\XRTMOD\\XRT\\SELRAT - \\TRNMOD\\PTSMOD\\PTY\\SELRAT / 100000
                                //  $sqrrat = $rat - \\CBSMOD\\XRTMOD\\CUR\\SQRMAR * \\CBSMOD\\XRTMOD\\XRTRATDIR
                                //  else
                                vrat = Decimals.sub(wrkZmqxrt.getSelrat(), Decimals.div(ptyrat.getSelrat(), 10000));
                                sqrrat = Decimals.sub(vrat, Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                                //  endif
                            }
                        } else if (ptyrat != null && MdaUtils.compareTo(Strings.trim(ptyrat.getSeltyp()), "2") == 0) {
                            vrat = Decimals.sub(wrkZmqxrt.getSelrat(), Decimals.div(Decimals.mul((Decimals.sub(wrkZmqxrt.getSelrat(), wrkZmqxrt.getMidrat())), ptyrat.getSelrat()), 100));
                            sqrrat = Decimals.sub(Decimals.sub(wrkZmqxrt.getSelrat(), Decimals.div(Decimals.mul((Decimals.sub(wrkZmqxrt.getSelrat(), wrkZmqxrt.getMidrat())), ptyrat.getSelrat()), 100)), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        } else {
                            vrat = wrkZmqxrt.getSelrat();
                            sqrrat = Decimals.sub(wrkZmqxrt.getSelrat(), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        }
                        break;
                    case "B":
                        if (ptyrat != null && MdaUtils.compareTo(Strings.trim(ptyrat.getBuytyp()), "1") == 0) {
                            //日圆从小数点后6位开始优惠
                            if (MdaUtils.compareTo(currency, "JPY") == 0) {
                                vrat = Decimals.add(wrkZmqxrt.getBuyrat(), Decimals.div(ptyrat.getBuyrat(), 1000000));
                                sqrrat = Decimals.add(vrat, Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                            } else {
                                //港币按点差优惠的计算方法是1bp=小数点后第4位
                                //刘文青需求
                                //  if $currency = "HKD" then
                                //    $rat = \\CBSMOD\\XRTMOD\\XRT\\BUYRAT + \\TRNMOD\\PTSMOD\\PTY\\BUYRAT / 100000
                                //    $sqrrat = $rat + \\CBSMOD\\XRTMOD\\CUR\\SQRMAR * \\CBSMOD\\XRTMOD\\XRTRATDIR
                                //  else
                                vrat = Decimals.add(wrkZmqxrt.getBuyrat(), Decimals.div(ptyrat.getBuyrat(), 10000));
                                sqrrat = Decimals.add(vrat, Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                                //  endif
                            }
                        } else if (ptyrat != null && MdaUtils.compareTo(Strings.trim(ptyrat.getBuytyp()), "2") == 0) {
                            vrat = Decimals.add(wrkZmqxrt.getBuyrat(), Decimals.div(Decimals.mul((Decimals.sub(wrkZmqxrt.getMidrat(), wrkZmqxrt.getBuyrat())), ptyrat.getBuyrat()), 100));
                            sqrrat = Decimals.add(Decimals.add(wrkZmqxrt.getBuyrat(), Decimals.div(Decimals.mul((Decimals.sub(wrkZmqxrt.getMidrat(), wrkZmqxrt.getBuyrat())), ptyrat.getBuyrat()), 100)), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        } else {
                            vrat = wrkZmqxrt.getBuyrat();
                            sqrrat = Decimals.add(wrkZmqxrt.getBuyrat(), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        }
                        break;
                    case "T":
                        vrat = wrkZmqxrt.getTtrrat();
                        sqrrat = Decimals.add(wrkZmqxrt.getTtrrat(), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        break;
                    case "O":
                        vrat = wrkZmqxrt.getOdrrat();
                        sqrrat = Decimals.add(wrkZmqxrt.getOdrrat(), Decimals.mul(wrkCur.getSqrmar(), xrtmodService.getXrtratdir()));
                        break;
                    case "M":
                        vrat = wrkZmqxrt.getMidrat();
                        sqrrat = wrkZmqxrt.getMidrat();
                        break;
                    case "A":
                        vrat = wrkZmqxrt.getBuy1rat();
                        sqrrat = Decimals.add(wrkZmqxrt.getBuy1rat(), Decimals.mul(Decimals.div(wrkCur.getSqrmar(), 2), xrtmodService.getXrtratdir()));
                        break;
                    case "H":
                        vrat = wrkZmqxrt.getSel1rat();
                        sqrrat = Decimals.sub(wrkZmqxrt.getSel1rat(), Decimals.mul(Decimals.div(wrkCur.getSqrmar(), 2), xrtmodService.getXrtratdir()));
                        break;
                    case "G":
                        vrat = xrtmodService.getCurGlbRat(argCur);
                        sqrrat = vrat;
                        break;
                    default:
                        SettleExceptionUtils.sysDump("SETGLG.GetRateXrtWithResRatesZZZ_ZMQ called with unknown exchangerate typ. Typ = '" + typ + "'");
                }
            }
            rat.value = Numerics.round(vrat, 6);
            sqrRat.value = Numerics.round(sqrrat, 6);
            resRat.value = wrkZmqxrt.getResrat();
            rebRat.value = wrkZmqxrt.getRebrat();
        }
    }

    /**
     * source:setglg.0037.script
     */
    @Override
    public boolean checkXrtChg_zmq(SetglgVo setglg) {
        //--zmqzmq---
        //检核交易中间价是否发生变化
        //如变化给出提示是否继续
        boolean prompt = true;
        String buycur = "";
        BigDecimal buyrat = new BigDecimal("0.000000");
        String selcur = "";
        String fromcur = "";
        BigDecimal selrat = new BigDecimal("0.000000");
        BigDecimal midrat = new BigDecimal("0.000000");
        BigDecimal buymidrat = new BigDecimal("0.000000");
        BigDecimal selmidrat = new BigDecimal("0.000000");
        BigDecimal newmidrat = new BigDecimal("0.000000");
        BigDecimal buymidratchage = new BigDecimal("0.000000");
        BigDecimal buymidratbefore = new BigDecimal("0.000000");
        BigDecimal selmidratchage = new BigDecimal("0.000000");
        BigDecimal selmidratbefore = new BigDecimal("0.000000");
        int buytyp = 0;
        int seltyp = 0;
        boolean boolVar = false;
        int cnt = setglg.getSetgll().size();
        String whmtyp = NULLSTR;
        String datSql = NULLSTR;
        String getxrtsql = NULLSTR;
        int error = 0;
        if (cnt > 0) {
            for (int idx = 0; idx < cnt; idx++) {
                whmtyp = "";
                if (((MdaUtils.compareTo(setglg.getSetgll().get(idx).getAcccur(), xrtmodService.sysiso()) == 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getCur(), xrtmodService.sysiso()) != 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getAmt(), 0) < 0) || (MdaUtils.compareTo(setglg.getSetgll().get(idx).getAcccur(), xrtmodService.sysiso()) != 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getCur(), xrtmodService.sysiso()) == 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getAmt(), 0) > 0))) {
                    whmtyp = "3";
                } else {
                    if (((MdaUtils.compareTo(setglg.getSetgll().get(idx).getAcccur(), xrtmodService.sysiso()) == 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getCur(), xrtmodService.sysiso()) != 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getAmt(), 0) > 0) || (MdaUtils.compareTo(setglg.getSetgll().get(idx).getAcccur(), xrtmodService.sysiso()) != 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getCur(), xrtmodService.sysiso()) == 0 && MdaUtils.compareTo(setglg.getSetgll().get(idx).getAmt(), 0) < 0))) {
                        whmtyp = "5";
                    }
                }
                //光大要求一笔业务中出现多次结售汇时只提示一次
                //光大业务中不会发生一笔业务中出现多币种的结售汇
                if (MdaUtils.compareTo(whmtyp, "") != 0) {
                    if (MdaUtils.compareTo(setglg.getSetgll().get(idx).getAcccur(), xrtmodService.sysiso()) != 0) {
                        fromcur = setglg.getSetgll().get(idx).getAcccur();
                    } else {
                        if (MdaUtils.compareTo(setglg.getSetgll().get(idx).getCur(), xrtmodService.sysiso()) != 0) {
                            fromcur = setglg.getSetgll().get(idx).getCur();
                        }
                    }
                    Zmqxrt wrkZmqxrt = zmqxrtMapper.selectByCurWithDatRng(fromcur, Dates.today());
                    if (MdaUtils.compareTo(whmtyp, "3") == 0 && MdaUtils.compareTo(wrkZmqxrt.getMidrat(), setglg.getSetgll().get(idx).getMidrat()) != 0) {
                        buycur = fromcur;
                        buymidratchage = wrkZmqxrt.getBuyrat();
                        buymidratbefore = setglg.getSetgll().get(idx).getRat();
                        buytyp = 1;
                    } else {
                        if (MdaUtils.compareTo(whmtyp, "5") == 0 && MdaUtils.compareTo(wrkZmqxrt.getMidrat(), setglg.getSetgll().get(idx).getMidrat()) != 0) {
                            selcur = fromcur;
                            selmidratchage = wrkZmqxrt.getSelrat();
                            selmidratbefore = setglg.getSetgll().get(idx).getRat();
                            seltyp = 1;
                        }
                    }
                }
            }
        }
        if (buytyp == 1) {
            prompt = true;
            if (prompt) {
                boolVar = false;
            } else {
                return true;
            }
        }
        if (seltyp == 1) {
            prompt = true;
            if (prompt) {
                boolVar = false;
            } else {
                return true;
            }
        }
        // ####### 改写 LABEL与GOTO   ####    label done
        return false;
    }

    /**
     * source:setglg.0040.script
     */
    @Override
    @JsonIgnore
    public boolean getFFAActFlg(SetglgVo setglg) {
        int gridcnt = setglg.getSetgll().size();
        boolean flag = false;
/*WD 可能不在使用
        String sql = "";
        String inr = "";
        Argument<String> _inrBox = Argument.box(inr);
        int err = 0;
        if (!MdaUtils.isEmpty(setglg.getFfaflg())) {
            //!交易中直接指定使用贷款专户
            flag = true;
        } else {
            for (int i = 0; i < gridcnt; i++) {
                //!客户账使用到了贷款专户
                //!xuyaofangkai
                sql = "";
                */
/**
 $Sql = "SELECT INR FROM ACT WHERE EXTKEY='" + Trim( SETGLL( $i )\\ACT ) + "' AND ACTPRO='2303'"
 **//*

                sql = "SELECT INR FROM ACT WHERE EXTKEY = ? AND ACTPRO='2303'";
                ctx.getDaoSession().dbExecuteSQL(sql, Strings.trim(setglg.getSetgll().get(i).getAct()));
                err = ctx.getErrorCode();
                ctx.getDaoSession().dbFetchFields("", _inrBox);
                inr = _inrBox.value;
                err = ctx.getErrorCode();
                ctx.getDaoSession().dbCloseCursor();
                if (!MdaUtils.isEmpty(inr)) {
                    flag = true;
                    break;
                }
            }
        }
*/
        return flag;
    }

    /**
     * source:setglg.0041.script
     */
/*
    @Override
    @TDMethod
    public void registerAddTxt(SetglgVo setglg, Doceot argDoc) {
        //Default of Sender-to-receiverinfo from Payment panel to doceot Details
        //Default per line in SETGLL
        int gridcnt = setglg.getSetgll().size();
        for (int i = 0; i < gridcnt; i++) {
            if (MdaUtils.compareTo(argDoc.getId(), "SETPAY" + MdaUtils.toString(i)) == 0) {
                Dynamic.setAddTxt(setglg.getSetgll().get(i).getSespay().getStrinf());
            }
            if (MdaUtils.compareTo(argDoc.getId(), "SETCOV" + MdaUtils.toString(i)) == 0) {
                Dynamic.setAddTxt(setglg.getSetgll().get(i).getSespay().getStrinf202());
            }
        }
    }
*/

    /**
     * source:setglg.0042.script
     */
    @Override
    public void getSettledAmtCurForRol(SetglgVo setglg, String argRol, Argument<String> argCur, Argument<BigDecimal> argAmt) {
        //! Get settled amount and currency of given rol. If this rol has more than one settlement-entries
        //! they will be added up. If theses lines have different currencies this method will cause an errorCode 999
        //! ArgRol: Rol to add the Amounts
        //! ArgAmt: Total settled amount
        //! ArgCur: currency of the settled amount
        argAmt.value = new BigDecimal("0");
        argCur.value = "";
        int numCnt = setglg.getSetgll().size();
        for (int numI = 0; numI < numCnt; numI++) {
            if (MdaUtils.compareTo(setglg.getSetgll().get(numI).getRol(), argRol) == 0) {
                if (MdaUtils.isEmpty(argCur.value)) {
                    argCur.value = setglg.getSetgll().get(numI).getCur();
                }
                if (MdaUtils.compareTo(argCur.value, setglg.getSetgll().get(numI).getCur()) == 0) {
                    argAmt.value = Decimals.add(argAmt.value, setglg.getSetgll().get(numI).getAmt());
                } else {
                    argAmt.value = new BigDecimal(-1);
                    SettleExceptionUtils.throwSettleException(Strings.getText("Settled amount in different currencies found for role $1, can not sum them up", argRol));
                    break;
                }
            }
        }
    }
}
