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

import com.brilliance.mda.runtime.mda.CodetableItem;
import com.brilliance.mda.runtime.mda.IStream;
import com.brilliance.mda.runtime.mda.impl.Argument;
import com.brilliance.mda.runtime.mda.impl.StreamImpl;
import com.brilliance.mda.runtime.mda.util.*;
import com.brilliance.isc.bo.Cur;
import com.brilliance.isc.bo.Fee;
import com.brilliance.isc.bo.Fep;
import com.brilliance.isc.common.cbsmod.service.XrtmodService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.component.PtsptaToolComponent;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.exception.CommonServiceException;
import com.brilliance.isc.common.setfeg.fee.FeeEntity;
import com.brilliance.isc.common.setfeg.fee.FeeSet;
import com.brilliance.isc.common.setfeg.fee.Setcbs;
import com.brilliance.isc.common.setfeg.fee.Setpty;
import com.brilliance.isc.common.setfeg.service.SetfegService;
import com.brilliance.isc.common.setfeg.vo.SetfegVo;
import com.brilliance.isc.common.setfeg.vo.SetfelVo;
import com.brilliance.isc.common.setglg.service.SetglgService;
import com.brilliance.isc.common.setmod.service.SetmodService;
import com.brilliance.isc.common.setmod.vo.SetmodVo;
import com.brilliance.isc.common.sysmod.SysmodService;
import com.brilliance.isc.common.transaction.help.TransactionHelpService;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.common.vo.BizInfoVo;
import com.brilliance.isc.common.vo.FecVo;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.common.vo.SimpleModuleVo;
import com.brilliance.isc.mda.dao.FeeMapper;
import com.brilliance.isc.mda.dao.FepMapper;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

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

@Service("setfegService")
public class SetfegServiceImpl implements SetfegService {

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

    private static ThreadLocal<FeeSet> feeSetLocal = new ThreadLocal() {
        @Override
        protected FeeSet initialValue() {
            return new FeeSet();
        }
    };
    @Autowired
    private FeeMapper feeMapper;

    @Autowired
    private FepMapper fepMapper;

    @Autowired
    private SysmodService sysmodService;

    @Autowired
    private PtsptaToolComponent ptsptaToolComponent;

    @Autowired
    private SetmodService setmodService;

    @Autowired
    private SetglgService setglgService;

    @Autowired
    private CodetableService codetableService;

    @Autowired
    private XrtmodService xrtmodService;

    @Autowired
    private TransactionHelpService transactionHelpService;

    public void clearFeeSet() {
        feeSetLocal.remove();
    }

    public FeeSet getFeeSet() {
        return feeSetLocal.get();
    }

    /**
     * source:setfeg.0018.script
     */
    public void calcMaceog(SetfegVo setfegVo) {
        // Calulate MAC for End processing from all MACs of SETFEL
        setfegVo.setMaceog(NULLSTR);
        IStream stm = new StreamImpl();
        Streams.streamClear(stm);
        int count = 0;
        if (setfegVo.getSetfel() != null) {
            count = setfegVo.getSetfel().size();
        }
        if (count > 0) {
            for (int i = 0; i < count; i++) {
                Streams.streamInsert(stm, 0, setfegVo.getSetfel().get(i).getMac());
            }
            setfegVo.setMaceog(Systems.macGen(stm, 0));
        }
    }

    /**
     * source:setfeg.0025.script
     */
    public void calcMacbog(SetfegVo setfegVo) {
        // caclulate MACBOG from input variables of Fee Defaulting (i.e. FEPINP)
        setfegVo.setMacbog(NULLSTR);
        IStream stm = new StreamImpl();
        FeeSet feeSet = feeSetLocal.get();
        feeSet.getAllFeeEntity().forEach(feeEntity -> {
            StringBuffer sb = new StringBuffer();
            sb.append(feeEntity.getFeeCod());
            sb.append(feeEntity.getUnit());
            sb.append(feeEntity.getDat1() == null ? "" : Utils.fmtDate(feeEntity.getDat1()));
            sb.append(feeEntity.getDat2() == null ? "" : Utils.fmtDate(feeEntity.getDat2()));
            sb.append(Numerics.round(feeEntity.getRatcal(), 6));
            sb.append(Numerics.round(feeEntity.getBasamt(), 2));
            sb.append(feeEntity.getCdtOldFlg());
            sb.append(feeEntity.getInfdetStm());
            sb.append(feeEntity.isReadRecFec());
            sb.append(feeEntity.getRoldbt());
            Streams.streamInsert(stm, 0, sb.toString());
        });
        List<String> rolList = feeSet.getAllSetpty().stream().map(setpty -> setpty.getRol()).collect(Collectors.toList());
        stm.getRows().addAll(rolList);
        setfegVo.setMacbog(Systems.macGen(stm, 0));
    }


    /**
     * source:setfeg.0000.script
     */
    public void recalcSetfegBog(SetmodVo setmodVo) {
        log.debug("Setfeg macbog{}和macbogold{}不相等，重算Setfeg", setmodVo.getSetfeg().getMacbog(), setmodVo.getSetfeg().getMacbogold());
        boolean firstCall = false;
        Argument<Boolean> firstCallBox = new Argument<Boolean>("", firstCall);
        getFepEntries(firstCallBox, setmodVo);

        firstCall = firstCallBox.value;

        defaultSetfel(setmodVo.getSetfeg(), setmodVo);
        if (firstCall) {
            ptsAdjust(setmodVo.getSetfeg());
        }
        this.calcMacbog(setmodVo.getSetfeg());
        setmodVo.getSetfeg().setMacbogold(setmodVo.getSetfeg().getMacbog());
    }

    /**
     * source:setfeg.0001.script
     */
    @JsonIgnore
    public BigDecimal getFeeSum(String argrol, SetfegVo setfegVo) {
        //! calculate fees per role Argrol
        //! If Argrol is empty the sum for all roles are collected
        BigDecimal erg = new BigDecimal("0");
        int gridcnt = setfegVo.getSetfel().size();
        for (int a = 0; a < gridcnt; a++) {
            if (MdaUtils.compareTo(argrol, setmodService.getGllRol(setfegVo.getSetfel().get(a).getRol())) == 0 || MdaUtils.isEmpty(argrol)) {
                erg = Decimals.add(erg, setfegVo.getSetfel().get(a).getAmt());
            }
        }
        return erg;

    }
    /**
     * source:setfeg.0002.script
     */
    public void defaultSetfel(SetfegVo setfegVo, SetmodVo setmodVo) {
        // decompress SETFEL
//        det2cpr( false );
        fep2setfel(setfegVo, setmodVo);

    }

    /**
     * source:setfeg.0003.script
     */
    @JsonIgnore
    public void getFepEntries(Argument<Boolean> argFirstCall, SetmodVo setmodVo) {
        //! Get entries from fee pool
        //! ArgFirstCall is true if it is the first call with a access to pool as roles are set
        // FEPinp contains the information about the fees from pool
        // 1. Read the pool records from FEP
        int cnt = 0;
        Argument<Integer> _cntBox = Argument.box(cnt);
        argFirstCall.value = false;
        IStream sqlStm = new StreamImpl();
        IStream cacsql = new StreamImpl();
        String id = NULLSTR;
        Argument<String> _idBox = Argument.box(id);
        IStream inrStm = new StreamImpl();
        int sqlStmCnt = 0;
        String sql = NULLSTR;
        String sepWrn = NULLSTR;
        IStream sepStm = new StreamImpl();
        int stmCnt = 0;
        IStream ptyInrStm = new StreamImpl();
        String ptynam = NULLSTR;
        Argument<String> _ptynamBox = Argument.box(ptynam);
        String ptyextkey = NULLSTR;
        Argument<String> _ptyextkeyBox = Argument.box(ptyextkey);
        if (Streams.streamCount(setmodVo.getRoldsc()) > 0) {
            Streams.streamClear(sqlStm);
            setFepSql(sqlStm, setmodVo);
            if (!MdaUtils.isEmpty(sqlStm)) {
                // read Sql from cache (not from FEPINP as it has to be reread in case of pickup)
//                Streams.streamClear(cacsql);
//                Caches.cacheRead(cacsql,"SEFMOD","FEPSQL");
//                if( ctx.getErrorCode() == tdCacheNotFound )
//                {
//                    argFirstCall.value = true;
//                }
//                else
//                {
//                    ctx.reraise();
//                    if( MdaUtils.compareTo(MdaUtils.toString(sqlStm),MdaUtils.toString(cacsql)) == 0 )
//                    {
//                        if(1==1) return;
//                    }
//                }
//                Caches.cacheWrite(sqlStm,"SEFMOD","FEPSQL");
//                // remove old pool entries from cache (if any)
//                Caches.cacheRead(_cntBox,"SETFEG","FEPCNT");
//                cnt = _cntBox.value;
//                if( ctx.getErrorCode() != tdCacheNotFound )
//                {
//                    ctx.reraise();
//                    if( cnt > 0 )
//                    {
//                        for(int  i = 1;i <= cnt;i++)
//                        {
//                            id = "";
//                            Caches.cacheRead(_idBox,"SETFEG","FEPIDS",i);
//                            id = _idBox.value;
//                            if( ctx.getErrorCode() != tdCacheNotFound )
//                            {
//                                Caches.cacheDelete("SETFEG","FEEVAL",id);
//                                Caches.cacheDelete("SETFEG","FEPIDS",i);
//                                ctx.reraise();
//                            }
//                        }
//                    }
//                }
                cnt = 0;
                Streams.streamClear(inrStm);
                sqlStmCnt = Streams.streamCount(sqlStm);
                List<Fep> fepList = new ArrayList<>();
                Map<String, Object> dyncMap = new HashMap<>();
                for (int sqlCnt = 1; sqlCnt <= sqlStmCnt; sqlCnt++) {
                    sql = Strings.getLine(sqlStm, sqlCnt);
                    sql = "select * from fep " + Utils.sdbEtyGenSql("fep", sql);
                    dyncMap.put("sql", sql);
                    List<Fep> rs = fepMapper.dyncRead(dyncMap);
                    if (rs != null) {
                        fepList.addAll(rs);
                    }
//                    ctx.getDaoSession().dbExecuteSQL("select inr from fep " + Platform.sdbEtyGenSql(this.getWrkfep(),sql));
//                    ctx.getDaoSession().dbFetchStream(inrStm);
//                    ctx.getDaoSession().dbCloseCursor();
                }
                sepWrn = "";
//                if( ! MdaUtils.isEmpty(ctx.absGet(Setmod.class).getSep().getInr()) && MdaUtils.isEmpty(ctx.absGet(Setmod.class).getTmpnotfnlflg()) )
//                {
//                    Streams.streamClear(sepStm);
//                    ctx.getDaoSession().dbExecuteSQL("select inr from fep where sepinr = ? and dontrninr = ' ' and rpltrninr = ' ' ",ctx.absGet(Setmod.class).getSep().getInr());
//                    ctx.getDaoSession().dbFetchStream(sepStm);
//                    ctx.getDaoSession().dbCloseCursor();
//                    stmCnt = Streams.streamCount(sepStm);
//                    for(int  i = 1;i <= stmCnt;i++)
//                    {
//                        if( Streams.streamSearch(inrStm,Strings.getLine(sepStm,i)) == 0 )
//                        {
//                            Streams.streamInsert(inrStm,0,Strings.getLine(sepStm,i));
//                            sepWrn = MdaUtils.getI18NString("setfeg","CT000305");
//                        }
//                    }
//                    Dynamic.sysWarningSet( SYSWRNTypeWarning, sepWrn, "SETFEGBOGSEPWRN" );
//                }
                Streams.streamClear(ptyInrStm);
                fillPtyInrStmForFep(ptyInrStm);
                fepList.forEach(fep -> {
                    if (Streams.streamSearch(ptyInrStm, fep.getPtyinr()) > 0) {
                        setOneFepInp(fep);
                    } else {
                        log.warn("未注册的pty inr{}:" + fep.getPtyinr());
                    }
                });
//                stmCnt = Streams.streamCount(inrStm);
//                for(int  idx = 1;idx <= stmCnt;idx++)
//                {
//                    Platform.sdbRead(this.getWrkfep(),Strings.getLine(inrStm,idx));
//                    if( Streams.streamSearch(ptyInrStm,this.getWrkfep().getPtyinr()) > 0 )
//                    {
//                        cnt = cnt + 1;
//                        Caches.cacheWrite(this.getWrkfep().getInr(),"SETFEG","FEPIDS",cnt);
//                        Caches.cacheWrite(cnt,"SETFEG","FEPIDS",this.getWrkfep().getInr());
//                        setOneFepInp();
//                    }
//                    else
//                    {
//                        ctx.getDaoSession().dbExecuteSQL("SELECT NAM,EXTKEY FROM PTY WHERE INR = ?",this.getWrkfep().getPtyinr());
//                        ptynam = "";
//                        ptyextkey = "";
//                        ctx.getDaoSession().dbFetchFields("NAM",_ptynamBox,"EXTKEY",_ptyextkeyBox);
//                        ptynam = _ptynamBox.value;
//                        ptyextkey = _ptyextkeyBox.value;
//                        if( ctx.getErrorCode() != tdOdbcNotFound )
//                        {
//                            ctx.reraise();
//                        }
//                        ctx.getDaoSession().dbCloseCursor();
//                        Dynamic.sysWarningSet( SYSWRNTypeWarning, Strings.getText(MdaUtils.getI18NString("setfeg","CT000010"),this.getWrkfep().getFeecod(),ptyextkey,ptynam), "FEPWRN-" + this.getWrkfep().getInr() );
//                    }
//                }
//
//                Caches.cacheWrite(cnt,"SETFEG","FEPCNT");
            }
        }

    }

