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

import com.brilliance.isc.bo.Cur;
import com.brilliance.isc.bo.Etg;
import com.brilliance.isc.bo.Xrt;
import com.brilliance.isc.bo.Zmqxrt;
import com.brilliance.isc.common.cbsmod.CbsRange;
import com.brilliance.isc.common.cbsmod.service.XrtmodService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.exception.CommonServiceException;
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.CurMapper;
import com.brilliance.isc.mda.dao.XrtMapper;
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.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;

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

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

@Service
@Data
@DependsOn("iniLoadConfig")
public class XrtmodServiceImpl implements XrtmodService {

    @Autowired
    private CbsRange cbsRange;

    @Autowired
    private CurMapper curMapper;

    @Autowired
    private XrtMapper xrtMapper;

    @Autowired
    private CodetableService codetableService;

    private IStream currndinf = new StreamImpl();

    public static Map<String,Cur> cachedCurMap = new ConcurrentHashMap<>();

    @PostConstruct
    public void loadInf(){
        // Load currencies from TDPARA on demand
        String curblk = Inis.getIniBlock("TDPARA.INI","CURRENCY","CURRENCY");
        Streams.streamSet(this.getCurrndinf(),curblk);
    }

    public BigDecimal amtRnd(BigDecimal argAmt, String argCur)
    {
        //! This function returns the rounded value of ArgAmt using the definition of decimal places of ArgCur, but not using the definition of the rounding unit.
        //! Normally this function is sufficient for rounding inside the system.
        //! Only if amounts are debited or credited to external accounts AmtRoundUnt is to be used instead.

        // If currency is set in section the number of digit is given by byte 24 of the line, otherwise ArgCur has 2 digitgs
        int line = Streams.streamSearch(this.getCurrndinf(),argCur);
        int places = 0;
        if( line > 0 )
        {
            places = Strings.parseInt(Strings.mid(Strings.getLine(this.getCurrndinf(),line),24,1));
        }
        else
        {
            places = 2;
        }
        // Round argument according to decimal places
        return  Numerics.round(argAmt,places);
    }

    /**
     *   source:xrtmod.0001.script
     */
    
    public String sysiso()
    {
        return  this.getSysisocac();
    }
    /**
     *   source:xrtmod.0002.script
     */

    public BigDecimal amtViaSysCnv(BigDecimal amt,BigDecimal fromRat,BigDecimal toRat,String fromCur,String toCur)
    {
        //取得上下文
        String refcur = this.getBascurcac();
        int refamt = 0;
        Argument<String> refcurBox = new Argument<String>("",refcur);
        Argument<BigDecimal> refamtBox = new Argument<BigDecimal>("",new BigDecimal(refamt));
        return  amtConvRates( amt, fromRat, toRat, fromCur, toCur, refcurBox, refamtBox );

    }
    /**
     *   source:xrtmod.0003.script
     */
    @JsonIgnore
    
    public void getXrt(String argCur, Date value, Cur curRec, Xrt xrtRec)
    {
        curRec.setCod( argCur);
        curRec.setSqrmar( getCurSqrMar( argCur ));
        xrtRec.setCur( argCur);
        cbsRange.sdbRngRead(xrtRec,value);
//        if( ctx.getErrorCode() > 0 )
//        {
//            ctx.reraise();
//        }
//        else
//        {
//            Caches.cacheRead(xrtRec,"XRT",ctx.absGet(Sysmod.class).getEty().getExtkey(),argCur,value);
//            if( ctx.getErrorCode() == tdCacheNotFound )
//            {
//                xrtRec.setCur( argCur);
//                cbsRange.sdbRngRead(xrtRec,value);
//                // Save result to cache in any case (even if nothing found)
//                if( ctx.getErrorCode() != tdOdbcNotFound )
//                {
//                    ctx.reraise();
//                }
//                Caches.cacheWrite(xrtRec,"XRT",ctx.absGet(Sysmod.class).getEty().getExtkey(),argCur,value);
//            }
//        }
    }
    /**
     *   source:xrtmod.0004.script
     */
    public Cur getCurByCode(String argCur) {
        return loadCacCur(argCur);
    }
    /**
     *   source:xrtmod.0006.script
     */
    
    public String basRatCur()
    {
        return  this.getBascurcac();
    }

    /**
     *   source:xrtmod.0007.script
     */
    public BigDecimal sysCurEqu(String fromCur,BigDecimal amt,Date value)
    {
        String bscur = this.getBascurcac();
        Argument<String> newcurBox = new Argument<String>();
        Argument<String> newsysBox = new Argument<String>();
        Argument<String> bscurBox = new Argument<String>("",bscur);
        Boolean ininflg;
        Argument<Boolean> ininflgBox = new Argument<Boolean>();
        xrtCheckInIn( fromCur, sysiso(), newcurBox, newsysBox, bscurBox, ininflgBox );

        bscur = bscurBox.value;
        ininflg = ininflgBox.value;

        BigDecimal frmrat;
        Argument<BigDecimal> frmratBox = new Argument<BigDecimal>();
        BigDecimal sqrrat;
        Argument<BigDecimal> sqrratBox = new Argument<BigDecimal>();
        getRateXrt( fromCur, bscur, ininflg, "M", value, frmratBox, sqrratBox );

        frmrat = frmratBox.value;
        sqrrat = sqrratBox.value;

        BigDecimal sysrat;
        Argument<BigDecimal> sysratBox = new Argument<BigDecimal>();
        Argument<BigDecimal> sqrratBox1 = new Argument<BigDecimal>("",sqrrat);
        getRateXrt( sysiso(), bscur, ininflg, "M", value, sysratBox, sqrratBox1 );

        sysrat = sysratBox.value;
//        sqrrat = sqrratBox1.value;

        String refcur = this.getBascurcac();
        int refamt = 0;
        Argument<String> refcurBox = new Argument<String>("",refcur);
        Argument<BigDecimal> refamtBox = new Argument<BigDecimal>("",new BigDecimal(refamt));
        return  amtConvRates( amt, frmrat, sysrat, fromCur, sysiso(), refcurBox, refamtBox );

    }
    /**
     *   source:xrtmod.0008.script
     */

    public BigDecimal basCurEqu(String fromCur,BigDecimal amt,Date value)
    {
        //! Function to return the amount converted to base currency using the middle rate as of the passed value date
        //! FromCur Currency of the passed amount
        //! Amt Amount to be converted into the base currency
        //! Value Valuedate of the currency conversion
        //! Corresponding functions:
        String bscur = this.getBascurcac();
        String newcur;
        Argument<String> newcurBox = new Argument<String>();
        String newsys;
        Argument<String> newsysBox = new Argument<String>();
        Argument<String> bscurBox = new Argument<String>("",bscur);
        Boolean ininflg;
        Argument<Boolean> ininflgBox = new Argument<Boolean>();
        xrtCheckInIn( fromCur, this.getBascurcac(), newcurBox, newsysBox, bscurBox, ininflgBox );

        newcur = newcurBox.value;
        newsys = newsysBox.value;
        bscur = bscurBox.value;
        ininflg = ininflgBox.value;

        BigDecimal frmrat;
        Argument<BigDecimal> frmratBox = new Argument<BigDecimal>();
        BigDecimal sqrrat;
        Argument<BigDecimal> sqrratBox = new Argument<BigDecimal>();
        getRateXrt( fromCur, this.getBascurcac(), ininflg, "M", value, frmratBox, sqrratBox );

        frmrat = frmratBox.value;
        sqrrat = sqrratBox.value;

        String refcur = this.getBascurcac();
        int refamt = 0;
        Argument<String> refcurBox = new Argument<String>("",refcur);
        Argument<BigDecimal> refamtBox = new Argument<BigDecimal>("",new BigDecimal(refamt));
        return  amtConvRates( amt, frmrat, new BigDecimal(1), fromCur, this.getBascurcac(), refcurBox, refamtBox );

    }

    /**
     *  获取币种的下拉列表
     * @return
     */
    public List<CodetableItem> validCurrencies() {
        List<CodetableItem> codetableItems = new ArrayList<>();
        List<String> curCodeList = getValidCurrenciesList(Dates.today());
        for (String cur : curCodeList) {
            String curtxt = codetableService.getTblLabel(cur, "CURTXT");
            codetableItems.add(new CodetableItem(curtxt, cur));
        }
        return codetableItems;
    }
    /**
     *   source:xrtmod.0009.script
     */
    public String validCurrencies(Date value)
    {
        //! Get list of currency code that are valid on value date
        // try cache first

//        String sql = Platform.sdbEtyGenSql(this.getCur(),getCurSQL_where( Dates.today() )) + getCurSQL_order();
//        ctx.getDaoSession().dbExecuteSQL("SELECT COD FROM CUR " + sql);
//        ctx.getDaoSession().dbFetchStream(valstm);
//        ctx.getDaoSession().dbCloseCursor();
        List<String> curCodeList = getValidCurrenciesList(Dates.today());
        if(MdaUtils.isEmpty(curCodeList)){
            return "";
        }
        String values = curCodeList.stream().reduce((a,b)->a+"\n"+b).get();

        return values;

    }