    /**
     * source:setfeg.0004.script
     */
    public void addFeeData(String feetyp, String feeflg, int feeunt, Date from, Date till) {
        //! Register a fee for fee defaulting
        //! To be called from Registersettlement to default fees in own charges grid.
        //! feetyp : Code of the fee to be defaulted (FEE\\COD).
        //!          In a transaction every fee code can be defaulted once, using AddTrnFee as the fee code that is also used as ID.
        //!          If a fee code is to be defaulted more than once, AddTrnFee may be used directly.
        //! feeflg : Flag deciding, if the fee has to be defaulted or to be removed, if it has already been defaulted via an earlier call of AddFeeData.
        //!          Y : Fee has to be defaulted
        //!          any other value : Fee has not to be defaulted
        //! feeunt : Default for units (if not 1)
        //! from   : Default from date (if required; if empty DAT1 is set to Today)
        //! till   : Default to date (if required; if empty DAT1 is set to Today)
        //!
        //! If a fee has to be defaulted depending on transaction entries, a call of Addfeedata with feeflg "N" is required to remove the fee.
        //! A typical sequence is (default fee MYFEE if $myfeeflg is set) :
        //! if not IsEmpty( $Myfeeflg ) then
        //!    AddFeeData( "MYFEE", "Y", 1, Today, Today )
        //! else
        //!   AddFeeData( "MYFEE", "N", 0, Today, Today )
        //! endif
        //!
        addTrnFee("TRN" + feetyp, feetyp, feeflg, feeunt, from, till, BigDecimal.ZERO, BigDecimal.ZERO, "", "");
    }

    /**
     * source:setfeg.0004.script
     */
    public void addFeeData(String feetyp, String feeflg, int feeunt, Date from, Date till, String addinf) {
        //! Register a fee for fee defaulting
        //! To be called from Registersettlement to default fees in own charges grid.
        //! feetyp : Code of the fee to be defaulted (FEE\\COD).
        //!          In a transaction every fee code can be defaulted once, using AddTrnFee as the fee code that is also used as ID.
        //!          If a fee code is to be defaulted more than once, AddTrnFee may be used directly.
        //! feeflg : Flag deciding, if the fee has to be defaulted or to be removed, if it has already been defaulted via an earlier call of AddFeeData.
        //!          Y : Fee has to be defaulted
        //!          any other value : Fee has not to be defaulted
        //! feeunt : Default for units (if not 1)
        //! from   : Default from date (if required; if empty DAT1 is set to Today)
        //! till   : Default to date (if required; if empty DAT1 is set to Today)
        //!
        //! If a fee has to be defaulted depending on transaction entries, a call of Addfeedata with feeflg "N" is required to remove the fee.
        //! A typical sequence is (default fee MYFEE if $myfeeflg is set) :
        //! if not IsEmpty( $Myfeeflg ) then
        //!    AddFeeData( "MYFEE", "Y", 1, Today, Today )
        //! else
        //!   AddFeeData( "MYFEE", "N", 0, Today, Today )
        //! endif
        //!
        addTrnFee("TRN" + feetyp, feetyp, feeflg, feeunt, from, till, BigDecimal.ZERO, BigDecimal.ZERO, "", addinf);
    }

    /**
     * source:setfeg.0005.script
     */
    public void addTrnFee(String id, String feetyp, String feeflg, int feeunt, Date from, Date till, BigDecimal rate, BigDecimal basamt, String cdtoldflg, String addinf) {
        // addinf may contain the following infos as lines <fld>=<content>
        String objmod = "\\MTABUT\\REC"; // contract module if not MTABUT\\REC
        String fecmod = ""; // special fee condition to be used
        String fecirt = ""; // special fee rate type to be used
        String roldbt = ""; // Role to pay that fee
        String cbtpfx = ""; // Cbs-type for fee calutation from liability sum
        String cextid = ""; // Ext-ID   for fee calutation from liability sum
        String dspDft = ""; // Set Disposition default. Used for VAT handling
        String proFlg = ""; // "ALL" protects line completely incl. DSP. If "ALL" basamt is the amount to be charged and disabled aswell.Used for VAT handling
        String relcur = ""; // Sets currecny of BASAMT (necessary if not DOCCUR); used for VAT handling
        String modflg = "r"; // modification status of that fee. Default 'R' means: redefault always
        String preDbt = ""; // Sets ID of predebit entry
        String irsDay = ""; // Sets contract period in days for access to interest rates depending on contract period. If not set, difference of calculation period is used
        IStream infDet = new StreamImpl();
        Streams.streamClear(infDet); // Set INFDETSTM. One line per entry.
        int stmcnt = 0;
        String addline = NULLSTR;
        if (!MdaUtils.isEmpty(addinf)) {
            IStream addstm = new StreamImpl();
            Streams.streamSet(addstm, addinf);
            stmcnt = Streams.streamCount(addstm);
            for (int i = 1; i <= stmcnt; i++) {
                addline = Strings.getLine(addstm, i);
                switch (Strings.toUpper(Strings.mid(addline, 1, 6))) {
                    case "OBJMOD":
                        objmod = Strings.mid(addline, 8);
                        break;
                    case "FECMOD":
                        fecmod = Strings.mid(addline, 8);
                        break;
                    case "FECIRT":
                        fecirt = Strings.mid(addline, 8);
                        break;
                    case "ROLDBT":
                        roldbt = Strings.mid(addline, 8);
                        break;
                    case "CBTPFX":
                        cbtpfx = Strings.mid(addline, 8);
                        break;
                    case "CEXTID":
                        cextid = Strings.mid(addline, 8);
                        break;
                    case "DSPDFT":
                        dspDft = Strings.mid(addline, 8);
                        break;
                    case "PROFLG":
                        proFlg = Strings.mid(addline, 8);
                        break;
                    case "RELCUR":
                        relcur = Strings.mid(addline, 8);
                        break;
                    case "MODFLG":
                        modflg = Strings.mid(addline, 8);
                        break;
                    case "PREDBT":
                        preDbt = Strings.mid(addline, 8);
                        break;
                    case "IRSDAY":
                        irsDay = Strings.mid(addline, 8);
                        break;
                    case "INFDET":
                        Streams.streamInsert(infDet, 0, Strings.mid(addline, 8));
                        break;
                }
            }
        }
        // nothing to do if no fee is used
        if (MdaUtils.isEmpty(feetyp)) {
            return; // ####### 改写 LABEL与GOTO  ####   goto done
        }
        // Feecode must have 6 characters in warning to be unic
        String wrnNamFeeCod = "";
        if (feetyp.length() >= 6) {
            wrnNamFeeCod = feetyp.substring(0, 6);
        } else {
            wrnNamFeeCod = feetyp;
            while (wrnNamFeeCod.length() < 6) {
                wrnNamFeeCod += ".";
            }
        }
        // check, if fee is defined
        if ("Y".equals(feeflg)) {
            if (Streams.streamSearch(this.getAvbfeecod(SettleContext.getTransName(), SettleContext.getUserEtg().getExtkey()), feetyp) == 0) {
                log.warn("费用类型不可用：{}", feetyp);
                return;
            }
        }
        // check, if transaction fee is already in stream
        // if so, define it
        FeeSet feeSet = feeSetLocal.get();
        FeeEntity feeEntity = feeSet.getFeeEntityById(id);
        if (MdaUtils.compareTo(feeflg, "Y") == 0) {
            if (feeEntity == null) {
                feeEntity = new FeeEntity();
                feeSet.putFeeEntity(id, feeEntity);
            }
            feeEntity.setFeeCod(feetyp);
            feeEntity.setCur("");
            feeEntity.setAmt(BigDecimal.ZERO);
            feeEntity.setDat1(from);
            feeEntity.setDat2(till);
            feeEntity.setModflg(modflg);
            feeEntity.setUntamt(rate);
            feeEntity.setRatcal(rate);
            feeEntity.setUnit(feeunt);
            feeEntity.setBasamt(basamt);
            feeEntity.setPtyInr(" ");
//            add2fepinp( id, "INFTXT", Strings.getText(MdaUtils.getI18NString("setfeg","CT000293"),Codetables.getCodetableLabelOfTd(feetyp,"FEETXT",Systems.getLang()),feeunt) );
           // feeEntity.setInftxt(feetyp + " " + feeunt);
            feeEntity.setRemove("");
            feeEntity.setType("TRN");
            feeEntity.setCdtOldFlg(cdtoldflg);
            feeEntity.setObjmod(objmod);
            feeEntity.setFecmod(fecmod);
            feeEntity.setFecirt(fecirt);
            feeEntity.setRoldbt(roldbt);
            feeEntity.setCextid(cextid);
            feeEntity.setCbtpfx(cbtpfx);
            feeEntity.setDspdft(dspDft);
            feeEntity.setProflg(proFlg);
            feeEntity.setRelcur(relcur);
            feeEntity.setPreDbt(preDbt);
            int ircDayCount = 0;
            if (!MdaUtils.isEmpty(irsDay)) {
                ircDayCount = Integer.parseInt(irsDay);
                feeEntity.setIrsDay(ircDayCount);
            }
            feeEntity.setInfdetStm(MdaUtils.toString(infDet));
        } else {
            //mark entry as fee to be removed from SETFEL
            if (feeEntity != null) {
//                add2fepinp( id, "REMOVE", "Y" );
                feeEntity.setRemove("Y");
            }
        }
        if (feeEntity != null) {
            feeSet.addFeeEntity(id, feeEntity);
            // Store MAC of arguments if fee is set to cache
            String mac = Systems.macGen(feetyp + feeflg + MdaUtils.toString(feeunt) + Formats.fmtDateShort(from) + Formats.fmtDateShort(till) + MdaUtils.toString(rate) + MdaUtils.toString(basamt) + cdtoldflg + addinf, 0);
//            Caches.cacheWrite(mac,"SETFEG","MAC",idx);
            feeEntity.setMac(mac);
        }
        // ####### 改写 LABEL与GOTO   ####    label done
    }

    public IStream getAvbfeecod(String transName, String etgGrp) {
        String shortRecType = transName.substring(0, 2);
        Date date = new Date();
        List<String> codeList = feeMapper.getAvbfeecod(shortRecType, transName, etgGrp, date);
        IStream codeSteam = new StreamImpl();
        if (codeList != null) {
            codeSteam.getRows().addAll(codeList);
        }
        return codeSteam;
    }

    /**
     * 获取可用的费用代码码值
     *
     * @param transName
     * @return
     */
    public List<CodetableItem> getAvbfeecod(String transName) {
        String shortRecType = transName.substring(0, 2);
        Date date = new Date();
        List<String> codeList = feeMapper.getAvbfeecod(shortRecType, transName, SettleContext.getUserEtg().getExtkey(), date);
        if (codeList != null) {
            List<CodetableItem> feecodeSet = new ArrayList<>();
            codeList.forEach(feecode -> {
                String feetxt = codetableService.getTblLabel(feecode.toUpperCase(), "FEETXT");
                if (StringUtils.isNotEmpty(feetxt)) {
                    feecodeSet.add(new CodetableItem(feetxt, feecode));
                }
            });
            return feecodeSet;
        }
        return null;
    }

    /**
     * source:setfeg.0008.script
     */
    public void fep2setfel(SetfegVo setfegVo, SetmodVo setmodVo) {
        // creates setfel from FEPINP
        IStream fepinrs = new StreamImpl();
        Streams.streamClear(fepinrs);
        getfepinrs(fepinrs, false);
        // 2. Remove wrong pool records from setfel and count empty lines
        int empcnt = 0;
        int gridcnt = 0;
        if (setfegVo.getSetfel() != null) {
            gridcnt = setfegVo.getSetfel().size();
        }
        int stmCnt = 0;
        int i = 0;
        int line = 0;

        if (gridcnt > 0) {
            for (int d = 0; d < gridcnt; d++) {
                stmCnt = Streams.streamCount(setfegVo.getSetfel().get(d).getFepinrlst());
                if (stmCnt > 0) {
                    i = 1;
                    while (i <= stmCnt) {
                        line = Streams.streamSearch(fepinrs, Strings.getLine(setfegVo.getSetfel().get(d).getFepinrlst(), i));
                        if (line == 0) {
                            Streams.streamDelete(setfegVo.getSetfel().get(d).getFepinrlst(), i);
                            stmCnt = Streams.streamCount(setfegVo.getSetfel().get(d).getFepinrlst());
                        } else {
                            String curinr = Strings.getLine(fepinrs, line);
                            SetfelVo setfelVo = setfegVo.getSetfel().get(d);
                            FeeSet feeSet = feeSetLocal.get();
                            //取出注册得到的费用实体
                            FeeEntity feeEntity = feeSet.getFeeEntityById(curinr);
                            if (!sysmodService.sptIsExeLoaded(transactionHelpService.getSptsta())) { //  do not reset fields from pool under PDX
                                // redefault everything from transaction if not changed by user.
                                //         select case setfel( $d )\\MODFLG
                                //           case "a", "u", "c", "R", "x", "d"
                                //           case else

                                if (!setfelVo.isModified("feecod")) {
                                    setfelVo.setFeecod(feeEntity.getFeeCod());
                                }
                                if (!setfelVo.isModified("feetxtinf")) {
                                    String dftInf = feeEntity.getFeetxtinf();
                                    if (!MdaUtils.isEmpty(dftInf)) {
                                        setfelVo.setFeetxtinf(dftInf);
                                    }
                                }
//                                dat1 = Strings.parseDate(getfepval( curinr, "DAT1" ));
                                if (!setfelVo.isModified("dat1")) {
                                    setfelVo.setDat1(feeEntity.getDat1());
                                }
                                Date dat2 = feeEntity.getDat2();
                                if (!setfelVo.isModified("dat2")) {
                                    setfelVo.setDat2(dat2);
                                }
                                setfelVo.setDat2dft(dat2);
                                if (!setfelVo.isModified("untamt")) {
                                    setfelVo.setUntamt(feeEntity.getUntamt());
                                    if (MdaUtils.isEmpty(setfelVo.getUntamt())) {
                                        setfelVo.setUntamt(setfelVo.getWrkfec().getUntamt());
                                    }
                                }
                                if (!setfelVo.isModified("ratcal")) {
                                    setfelVo.setRatcal(feeEntity.getRatcal());
                                    if (MdaUtils.isEmpty(setfelVo.getRatcal())) {
                                        setfelVo.setRatcal(setfelVo.getWrkfec().getRatcal());
                                    }
                                }
                                setfelVo.setBasamtin(feeEntity.getBasamt());
                                if (!setfelVo.isModified("unt")) {
                                    int unt = feeEntity.getUnit();
                                    if (!MdaUtils.isEmpty(unt)) {
                                        setfelVo.setUnt(unt);
                                    }
                                }
                                if (!MdaUtils.isEmpty(feeEntity.getCur())) {
                                    if (!setfelVo.isModified("cur") && !setfelVo.isModified("amt")) {
                                        setfelVo.setCur(feeEntity.getCur());
                                    }
                                }
                                BigDecimal fepamt = feeEntity.getAmt();
                                if (!MdaUtils.isEmpty(fepamt)) {
                                    if (!setfelVo.isModified("amt")) {
                                        setfelVo.setAmt(fepamt);
                                    }
                                }
                                BigDecimal fepogiamt = feeEntity.getOgiamt();
                                if (!MdaUtils.isEmpty(fepogiamt)) {
                                    if (!setfelVo.isModified("ogiamt")) {
                                        setfelVo.setOgiamt(fepogiamt);
                                    }
                                }
                                if (!setfelVo.isModified("cdtoldflg")) {
                                    String cdtOldflg = feeEntity.getCdtOldFlg();
                                    if (!MdaUtils.isEmpty(cdtOldflg)) {
                                        setfelVo.setCdtoldflg(cdtOldflg);
                                    }
                                }
                                if (!setfelVo.isModified("objmod")) {
                                    String objmod = feeEntity.getObjmod();
                                    if (!MdaUtils.isEmpty(objmod)) {
                                        setfelVo.setObjmod(objmod);
                                        //setfelVo.setObjOfSETFEL ( setfegVo.getSetfel().get(d).getObjmod() );
                                    }
                                }
                                if (!setfelVo.isModified("fecmod")) {
                                    String fecmod = feeEntity.getFecmod();
                                    if (!MdaUtils.isEmpty(fecmod)) {
                                        setfelVo.setFecmod(fecmod);
                                    }
                                }
                                if (!setfelVo.isModified("fecirt")) {
                                    String fecIrt = feeEntity.getFecirt();
                                    if (!MdaUtils.isEmpty(fecIrt)) {
                                        setfelVo.setFecirt(fecIrt);
                                    }
                                }
                                if (!setfelVo.isModified("irsday")) {
                                    int irsDay = feeEntity.getIrsDay();
                                    if (!MdaUtils.isEmpty(irsDay)) {
                                        setfelVo.setIrsday(irsDay);
                                    }
                                }
                                if (!setfelVo.isModified("rolptyinr")) {
                                    String rolPtyInr = feeEntity.getPtyInr();
                                    if (!MdaUtils.isEmpty(rolPtyInr)) {
                                        setfelVo.setRolptyinr(rolPtyInr);
                                    }
                                }
                                if (!setfelVo.isModified("roldbt")) {
                                    String roldbt = feeEntity.getRoldbt();
                                    if (!MdaUtils.isEmpty(roldbt)) {
                                        setfelVo.setRoldbt(roldbt);
                                    }
                                }
                                if (!setfelVo.isModified("cextid")) {
                                    String cExtid = feeEntity.getCextid();
                                    if (!MdaUtils.isEmpty(cExtid)) {
                                        setfelVo.setCextid(cExtid);
                                    }
                                }
                                if (!setfelVo.isModified("cbtpfx")) {
                                    String cbtpfx = feeEntity.getCbtpfx();
                                    if (!MdaUtils.isEmpty(cbtpfx)) {
                                        setfelVo.setCbtpfx(cbtpfx);
                                    }
                                }
                                if (!setfelVo.isModified("advtrninr")) {
                                    String advtrninr = feeEntity.getAdvtrninr();
                                    if (!MdaUtils.isEmpty(advtrninr)) {
                                        setfelVo.setAdvtrninr(advtrninr);
                                    }
                                }
                                if (!setfelVo.isModified("advdat")) {
                                    Date advdat = feeEntity.getAdvdat();
                                    if (!MdaUtils.isEmpty(advdat)) {
                                        setfelVo.setAdvdat(advdat);
                                    }
                                }
                                if (!setfelVo.isModified("dspdft")) {
                                    String dspDft = feeEntity.getDspdft();
                                    if (!MdaUtils.isEmpty(dspDft)) {
                                        setfelVo.setDspdft(dspDft);
                                    }
                                }
                                if (!setfelVo.isModified("proflg")) {
                                    String proflg = feeEntity.getProflg();
                                    if (!MdaUtils.isEmpty(proflg)) {
                                        setfelVo.setProflg(proflg);
                                    }
                                }
                                if (!setfelVo.isModified("relcur")) {
                                    String relcur = feeEntity.getRelcur();
                                    if (!MdaUtils.isEmpty(relcur)) {
                                        setfelVo.setRelcur(relcur);
                                    }
                                }
                                if (!setfelVo.isModified("minmaxflg")) {
                                    String minMaxFlg = feeEntity.getMinmaxflg();
                                    if (!MdaUtils.isEmpty(minMaxFlg)) {
                                        setfelVo.setMinmaxflg(minMaxFlg);
                                    }
                                }
                                if (!setfelVo.isModified("predbt")) {
                                    String preDbt = feeEntity.getPreDbt();
                                    if (!MdaUtils.isEmpty(preDbt)) {
                                        setfelVo.setPredbt(preDbt);
                                    }
                                }
                                /**
                                 SetFelCusFields( $curinr, $d )
                                 **/
                                setFelCusFields(setfelVo, feeEntity);
                                if (!setfelVo.isModified("infdetstm")) {
                                    String infdetstm = feeEntity.getInfdetStm();
                                    if (!MdaUtils.isEmpty(infdetstm)) {
                                        Streams.streamSet(setfegVo.getSetfel().get(d).getInfdetstm(), infdetstm);
                                        if (Streams.streamSearch(setfegVo.getSetfel().get(d).getInfdetstm(), "FEETXTMOD" + TAB) > 0) {
                                            //TODO Systems.setAttribute(this.getSetfel().getElement(d),"feetxtinf",tdAttrModified,2);
                                        }
                                    }
                                }
                            }
                            fep2SetfelSetRol(feeEntity, setfelVo);
                            // remove lines of fees not longer calculated
                            if (!MdaUtils.isEmpty(feeEntity.getRemove())) {
                                Streams.streamDelete(setfelVo.getFepinrlst(), i);
                                stmCnt = Streams.streamCount(setfelVo.getFepinrlst());
                            }
                            Streams.streamDelete(fepinrs, line);
                            i = i + 1;
                        }
                    }
                    if (stmCnt == 0) {
                        // do not clear complete module as arguments passed (e.g. DOCCUR) must not be cleared
                        setfegVo.getSetfel().get(d).setRol(NULLSTR);
                        setfegVo.getSetfel().get(d).setFeecod(NULLSTR);
                        setfegVo.getSetfel().get(d).setSrc(NULLSTR);
                        setfegVo.getSetfel().get(d).setDsp(NULLSTR);
                        setfegVo.getSetfel().get(d).setDspdft(NULLSTR);
                        setfegVo.getSetfel().get(d).setProflg(NULLSTR);
                        setfegVo.getSetfel().get(d).setUnt(0);
                        setfegVo.getSetfel().get(d).setFeetxtinf(NULLSTR);
                        setfegVo.getSetfel().get(d).setInftxt(NULLSTR);
                        setfegVo.getSetfel().get(d).setCur(NULLSTR);
                        setfegVo.getSetfel().get(d).setOgiamt(new BigDecimal(0));
                        setfegVo.getSetfel().get(d).setAmt(new BigDecimal(0));
                        setfegVo.getSetfel().get(d).setFecmod(NULLSTR);
                        setfegVo.getSetfel().get(d).setObjmod(NULLSTR);
                        setfegVo.getSetfel().get(d).setPredbt(NULLSTR);
                        setfegVo.getSetfel().get(d).setObjtyp(NULLSTR);
                        setfegVo.getSetfel().get(d).setObjinr(NULLSTR);
                        setfegVo.getSetfel().get(d).setWrkfec(new FecVo());
                        setfegVo.getSetfel().get(d).setDat1(null);
                        setfegVo.getSetfel().get(d).setDat2(null);
                        setfegVo.getSetfel().get(d).setDat2dft(null);
                        setfegVo.getSetfel().get(d).setCommFeeFlag("");
                        //清掉修改标识
                        setfegVo.getSetfel().get(d).setModflg("");
                        setfegVo.getSetfel().get(d).resetModified();
                    }
                }
                if (MdaUtils.isEmpty(setfegVo.getSetfel().get(d).getFeecod()) && MdaUtils.isEmpty(setfegVo.getSetfel().get(d).getRol()) && MdaUtils.isEmpty(setfegVo.getSetfel().get(d).getFepinrlst())) {
                    empcnt = empcnt + 1;
                }
            }
        }
        // 3. insert lines to setfel to use Gridinsertrow only once.
        int fepcnt = Streams.streamCount(fepinrs);
        if (fepcnt > empcnt) {
//            Grids.gridInsertRow(this.getSetfel(),0,fepcnt - empcnt + 1);
            setfegVo.getSetfel().addAll(
                    IntStream.range(0, fepcnt - empcnt).mapToObj(n -> new SetfelVo())
                            .collect(Collectors.toList()));
            gridcnt = setfegVo.getSetfel().size();
        }
        // 4. Add lines in setfel
        int detlin = 0;
        int detinfidx = 0;
        IStream detinfval = new StreamImpl();
        if (fepcnt > 0) {
            for (i = 1; i <= fepcnt; i++) {
                while ((!MdaUtils.isEmpty(setfegVo.getSetfel().get(detlin).getFeecod())) || (!MdaUtils.isEmpty(setfegVo.getSetfel().get(detlin).getRol())) || (!MdaUtils.isEmpty(setfegVo.getSetfel().get(detlin).getFepinrlst()))) {
                    detlin = detlin + 1;
                }
                String curinr = Strings.getLine(fepinrs, i);
                FeeEntity feeEntity = feeSetLocal.get().getFeeEntityById(curinr);
                if (MdaUtils.isEmpty(feeEntity.getRemove())) {
                    SetfelVo setfelVo = setfegVo.getSetfel().get(detlin);
                    setfelVo.setFeecod(feeEntity.getFeeCod());
                    setfelVo.setFeetxtinf(feeEntity.getFeetxtinf());
                    setfelVo.setCur(feeEntity.getCur());
                    setfelVo.setAmt(feeEntity.getAmt());
                    setfelVo.setOgiamt(feeEntity.getOgiamt());
                    setfelVo.setDat1(feeEntity.getDat1());
                    setfelVo.setDat2(feeEntity.getDat2());
                    setfelVo.setDat2dft(setfelVo.getDat2());
                    if (MdaUtils.isEmpty(setfelVo.getModflg())) {
                        setfelVo.setModflg("r");
                    }
                    setfelVo.setUntamt(feeEntity.getUntamt());
                    setfelVo.setRatcal(feeEntity.getRatcal());
                    setfelVo.setBasamtin(feeEntity.getBasamt());
                    setfelVo.setUnt(feeEntity.getUnit());
                    setfelVo.setRolptyinr(feeEntity.getPtyInr());
                    setfelVo.setInftxt(feeEntity.getInftxt());
                    setfelVo.setObjmod(feeEntity.getObjmod());
                    //setfelVo.setObjOfSETFEL ( setfelVo.getObjmod() );
                    setfelVo.setFecmod(feeEntity.getFecmod());
                    setfelVo.setFecirt(feeEntity.getFecirt());
                    setfelVo.setIrsday(feeEntity.getIrsDay());
                    setfelVo.setRoldbt(feeEntity.getRoldbt());
                    setfelVo.setCbtpfx(feeEntity.getCbtpfx());
                    setfelVo.setCextid(feeEntity.getCextid());
                    setfelVo.setDspdft(feeEntity.getDspdft());
                    setfelVo.setProflg(feeEntity.getProflg());
                    setfelVo.setAdvtrninr(feeEntity.getAdvtrninr());
                    setfelVo.setAdvdat(feeEntity.getAdvdat());
                    setfelVo.setMinmaxflg(feeEntity.getMinmaxflg());
                    setfelVo.setPredbt(feeEntity.getPreDbt());
                    /**
                     SetFelCusFields( $curinr, $detlin )
                     **/
                    setFelCusFields(setfelVo, feeEntity);
                    Streams.streamSet(setfelVo.getInfdetstm(), feeEntity.getInfdetStm());
                    // check if DETINF is available. If so restore additional fields
                    // (has to match with storage function in Defaultsetfel)
                    detinfidx = Streams.streamSearch(setfelVo.getInfdetstm(), "DETINF");
                    if (detinfidx > 0) {
                        Streams.streamClear(detinfval);
                        Utils.getTabValues(detinfval, Strings.getLine(setfelVo.getInfdetstm(), detinfidx) + TAB);
                        if (Streams.streamCount(detinfval) > 6) {
                            setfelVo.getWrkfec().setCalrul(Strings.getLine(detinfval, 2));
                            setfelVo.getWrkfec().setRatcal(Strings.parseDecimal(Strings.getLine(detinfval, 3)));
                            setfelVo.getWrkfec().setUntamt(Strings.parseDecimal(Strings.getLine(detinfval, 4)));
                            setfelVo.getWrkfec().setPertyp(Strings.getLine(detinfval, 5));
                            setfelVo.setAllcalflg(Strings.getLine(detinfval, 6));
                            setfelVo.setBasamt(new BigDecimal(Strings.getLine(detinfval, 7)));
                        }
                    }
                    int lines = Streams.streamSearch(setfelVo.getInfdetstm(), "DAT2DFT" + TAB);
                    if (lines > 0) {
                        String value = Strings.getLine(setfelVo.getInfdetstm(), lines);
                        String[] dat2dftStrs = value.split(TAB);
                        if (dat2dftStrs.length == 2) {
                            setfelVo.setDat2dft(Utils.parseDate(dat2dftStrs[1]));
                        }
                    }
                    fep2SetfelSetRol(feeEntity, setfelVo);
                    // if no direct role, check ADDFEPPTYINR
                    //根本没有注册"ADDFEEPTYINR"的地方
//                    if( MdaUtils.isEmpty(setfelVo.getRol()) )
//                    {
//                        Caches.cacheRead(this.getSetpty(),"ADDFEEPTYINR",setfelVo.getRolptyinr());
//                        if( ctx.getErrorCode() != tdCacheNotFound )
//                        {
//                            ctx.reraise();
//                            setfelVo.setRol( this.getSetpty().getRol());
//                        }
//                    }
                    if (Streams.streamSearch(setfelVo.getInfdetstm(), "FEETXTMOD" + TAB) > 0) {
                        //Systems.setAttribute(this.getSetfel().getElement(detlin),"feetxtinf",tdAttrModified,2);
                    }
                    Streams.streamInsert(setfelVo.getFepinrlst(), 0, curinr);
                    // as otherwise sometimes ?? WRKSUM is calculated before DSP
                }
            }
        }

    }