    private List<String> getValidCurrenciesList(Date date) {
        Date begDate = date;
        Date endDate = date;
        /*String argSql = "WHERE (BEGDAT is NULL or BEGDAT <= " + Utils.dbSqlDate(begDate) + " ) and ( ENDDAT is NULL or ENDDAT > " + Utils.dbSqlDate(endDate) +")";
        String sql = "select cod from cur " + Utils.sdbEtyGenSql("CUR", argSql);
        Map<String, Object> dyncMap = new HashMap<>();
        dyncMap.put("sql", sql);
        List<Cur> curList = curMapper.dyncRead(dyncMap);*/
        Cur queryCur=new Cur();
        queryCur.setBegdat(begDate);
        queryCur.setEnddat(endDate);
        queryCur.setEtgextkey(SettleContext.getUserEtg().getExtkey());
        List<Cur> curList = curMapper.getValidCurrenciesList(queryCur);
        if (curList != null) {
            List<String> list = new ArrayList<>();
            curList.forEach(cur -> list.add(cur.getCod()));
            return list;
        } else {
            return null;
        }
    }

    /**
     *   source:xrtmod.0010.script
     */
    
    public String calendar()
    {
        return  this.getSyscal();

    }
    /**
     *   source:xrtmod.0011.script
     */
    @JsonIgnore
    public int getCurbas(String curCod)
    {
        // Obsolete function
        Cur cacCur = loadCacCur( curCod );
        return  cacCur.getBas();

    }
    /**
     *   source:xrtmod.0012.script
     */
    @JsonIgnore
    public BigDecimal getCurSqrMar(String curCod)
    {
        // Obsolete function
        Cur cacCur = loadCacCur( curCod );
        return  cacCur.getSqrmar();

    }
    /**
     *   source:xrtmod.0013.script
     */
    @JsonIgnore
    
    public String getCurNewCur(String curCod)
    {
        // Obsolete function
        Cur cacCur = loadCacCur( curCod );
        return  cacCur.getNewcur();

    }
    /**
     *   source:xrtmod.0014.script
     */
    
    public BigDecimal amtConvRates(BigDecimal amt,BigDecimal fromRat,BigDecimal toRat,String fromCur,String toCur,Argument<String> refCur,Argument<BigDecimal> refAmt)
    {
        //amtConvRates( Amt , fromrat , torat , FromCur , tocur , refcur ,  refamt  )
        // check if old currencies involved
        boolean ininflg = false;
        String fromnew;
        Argument<String> fromnewBox = new Argument<String>();
        String tonew;
        Argument<String> tonewBox = new Argument<String>();
        Argument<Boolean> ininflgBox = new Argument<Boolean>("",ininflg);
        xrtCheckInIn( fromCur, toCur, fromnewBox, tonewBox, refCur, ininflgBox );

        fromnew = fromnewBox.value;
        tonew = tonewBox.value;
        ininflg = ininflgBox.value;

        BigDecimal fromprerat = new BigDecimal("1");
        BigDecimal topstrat = new BigDecimal("1");
        if( ! MdaUtils.isEmpty(fromnew) )
        {
            fromprerat = getCurGlbRat( fromCur );
        }
        if( ! MdaUtils.isEmpty(tonew) )
        {
            topstrat = getCurGlbRat( toCur );
        }
        // simple cases
        BigDecimal imdamt = null;
        if( MdaUtils.compareTo(fromCur,toCur) == 0 && MdaUtils.compareTo(fromRat,toRat) == 0 )
        {
            if( ininflg )
            {
                imdamt = Decimals.div(amt,fromprerat);
                refAmt.value = amtRnd( imdamt, refCur.value );
            }
            else
            {
                refCur.value = toCur;
                refAmt.value = amt;
            }
            return  amt;
        }
        if( MdaUtils.compareTo(fromRat,0) == 0 || MdaUtils.compareTo(toRat,0) == 0 )
        {
            refCur.value = fromCur;
            refAmt.value = new BigDecimal("0");
            return  new BigDecimal(0);
        }
        // calculate amount
        int frombas = 0;
        int tobas = 0;
        if( ininflg )
        {
            // if IN/IN -> use fixed rates between currencies with EUR-logic
            imdamt = Decimals.div(amt,fromprerat);
            refAmt.value = amtRnd( imdamt, refCur.value );
            return  amtRnd( Decimals.mul(imdamt,topstrat), toCur );
        }
        else
        {
            // 1. convert to new currency if necessary
            if( MdaUtils.compareTo(this.getXrt2inflg(),"N") == 0 && MdaUtils.compareTo(fromnew,this.getBascurcac()) != 0 && ( ! MdaUtils.isEmpty(fromnew) ) )
            {
                imdamt = Decimals.div(amt,fromprerat);
            }
            else
            {
                imdamt = amt;
                // 2. apply rate shift
                frombas = getCurbas( fromCur );
                if( frombas > 0 )
                {
                    imdamt = Decimals.div(imdamt,frombas);
                }
            }
            // 3. apply from rate
            if( this.getXrtratdir() > 0 )
            {
                imdamt = Decimals.mul(imdamt,fromRat);
            }
            else
            {
                imdamt = Decimals.div(imdamt,fromRat);
            }
            // 4. This is the reference amount
            refAmt.value = imdamt;
            refCur.value = this.getBascurcac();
            // 5. Apply rate
            if( this.getXrtratdir() > 0 )
            {
                imdamt = Decimals.div(imdamt,toRat);
            }
            else
            {
                imdamt = Decimals.mul(imdamt,toRat);
            }
            // 6. convert to old currency if necessary
            if( MdaUtils.compareTo(this.getXrt2inflg(),"N") == 0 && MdaUtils.compareTo(tonew,this.getBascurcac()) != 0 && ( ! MdaUtils.isEmpty(tonew) ) )
            {
                imdamt = Decimals.mul(imdamt,topstrat);
            }
            else
            {
                // 6. apply rate shift
                tobas = getCurbas( toCur );
                if( tobas > 0 )
                {
                    imdamt = Decimals.mul(imdamt,tobas);
                }
            }
            imdamt = amtRnd( imdamt, toCur );
            return  imdamt;
        }

    }
    /**
     *   source:xrtmod.0015.script
     */
    
    public void xrtCheckInIn(String cur1,String cur2,Argument<String> newCur1,Argument<String> newCur2,Argument<String> refCur,Argument<Boolean> ininFlg)
    {
        newCur1.value = getCurNewCur( cur1 );
        Cur cacCur = loadCacCur( cur2 );
        newCur2.value = cacCur.getNewcur();
        if( MdaUtils.compareTo(newCur1.value,newCur2.value) == 0 && Dates.diff(cacCur.getEnddat(),Dates.today())>0 )
        {
            ininFlg.value = true;
            refCur.value = newCur2.value;
        }
        else
        {
            if( MdaUtils.compareTo(newCur1.value,cur2) == 0 )
            {
                ininFlg.value = true;
                refCur.value = newCur1.value;
            }
            else
            {
                if( MdaUtils.compareTo(newCur2.value,cur1) == 0 )
                {
                    ininFlg.value = true;
                    refCur.value = newCur2.value;
                }
                else
                {
                    ininFlg.value = false;
                    refCur.value = this.getBascurcac();
                }
            }
        }

    }
    /**
     *   source:xrtmod.0016.script
     */
    @JsonIgnore
    
    public BigDecimal getCurGlbRat(String curCod)
    {
        // Obsolete function
        Cur cacCur = loadCacCur( curCod );
        return  cacCur.getGlbrat();

    }
    /**
     *   source:xrtmod.0017.script
     */
    @JsonIgnore
    