    /**
     *   source:setfeg.0009.script
     */
//    @JsonIgnore
//    @TDStatic
//    public String getFeeGrp(String feecod)
//    {
//
//        String res = "";
//        int grpidx = Streams.streamSearch(ctx.absGet(Trnmod.class).getWrkstm().getStm1(),"FEEGRPCOD-" + feecod + TAB);
//        String grplin = NULLSTR;
//        if( grpidx > 0 )
//        {
//            grplin = Strings.getLine(ctx.absGet(Trnmod.class).getWrkstm().getStm1(),grpidx);
//            res = Strings.mid(grplin,Strings.pos(grplin,TAB) + 1);
//        }
//        return  res;
//
//    }

    /**
     * source:setfeg.0010.script
     */
    @JsonIgnore
    public void getfepinrs(IStream res, boolean feponly) {
        Streams.streamClear(res);
        List<String> allFepInrs = feeSetLocal.get().getAllFepInrs();
        res.getRows().addAll(allFepInrs);
//        int cnt = 0;
//        Argument<Integer> cntBox = new Argument<Integer>("",0);
//        Caches.cacheRead(cntBox,"SETFEG","FEPCNT");
//        cnt = cntBox.value;
//        String id = NULLSTR;
//        if( ctx.getErrorCode() != tdCacheNotFound )
//        {
//            ctx.reraise();
//            if( cnt > 0 )
//            {
//                for(int  i = 1;i <= cnt;i++)
//                {
//                    id = "";
//                    Argument<String> idBox = new Argument<String>("","");
//                    Caches.cacheRead(idBox,"SETFEG","FEPIDS",i);
//                    id = idBox.value;
//                    if( ctx.getErrorCode() != tdCacheNotFound )
//                    {
//                        ctx.reraise();
//                        Streams.streamInsert(res,0,id);
//                    }
//                }
//            }
//        }
        if (!feponly) {
            List<String> feeInrs = feeSetLocal.get().getAllFeeInrs();
            res.getRows().addAll(feeInrs);
//            cnt = 0;
//            Argument<Integer> cntBox1 = new Argument<Integer>("",0);
//            Caches.cacheRead(cntBox1,"SETFEG","FEECNT");
//            cnt = cntBox1.value;
//            if( ctx.getErrorCode() != tdCacheNotFound )
//            {
//                ctx.reraise();
//                if( cnt > 0 )
//                {
//                    for(int  i = 1;i <= cnt;i++)
//                    {
//                        id = "";
//                        Argument<String> idBox = new Argument<String>("","");
//                        Caches.cacheRead(idBox,"SETFEG","FEEIDS",i);
//                        id = idBox.value;
//                        if( ctx.getErrorCode() != tdCacheNotFound )
//                        {
//                            ctx.reraise();
//                            Streams.streamInsert(res,0,id);
//                        }
//                    }
//                }
//            }
        }

    }

    /**
     * source:setfeg.0011.script
     */
    public int getintidx(int ext) {
//        int gridcnt = Grids.gridCount(setfegVo.getSetfel());
//        for(int  i = 1;i <= gridcnt;i++)
//        {
//            if( MdaUtils.compareTo(Grids.getGridRow(this.getSetfel(),i),ext) == 0 )
//            {
//                return  i;
//            }
//        }
        return ext;

    }

    /**
     * source:setfeg.0013.script
     */
    public void remTrnFeeGroup(String key) {
        //! remove logically a group of entries from list of fee positions
        //! ArgId : Prefix of Ids to be removed as used in AddTrnFee
        feeSetLocal.get().clearFeeEntity(key);
    }
    /**
     *   source:setfeg.0014.script
     */
//    @JsonIgnore
//    @TDMethod
//    public void setAVBFEECOD()
//    {
//        //! set available fees into AVBFEECOD
//        String sqlWhere = " WHERE ( " + Platform.sqlFldUpper("RELTRN") + " LIKE " + Platform.sqlLit("%+" + Strings.toUpper(Strings.mid(Platform.recGetObj(ctx.absGet(Mtabut.class).getRec()),1,2)) + "+%") + " OR " + Platform.sqlFldUpper("RELTRN") + " LIKE " + Platform.sqlLit("%+" + Strings.toUpper(ctx.getTransName()) + "+%") + " OR RELTRN = " + Platform.sqlLit("") + " ) ";
//        String begDatSql = "( BEGDAT <= " + ctx.getDaoSession().dbSqlDate(Dates.today()) + " OR BEGDAT IS NULL )";
//        String endDatSql = "( ENDDAT > " + ctx.getDaoSession().dbSqlDate(Dates.today()) + " OR ENDDAT IS NULL )";
//        sqlWhere = sqlWhere + " AND " + begDatSql + " AND " + endDatSql;
//        String sql = "SELECT COD FROM FEE " + Platform.sdbEtyGenSql(this.getWrkfee(),sqlWhere) + " ORDER BY COD";
//        Streams.streamClear(this.getAvbfeecod());
//        ctx.getDaoSession().dbExecuteSQL(sql);
//        ctx.getDaoSession().dbFetchStream(this.getAvbfeecod());
//        ctx.getDaoSession().dbCloseCursor();
//
//    }

    /**
     * source:setfeg.0015.script
     */
    public Fep setwrkfep(SetfelVo setfelVo, List<PtsptaVo> ptsList, BizInfoVo rec, String trninr) {
        Fep wrkFep = new Fep();
        wrkFep.setNam(setfelVo.getFeetxtinf());
        if (MdaUtils.isEmpty(wrkFep.getExtkey())) {
            wrkFep.setExtkey(setfelVo.getFeecod() + "/" + trninr);
        }
        wrkFep.setFeecod(setfelVo.getFeecod());
        wrkFep.setCur(setfelVo.getCur());
        wrkFep.setAmt(setfelVo.getAmt());
        wrkFep.setOgiamt(setfelVo.getOgiamt());
        wrkFep.setDctamt(setfelVo.getOgiamt().subtract(setfelVo.getAmt()));
        wrkFep.setXrfcur(setfelVo.getXrfcur());
        wrkFep.setXrfamt(setfelVo.getXrfamt());
        wrkFep.setDat1(setfelVo.getDat1());
        wrkFep.setDat2(setfelVo.getDat2());
        wrkFep.setModflg(setfelVo.getModflg());
        wrkFep.setUntamt(setfelVo.getUntamt());
        wrkFep.setRatcal(setfelVo.getRatcal());
        wrkFep.setMinmaxflg(setfelVo.getMinmaxflg());
        wrkFep.setInfdetstm(MdaUtils.toString(setfelVo.getInfdetstm()));
        wrkFep.setUnt(setfelVo.getUnt());
        wrkFep.setPtyinr(setfelVo.getRolptyinr());
        // set warning if FEP is stored without PTYINR as such entries cannout be assiged to party on pickup
        if (MdaUtils.isEmpty(wrkFep.getPtyinr())) {
//            Dynamic.sysWarningSet( SYSWRNTypeFinal, Strings.getText(MdaUtils.getI18NString("setfeg","CT000301"),detidx,setfelVo.getRol()), "SETWRKFEP" + MdaUtils.toString(detidx) );
            //log.warn("CAUTION : Own charge line {} in settlement settled to {} does not hold party information.\nRole defaulting on pickup will not be possible", detidx, setfelVo.getRol() );
        }
        wrkFep.setRol(setfelVo.getRol());
        String objmod = setfelVo.getObjmod();
        SimpleModuleVo linkModule = null;
        if (StringUtils.isNotEmpty(objmod)) {
            try {
                linkModule = Utils.toObject(SimpleModuleVo.class, objmod);
                wrkFep.setObjinr(linkModule.getObjinr());
                wrkFep.setObjtyp(linkModule.getObjtyp());
            } catch (Exception e) {
                linkModule = null;
            }
        }
        if (linkModule == null) {
            wrkFep.setObjinr(rec.getObjinr());
            wrkFep.setObjtyp(rec.getObjtyp());
        }
        // Set relevant object if not already set or not received from pool only
        boolean setRelobj = false;
        if (MdaUtils.isEmpty(wrkFep.getRelobjinr())) {
            setRelobj = true;
        } else {
            switch (setfelVo.getSrc()) {
                case "P":
                case "D":
                case "A":
                case "O":
                    setRelobj = false;
                    break;
                default:
                    setRelobj = true;
            }
        }
        if (setRelobj || "Y".equals(setfelVo.getCommFeeFlag())) {
            wrkFep.setRelobjtyp(wrkFep.getObjtyp());
            wrkFep.setRelobjinr(wrkFep.getObjinr());
        }
//        if( ( MdaUtils.compareTo(setfelVo.getDsp(),"X")== 0 ) && Strings.pos(ctx.absGet(Setmod.class).getDspflg(),"G") > 0 )
        //没有临时收费一说，dspflg固定为“CG”
        if (MdaUtils.compareTo(setfelVo.getDsp(), "X") == 0 || "Y".equals(setfelVo.getCommFeeFlag())) {
            wrkFep.setDontrninr(trninr);
            wrkFep.setDondat(Dates.today());
        }
        // if fee is advised with this transaction, store this transaction as ADV...
        //光大的需求，屏蔽临时记账
        /**
         if \\SETMOD\\SETFEG\\SETFEL( detidx )\\DSP.is ( "S" ) then
         \\SETMOD\\SETFEG\\WRKFEP\\ADVTRNINR = \\TRNMOD\\TRN\\INR
         \\SETMOD\\SETFEG\\WRKFEP\\ADVDAT = Today
         endif
         **/
        // if fee was advised before, store info from pool in new pool entry
        if ((MdaUtils.compareTo(setfelVo.getSrc(), "D") == 0 || MdaUtils.compareTo(setfelVo.getSrc(), "A") == 0) && (MdaUtils.compareTo(setfelVo.getDsp(), "D") == 0 || MdaUtils.compareTo(setfelVo.getDsp(), "S") == 0)) {
            wrkFep.setAdvtrninr(setfelVo.getAdvtrninr());
            wrkFep.setAdvdat(setfelVo.getAdvdat());
        }
        String conditionSql = Utils.sdbEtyGenSql("FEE", "COD = '" + setfelVo.getFeecod() + "'");
        List<Fee> feeList = feeMapper.getFeeByConditionSql(conditionSql);
        if (feeList != null) {
            Fee wrkFee = feeList.get(0);
            wrkFep.setFeeacc(wrkFee.getAcc());
        }
        //Acr 应该收费都是核心去算的。这块不需要
        if (MdaUtils.isEmpty(wrkFep.getAcrinr()) && MdaUtils.compareTo(setfelVo.getSrc(), "E") == 0) {
            wrkFep.setAcrinr(setfelVo.getAcrinr());
        }
        // Set istallation specific fields (if any)
        return wrkFep;
    }

    /**
     * source:setfeg.0016.script
     */
    public String swiftGetERIfee(SetfegVo setfeg, String rol, String dsp, String fldcur) {
        String res = "";
        BigDecimal sum = new BigDecimal("0");
        String cur = "";
        int gridcnt = setfeg.getSetfel() == null ? 0 : setfeg.getSetfel().size();
        for (int d = 0; d < gridcnt; d++) {
            SetfelVo setfel = setfeg.getSetfel().get(d);
            if (MdaUtils.compareTo(setfel.getRol(), rol) == 0 && (MdaUtils.compareTo(setfel.getDsp(), dsp) == 0 || MdaUtils.compareTo(dsp, "A") == 0)) {
                sum = Decimals.add(sum, setfel.getAmt());
                cur = setfel.getCur();
            }
        }
        if (MdaUtils.compareTo(sum, 0) != 0 && (!MdaUtils.isEmpty(cur)) && MdaUtils.compareTo(fldcur, cur) != 0 && MdaUtils.compareTo(fldcur, "EUR") == 0) {
            Cur curObj = xrtmodService.getCurByCode(cur);
            if (curObj.getSeq() == -1) {
                BigDecimal eurAmt = xrtmodService.amtConvTypes(cur, sum, "M", "EUR", "M", Dates.today());
                String label = "EUR" + Utils.fmtAmountSwift(eurAmt, "EUR");
                res = "/CHGS/" + label + "/";
            }
        }
        return res;

    }

    /**
     * source:setfeg.0017.script
     */
    public void getCurFeeRolbyDsp(List<SetfelVo> setfelVos, String rol, String dsp, Argument<String> cur, Argument<BigDecimal> amt) {
        //! Get fee currency and total amount of fees for role ROL
        //! dsp X = collected, "V" = advised in this transaction, D-advised in former transactions, A = all
        cur.value = "";
        amt.value = new BigDecimal("0");
        boolean found = false;
        for (SetfelVo setfelVo : setfelVos) {
            if (MdaUtils.compareTo(rol, setmodService.getGllRol(setfelVo.getRol())) == 0 && (MdaUtils.compareTo(setfelVo.getDsp(), dsp) == 0 || MdaUtils.compareTo(dsp, "A") == 0)) {
                if (found && MdaUtils.compareTo(setfelVo.getCur(), cur.value) != 0) {
                    throw new CommonServiceException("Fees in different currencies found for role " + rol + ", cannot sum them up");
                }
                cur.value = setfelVo.getCur();
                amt.value = Decimals.add(amt.value, setfelVo.getAmt());
                found = true;
            }
        }
    }
    /**
     *   source:setfeg.0019.script
     */
//    @JsonIgnore
//    @TDMethod
//    public String getfepval(String inr,String nam)
//    {
//        //! get value stored with function add2fepinp for INR and name
//        //! Corresponding function:add2fepinp
//        String value = "";
//        Argument<String> valueBox = new Argument<String>("","");
//        Caches.cacheRead(valueBox,"SETFEG","FEEVAL",inr,nam);
//        value = valueBox.value;
//        if( ctx.getErrorCode() == tdCacheNotFound )
//        {
//            //Platform.clear( value );
//            value = NULLSTR;
//        }
//        else
//        {
//            ctx.reraise();
//        }
//        return  value;
//
//    }