    public void getRateXrt(String argCur,String basCur,boolean ininFlg,String typ,Date value,Argument<BigDecimal> rat,Argument<BigDecimal> sqrRat)
    {
        //! Routine to determine the rate and the squaring rate of a currency of a certain type on a passed date
        //! ArgCur Currency
        //! BasCur Base currency
        //! IninFlg boolean
        //! Typ text
        //! Value datetype
        //! Rat numeric
        //! out SqrRat numeric
        //! Corresponding functions: GetRateXrtWithResRates
        //---ZMQZMQ-----
        //--zmqtest--
        BigDecimal resrat = null;
        BigDecimal rebrat = null;
        if( MdaUtils.compareTo(getzmqflg(),"X") == 0 )
        {
            Argument<BigDecimal> resratBox = new Argument<BigDecimal>();
            Argument<BigDecimal> rebratBox = new Argument<BigDecimal>();
            getRateXrtWithResRates_ZMQ( argCur, basCur, ininFlg, typ, value, rat, sqrRat, resratBox, rebratBox );

            resrat = resratBox.value;
            rebrat = rebratBox.value;

        }
        else
        {
            if(SettleContext.getUserSession().getAtp() != null  && (MdaUtils.compareTo(Strings.mid(SettleContext.getUserSession().getAtp().getCod(),1,2),"JS") == 0 || MdaUtils.compareTo(Strings.mid(SettleContext.getUserSession().getAtp().getCod(),1,2),"WI") == 0 ))
            {
                Argument<BigDecimal> resratBox1 = new Argument<BigDecimal>("",resrat);
                Argument<BigDecimal> rebratBox1 = new Argument<BigDecimal>("",rebrat);
                getRateXrtWithRESRates_YSP( argCur, basCur, ininFlg, typ, value, rat, sqrRat, resratBox1, rebratBox1 );

                resrat = resratBox1.value;
                rebrat = rebratBox1.value;

            }
            else
            {
                Argument<BigDecimal> resratBox2 = new Argument<BigDecimal>("",resrat);
                Argument<BigDecimal> rebratBox2 = new Argument<BigDecimal>("",rebrat);
                getRateXrtWithResRates( argCur, basCur, ininFlg, typ, value, rat, sqrRat, resratBox2, rebratBox2 );

                resrat = resratBox2.value;
                rebrat = rebratBox2.value;

            }
        }

    }
    /**
     *   source:xrtmod.0018.script
     */
    @JsonIgnore
    
    public BigDecimal getCurRNDUNT(String curCod)
    {
        // Obsolete function
        Cur cacCur = loadCacCur( curCod );
        return  cacCur.getRndunt();

    }
    /**
     *   source:xrtmod.0019.script
     */
    
    public BigDecimal amtConvTypes(String fromCur,BigDecimal amt,String fromTyp,String toCur,String toTyp,Date value)
    {
        // AmtConvTypes( FromCur , Amt , fromtyp , tocur , totyp, value  )
        int ignorecross = 1;
        Argument<BigDecimal> ignorecrossBox = new Argument<BigDecimal>("",new BigDecimal(ignorecross));
        return  amtConvTypesWithCrossrate( fromCur, amt, fromTyp, toCur, toTyp, value, ignorecrossBox );

    }
    /**
     *   source:xrtmod.0020.script
     */
    
    public BigDecimal amtConvTypesWithCrossrate(String fromCur,BigDecimal amt,String fromTyp,String toCur,String toTyp,Date value,Argument<BigDecimal> crossRate)
    {
        // AmtConvTypes( FromCur , Amt , fromtyp , tocur , totyp, value  )
        String bscur = this.getBascurcac();
        int refamt = 0;
//        String newcur;
        Argument<String> newcurBox = new Argument<String>();
//        String newsys;
        Argument<String> newsysBox = new Argument<String>();
        Argument<String> bscurBox = new Argument<String>("",bscur);
        Boolean ininflg;
        Argument<Boolean> ininflgBox = new Argument<Boolean>();
        xrtCheckInIn( fromCur, toCur, newcurBox, newsysBox, bscurBox, ininflgBox );

//        newcur = newcurBox.value;
//        newsys = newsysBox.value;
        bscur = bscurBox.value;
        ininflg = ininflgBox.value;

        BigDecimal frmrat;
        Argument<BigDecimal> frmratBox = new Argument<BigDecimal>();
        BigDecimal sqrrat;
        Argument<BigDecimal> sqrratBox = new Argument<BigDecimal>();
        getRateXrt( fromCur, bscur, ininflg, fromTyp, value, frmratBox, sqrratBox );

        frmrat = frmratBox.value;
        sqrrat = sqrratBox.value;

        BigDecimal torat;
        Argument<BigDecimal> toratBox = new Argument<BigDecimal>();
        Argument<BigDecimal> sqrratBox1 = new Argument<BigDecimal>("",sqrrat);
        getRateXrt( toCur, bscur, ininflg, toTyp, value, toratBox, sqrratBox1 );

        torat = toratBox.value;
        sqrrat = sqrratBox1.value;

        if( MdaUtils.compareTo(frmrat,0) == 0 || MdaUtils.compareTo(torat,0) == 0 )
        {
            crossRate.value = new BigDecimal("0");
        }
        else
        {
            if( MdaUtils.compareTo(frmrat,torat)>0 )
            {
                crossRate.value = Decimals.div(frmrat,torat);
            }
            else
            {
                crossRate.value = Decimals.div(torat,frmrat);
            }
        }
        Argument<String> bscurBox1 = new Argument<String>("",bscur);
        Argument<BigDecimal> refamtBox = new Argument<BigDecimal>("",new BigDecimal(refamt));
        return  amtConvRates( amt, frmrat, torat, fromCur, toCur, bscurBox1, refamtBox );

    }
    /**
     *   source:xrtmod.0021.script
     */
    @JsonIgnore

    public void getrat(String fromCur,String toCur,String typ,Date value,Argument<BigDecimal> rat,Argument<BigDecimal> sqrRat)
    {
        String bscur = "";
        Argument<String> newcurBox = new Argument<String>();
        Argument<String> newsysBox = new Argument<String>();
        Argument<String> bscurBox = new Argument<String>("",bscur);
        Boolean ininflg;
        Argument<Boolean> ininflgBox = new Argument<Boolean>();
        xrtCheckInIn( fromCur, toCur, newcurBox, newsysBox, bscurBox, ininflgBox );

        bscur = bscurBox.value;
        ininflg = ininflgBox.value;

        BigDecimal frmrat;
        Argument<BigDecimal> frmratBox = new Argument<BigDecimal>();
        BigDecimal frmsqrrat;
        Argument<BigDecimal> frmsqrratBox = new Argument<BigDecimal>();
        getRateXrt( fromCur, bscur, ininflg, typ, value, frmratBox, frmsqrratBox );

        frmrat = frmratBox.value;
        frmsqrrat = frmsqrratBox.value;

        BigDecimal torat;
        Argument<BigDecimal> toratBox = new Argument<BigDecimal>();
        BigDecimal tosqrrat;
        Argument<BigDecimal> tosqrratBox = new Argument<BigDecimal>();
        getRateXrt( toCur, bscur, ininflg, typ, value, toratBox, tosqrratBox );

        torat = toratBox.value;
        tosqrrat = tosqrratBox.value;

        if( MdaUtils.compareTo(frmrat,0) == 0 || MdaUtils.compareTo(torat,0) == 0 )
        {
            rat.value = new BigDecimal("0");
            sqrRat.value = new BigDecimal("0");
        }
        else
        {
            rat.value = Decimals.div(frmrat,torat);
            sqrRat.value = Decimals.div(frmsqrrat,tosqrrat);
        }

    }
    /**
     *   source:xrtmod.0022.script
     */
    
    public boolean xrtCrossRateDirFlg(String cur1,String cur2,BigDecimal rat1,BigDecimal rat2)
    {
        if( MdaUtils.compareTo(cur1,"EUR") == 0 )
        {
            return  true;
        }
        else
        {
            if( MdaUtils.compareTo(cur2,"EUR") == 0 )
            {
                return  false;
            }
            else
            {
                if( MdaUtils.compareTo(rat1,rat2)>0 )
                {
                    return  true;
                }
                else
                {
                    return  false;
                }
            }
        }

    }
    /**
     *   source:xrtmod.0023.script
     */
    @JsonIgnore
    
    public String getCurAltCod(String curCod)
    {
        // Obsolete function
        Cur cacCur = loadCacCur( curCod );
        return  cacCur.getAltcod();

    }
    /**
     *   source:xrtmod.0024.script
     */
    @JsonIgnore
    
    public int getCurDEC(String curCod)
    {
        // Obsolete function
        Cur cacCur = loadCacCur( curCod );
        return  cacCur.getDec();

    }
    /**
     *   source:xrtmod.0025.script
     */
    
    public BigDecimal crossRatebas(String fromCur,String toCur)
    {
        String refcur = this.getBascurcac();
        String fromnew;
        Argument<String> fromnewBox = new Argument<String>();
        String tonew;
        Argument<String> tonewBox = new Argument<String>();
        Argument<String> refcurBox = new Argument<String>("",refcur);
        Boolean ininflg;
        Argument<Boolean> ininflgBox = new Argument<Boolean>();
        xrtCheckInIn( fromCur, toCur, fromnewBox, tonewBox, refcurBox, ininflgBox );

        fromnew = fromnewBox.value;
        tonew = tonewBox.value;
        refcur = refcurBox.value;
        ininflg = ininflgBox.value;

        int res = 0;
        int frombas = 0;
        int tobas = 0;
        if( ininflg )
        {
            // if IN/IN -> use fixed rates between currencies with EUR-logic
            return  new BigDecimal(1);
        }
        else
        {
            res = 1;
            // 1. apply rate shift FromCur
            frombas = getCurbas( fromCur );
            if(frombas > 0 )
            {
                res = Decimals.div(res,frombas).intValue();
            }
            // 2. apply rate shift tocur
            tobas = getCurbas( toCur );
            if(tobas > 0 )
            {
                res = res * tobas;
            }
            return  new BigDecimal(res);
        }

    }
    /**
     *   source:xrtmod.0026.script
     */
    @JsonIgnore
    