    /**
     * source:setfeg.0020.script
     */
    public Date getLatestFepDate(String argFeeCod, SetmodVo setmodVo, int idx) {
        //! gets lates FEP-Date for fee code of this row
        //! if no old fep is available OPNDAT is taken
        Date date = NULLDATE;
        Fep wrkFep = setwrkfep(setmodVo.getSetfeg().getSetfel().get(idx), setmodVo.getPtsList(), setmodVo.getRec(), transactionHelpService.getTrninr());
        String sql = "SELECT DAT2 FROM FEP WHERE FEECOD = '" + argFeeCod + "' AND OBJTYP = '" + wrkFep.getObjtyp() + "' AND OBJINR = '" + wrkFep.getObjinr() + "' ORDER BY DAT2 DESC";
        Map<String, Object> map = new HashMap<>();
        map.put("sql", sql);
        List<Fep> fepList = fepMapper.dyncRead(map);
        if (MdaUtils.isEmpty(fepList)) {
            return setmodVo.getOpndat();
        }
        date = fepList.get(0).getDat2();
//        IStream retstream = new StreamImpl();
//        Streams.streamClear(retstream);
//        ctx.getDaoSession().dbExecuteSQL(sql,retstream);
//        ctx.getDaoSession().dbFetchFields("DAT2",date);
//        if( ctx.getErrorCode() > 0 )
//        {
//            if( ctx.getErrorCode() == tdOdbcNotFound )
//            {
//                date = ctx.absGet(Setmod.class).getOpndat();
//            }
//            else
//            {
//                ctx.reraise();
//            }
//        }
//        ctx.getDaoSession().dbCloseCursor();
        return date;

    }

    /**
     * source:setfeg.0021.script
     */
    public void recalcSetfegEog(SetmodVo setmodVo) {
        setglgService.setglgClrAmount(setmodVo.getSetglg(), "*SETFEG");
        SetfegVo setfegVo = setmodVo.getSetfeg();
        int gridcnt = 0;
        if (setfegVo.getSetfel() != null) {
            gridcnt = setfegVo.getSetfel().size();
        }
        for (int i = 0; i < gridcnt; i++) {
            SetfelVo setfelVo = setfegVo.getSetfel().get(i);
            if (!MdaUtils.isEmpty(setfelVo.getRol()) && !MdaUtils.isEmpty(setfelVo.getAmt())) {
                if (MdaUtils.compareTo(setfelVo.getDsp(), "X") == 0 || MdaUtils.compareTo(setfelVo.getDsp(), "S") == 0) {
                    setglgService.setglgAddAmount(setmodVo.getSetglg(), "*SETFEG", setfelVo.getRol(), setfelVo.getCur(), setfelVo.getAmt(), "FEG", "", "", "", "");
                }
            }
        }
        this.calcMaceog(setfegVo);
        setfegVo.setMaceogold(setfegVo.getMaceog());
    }
    /**
     *   source:setfeg.0022.script
     */
//    @JsonIgnore
//    public void getmodulesoftype(IStream strm,IModule mod,String typ)
//    {
//        IStream trnmodules = new StreamImpl();
//        Streams.streamClear(trnmodules);
//        String path = MdaDriver.getModuleInfo(mod,tdModuleInfoFullName);
//        MdaDriver.getModuleInfoStream(trnmodules,mod,tdModuleModules);
//        int stmCnt = Streams.streamCount(trnmodules);
//        String line = NULLSTR;
//        IModule thismod = null;
//        String thistype = NULLSTR;
//        for(int  i = 1;i <= stmCnt;i++)
//        {
//            line = path + "\\" + Strings.getLine(trnmodules,i);
//            thismod = MdaDriver.getModule(this,line);
//            if( ctx.getErrorCode() == 0 )
//            {
//                thistype = MdaDriver.getModuleInfo(thismod,tdModuleInfoClass);
//                if( MdaUtils.compareTo(thistype,typ) == 0 )
//                {
//                    Streams.streamInsert(strm,0,line);
//                }
//            }
//        }
//
//    }

    /**
     * source:setfeg.0023.script
     *
     * @param modId
     */
    public void setfegClrCbsAmt(String modId) {
        //! Clear CBS-Amounts set by ArgCallMod to allow complete redefaulting with following calls of SetglgAddCbsAmt
        // remove Cache entries for Argid
        FeeSet feeSet = getFeeSet();
        feeSet.removeSetCbs(modId);
    }

    /**
     * source:setfeg.0024.script
     */
    public String setfegAddCbsAmt(String modId, String argRol, String argCur, BigDecimal argAmt, String argExtId, String argCbc, String argObjpath, Date argbegDat) {
        //! Add Amount Argamt to amounts to be settled to ArgRol
        //! ArgCallMod: The calling module. 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
        //!
        //! Function returns key allowing setting additional information with SetglgAddAmtFld<xxx> -Functions
//        String modId = MdaDriver.getModuleInfo(argCallMod,tdModuleInfoFullName);
        String cacKey = argRol + argCur + TAB + argExtId + TAB + argCbc + TAB + argObjpath;
        String stmKey = modId + TAB + cacKey;
        FeeSet feeSet = getFeeSet();
        Setcbs setcbs = feeSet.getSetcbs(stmKey);
        if (setcbs == null) {
            setcbs = new Setcbs();
        }
        setcbs.setAmt(Decimals.add(setcbs.getAmt(), argAmt));
        setcbs.setCur(argCur);
        setcbs.setRol(argRol);
        setcbs.setExtid(argExtId);
        setcbs.setCbc(argCbc);
        setcbs.setObjmod(argObjpath);
        setcbs.setBegdat(argbegDat);
        feeSet.putSetcbs(stmKey, setcbs);
        return cacKey;
    }
    /**
     * source:setfeg.0026.script
     */
    @JsonIgnore
    public void setFelCusFields(SetfelVo setfelVo, FeeEntity feeEntity) {
        //! Set customer specific fields in FEE line
        //!======================================================
        //!参数：    rownum : SETFEL行号
        //!          fepinr :
        //!返回值：  无
        //!说明：    修改原函数SetFelCusFields，增加两个参数
        //!======================================================
        Date oldmatdat = feeEntity.getOldmatdat();
        if (!setfelVo.isModified("oldmatdat")) {
            setfelVo.setOldmatdat(oldmatdat);
        }

    }

    /**
     * source:setfeg.0027.script
     */
    public void setDspPolDft(SetfegVo setfegVo, String argDspPolDft, String argDisableFlag) {
        //! to be used for settlement defaulting from RegisterSettlement functions
        //! sets the default disposition for pool entries
        //! Only necessary, if not "V" (i.e. pool entries are advised asap)
        setfegVo.setDsppoldft(argDspPolDft);
        setfegVo.setDsppoldftflg(argDisableFlag);

    }

    /**
     * source:setfeg.0028.script
     */
    public void fep2SetfelSetRol(FeeEntity feeEntity, SetfelVo setfelVo) {
        String feprol = NULLSTR;
        if (!MdaUtils.isEmpty(setfelVo.getRolptyinr())) {
            feprol = feeEntity.getFeprol();
            if (!MdaUtils.isEmpty(feprol)) {
                Setpty setpty = feeSetLocal.get().getSetpty(feprol);
                if (setpty == null) {
                    return;
                }
                if (!setfelVo.isModified("rol")) {
                    setfelVo.setRol(setpty.getRol());
                }
                if (!MdaUtils.isEmpty(setpty.getRol()) && !MdaUtils.isEmpty(feprol)) {
                    setfelVo.setRoldbt(setpty.getRol());
                }
            }
        }

    }

    /**
     * source:setfeg.0029.script
     */
    @JsonIgnore
    public void getrolandptxinr(SetmodVo setmodVo, Argument<String> argRol, Argument<String> ptyinr, Argument<String> ptainr, String chato, String argFeeRol) {
        //! get role paying fee
        //!  ROL may be an defined role (in that case it is taken)
        //! Special values are:
        //!  - CLI or U (for our client) as defined in FEeclirol
        //!  - COR or B (for correspondent bank) as defined feecorrol
        //!  - S if no defaulting shall happen
        ptyinr.value = "";
        ptainr.value = "";
        // if chato is set and fee is not to be used always, use CHATO, otherwise use default from fee
        if (!MdaUtils.isEmpty(chato) && MdaUtils.compareTo(argFeeRol, "COF") != 0 && MdaUtils.compareTo(argFeeRol, "CLF") != 0) {
            argRol.value = chato;
        } else {
            if (!MdaUtils.isEmpty(argFeeRol)) {
                argRol.value = argFeeRol;
            }
        }
        switch (argRol.value) {
            case "CLI":
            case "U":
            case "CLF":
                argRol.value = setmodVo.getFeeclirol();
                break;
            case "COR":
            case "B":
            case "COF":
                argRol.value = setmodVo.getFeecorrol();
                break;
            default:
                // else take it
        }
        if (Streams.streamSearch(setmodVo.getRoldsc(), argRol.value + TAB) > 0) {
            setmodService.getPtxInr(argRol.value, ptyinr, ptainr);
        } else {
            if (!MdaUtils.isEmpty(setmodVo.getRoldsc())) {
                MdaUtils.clear(argRol);
                MdaUtils.clear(ptyinr);
                MdaUtils.clear(ptainr);
            }
        }

    }

    public void fillPtyInrStm(IStream argStm) {
        feeSetLocal.get().getAllSetpty().forEach(setpty -> {
            argStm.getRows().add(setpty.getPtyInr());
        });
    }

    /**
     * source:setfeg.0030.script
     */
    public void fillPtyInrStmForFep(IStream argStm) {
        Streams.streamClear(argStm);
        fillPtyInrStm(argStm);

        feeSetLocal.get().getAllFepEntity().forEach(feeEntity -> {
            argStm.getRows().add(feeEntity.getPtyInr());
        });
    }
    /**
     *   source:setfeg.0031.script
     */
//    @JsonIgnore
//    @TDStatic
//    public boolean isFeeCodSettled(String argFeeCod,IModule argGrp)
//    {
//        //取得上下文
//        IContext ctx = MdaEnv.getContext();
//        ctx.setErrorCode(NO_ERROR);
//        //! Checks, if a fee code is already settled before by searching in fee pool (FEP).
//        //! Function returns true if ArgFeeCod was already set for ArgGrp
//        boolean res = false;
//        String objTyp = Platform.recGetObj(argGrp);
//        String objInr = Platform.recGetInr(argGrp);
//        int fepCnt = 0;
//        Argument<Integer> _fepCntBox = Argument.box(fepCnt);
//        String lbl = NULLSTR;
//        if( ! MdaUtils.isEmpty(objInr) )
//        {
//            fepCnt = 0;
//            lbl = objTyp + objInr + argFeeCod;
//            Caches.cacheRead(_fepCntBox,lbl);
//            fepCnt = _fepCntBox.value;
//            if( ctx.getErrorCode() != tdCacheNotFound )
//            {
//                ctx.reraise();
//            }
//            else
//            {
//                ctx.getDaoSession().dbExecuteSQL("Select count(*) from FEP Where OBJTYP = ? AND OBJINR = ? AND FEECOD = ?",objTyp,objInr,argFeeCod);
//                ctx.getDaoSession().dbFetchFields("",_fepCntBox);
//                fepCnt = _fepCntBox.value;
//                ctx.getDaoSession().dbCloseCursor();
//                Caches.cacheWrite(fepCnt,lbl);
//            }
//            if( fepCnt > 0 )
//            {
//                res = true;
//            }
//        }
//        return  res;
//
//    }

    /**
     * source:setfeg.0032.script
     */
    public void ptsAdjust(SetfegVo setfegVo) {
        //! disallow changes for parties with fee entries retrieved from pool
        int gridcnt = 0;
        if (MdaUtils.compareTo(Strings.mid(SettleContext.getTransName(), 4, 3), "TRF") != 0) {
            gridcnt = setfegVo.getSetfel().size();
            for (int i = 0; i < gridcnt; i++) {
                if (!MdaUtils.isEmpty(setfegVo.getSetfel().get(i).getRol()) && MdaUtils.compareTo(Strings.mid(Strings.getLine(setfegVo.getSetfel().get(i).getFepinrlst(), 1), 1, 1), "T") != 0) {
                    //此位置只是为了控制UI输入模式，不适用组件化
                    //setmodTool.ptsSetRolChgFlg( setfegVo.getSetfel().get(i).getRol(), ctx.absGet(Mtabut.class).getRec(), "PO",  );

                }
            }
        }

    }

    /**
     * source:setfeg.0033.script
     */
    public void clearSetFelCusFields(int argIdx) {
        //! Set customer specific fields in FEE line

    }

    /**
     * source:setfeg.0034.script
     */
    @JsonIgnore
    public void setOneFepInp(Fep wrkFep) {
        FeeEntity feeEntity = new FeeEntity();
        //! Insert one complete FEP entry in FEPINP
//        add2fepinp( this.getWrkfep().getInr(), "FEECOD", this.getWrkfep().getFeecod() );
        feeEntity.setFeeCod(wrkFep.getFeecod());
//        add2fepinp( this.getWrkfep().getInr(), "CUR", this.getWrkfep().getCur() );
        feeEntity.setCur(wrkFep.getCur());
//        add2fepinp( this.getWrkfep().getInr(), "AMT", MdaUtils.toString(this.getWrkfep().getAmt()) );
        feeEntity.setAmt(wrkFep.getAmt());
//        add2fepinp( this.getWrkfep().getInr(), "OGIAMT", MdaUtils.toString(this.getWrkfep().getOgiamt()) );
        feeEntity.setOgiamt(wrkFep.getOgiamt());
//        add2fepinp( this.getWrkfep().getInr(), "DAT1", Formats.format(this.getWrkfep().getDat1(),"DD/MM/YYYY") );
        feeEntity.setDat1(wrkFep.getDat1());
//        add2fepinp( this.getWrkfep().getInr(), "DAT2", Formats.format(this.getWrkfep().getDat2(),"DD/MM/YYYY") );
        feeEntity.setDat2(wrkFep.getDat2());
//        add2fepinp( this.getWrkfep().getInr(), "MODFLG", this.getWrkfep().getModflg() );
        feeEntity.setModflg(wrkFep.getModflg());
//        add2fepinp( this.getWrkfep().getInr(), "RAT", MdaUtils.toString(this.getWrkfep().getRat()) );
        feeEntity.setRat(wrkFep.getRat());
//        add2fepinp( this.getWrkfep().getInr(), "UNTAMT", MdaUtils.toString(this.getWrkfep().getUntamt()) );
        feeEntity.setUntamt(wrkFep.getUntamt());
//        add2fepinp( this.getWrkfep().getInr(), "RATCAL", MdaUtils.toString(this.getWrkfep().getRatcal()) );
        feeEntity.setRatcal(wrkFep.getRatcal());
//        add2fepinp( this.getWrkfep().getInr(), "UNIT", MdaUtils.toString(this.getWrkfep().getUnt()) );
        feeEntity.setUnit(wrkFep.getUnt());
//        add2fepinp( this.getWrkfep().getInr(), "PTYINR", this.getWrkfep().getPtyinr() );
        feeEntity.setPtyInr(wrkFep.getInr());
//        add2fepinp( this.getWrkfep().getInr(), "FEPROL", this.getWrkfep().getRol() );
        feeEntity.setFeprol(wrkFep.getRol());
//        add2fepinp( this.getWrkfep().getInr(), "INFDETSTM", this.getWrkfep().getInfdetstm() );
        feeEntity.setInfdetStm(wrkFep.getInfdetstm());
//        add2fepinp( this.getWrkfep().getInr(), "ADVDAT", Formats.format(this.getWrkfep().getAdvdat(),"DD/MM/YYYY") );
        feeEntity.setAdvdat(wrkFep.getAdvdat());
//        add2fepinp( this.getWrkfep().getInr(), "ADVTRNINR", this.getWrkfep().getAdvtrninr() );
        feeEntity.setAdvtrninr(wrkFep.getAdvtrninr());
        String infTxt = Strings.getText("$5 unit(s) of $1 stored in pool on $2: $3 $4", codetableService.getTblLabel(wrkFep.getFeecod(), "FEETXT"), Formats.fmtDateShort(wrkFep.getSrcdat()), wrkFep.getCur(), Utils.fmtAmount(wrkFep.getAmt(), wrkFep.getCur()), wrkFep.getUnt());
        if (!MdaUtils.isEmpty(wrkFep.getAdvdat())) {
            infTxt = infTxt + CR + Strings.getText("Fee has been advised on $1", Formats.fmtDateShort(wrkFep.getAdvdat()));
        }
//        add2fepinp( this.getWrkfep().getInr(), "INFTXT", infTxt );
        feeEntity.setInftxt(infTxt);
//        add2fepinp( this.getWrkfep().getInr(), "FEETXTINF", this.getWrkfep().getNam() );
        feeEntity.setFeetxtinf(wrkFep.getNam());
//        add2fepinp( this.getWrkfep().getInr(), "TYP", "FEP" );
        feeEntity.setType("FEP");
        feeEntity.setObjmod(Utils.toJson(SimpleModuleVo.buildModule(wrkFep.getObjinr(), wrkFep.getObjtyp())));

        feeSetLocal.get().putFepEntity(wrkFep.getInr(), feeEntity);
//        add2fepinp( this.getWrkfep().getInr(), "SEPINR", this.getWrkfep().getSepinr() );
        //SEP表示临时收费，并没有什么用
        //feeEntity.setSepInr(wrkFep.getSepinr());
    }
    /**
     *   source:setfeg.0035.script
     */
//    @TDMethod
//    public void registerSettlementCorrCha()
//    {
//        //取得上下文
//        IContext ctx = MdaEnv.getContext();
//        ctx.setErrorCode(NO_ERROR);
//        int couAnz = 0;
//        String couSw = "";
//        int letAnz = 0;
//        String letSw = "";
//        int swtAnz = 0;
//        String swtSw = "";
//        String fintyp = "";
//        int line = 0;
//        //########国内信用证电报费、快邮费及平邮费####################
//        //!电报费DTELEX
//        //!开邮费DDHL11
//        //!平邮费DPOST
//        //!国内信用证的融资交易与国际信用证交易名称一样，需要单独处理。
//        //############################################################
//        IStream dhlfee = new StreamImpl();
//        Streams.streamClear(dhlfee);
//        String trnNam = Strings.mid(ctx.getTransName(),1,2);
//        String feeCod = NULLSTR;
//        if( MdaUtils.compareTo(trnNam,"DI") == 0 || MdaUtils.compareTo(trnNam,"DE") == 0 || MdaUtils.compareTo(trnNam,"BD") == 0 || MdaUtils.compareTo(trnNam,"BF") == 0 )
//        {  //国内信用证
//            feeCod = "DTELEX";
//        }
//        int err = 0;
//        if( ( MdaUtils.compareTo(MdaDriver.getModuleInfo(ctx.getRoot(),1),"LITOPN") == 0 ) || ( MdaUtils.compareTo(MdaDriver.getModuleInfo(ctx.getRoot(),1),"LTTOPN") == 0 ) || ( MdaUtils.compareTo(MdaDriver.getModuleInfo(ctx.getRoot(),1),"GITOPN") == 0 ) || ( MdaUtils.compareTo(MdaDriver.getModuleInfo(ctx.getRoot(),1),"GITODZ") == 0 ) )
//        {
//            /**
//             if ( GetModuleInfo( \\, 1 ) == "LITOPN" ) or ( GetModuleInfo( \\, 1 ) == "LTTOPN" ) or ( GetModuleInfo( \\, 1 ) == "GITOPN" ) then
//             **/
//            feeCod = "TELEXH";
//        }
//        else
//        {
//            //融资交易单独处理
//            if( MdaUtils.compareTo(MdaDriver.getModuleInfo(ctx.getRoot(),1),"TRTOPN") == 0 )
//            {
//                fintyp = Datas.getContent(this,"\\TRDGRP\\REC\\FINTYP");
//                err = ctx.getErrorCode();
//                if( MdaUtils.compareTo(fintyp,"DRF") == 0 )
//                {   //国内证买方融资
//                    feeCod = "DTELEX";
//                }
//                else
//                {
//                    feeCod = "TELEX";       //国际证进口融资
//                }
//            }
//            if( MdaUtils.compareTo(MdaDriver.getModuleInfo(ctx.getRoot(),1),"BPTOPN") == 0 )
//            {
//                fintyp = Datas.getContent(this,"\\BPDGRP\\REC\\FINTYP");
//                err = ctx.getErrorCode();
//                if( MdaUtils.compareTo(fintyp,"T") == 0 || MdaUtils.compareTo(fintyp,"M") == 0 || MdaUtils.compareTo(fintyp,"G") == 0 || MdaUtils.compareTo(fintyp,"V") == 0 )
//                {   //国内证卖方融资
//                    feeCod = "DTELEX";
//                }
//                else
//                {
//                    feeCod = "TELEX";        //国际证出口融资
//                }
//            }
//            //非融资交易，非国内信用证交易
//            if( MdaUtils.compareTo(MdaDriver.getModuleInfo(ctx.getRoot(),1),"TRTOPN") != 0 && MdaUtils.compareTo(MdaDriver.getModuleInfo(ctx.getRoot(),1),"BPTOPN") != 0 && ( MdaUtils.compareTo(trnNam,"DI") != 0 && MdaUtils.compareTo(trnNam,"DE") != 0 && MdaUtils.compareTo(trnNam,"BD") != 0 && MdaUtils.compareTo(trnNam,"BF") != 0 ) )
//            {
//                feeCod = "TELEX";
//            }
//        }
//        //清理所有与面函相关的收费
//        addFeeData( "POST", "", couAnz, Dates.today(), Dates.today() );
//        addFeeData( "DHL01", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "DHL02", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "DHL03", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "DHL04", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "DHL05", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "DHL06", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "DHL07", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "DHL08", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "DHL09", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "DHL10", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "TELEX", "", couAnz, Dates.today(), Dates.today() );
//        addFeeData( "TELEXH", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "DPOST", "", letAnz, Dates.today(), Dates.today() );
//        addFeeData( "DTELE", "", couAnz, Dates.today(), Dates.today() );
//        addFeeData( "DDHL11", "", letAnz, Dates.today(), Dates.today() );
//        IStream corTypStm = new StreamImpl();
//        Streams.streamClear(corTypStm);
//        Streams.streamSet(corTypStm,Codetables.getTblKeyList("CORTYP",Systems.getLang()));
//        int stmCnt = Streams.streamCount(corTypStm);
//        for(int  i = 1;i <= stmCnt;i++)
//        {
//            Streams.streamSetLine(corTypStm,i,Strings.getLine(corTypStm,i) + TAB + "0");
//        }
//        if( ! MdaUtils.isEmpty(this.getCorchaflg()) )
//        {
//            //return ; // ####### 改写 LABEL与GOTO  ####   goto setFees
//        }else{
//            // ensure recalculation of documents
//            Dynamic.assertDOCS();
//            // count correspondence items
//            IStream docMods = new StreamImpl();
//            Streams.streamClear(docMods);
//            getmodulesoftype( docMods, ctx.getRoot(), "DOCEOT" );
//            IModule rmbclm = MdaDriver.getModule("\\RMBCLM");
//            if( ctx.getErrorCode() == 0 )
//            {
//                getmodulesoftype( docMods, rmbclm, "DOCEOT" );
//            }
//            // using gridcount results in circular ref,.
//            String ins = NULLSTR;
//            IModule mod = null;
//            for(int  i = 1;i <= 50;i++)
//            {
//                ins = "\\TRNMOD\\TRNDOC\\DOCEOT(" + MdaUtils.toString(i) + ")";
//                mod = MdaDriver.getModule(this,ins);
//                if( ctx.getErrorCode() == 0 )
//                {
//                    Streams.streamInsert(docMods,0,ins);
//                }
//            }
//            int stmCntDoc = Streams.streamCount(docMods);
//            String eot = NULLSTR;
//            String delFlg = NULLSTR;
//            String lev = NULLSTR;
//            String oriFlg = NULLSTR;
//            String docEotCorTyp = NULLSTR;
//            String loccty = NULLSTR;
//            String find = NULLSTR;
//            Argument<String> _findBox = Argument.box(find);
//            String sql = NULLSTR;
//
//            int value = 0;
//            for(int  i = 1;i <= stmCntDoc;i++)
//            {
//                eot = Strings.getLine(docMods,i);
//                delFlg = Datas.getContent(this,eot + "\\DELFLG");
//                lev = Datas.getContent(this,eot + "\\LEV");
//                oriFlg = Datas.getContent(this,eot + "\\ORIFLG");
//                // do not count suppressed or deleted messages or send-to-copies
//                if( MdaUtils.compareTo(delFlg,"D") != 0 && ( MdaUtils.compareTo(lev,"1") == 0 || ( MdaUtils.compareTo(lev,"1") != 0 && MdaUtils.compareTo(oriFlg,"C") == 0 ) ) )
//                {
//                    docEotCorTyp = Datas.getContent(this,eot + "\\CORTYP");
//                    if( MdaUtils.compareTo(docEotCorTyp,"LET") == 0 && MdaUtils.isEmpty(ctx.absGet(Setmod.class).getChgpstflg()) )
//                    {
//                        if( MdaUtils.compareTo(Datas.getContent(this,eot + "\\DOCSNF"),"LETAML") == 0 )
//                        {
//                            couAnz = couAnz + 1;
//                            couSw = "Y";
//                        }
//                        if( MdaUtils.compareTo(Datas.getContent(this,eot + "\\DOCSNF"),"LETCOU") == 0 )
//                        {
//                            //按照不同的地区，收取快邮费
//                            //   $ptyinr = GetContent( $Eot + "\\\\PTA\\\\PTYINR" )
//                            loccty = Datas.getContent(this,eot + "\\RCV\\ADR\\LOCCTY");
//                            find = "";
//                            sql = "select DHLREG from CTY where CTY.COD='" + loccty + "'";
//                            ctx.getDaoSession().dbExecuteSQL(sql);
//                            ctx.getDaoSession().dbFetchFields("",_findBox);
//                            find = _findBox.value;
//                            if( ! ( ctx.getErrorCode() == 228 ) )
//                            {
//                                line = Streams.streamSearch(dhlfee,"DHL" + find);
//                                if( line == 0 )
//                                {
//                                    Streams.streamInsert(dhlfee,0,"DHL" + find);
//                                    Streams.streamInsert(dhlfee,0,MdaUtils.toString(1));
//                                }
//                                else
//                                {
//                                    value = Strings.parseInt(Strings.getLine(dhlfee,line + 1)) + 1;
//                                    Streams.streamSetLine(dhlfee,line + 1,MdaUtils.toString(value));
//                                }
//                            }
//                            ctx.getDaoSession().dbCloseCursor();
//                            letAnz = letAnz + 1;
//                            letSw = "Y";
//                        }
//                    }
//                    if( MdaUtils.compareTo(docEotCorTyp,"SWT") == 0 || MdaUtils.compareTo(docEotCorTyp,"TLX") == 0 )
//                    {
//                        swtAnz = swtAnz + 1;
//                        swtSw = "Y";
//                    }
//                    /**
//                     // set count of available messages
//                     $SeaIdx = StreamSearch( $CorTypStm, $DocEotCorTyp )
//                     $SeaLin = StreamGetLine( $CorTypStm, $SeaIdx )
//                     $Idx = Val( Mid( $SeaLin, Pos( $SeaLin, TAB ) + 1 ) ) + 1
//                     StreamSetLine( $CorTypStm, $SeaIdx, $DocEotCorTyp + TAB + Str( $Idx ) )
//                     **/
//                }
//            }
//        }
//        // ####### 改写 LABEL与GOTO   ####    label setFees
//        // Add correspondence fees
//        //收取平邮费
//        if( couAnz > 0 )
//        {
//            //if $TrnNam = "DI" or $TrnNam = "DE" or $TrnNam = "BD" or $TrnNam = "BF" or $FINTYP = "T" or $FINTYP = "M" or $FINTYP = "DRF" then
//            if( MdaUtils.compareTo(trnNam,"DI") == 0 || MdaUtils.compareTo(trnNam,"DE") == 0 || MdaUtils.compareTo(trnNam,"BD") == 0 || MdaUtils.compareTo(trnNam,"BF") == 0 || MdaUtils.compareTo(fintyp,"T") == 0 || MdaUtils.compareTo(fintyp,"M") == 0 || MdaUtils.compareTo(fintyp,"G") == 0 || MdaUtils.compareTo(fintyp,"V") == 0 || MdaUtils.compareTo(fintyp,"DRF") == 0 )
//            {
//                addFeeData( "DPOST", "Y", couAnz, Dates.today(), Dates.today() );   //国内证交易
//            }
//            else
//            {
//                addFeeData( "POST", "Y", couAnz, Dates.today(), Dates.today() ); //只对airmail收取邮费.
//            }
//        }
//        //收取快邮费
//        String couexp = NULLSTR;
//        String ptyextkey = NULLSTR;
//        if( letAnz > 0 )
//        {
//            //if $TrnNam = "DI" or $TrnNam = "DE" or $TrnNam = "BD" or $TrnNam = "BF" or $FINTYP = "T" or $FINTYP = "M" or $FINTYP = "DRF" then
//            if( MdaUtils.compareTo(trnNam,"DI") == 0 || MdaUtils.compareTo(trnNam,"DE") == 0 || MdaUtils.compareTo(trnNam,"BD") == 0 || MdaUtils.compareTo(trnNam,"BF") == 0 || MdaUtils.compareTo(fintyp,"T") == 0 || MdaUtils.compareTo(fintyp,"M") == 0 || MdaUtils.compareTo(fintyp,"G") == 0 || MdaUtils.compareTo(fintyp,"V") == 0 || MdaUtils.compareTo(fintyp,"DRF") == 0 )
//            {
//                addFeeData( "DDHL11", "Y", letAnz, Dates.today(), Dates.today() );   //国内证交易
//            }
//            else
//            {
//                //国际证
//                //快邮费分10个地区收取，按目的地不同分开收取
//                for(int  i = 1;i <= 10;i++)
//                {
//                    if( i < 10 )
//                    {
//                        couexp = "DHL0" + MdaUtils.toString(i);
//                    }
//                    else
//                    {
//                        couexp = "DHL" + MdaUtils.toString(i);
//                    }
//                    line = Streams.streamSearch(dhlfee,couexp);
//                    if( line != 0 )
//                    {
//                        couSw = "Y";
//                        couAnz = Strings.parseInt(Strings.getLine(dhlfee,line + 1));
//                        addFeeData( couexp, couSw, couAnz, Dates.today(), Dates.today() );
//                    }
//                    else
//                    {
//                    }
//                }
//                ptyextkey = "";
//                if( MdaUtils.compareTo(ctx.absGet(Sysmod.class).getAtp().getCod(),"BOTDAV") == 0 )
//                {
//                    ptyextkey = Datas.getContent(this,"\\BODGRP\\COL\\PTA\\PTYEXTKEY");
//                    err = ctx.getErrorCode();
//                }
//                if( MdaUtils.compareTo(ctx.absGet(Sysmod.class).getAtp().getCod(),"CCTDAV") == 0 )
//                {
//                    ptyextkey = Datas.getContent(this,"\\CCDGRP\\COL\\PTA\\PTYEXTKEY");
//                    err = ctx.getErrorCode();
//                }
//                if( ! MdaUtils.isEmpty(ptyextkey) )
//                {
//                    if( Strings.len(ptyextkey) != 11 )
//                    {
//                        addFeeData( "DHL01", "Y", letAnz, Dates.today(), Dates.today() );
//                    }
//                }
//                //   AddFeeData( "DHL01", "Y", $letAnz, Today, Today )   #对courier收取快邮费
//            }
//        }
//        //收取电报费
//        if( swtAnz > 0 )
//        {
//            addFeeData( feeCod, "Y", swtAnz, Dates.today(), Dates.today() );
//        }
//    }