    public BigDecimal getCurMaxAmt(String curCod)
    {
        // Obsolete function
        Cur cacCur = loadCacCur( curCod );
        return  cacCur.getMaxamt();

    }
    /**
     *   source:xrtmod.0027.script
     */
    @JsonIgnore
    
    public BigDecimal getCurDif(String curCod)
    {
        // Obsolete function
        Cur cacCur = loadCacCur( curCod );
        return  cacCur.getDif();

    }
    /**
     *   source:xrtmod.0028.script
     */
    public void xrtCheckRate(BigDecimal argRate,String argCur,Date argValue)
    {
        //! Check if rate has been filled and is inside tolerance
        //! ArgRate : Rate entered
        //! ArgCur: Currency
        //! ArgValue: Value date for rate check; if empty today is used
        BigDecimal tolallow = null;
        Date value = null;
        BigDecimal rat = null;
        BigDecimal sqrrat = null;
        BigDecimal res = null;
        if( MdaUtils.compareTo(argRate,0) == 0 )
        {
            throw new CommonServiceException("This field is mandatory");
        }
        else
        {
            tolallow = getCurDif( argCur );
            if( MdaUtils.isEmpty(argValue) )
            {
                value = Dates.today();
            }
            else
            {
                value = argValue;
            }
            Argument<BigDecimal> ratBox = new Argument<BigDecimal>();
            Argument<BigDecimal> sqrratBox = new Argument<BigDecimal>();
            getRateXrt( argCur, basRatCur(), false, "M", value, ratBox, sqrratBox );

            rat = ratBox.value;
            sqrrat = sqrratBox.value;

            if( MdaUtils.compareTo(rat,0) != 0 )
            {
                if( MdaUtils.compareTo(argRate,rat)>0 )
                {
                    res = Decimals.sub(Decimals.div(argRate,rat),1);
                }
                else
                {
                    res = Decimals.sub(Decimals.div(rat,argRate),1);
                }
                if( MdaUtils.compareTo(Decimals.mul(100,res),tolallow)>0 )
                {
                    SettleExceptionUtils.sysDump(String.format("Rate entered outside %s rate tolerance.",MdaUtils.toString(tolallow)));
                }
            }
        }

    }
    /**
     *   source:xrtmod.0029.script
     *   //更新Ini文件？？？不建议使用
     */
    @Deprecated
    public void updateTdparaCurTable()
    {
        // retrieve the system and the exchange rate base currency
        //???
//        String cur1 = Inis.getIniStr("TDPARA.INI","System","SysCurrency");
//        String cur2 = Inis.getIniStr("TDPARA.INI","System","RateBaseCurrency");
//        // No multientity on access to the table as tdpara.ini is a global datastructure
//        String sql = "Select distinct COD, DEC from CUR where DEC <> 2";
//        if( ! MdaUtils.isEmpty(cur1) )
//        {
//            sql = sql + " or COD = '" + cur1 + "'";
//        }
//        if( ! MdaUtils.isEmpty(cur2) )
//        {
//            sql = sql + " or COD = '" + cur2 + "'";
//        }
//        String curTbl = "";
//        String curCod = "";
//        Argument<String> _curCodBox = Argument.box(curCod);
//        int curDec = 0;
//        Argument<Integer> _curDecBox = Argument.box(curDec);
//        ctx.getDaoSession().dbExecuteSQL(sql);
//        // #######TODO 改写 LABEL与GOTO   ####    label GetNext
//        ctx.getDaoSession().dbFetchFields("COD",_curCodBox,"DEC",_curDecBox);
//        curCod = _curCodBox.value;
//        curDec = _curDecBox.value;
//        String curNam = NULLSTR;
//        String curLin = NULLSTR;
//        if( ctx.getErrorCode() <= 0 )
//        {
//            curNam = Codetables.getCodetableLabelOfTd(curCod,"CURTXT",Systems.getLang());
//            curLin = Strings.mid(curCod,1,3) + Strings.mid(curNam,1,20) + MdaUtils.toString(curDec);
//            if( MdaUtils.isEmpty(curTbl) )
//            {
//                curTbl = curLin;
//            }
//            else
//            {
//                curTbl = curTbl + CR + curLin;
//            }
//            return ; // #######TODO 改写 LABEL与GOTO  ####   goto GetNext
//        }
//        else
//        {
//            if( ctx.getErrorCode() != tdOdbcNotFound )
//            {
//                ctx.reraise();
//            }
//        }
//        ctx.getDaoSession().dbCloseCursor();
//        Inis.setIniBlock("TDPARA.INI","CURRENCY","Currency",curTbl);
//        Caches.cacheClear();

    }
    /**
     *   source:xrtmod.0030.script
     */
    @JsonIgnore
    
    public String getCurAct(String curCod)
    {
        // Obsolete function
        Cur cacCur = loadCacCur( curCod );
        return  cacCur.getAcc1();

    }
    /**
     *   source:xrtmod.0031.script
     */
    @JsonIgnore
    
    public String getCurCat(String curCod)
    {
        // Obsolete function
        Cur cacCur = loadCacCur( curCod );
        return  cacCur.getAcc2();

    }
    /**
     *   source:xrtmod.0032.script
     */
    
    public BigDecimal amtRndUnt(BigDecimal argAmt,String argCur)
    {
        //! returns ArgAmt rounded respecting the rounding unit of Currency ArgCur
        //! This function has to be used only for amounts booked on external accounts (i.e. payings & debits)
        //! For internal amounts the function AmtRnd should be used, which just rounds using the decimal places defined in ArgCur
        // get rounding unit
        BigDecimal rndunt = getCurRNDUNT( argCur );
        // if not set, round according to decimal places using AmtRnd
        BigDecimal imd = null;
        if( MdaUtils.compareTo(rndunt,0) == 0 )
        {
            return  amtRnd( argAmt, argCur );
        }
        else
        {
            // otherwise round with rounding unit
            if( MdaUtils.compareTo(Numerics.abs(argAmt),Decimals.mul(0.5,rndunt))<0 )
            {
                return  new BigDecimal(0);
            }
            else
            {
                imd = Decimals.div(argAmt,rndunt);
                imd = new BigDecimal(Numerics.toInt(Decimals.add(imd,Decimals.mul(0.5,Numerics.sgn(argAmt)))));
                imd = Decimals.mul(imd,rndunt);
                return  imd;
            }
        }

    }
    /**
     *   source:xrtmod.0033.script
     *   组件模式下不支持的方法
     */
    @Deprecated
    public String xrtGetValidRateTypes()
    {
        //! Function to get the list of implemented rate types.
        //!
        //! The list is returned as Textblock with one line per valid RateType.
        //! Each Line holds the Code of the RateType followed by the Description.
        //! The Text is intended to be used for SetCodeValues of a field holding
        //! valid rate types.
        //
        // To set the values of rate type for field <rattypfld> in transactions use
        //
        //   StreamSet( $valset, XrtGetRateTypes )
        //   # If special rate types are used (like "F" for fixed rate) add
        //   # those to the stream here via StreamInsert.
        //   SetCodeValues( <rattypfld> , $valset )
        //
        // The software has to check that these additional types are not passed to
        // the conversion routine GetRateXrtWithResRates.
        //
        //
        return  "";//Systems.getAttributeText(this,"rattyp",tdAttrCodeValues);

    }
    /**
     *   source:xrtmod.0034.script
     */
    public Cur loadCacCur(String argCur) {
        String argSql = Utils.sdbEtyGenSql("CUR", "WHERE COD = '" + argCur + "'");
        Cur cacCur = cachedCurMap.get(argSql);
        if (cacCur != null) {
            return cacCur;
        } else {
            cacCur = curMapper.getCurByCodeAndEty(argSql);
            if (cacCur == null) {
                cacCur = new Cur();
                cacCur.setBas( 1);
                cacCur.setSqrmar( new BigDecimal("1"));
                cacCur.setGlbrat( new BigDecimal("1"));
                cacCur.setRndunt( new BigDecimal("1"));
                cacCur.setDec( 2);
                cacCur.setDif( new BigDecimal("10"));
            }
            cachedCurMap.put(argSql, cacCur);
            return cacCur;
        }
//        if( MdaUtils.compareTo(this.getCaccur().getCod(),argCur) != 0 )
//        {
//            if( MdaUtils.isEmpty(argCur) )
//            {
//                MdaUtils.clear(this.getCaccur());
//            }
//            else
//            {
//                Caches.cacheRead(this.getCaccur(),"CUR",ctx.absGet(Sysmod.class).getEty().getExtkey(),argCur);
//                if( ctx.getErrorCode() == tdCacheNotFound )
//                {
//                    Platform.sdbEtyRead(this.getCaccur(),argCur,"COD");
//                    if( ctx.getErrorCode() != tdOdbcNotFound )
//                    {
//                        ctx.reraise();
//                        Caches.cacheWrite(this.getCaccur(),"CUR",ctx.absGet(Sysmod.class).getEty().getExtkey(),argCur);
//                    }
//                    else
//                    {
//                        MdaUtils.clear(this.getCaccur());
//                    }
//                }
//            }
//            if( MdaUtils.isEmpty(this.getCaccur().getInr()) )
//            {
//                Cur cacCur = new Cur();
//                this.getCaccur().setBas( 1);
//                this.getCaccur().setSqrmar( new BigDecimal("1"));
//                this.getCaccur().setGlbrat( new BigDecimal("1"));
//                this.getCaccur().setRndunt( new BigDecimal("1"));
//                this.getCaccur().setDec( 2);
//                this.getCaccur().setDif( new BigDecimal("10"));
//            }
//        }

    }