    /**
     * source:setfeg.0036.script
     */
    @JsonIgnore
    public void setFepSql(IStream argSqlStm, SetmodVo setmodVo) {
        //! set SQL for fee pool according to FEPPNTLEV
        //! return a set of sql statements for each contract in ArgSqlStm
        Streams.streamClear(argSqlStm);
        // get pool entries of temporary settlement loaded (if loaded)
        // if no SEP is loaded ( SEP\\INR is empty) only entries without SEPINR set are loaded
        String prefixSql = "WHERE RPLTRNINR = ' ' AND DONTRNINR = ' ' ";
//        if( ! MdaUtils.isEmpty(ctx.absGet(Setmod.class).getSep().getInr()) )
//        {
//            prefixSql = prefixSql + " AND SEPINR in ( " + Platform.sqlLit(ctx.absGet(Setmod.class).getSep().getInr()) + ", ' ' ) AND ";
//        }
//        else
//        {
        prefixSql = prefixSql + " AND SEPINR = ' ' AND ";
//        }
        // get Records of main contract, if FEPPNTLEV >= 0
        int addCnt = 0;
        String line = NULLSTR;
        String objTyp = NULLSTR;
        String objInr = NULLSTR;
        if (this.getFeppntlev(setmodVo.getSetfeg()) >= 0) {
            if (!MdaUtils.isEmpty(setmodVo.getRec().getObjinr())) {
                Streams.streamInsert(argSqlStm, 0, prefixSql + " OBJTYP = '" + setmodVo.getRec().getObjtyp() + "' AND OBJINR = '" + setmodVo.getRec().getObjinr() + "'");
            }
            if (this.getFeppntlev(setmodVo.getSetfeg()) >= 1) {
                // get records listed in \\setmod\\setaddconstm
                addCnt = Streams.streamCount(setmodVo.getSetaddconstm());
                if (addCnt > 0) {
                    for (int i = 1; i <= addCnt; i++) {
                        line = Strings.getLine(setmodVo.getSetaddconstm(), i);
                        objTyp = Strings.mid(line, 1, Strings.pos(line, TAB) - 1);
                        objInr = Strings.mid(line, Strings.pos(line, TAB) + 1);
                        line = prefixSql + " OBJTYP = '" + objTyp + "' AND OBJINR = '" + objInr + "'";
                        if (Streams.streamSearch(argSqlStm, line) == 0) {
                            Streams.streamInsert(argSqlStm, 0, line);
                        }
                    }
                }
            }
        }
        // reset errors from Getcontent and return result
    }

    public int getFeppntlev(SetfegVo setfegVo) {
        if (setfegVo.getFeppntlev() == 0) {
            return 1;
        } else {
            return setfegVo.getFeppntlev();
        }
    }
    /**
     *   source:setfeg.0038.script
     */
//    @TDMethod
//    public void addFepinpField(String id,String key,String argvalue)
//    {
//        //取得上下文
//        IContext ctx = MdaEnv.getContext();
//        ctx.setErrorCode(NO_ERROR);
//        //!写入Cache，用于给SETFEL中字段赋值
//        //!==================================
//        //!参数：   id  : Cache ID
//        //!         key : 字段名
//        //!    Argvalue : 字段值
//        //!返回值：无
//        //!==================================
//        add2fepinp( id, key, argvalue );
//
//    }


}