    /**
     *   source:xrtmod.0037.script
     */
    @JsonIgnore

    public boolean isCurrencyValid(String inCur)
    {
        String valCur = validCurrencies( Dates.today() );
        int idx = Strings.searchBlock(valCur,inCur);
        if( idx > 0 )
        {
            return  true;
        }
        else
        {
            return  false;
        }

    }
    /**
     *   source:xrtmod.0038.script
     */
    @JsonIgnore
    
    public void getRateXrtWithResRates(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 cur = new Cur();
            Xrt xrt = new Xrt();
            newcur = getCurNewCur( argCur );
            if( ininFlg || MdaUtils.compareTo(basCur,newcur) == 0 )
            {
                vrat = getCurGlbRat( argCur );
                sqrrat = vrat;
            }
            else
            {
                if( MdaUtils.isEmpty(newcur) )
                {
                    currency = argCur;
                }
                else
                {
                    currency = newcur;
                }

                getXrt( currency, value, cur, xrt);
                //  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 )
                {
                    case "B":
                        vrat = xrt.getBuyrat();
                        sqrrat = Decimals.add(xrt.getBuyrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "S":
                        vrat = xrt.getSelrat();
                        sqrrat = Decimals.sub(xrt.getSelrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "T":
                        vrat = xrt.getTtrrat();
                        sqrrat = Decimals.add(xrt.getTtrrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "O":
                        vrat = xrt.getOdrrat();
                        sqrrat = Decimals.add(xrt.getOdrrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "M":
                        vrat = xrt.getMidrat();
                        sqrrat = xrt.getMidrat();
                        break;
                    case "A":
                        vrat = xrt.getBuy1rat();
                        sqrrat = Decimals.add(xrt.getBuy1rat(),Decimals.mul(Decimals.div(cur.getSqrmar(),2),this.getXrtratdir()));
                        break;
                    case "H":
                        vrat = xrt.getSel1rat();
                        sqrrat = Decimals.sub(xrt.getSel1rat(),Decimals.mul(Decimals.div(cur.getSqrmar(),2),this.getXrtratdir()));
                        break;
                    case "G":
                        vrat = getCurGlbRat( argCur );
                        sqrrat = vrat;
                        break;
                    default:
                        SettleExceptionUtils.sysDump("XRTMOD.GetRateXrtWithResRates called with unknown exchangerate typ. Typ = '" + typ + "'");
                }
            }
            rat.value = Numerics.round(vrat,6);
            sqrRat.value = Numerics.round(sqrrat,6);
            resRat.value = xrt.getResrat();
            rebRat.value = xrt.getRebrat();
        }

    }
    /**
     *   source:xrtmod.0039.script
     */
    public boolean isCurrentXrtAvailable(IStream argCurStm,Date argDat)
    {
        //! returns true, if current rates for all currencies listed in ArgCurStm are available at Date Argdat
        //! ArgCurStm is a list of currencies
        // In DEMOBANK current rates are assumed as available if a rate for the ArgDat or later is stored
        boolean res = true;
        // scan stream
        int stmCnt = Streams.streamCount(argCurStm);
        String cur = NULLSTR;
        for(int  i = 1;i <= stmCnt;i++)
        {
            cur = Strings.getLine(argCurStm,i);
            if( ! MdaUtils.isEmpty(cur) )
            {
                // Get rate to retrieve
                Xrt xrt = new Xrt();
                getXrt( cur, argDat, new Cur(), xrt);
                if( Dates.diff(xrt.getBegdat(),argDat)<0 )
                {
                    res = false;
                    break;
                }
            }
        }
        return  res;

    }
    /**
     *   source:xrtmod.0040.script
     */
    @JsonIgnore
    public String getCurSQL_where(Date argDate)
    {
        //! Defines where part for Currency selection in business transactions
        String sql = "";
//        sql = sql + "WHERE (BEGDAT is NULL or BEGDAT <= " + ctx.getDaoSession().dbSqlDate(argDate) + " ) and ( ENDDAT is NULL or ENDDAT > " + ctx.getDaoSession().dbSqlDate(argDate) + " )";
        return  sql;

    }
    /**
     *   source:xrtmod.0041.script
     */
    @JsonIgnore
    public String getCurSQL_order()
    {
        //! Defines order part for Currency selection in business transactions
        return  " order by COD";

    }
    /**
     *   source:xrtmod.0042.script
     */
    @JsonIgnore

    public void getratCeb(String fromcur,String tocur,String typ,Date value,Argument<BigDecimal> rmbrat)
    {
        // Add by ZJ on Feb 2008
        // 会计模组修改，从5.01移植
        String sysiso = sysiso();
        int frmrat = 1;
        int torat = 1;
        rmbrat.value = new BigDecimal("0.000000");
        if( MdaUtils.compareTo(fromcur,tocur) == 0 )
        {
            rmbrat.value = new BigDecimal("1");
            return ;
        }
        if( ( MdaUtils.compareTo(fromcur,sysiso) != 0 ) && ( ! MdaUtils.isEmpty(fromcur) ) )
        {
            Xrt xrt = new Xrt();
            getXrt( fromcur, value, new Cur(), xrt);
            switch( typ )
            {
                case "B":
                    rmbrat.value = Numerics.round(xrt.getBuyrat(),6);
                    break;
                case "S":
                    rmbrat.value = Numerics.round(xrt.getSelrat(),6);
                    break;
                case "T":
                    rmbrat.value = Numerics.round(xrt.getTtrrat(),6);
                    break;
                case "O":
                    rmbrat.value = Numerics.round(xrt.getOdrrat(),6);
                    break;
                default:
                    rmbrat.value = Numerics.round(xrt.getMidrat(),6);
            }
        }

    }
    /**
     *   source:xrtmod.0043.script
     */
    @JsonIgnore

    public void getratCebTim(String fromcur,String tocur,Date value,Argument<String> rmbrat,Argument<BigDecimal> brate,Argument<BigDecimal> srate,Argument<BigDecimal> mrate)
    {
        // Add by ZJ on Feb 2008
        // 会计模组修改，从5.01移植
        //------一日多价新增或取牌价时间函数--------------
        String sysiso = sysiso();
        int frmrat = 1;
        int torat = 1;
        rmbrat.value = "";
        if( MdaUtils.compareTo(fromcur,tocur) == 0 )
        {
            rmbrat.value = "";
            return ;
        }
        if( ( MdaUtils.compareTo(fromcur,sysiso) != 0 || MdaUtils.compareTo(tocur,sysiso) != 0 ) && ( ! MdaUtils.isEmpty(fromcur) ) )
        {
            Xrt xrt = new Xrt();
            if( MdaUtils.compareTo(fromcur,sysiso) != 0 )
            {
                getXrt( fromcur, value, new Cur(), xrt);
            }
            else
            {
                if( MdaUtils.compareTo(tocur,sysiso) != 0 )
                {
                    getXrt( tocur, value, new Cur(), xrt);
                }
            }
            rmbrat.value = xrt.getXrttim();
            brate.value = xrt.getBuyrat();
            srate.value = xrt.getSelrat();
            mrate.value = xrt.getMidrat();
        }

    }
    /**
     *   source:xrtmod.0044.script
     */

    public BigDecimal amtViaCebRat(BigDecimal amt,BigDecimal rat,String acccur,String doccur,String dpy)
    {
        // Add by ZJ on Feb 2008
        // 会计模组修改，从5.01移植
        String vdpy = Strings.mid(dpy,1,3);
        if( MdaUtils.compareTo(acccur,doccur) == 0 )
        {
            return  amt;
        }
        if( MdaUtils.compareTo(rat,0) == 0 )
        {
            return  new BigDecimal(0);
        }
        int tobas = getCurbas( acccur );
        int bas = 0;
        if( tobas > 0 )
        {
            bas = tobas;
        }
        else
        {
            bas = 1;
        }
        int frombas = getCurbas( doccur );
        if( frombas > 0 )
        {
            bas = Decimals.div(bas,frombas).intValue();
        }
        BigDecimal actamt = null;
        if( MdaUtils.compareTo(doccur,vdpy) == 0 )
        {
            actamt = amtRnd( Decimals.mul(Decimals.mul(amt,rat),bas), acccur );
        }
        else
        {
            actamt = amtRnd( Decimals.mul(Decimals.div(amt,rat),bas), acccur );
        }
        return  actamt;

    }
    /**
     *   source:xrtmod.0045.script
     */

    public BigDecimal amtcnv(BigDecimal amt,BigDecimal rat,String fromcur,String tocur)
    {
        if( MdaUtils.compareTo(rat,0) == 0 )
        {
            return  new BigDecimal(0);
        }
        int tobas = getCurbas( tocur );
        int bas = 0;
        if( tobas > 0 )
        {
            bas = tobas;
        }
        else
        {
            bas = 1;
        }
        int frombas = getCurbas( fromcur );
        if( frombas > 0 )
        {
            bas = Decimals.div(bas,frombas).intValue();
        }
        return  amtRnd( Decimals.mul(Decimals.div(amt,rat),bas), tocur );

    }
    /**
     *   source:xrtmod.0046.script
     */
    @JsonIgnore
    
    public void getRateXrtForFee(String argCur,String basCur,boolean ininFlg,String typ,Date value,Argument<BigDecimal> rat,Argument<BigDecimal> sqrRat)
    {
        //! Routine to determine the rate and the squaring rate of a currency of a certain type on a passed date
        //! ArgCur Currency
        //! BasCur Base currency
        //! IninFlg boolean
        //! Typ text
        //! Value datetype
        //! Rat numeric
        //! out SqrRat numeric
        //! Corresponding functions: GetRateXrtWithResRates
        //--zmqtest----
        BigDecimal resrat = null;
        BigDecimal rebrat = null;
        if( MdaUtils.compareTo(getzmqflg(),"X") == 0 )
        {
            Argument<BigDecimal> resratBox = new Argument<BigDecimal>();
            Argument<BigDecimal> rebratBox = new Argument<BigDecimal>();
            getRateXrtWithResRatesForFee_ZMQ( argCur, basCur, ininFlg, typ, value, rat, sqrRat, resratBox, rebratBox );

            resrat = resratBox.value;
            rebrat = rebratBox.value;

        }
        else
        {
            Argument<BigDecimal> resratBox1 = new Argument<BigDecimal>("",resrat);
            Argument<BigDecimal> rebratBox1 = new Argument<BigDecimal>("",rebrat);
            getRateXrtWithResRatesForFee( argCur, basCur, ininFlg, typ, value, rat, sqrRat, resratBox1, rebratBox1 );

            resrat = resratBox1.value;
            rebrat = rebratBox1.value;

        }

    }
    /**
     *   source:xrtmod.0047.script
     */
    
    public BigDecimal amtConvTypesWithCrossrateForFee(String fromCur,BigDecimal amt,String fromTyp,String toCur,String toTyp,Date value,Argument<BigDecimal> crossRate)
    {
        // AmtConvTypes( FromCur , Amt , fromtyp , tocur , totyp, value  )
        String bscur = this.getBascurcac();
        int refamt = 0;
        String newcur;
        Argument<String> newcurBox = new Argument<String>();
        String newsys;
        Argument<String> newsysBox = new Argument<String>();
        Argument<String> bscurBox = new Argument<String>("",bscur);
        Boolean ininflg;
        Argument<Boolean> ininflgBox = new Argument<Boolean>();
        xrtCheckInIn( fromCur, toCur, newcurBox, newsysBox, bscurBox, ininflgBox );

        newcur = newcurBox.value;
        newsys = newsysBox.value;
        bscur = bscurBox.value;
        ininflg = ininflgBox.value;

        BigDecimal frmrat;
        Argument<BigDecimal> frmratBox = new Argument<BigDecimal>();
        BigDecimal sqrrat;
        Argument<BigDecimal> sqrratBox = new Argument<BigDecimal>();
        getRateXrtForFee( fromCur, bscur, ininflg, fromTyp, value, frmratBox, sqrratBox );

        frmrat = frmratBox.value;
        sqrrat = sqrratBox.value;

        BigDecimal torat;
        Argument<BigDecimal> toratBox = new Argument<BigDecimal>();
        Argument<BigDecimal> sqrratBox1 = new Argument<BigDecimal>("",sqrrat);
        getRateXrtForFee( toCur, bscur, ininflg, toTyp, value, toratBox, sqrratBox1 );

        torat = toratBox.value;
        sqrrat = sqrratBox1.value;

        if( MdaUtils.compareTo(frmrat,0) == 0 || MdaUtils.compareTo(torat,0) == 0 )
        {
            crossRate.value = new BigDecimal("0");
        }
        else
        {
            if( MdaUtils.compareTo(frmrat,torat)>0 )
            {
                crossRate.value = Decimals.div(frmrat,torat);
            }
            else
            {
                crossRate.value = Decimals.div(torat,frmrat);
            }
        }
        Argument<String> bscurBox1 = new Argument<String>("",bscur);
        Argument<BigDecimal> refamtBox = new Argument<BigDecimal>("",new BigDecimal(refamt));
        return  amtConvRatesforfee( amt, frmrat, torat, fromCur, toCur, bscurBox1, refamtBox );

    }
    /**
     *   source:xrtmod.0048.script
     */
    @JsonIgnore
    
    public void getRateXrtWithResRatesForFee(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
        {
            Xrt xrt = new Xrt();
            newcur = getCurNewCur( argCur );
            if( ininFlg || MdaUtils.compareTo(basCur,newcur) == 0 )
            {
                vrat = getCurGlbRat( argCur );
                sqrrat = vrat;
            }
            else
            {
                if( MdaUtils.isEmpty(newcur) )
                {
                    currency = argCur;
                }
                else
                {
                    currency = newcur;
                }
                Cur cur = new Cur();
                getXrt( currency, value,cur , xrt);
                //  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 )
                {
                    case "B":
                        //根据银监会需求将费用牌价改为中间价
                        vrat = xrt.getMidrat();
                        sqrrat = Decimals.add(xrt.getBuyrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "S":
                        //根据银监会需求将费用牌价改为中间价
                        vrat = xrt.getMidrat();
                        sqrrat = Decimals.sub(xrt.getSelrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "T":
                        vrat = xrt.getTtrrat();
                        sqrrat = Decimals.add(xrt.getTtrrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "O":
                        vrat = xrt.getOdrrat();
                        sqrrat = Decimals.add(xrt.getOdrrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "M":
                        vrat = xrt.getMidrat();
                        sqrrat = xrt.getMidrat();
                        break;
                    case "A":
                        vrat = xrt.getBuy1rat();
                        sqrrat = Decimals.add(xrt.getBuy1rat(),Decimals.mul(Decimals.div(cur.getSqrmar(),2),this.getXrtratdir()));
                        break;
                    case "H":
                        vrat = xrt.getSel1rat();
                        sqrrat = Decimals.sub(xrt.getSel1rat(),Decimals.mul(Decimals.div(cur.getSqrmar(),2),this.getXrtratdir()));
                        break;
                    case "G":
                        vrat = getCurGlbRat( argCur );
                        sqrrat = vrat;
                        break;
                    default:
                        SettleExceptionUtils.sysDump("XRTMOD.GetRateXrtWithResRates called with unknown exchangerate typ. Typ = '" + typ + "'");
                }
            }
            rat.value = Numerics.round(vrat,6);
            sqrRat.value = Numerics.round(sqrrat,6);
            resRat.value = xrt.getResrat();
            rebRat.value = xrt.getRebrat();
        }

    }
    /**
     *   source:xrtmod.0049.script
     */
    
    public BigDecimal amtConvRatesforfee(BigDecimal amt,BigDecimal fromRat,BigDecimal toRat,String fromCur,String toCur,Argument<String> refCur,Argument<BigDecimal> refAmt)
    {
        //amtConvRates( Amt , fromrat , torat , FromCur , tocur , refcur ,  refamt  )
        // check if old currencies involved
        boolean ininflg = false;
        String fromnew;
        Argument<String> fromnewBox = new Argument<String>();
        String tonew;
        Argument<String> tonewBox = new Argument<String>();
        Argument<Boolean> ininflgBox = new Argument<Boolean>("",ininflg);
        xrtCheckInIn( fromCur, toCur, fromnewBox, tonewBox, refCur, ininflgBox );

        fromnew = fromnewBox.value;
        tonew = tonewBox.value;
        ininflg = ininflgBox.value;

        BigDecimal fromprerat = new BigDecimal("1");
        BigDecimal topstrat = new BigDecimal("1");
        if( ! MdaUtils.isEmpty(fromnew) )
        {
            fromprerat = getCurGlbRat( fromCur );
        }
        if( ! MdaUtils.isEmpty(tonew) )
        {
            topstrat = getCurGlbRat( toCur );
        }
        // simple cases
        BigDecimal imdamt = null;
        if( MdaUtils.compareTo(fromCur,toCur) == 0 && MdaUtils.compareTo(fromRat,toRat) == 0 )
        {
            if( ininflg )
            {
                imdamt = Decimals.div(amt,fromprerat);
                refAmt.value = amtRnd( imdamt, refCur.value );
            }
            else
            {
                refCur.value = toCur;
                refAmt.value = amt;
            }
            return  amt;
        }
        if( MdaUtils.compareTo(fromRat,0) == 0 || MdaUtils.compareTo(toRat,0) == 0 )
        {
            refCur.value = fromCur;
            refAmt.value = new BigDecimal("0");
            return  new BigDecimal(0);
        }
        // calculate amount
        int frombas = 0;
        int tobas = 0;
        if( ininflg )
        {
            // if IN/IN -> use fixed rates between currencies with EUR-logic
            imdamt = Decimals.div(amt,fromprerat);
            refAmt.value = amtRnd( imdamt, refCur.value );
            return  amtRnd( Decimals.mul(imdamt,topstrat), toCur );
        }
        else
        {
            // 1. convert to new currency if necessary
            if( MdaUtils.compareTo(this.getXrt2inflg(),"N") == 0 && MdaUtils.compareTo(fromnew,this.getBascurcac()) != 0 && ( ! MdaUtils.isEmpty(fromnew) ) )
            {
                imdamt = Decimals.div(amt,fromprerat);
            }
            else
            {
                imdamt = amt;
                // 2. apply rate shift
                frombas = getCurbas( fromCur );
                if( frombas > 0 )
                {
                    imdamt = Decimals.div(imdamt,frombas);
                }
            }
            // 3. apply from rate
            if( this.getXrtratdir() > 0 )
            {
                imdamt = Decimals.mul(imdamt,fromRat);
            }
            else
            {
                imdamt = Decimals.div(imdamt,fromRat);
            }
            // 4. This is the reference amount
            refAmt.value = imdamt;
            refCur.value = this.getBascurcac();
            // 5. Apply rate
            if( this.getXrtratdir() > 0 )
            {
                imdamt = Decimals.div(imdamt,toRat);
            }
            else
            {
                imdamt = Decimals.mul(imdamt,toRat);
            }
            // 6. convert to old currency if necessary
            if( MdaUtils.compareTo(this.getXrt2inflg(),"N") == 0 && MdaUtils.compareTo(tonew,this.getBascurcac()) != 0 && ( ! MdaUtils.isEmpty(tonew) ) )
            {
                imdamt = Decimals.mul(imdamt,topstrat);
            }
            else
            {
                // 6. apply rate shift
                tobas = getCurbas( toCur );
                if( tobas > 0 )
                {
                    imdamt = Decimals.mul(imdamt,tobas);
                }
            }
            imdamt = amtRnd( imdamt, toCur );
            return  Numerics.round(imdamt,2);
        }

    }
    /**
     *   source:xrtmod.0050.script
     */
    @JsonIgnore
    
    public void getzmqXrt(String argCur, Date value, Cur curRec, Zmqxrt xrtRec)
    {
        //--ZMQZMQ---
        curRec.setCod( argCur);
        curRec.setSqrmar( getCurSqrMar( argCur ));
        xrtRec.setCur(argCur);
        cbsRange.sdbRngRead(xrtRec,value);
//        if( ctx.getErrorCode() > 0 )
//        {
//            ctx.reraise();
//        }
//        else
//        {
//            Caches.cacheRead(xrtRec,"ZMQXRT",ctx.absGet(Sysmod.class).getEty().getExtkey(),argCur,value);
//            if( ctx.getErrorCode() == tdCacheNotFound )
//            {
//                xrtRec.setCur( argCur);
//                Platform.sdbRngRead(xrtRec,value);
//                // Save result to cache in any case (even if nothing found)
//                if( ctx.getErrorCode() != tdOdbcNotFound )
//                {
//                    ctx.reraise();
//                }
//                Caches.cacheWrite(xrtRec,"ZMQXRT",ctx.absGet(Sysmod.class).getEty().getExtkey(),argCur,value);
//            }
//        }

    }
    /**
     *   source:xrtmod.0051.script
     */
    @JsonIgnore

    public void getratCebTim_ZMQ(String fromcur,String tocur,Date value,Argument<String> rmbrat,Argument<BigDecimal> brate,Argument<BigDecimal> srate,Argument<BigDecimal> mrate)
    {
        //--ZMQZMQ---
        // Add by ZJ on Feb 2008
        // 会计模组修改，从5.01移植
        //------一日多价新增或取牌价时间函数--------------
        String sysiso = sysiso();
        int frmrat = 1;
        int torat = 1;
        rmbrat.value = "";
        if( MdaUtils.compareTo(fromcur,tocur) == 0 )
        {
            rmbrat.value = "";
            return ;
        }
        if( ( MdaUtils.compareTo(fromcur,sysiso) != 0 || MdaUtils.compareTo(tocur,sysiso) != 0 ) && ( ! MdaUtils.isEmpty(fromcur) ) )
        {
            Zmqxrt zmqxrt = new Zmqxrt();
            if( MdaUtils.compareTo(fromcur,sysiso) != 0 )
            {
                getzmqXrt( fromcur, value, new Cur(), zmqxrt);
            }
            else
            {
                if( MdaUtils.compareTo(tocur,sysiso) != 0 )
                {
                    getzmqXrt( tocur, value, new Cur(), zmqxrt);
                }
            }
            rmbrat.value = zmqxrt.getXrttim();
            brate.value = zmqxrt.getBuyrat();
            srate.value = zmqxrt.getSelrat();
            mrate.value = zmqxrt.getMidrat();
        }
    }
    /**
     *   source:xrtmod.0052.script
     */
    @JsonIgnore
    
    public void getRateXrtWithResRates_ZMQ(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
        {
            newcur = getCurNewCur( argCur );
            Zmqxrt zmqxrt = new Zmqxrt();
            Cur cur = new Cur();
            if( ininFlg || MdaUtils.compareTo(basCur,newcur) == 0 )
            {
                vrat = getCurGlbRat( argCur );
                sqrrat = vrat;
            }
            else
            {
                if( MdaUtils.isEmpty(newcur) )
                {
                    currency = argCur;
                }
                else
                {
                    currency = newcur;
                }
                getzmqXrt( currency, value, new Cur(), zmqxrt);
                //  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 )
                {
                    case "B":
                        vrat = zmqxrt.getBuyrat();
                        sqrrat = Decimals.add(zmqxrt.getBuyrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "S":
                        vrat = zmqxrt.getSelrat();
                        sqrrat = Decimals.sub(zmqxrt.getSelrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "T":
                        vrat = zmqxrt.getTtrrat();
                        sqrrat = Decimals.add(zmqxrt.getTtrrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "O":
                        vrat = zmqxrt.getOdrrat();
                        sqrrat = Decimals.add(zmqxrt.getOdrrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "M":
                        vrat = zmqxrt.getMidrat();
                        sqrrat = zmqxrt.getMidrat();
                        break;
                    case "A":
                        vrat = zmqxrt.getBuy1rat();
                        sqrrat = Decimals.add(zmqxrt.getBuy1rat(),Decimals.mul(Decimals.div(cur.getSqrmar(),2),this.getXrtratdir()));
                        break;
                    case "H":
                        vrat = zmqxrt.getSel1rat();
                        sqrrat = Decimals.sub(zmqxrt.getSel1rat(),Decimals.mul(Decimals.div(cur.getSqrmar(),2),this.getXrtratdir()));
                        break;
                    case "G":
                        vrat = getCurGlbRat( argCur );
                        sqrrat = vrat;
                        break;
                    default:
                        SettleExceptionUtils.sysDump("XRTMOD.GetRateXrtWithResRates_ZMQ called with unknown exchangerate typ. Typ = '" + typ + "'");
                }
            }
            rat.value = Numerics.round(vrat,6);
            sqrRat.value = Numerics.round(sqrrat,6);
            resRat.value = zmqxrt.getResrat();
            rebRat.value = zmqxrt.getRebrat();
        }

    }
    /**
     *   source:xrtmod.0053.script
     */
    public void getRateXrtWithResRatesForFee_ZMQ(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
        {
            newcur = getCurNewCur( argCur );
            Zmqxrt zmqxrt = new Zmqxrt();
            Cur cur = new Cur();
            if( ininFlg || MdaUtils.compareTo(basCur,newcur) == 0 )
            {
                vrat = getCurGlbRat( argCur );
                sqrrat = vrat;
            }
            else
            {
                if( MdaUtils.isEmpty(newcur) )
                {
                    currency = argCur;
                }
                else
                {
                    currency = newcur;
                }
                getzmqXrt( currency, value, cur, zmqxrt);
                //  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 )
                {
                    case "B":
                        //根据银监会需求将费用牌价改为中间价
                        vrat = zmqxrt.getMidrat();
                        sqrrat = Decimals.add(zmqxrt.getBuyrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "S":
                        //根据银监会需求将费用牌价改为中间价
                        vrat = zmqxrt.getMidrat();
                        sqrrat = Decimals.sub(zmqxrt.getSelrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "T":
                        vrat = zmqxrt.getTtrrat();
                        sqrrat = Decimals.add(zmqxrt.getTtrrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "O":
                        vrat = zmqxrt.getOdrrat();
                        sqrrat = Decimals.add(zmqxrt.getOdrrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "M":
                        vrat = zmqxrt.getMidrat();
                        sqrrat = zmqxrt.getMidrat();
                        break;
                    case "A":
                        vrat = zmqxrt.getBuy1rat();
                        sqrrat = Decimals.add(zmqxrt.getBuy1rat(),Decimals.mul(Decimals.div(cur.getSqrmar(),2),this.getXrtratdir()));
                        break;
                    case "H":
                        vrat = zmqxrt.getSel1rat();
                        sqrrat = Decimals.sub(zmqxrt.getSel1rat(),Decimals.mul(Decimals.div(cur.getSqrmar(),2),this.getXrtratdir()));
                        break;
                    case "G":
                        vrat = getCurGlbRat( argCur );
                        sqrrat = vrat;
                        break;
                    default:
                        SettleExceptionUtils.sysDump("XRTMOD.GetRateXrtWithResRates_ZMQ called with unknown exchangerate typ. Typ = '" + typ + "'");
                }
            }
            rat.value = Numerics.round(vrat,6);
            sqrRat.value = Numerics.round(sqrrat,6);
            resRat.value = zmqxrt.getResrat();
            rebRat.value = zmqxrt.getRebrat();
        }

    }
    /**
     *   source:xrtmod.0054.script
     */
    public void getRateXrtWithRESRates_YSP(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
        {
            newcur = getCurNewCur( argCur );
            Cur cur = new Cur();
            Xrt yspXrt = null;
            if( ininFlg || MdaUtils.compareTo(basCur,newcur) == 0 )
            {
                vrat = getCurGlbRat( argCur );
                sqrrat = vrat;
            }
            else
            {
                if( MdaUtils.isEmpty(newcur) )
                {
                    currency = argCur;
                }
                else
                {
                    currency = newcur;
                }
                yspXrt = getYSPXrt( currency, value, cur);
                //  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 )
                {
                    case "B":
                        vrat = yspXrt.getBuyrat();
                        sqrrat = Decimals.add(yspXrt.getBuyrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "S":
                        vrat = yspXrt.getSelrat();
                        sqrrat = Decimals.sub(yspXrt.getSelrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "T":
                        vrat = yspXrt.getTtrrat();
                        sqrrat = Decimals.add(yspXrt.getTtrrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "O":
                        vrat = yspXrt.getOdrrat();
                        sqrrat = Decimals.add(yspXrt.getOdrrat(),Decimals.mul(cur.getSqrmar(),this.getXrtratdir()));
                        break;
                    case "M":
                        vrat = yspXrt.getMidrat();
                        sqrrat = yspXrt.getMidrat();
                        break;
                    case "A":
                        vrat = yspXrt.getBuy1rat();
                        sqrrat = Decimals.add(yspXrt.getBuy1rat(),Decimals.mul(Decimals.div(cur.getSqrmar(),2),this.getXrtratdir()));
                        break;
                    case "H":
                        vrat = yspXrt.getSel1rat();
                        sqrrat = Decimals.sub(yspXrt.getSel1rat(),Decimals.mul(Decimals.div(cur.getSqrmar(),2),this.getXrtratdir()));
                        break;
                    case "G":
                        vrat = getCurGlbRat( argCur );
                        sqrrat = vrat;
                        break;
                    default:
                        SettleExceptionUtils.sysDump("XRTMOD.GetRateXrtWithResRatesYSP called with unknown exchangerate typ. Typ = '" + typ + "'");
                }
            }
            rat.value = Numerics.round(vrat,6);
            sqrRat.value = Numerics.round(sqrrat,6);
            if (yspXrt != null) {
                resRat.value = yspXrt.getResrat();
                rebRat.value = yspXrt.getRebrat();
            }
        }

    }
    /**
     *   根据币种和日期 （当前日期 16:30之前的数据） 找到xrt_inr,再找到Xrt
     */
    public Xrt getYSPXrt(String argCur,Date value, Cur curRec) {
        curRec.setCod( argCur);
        curRec.setSqrmar( getCurSqrMar( argCur ));
        String year = MdaUtils.toString(Dates.getYear(value));
        String month = MdaUtils.toString(Dates.getMonth(value));
        String day = MdaUtils.toString(Dates.getDay(value));
        String dat = year + "-" + month + "-" + day + " 16:30";

        String inr = xrtMapper.getMaxXrtInr(argCur,dat);
        if (StringUtils.isEmpty(inr)) {
            SettleExceptionUtils.sysDump("当前所选币种【" + argCur + "】在XRT表中不存在对应的汇率信息");
        }
        Xrt xrt = new Xrt();
        xrt.setInr(inr);
        Xrt result = xrtMapper.selectByPrimaryKey(xrt);
        if (result == null) {
            SettleExceptionUtils.sysDump("当前所选币种【" + argCur + "】在XRT表中不存在对应的汇率信息");
        }
        return result;

    }
    /**
     *   source:xrtmod.0056.script
     */
    public void getratForENT(String fromCur,String fromTyp,String toCur,String toTyp,Date value,Argument<BigDecimal> rat,Argument<BigDecimal> sqrRat)
    {
        String bscur = "";
        String newcur;
        Argument<String> newcurBox = new Argument<String>();
        String newsys;
        Argument<String> newsysBox = new Argument<String>();
        Argument<String> bscurBox = new Argument<String>("",bscur);
        Boolean ininflg;
        Argument<Boolean> ininflgBox = new Argument<Boolean>();
        xrtCheckInIn( fromCur, toCur, newcurBox, newsysBox, bscurBox, ininflgBox );

        newcur = newcurBox.value;
        newsys = newsysBox.value;
        bscur = bscurBox.value;
        ininflg = ininflgBox.value;

        BigDecimal frmrat;
        Argument<BigDecimal> frmratBox = new Argument<BigDecimal>();
        BigDecimal frmsqrrat;
        Argument<BigDecimal> frmsqrratBox = new Argument<BigDecimal>();
        getRateXrt( fromCur, bscur, ininflg, fromTyp, value, frmratBox, frmsqrratBox );

        frmrat = frmratBox.value;
        frmsqrrat = frmsqrratBox.value;

        BigDecimal torat;
        Argument<BigDecimal> toratBox = new Argument<BigDecimal>();
        BigDecimal tosqrrat;
        Argument<BigDecimal> tosqrratBox = new Argument<BigDecimal>();
        getRateXrt( toCur, bscur, ininflg, toTyp, value, toratBox, tosqrratBox );

        torat = toratBox.value;
        tosqrrat = tosqrratBox.value;

        if( MdaUtils.compareTo(frmrat,0) == 0 || MdaUtils.compareTo(torat,0) == 0 )
        {
            rat.value = new BigDecimal("0");
            sqrRat.value = new BigDecimal("0");
        }
        else
        {
            rat.value = Decimals.div(frmrat,torat);
            sqrRat.value = Decimals.div(frmsqrrat,tosqrrat);
        }

    }

    public String getSysisocac(){
        Etg etg = SettleContext.getUserEtg();
        if( ! MdaUtils.isEmpty(etg.getSyscur()) )
        {
            return etg.getSyscur();
        }
        else
        {
            return Inis.getIniStr("TDPARA.INI","System","SysCurrency");
        }
    }

    public String getBascurcac(){
        String bascurcac = null;
        Etg etg = SettleContext.getUserEtg();
        if( ! MdaUtils.isEmpty(etg.getRatbascur()) )
        {
            bascurcac = etg.getRatbascur();
        }
        else
        {
            bascurcac = Inis.getIniStr("TDPARA.INI","System","RateBaseCurrency");
        }
        if( MdaUtils.isEmpty(bascurcac))
        {
            bascurcac = this.getSysisocac();
        }
        return bascurcac;
    }

    public String getSyscal(){
        return Inis.getIniStr("TDPARA.INI","System","Calendar");
    }

    public int getXrtratdir(){
        Etg etg = SettleContext.getUserEtg();
        if( ! MdaUtils.isEmpty(etg.getXrtratdir()) )
        {
            return etg.getXrtratdir();
        }
        else
        {
            if( MdaUtils.compareTo(this.getBascurcac(),"EUR") == 0 )
            {
                return -1;
            }
            else
            {
                if( MdaUtils.compareTo(this.getBascurcac(),"GBP") == 0 )
                {
                    return -1;
                }
                else
                {
                    return 1;
                }
            }
        }
    }

    public String getXrt2inflg(){
        return "N";
    }

    public String getzmqflg(){
        if(null != SettleContext.getUserSession().getBch()){
            return SettleContext.getUserSession().getBch().getZmqflg();
        }
        return NULLSTR;
    }

}
