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

import com.brilliance.mda.runtime.mda.util.Dates;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import com.brilliance.mda.runtime.mda.util.Strings;
import com.brilliance.isc.bo.*;
import com.brilliance.isc.bo.collection.Clacbs;
import com.brilliance.isc.bo.model.*;
import com.brilliance.isc.common.cbsmod.Cbsget;
import com.brilliance.isc.common.cbsmod.service.CbsmodService;
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.liaget.service.LiagetService;
import com.brilliance.isc.common.sysmod.SysmodService;
import com.brilliance.isc.common.transaction.help.TransactionServiceSet;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.common.vo.FremsgVo;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.common.vo.SimpleModuleVo;
import com.brilliance.isc.mda.dao.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

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

@Component
public class DpToolComponents {

    private static final String BOD_DATA_TYPE = "BOD";

    private static final String CCD_DATA_TYPE = "CCD";

    private static final String BCD_DATA_TYPE = "BCD";

    private static final String CLD_DATA_TYPE = "CLD";

    private static final String IS_ERROR = "N";

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

    @Autowired
    private BodMapper bodMapper;

    @Autowired
    private BotMapper botMapper;

    @Autowired
    private CcdMapper ccdMapper;

    @Autowired
    private CctMapper cctMapper;

    @Autowired
    private BcdMapper bcdMapper;

    @Autowired
    private BctMapper bctMapper;

    @Autowired
    private CbsmodService cbsmodService;

    @Autowired
    private Cbsget cbsget;

    @Autowired
    private PtsptaToolComponent ptsptaToolComponent;

    @Autowired
    private LiagetService liagetService;

    @Autowired
    private SysmodService sysmodService;

    @Autowired
    private PublicMapper publicMapper;

    public void collectCbsMap(TransactionServiceSet set, String prefix, Clacbs cbs, String... cbsNames) {
        Map<String, Cbb> cbsMap = set.getCbsMap();
        if (cbsMap == null) {
            cbsMap = new HashMap<>();
        }
        for (String name : cbsNames) {
            Cbb cbb = Utils.getFieldValue(cbs, name);
            if (cbb != null) {
                cbsMap.put(prefix.toUpperCase() + name.toUpperCase(), cbb);
            }
        }
        set.setCbsMap(cbsMap);
    }

    public void collectCbsMap(TransactionServiceSet set, String prefix, Boacbs cbs, String... cbsNames) {
        Map<String, Cbb> cbsMap = set.getCbsMap();
        if (cbsMap == null) {
            cbsMap = new HashMap<>();
        }
        for (String name : cbsNames) {
            Cbb cbb = Utils.getFieldValue(cbs, name);
            if (cbb != null) {
                cbsMap.put(prefix.toUpperCase() + name.toUpperCase(), cbb);
            }
        }
        set.setCbsMap(cbsMap);
    }

    public void collectCbsMap(TransactionServiceSet set, String prefix, Bcacbs cbs, String... cbsNames) {
        Map<String, Cbb> cbsMap = set.getCbsMap();
        if (cbsMap == null) {
            cbsMap = new HashMap<>();
        }
        for (String name : cbsNames) {
            Cbb cbb = Utils.getFieldValue(cbs, name);
            if (cbb != null) {
                cbsMap.put(prefix.toUpperCase() + name.toUpperCase(), cbb);
            }
        }
        set.setCbsMap(cbsMap);
    }

    public void collectCbsMap(TransactionServiceSet set, String prefix, Ccacbs cbs, String... cbsNames) {
        Map<String, Cbb> cbsMap = set.getCbsMap();
        if (cbsMap == null) {
            cbsMap = new HashMap<>();
        }
        for (String name : cbsNames) {
            Cbb cbb = Utils.getFieldValue(cbs, name);
            if (cbb != null) {
                cbsMap.put(prefix.toUpperCase() + name.toUpperCase(), cbb);
            }
        }
        set.setCbsMap(cbsMap);
    }

    public void collectPtsList(TransactionServiceSet set, Bodgrp bodgrp, String... ptsNames) {
        if (ptsNames == null) {
            //找所有的ptspta对象
            Field[] fields = bodgrp.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                if (PtsptaVo.class.equals(field.getType())) {
                    PtsptaVo ptspta = Utils.getFieldValue(bodgrp, field.getName());
                    if (ptspta != null) {
                        set.addPtspta(ptsptaToolComponent.fillPtspta(ptspta));
                    }
                }
            }
        } else {
            for (String name : ptsNames) {
                PtsptaVo ptspta = Utils.getFieldValue(bodgrp, name);
                if (ptspta != null) {
                    set.addPtspta(ptsptaToolComponent.fillPtspta(ptspta));
                }
            }
        }
    }

    public void collectPtsList(TransactionServiceSet set, Bcdgrp bcdgrp, String... ptsNames) {
        if (ptsNames == null) {
            //找所有的ptspta对象
            Field[] fields = bcdgrp.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                if (PtsptaVo.class.equals(field.getType())) {
                    PtsptaVo ptspta = Utils.getFieldValue(bcdgrp, field.getName());
                    if (ptspta != null) {
                        set.addPtspta(ptsptaToolComponent.fillPtspta(ptspta));
                    }
                }
            }
        } else {
            for (String name : ptsNames) {
                PtsptaVo ptspta = Utils.getFieldValue(bcdgrp, name);
                if (ptspta != null) {
                    set.addPtspta(ptsptaToolComponent.fillPtspta(ptspta));
                }
            }
        }
    }

    public void collectPtsList(TransactionServiceSet set, FremsgVo fremsg, String... ptsNames) {
        if (ptsNames == null) {
            //找所有的ptspta对象
            Field[] fields = fremsg.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                if (PtsptaVo.class.equals(field.getType())) {
                    PtsptaVo ptspta = Utils.getFieldValue(fremsg, field.getName());
                    if (ptspta != null) {
                        set.addPtspta(ptsptaToolComponent.fillPtspta(ptspta));
                    }
                }
            }
        } else {
            for (String name : ptsNames) {
                PtsptaVo ptspta = Utils.getFieldValue(fremsg, name);
                if (ptspta != null) {
                    set.addPtspta(ptsptaToolComponent.fillPtspta(ptspta));
                }
            }
        }
    }
    public void collectPtsList(TransactionServiceSet set, Ccdgrp ccdgrp, String... ptsNames) {
        if (ptsNames == null) {
            //找所有的ptspta对象
            Field[] fields = ccdgrp.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                if (PtsptaVo.class.equals(field.getType())) {
                    PtsptaVo ptspta = Utils.getFieldValue(ccdgrp, field.getName());
                    if (ptspta != null) {
                        set.addPtspta(ptsptaToolComponent.fillPtspta(ptspta));
                    }
                }
            }
        } else {
            for (String name : ptsNames) {
                PtsptaVo ptspta = Utils.getFieldValue(ccdgrp, name);
                if (ptspta != null) {
                    set.addPtspta(ptsptaToolComponent.fillPtspta(ptspta));
                }
            }
        }
    }


    public Bod getBodByOwnref(Bod bod) {
        Bod bodTemp = new Bod();
        bodTemp = bodMapper.selectByOwnref(bod.getOwnref());
        return bodTemp;
    }


    public static String sqlLit(String argTxt) {
        String arg = NULLSTR;
        if (MdaUtils.isEmpty(argTxt)) {
            arg = " ";
        } else {
            arg = Strings.trim(argTxt);
        }
        // search for single quotes as they have to be doubled
        int pos = Strings.pos(arg, "'");
        int nxt = pos;
        while (nxt > 0) {
            arg = Strings.mid(arg, 1, pos - 1) + "''" + Strings.mid(arg, pos + 1);
            nxt = Strings.pos(Strings.mid(arg, pos + 2), "'");
            pos = pos + nxt + 1;
        }
        return "'" + arg + "'";

    }

    public String isBOTrnAllowed(Bodgrp bodgrp, String trnNam) {


        String errSel = MdaUtils.getI18NString("bodlod", "CT000004");
        String errClsY = MdaUtils.getI18NString("bodlod", "CT000001");
        String errClsN = MdaUtils.getI18NString("bodlod", "CT000009");
        String errOpnY = MdaUtils.getI18NString("bodlod", "CT000002");
        String errOpnN = MdaUtils.getI18NString("bodlod", "CT000005");
        String errClnCol = MdaUtils.getI18NString("bodlod", "CT000003");
        String errOpnAdv = MdaUtils.getI18NString("bodlod", "CT000006");
        String errOpnTenN = MdaUtils.getI18NString("bodlod", "CT000007");
        String errOpnSubY = MdaUtils.getI18NString("bodlod", "CT000008");
        String errOpnInt = MdaUtils.getI18NString("bodlod", "CT000010");
        String errFPT = MdaUtils.getI18NString("bodlod", "CT000011");
        String errClnColN = MdaUtils.getI18NString("bodlod", "CT000042");
        String errAccY = MdaUtils.getI18NString("bodlod", "CT000044");
        String errOpnAmtN = MdaUtils.getI18NString("bodlod", "CT000046");
        String errIntN = MdaUtils.getI18NString("bodlod", "CT000047");
        // All transactions should be listed in the select case.
        // A condition might inhibit the usage of the contract with the specified
        // transaction by either setting $Res to false or by setting an errormessage
        // into ArgRes.

        trnNam = trnNam.toUpperCase();
        int cnt = 0;
        Map<String, Object> dyncMap = new HashMap<>();

        SimpleModuleVo linkModule = SimpleModuleVo.buildModule(bodgrp.getRec().getInr(), Utils.recGetObj(bodgrp));

        if ("BOTPOP".equals(trnNam)) {
            if (!MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                // not allowed if selected contract is already opened
                if (!MdaUtils.isEmpty(bodgrp.getRec().getOpndat())) {
                    log.warn(errOpnY);
                    return IS_ERROR;
                }
            }
            return "";
        }
        if ("BOTDAV".equals(trnNam)) {
            if (!MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                // not allowed if selected contract is already opened
                if (!MdaUtils.isEmpty(bodgrp.getRec().getOpndat())) {
                    log.warn(errOpnY);
                    return IS_ERROR;
                }
                // not allowed in case of an clean collection
                if (MdaUtils.compareTo(bodgrp.getRec().getDoctypcod(), "C") == 0) {
                    log.warn(errClnCol);
                    return IS_ERROR;
                }
            }
            return "";
        }
        if ("BOTSCC".equals(trnNam)) {
            if (!MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                // not allowed if selected contract is already opened
                if (!MdaUtils.isEmpty(bodgrp.getRec().getOpndat())) {
                    log.warn(errOpnY);
                    return IS_ERROR;
                }
                // not allowed if no clean collection is selected
                if (MdaUtils.compareTo(bodgrp.getRec().getDoctypcod(), "C") != 0) {
                    log.warn(errClnColN);
                    return IS_ERROR;
                }
            }
            return "";
        }
        if ("BOTRAD".equals(trnNam)) {
            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            } else {
                // not allowed if selected contract is closed
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                // not allowed if selected contract is not yet opened
                if (MdaUtils.isEmpty(bodgrp.getRec().getOpndat())) {
                    log.warn(errOpnN);
                    return IS_ERROR;
                }
            }
            // not allowed in case of a clean collection
            if (MdaUtils.compareTo(bodgrp.getRec().getDoctypcod(), "C") == 0) {
                log.warn(errClnCol);
                return IS_ERROR;
            }
            return "";

        }
        if ("BOTDCR".equals(trnNam)) {
            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            } else {
                // not allowed if selected contract is closed
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                // not allowed if selected contract is not yet opened
                if (MdaUtils.isEmpty(bodgrp.getRec().getOpndat())) {
                    log.warn(errOpnN);
                    return IS_ERROR;
                }
                // not allowed if selected contract has already been accepted
                if (MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "DPU" + CR + "DPZ" + CR + "AKZ"))) {
                    log.warn(errAccY);
                    return IS_ERROR;
                }
                // not allowed if there are open advances
                String sqlquery = "SELECT COUNT(*) FROM BPD WHERE PNTTYP = 'BOD' AND PNTINR = '" + bodgrp.getRec().getInr() + "' AND CLSDAT IS NULL ";
                dyncMap.put("sql", sqlquery);
                cnt = publicMapper.dyncCount(dyncMap);
                // No errorchecking because select count has to return a result
                if (cnt > 0) {
                    log.warn(errOpnAdv);
                    return IS_ERROR;
                }
            }
            return "";
        }


        if ("BOTAME".equals(trnNam)) {
            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            } else {
                // not allowed if selected contract is closed
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                // not allowed if selected contract is not yet opened
                if (MdaUtils.isEmpty(bodgrp.getRec().getOpndat())) {
                    log.warn(errOpnN);
                    return IS_ERROR;
                }
            }
            return "";
        }

        if ("BOTADD".equals(trnNam)) {
            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            } else {
                // not allowed if selected contract is closed
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
            }
            return "";
        }

        if ("BOTSET".equals(trnNam)) {
            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            } else {
                // not allowed if selected contract is closed
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                /**
                 //    if bodgrpVo\\REC\\DOCTYPCOD <> "P" then
                 if bodgrpVo\\REC\\DOCTYPCOD == "M" then
                 // not allowed if no usance tenors for selected set of documents are available
                 if IsEmpty( TrnmodGetTenors( bodgrpVo, TrnmodGetUsanceCbtpfxLst + CR + "INT" ) ) then
                 //  $MsgTxt = $MsgTxt + $CR + $ErrIntN
                 //  $CR = CR
                 $res = FALSE
                 endif
                 else
                 if bodgrpVo\\REC\\DOCTYPCOD <> "P" and bodgrpVo\\REC\\DOCTYPCOD <> "A" then
                 // not allowed if there are no open maturities
                 if IsEmpty( TrnmodGetTenors( bodgrpVo, TrnmodGetUsanceCbtpfxLst + CR + "REP" ) ) then
                 $MsgTxt = $MsgTxt + $CR + $ErrOpnTenN
                 $CR = CR
                 $res = FALSE
                 endif
                 endif
                 endif
                 **/
                /**
                 if bodgrpVo\\CBS\\OPN1\\AMT == 0 then
                 $MsgTxt = $MsgTxt + $CR + $ErrOpnAmt
                 $CR = CR
                 $res = FALSE
                 endif
                 **/
                if (MdaUtils.compareTo(bodgrp.getRec().getDoctypcod(), "P") == 0) {
                    // not allowed if no usance tenors for selected set of documents are available
                    if (MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "INT"))) {
                        log.warn(errIntN);
                        return IS_ERROR;
                    }
                } else {
                    //        if bodgrpVo\\REC\\DOCTYPCOD = "M" then
                    // not allowed if no usance tenors for selected set of documents are available
                    if (MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "DPU" + CR + "DPZ" + CR + "AKZ" + CR + "INT"))) {
                        //  $MsgTxt = $MsgTxt + $CR + $ErrIntN
                        //  $CR = CR
                        return IS_ERROR;
                    }
                    /**
                     else
                     if IsEmpty( TrnmodGetTenors( bodgrpVo, TrnmodGetUsanceCbtpfxLst ) ) then
                     //  $MsgTxt = $MsgTxt + $CR + $ErrTenN
                     // $CR = CR
                     $res = FALSE
                     endif
                     endif
                     **/
                }
            }
            return "";
        }

        if ("BOTTRA".equals(trnNam) || "BOTFEE".equals(trnNam) || "BOTFRE".equals(trnNam)) {
            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            }
            return "";
        }

        if ("BOTTEN".equals(trnNam) || "BOTTRF".equals(trnNam)) {

            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            } else {
                // not allowed if selected contract is closed
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                // not allowed if selected contract is not yet opened
                if (MdaUtils.isEmpty(bodgrp.getRec().getOpndat())) {
                    log.warn(errOpnN);
                    return IS_ERROR;
                }
            }
            return "";

        }

        if ("BOTPAY".equals(trnNam)) {
            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            } else {
                // not allowed if selected contract is closed
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                // not allowed if selected contract is not yet opened
                if (MdaUtils.isEmpty(bodgrp.getRec().getOpndat())) {
                    log.warn(errOpnN);
                    return IS_ERROR;
                }
                // not allowed if no open INT engagement
                if (!MdaUtils.isEmpty(bodgrp.getRec().getOpndat()) && MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "INT"))) {
                    log.warn(errOpnInt);
                    return IS_ERROR;
                }
                // not allowed if open Amount is zero
                if (MdaUtils.compareTo(bodgrp.getCbs().getOpn1().getAmt(), 0) <= 0) {
                    log.warn(errOpnAmtN);
                    return IS_ERROR;
                }
            }
            return "";
        }

        if ("BOTCAN".equals(trnNam)) {

            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            } else {
                // not allowed if selected contract is closed
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                // not allowed, if there are subcontracts with open amount for BO
                String sql = "select count(*) from BPD,CBB where PNTTYP = 'BOD' and PNTINR = " +
                        sqlLit(bodgrp.getRec().getInr()) + " AND " +
                        cbsget.cbsGetCbbSql("'BPD'", "BPD.INR", "CBB", "OPN", "AMT1", Dates.today()) + " AND CBB.AMT <> 0";
                dyncMap.put("sql", sql);
                cnt = publicMapper.dyncCount(dyncMap);
                if (cnt > 0) {
                    log.warn(errOpnSubY);
                    return IS_ERROR;
                }
            }
            return "";
        }

        if ("BOTROP".equals(trnNam)) {
            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            } else {
                // not allowed if contract is not closed
                if (MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsN);
                    return IS_ERROR;
                }
            }
            return "";
        }
        if ("BOTATT".equals(trnNam)) {
            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                return IS_ERROR;
            }
            return "";

        }
        if ("BOTCHG".equals(trnNam)) {
            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            }
            return "";
        }

        if ("FPTOPN".equals(trnNam)) {
            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            } else {
                // not allowed if contract is closed
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                } else {
                    // not allowed if not by deferred payment
                    if (MdaUtils.compareTo(bodgrp.getRec().getDoctypcod(), "D") != 0) {
                        log.warn(errFPT);
                        return IS_ERROR;
                    }
                }
            }
            return "";
        }
        if ("BOTACC".equals(trnNam)) {

            if (MdaUtils.isEmpty(bodgrp.getRec().getInr())) {
                log.warn(errSel);
                return IS_ERROR;
            } else {
                // not allowed if selected contract is closed
                if (!MdaUtils.isEmpty(bodgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                // not allowed if selected contract is not yet opened
                if (MdaUtils.isEmpty(bodgrp.getRec().getOpndat())) {
                    log.warn(errOpnN);
                    return IS_ERROR;
                }
                if (MdaUtils.compareTo(bodgrp.getRec().getDoctypcod(), "P") == 0) {
                    log.warn(errClnCol);
                    return IS_ERROR;
                }
                //---------modify by zt-----------
                if (MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "INT"))) {
                    log.warn(errOpnInt);
                    return IS_ERROR;
                }
                //-------------end----------------
            }
            return "";
        }

//        // If $Res is set to false and no errormessage is set
//        // set a default errormessage.
//        if( ! res && MdaUtils.isEmpty(msgTxt) )
//        {
//            msgTxt = MdaUtils.getI18NString("bodlod","CT000000");
//        }
//        // transfer of assembled errormessage to ArgRes
//        argRes.value = msgTxt;

        String msgTxt = "The selected transaction cannot be started under the selected contract";
        log.warn(msgTxt);
        return IS_ERROR;
    }

    public String isCCTrnAllowed(Ccdgrp ccdgrpVo, String trnNam) {
        if ("CCTDAV".equals(trnNam)) {
            if ((!MdaUtils.isEmpty(ccdgrpVo.getRec().getOpndat())) ||
                    (!MdaUtils.isEmpty(ccdgrpVo.getRec().getClsdat()))) {
                return IS_ERROR;
            }
            return "";
        }
        if ("CCTDCR".equals(trnNam)) {
            if (MdaUtils.isEmpty(ccdgrpVo.getRec().getOpndat()) ||
                    (!MdaUtils.isEmpty(ccdgrpVo.getRec().getClsdat()))) {
                return IS_ERROR;
            } else if (MdaUtils.compareTo(ccdgrpVo.getCbs().getOpn1().getAmt(), 0) == 0 ||
                    MdaUtils.isEmpty(ccdgrpVo.getRec().getInr()) ||
                    (MdaUtils.compareTo(ccdgrpVo.getCbs().getMax().getAmt(), 0) == 0)) {
                return IS_ERROR;
            }
            return "";
        }
        if ("CCTSET".equals(trnNam)) {
            if (MdaUtils.isEmpty(ccdgrpVo.getRec().getOpndat()) ||
                    (!MdaUtils.isEmpty(ccdgrpVo.getRec().getClsdat()))) {
                return IS_ERROR;
            } else {
                if (MdaUtils.compareTo(ccdgrpVo.getCbs().getOpn1().getAmt(), 0) == 0) {
                    return IS_ERROR;
                } else {
                    if (MdaUtils.isEmpty(ccdgrpVo.getRec().getInr()) ||
                            (MdaUtils.compareTo(ccdgrpVo.getCbs().getMax().getAmt(), 0) == 0)) {
                        return IS_ERROR;
                    } else {
                        if (MdaUtils.compareTo(ccdgrpVo.getRec().getModset(), "2") == 0) {
                            if (MdaUtils.isEmpty(ccdgrpVo.getRec().getProdat())) {
                                return IS_ERROR;
                            }
                        } else {
                            if (!MdaUtils.isEmpty(ccdgrpVo.getRec().getRptbtchno())) {
                                return IS_ERROR;
                            }
                        }
                    }
                }
            }
            return "";
        }
        if ("CCTFEE".equals(trnNam) || "CCTFRE".equals(trnNam) || "CCTTRA".equals(trnNam)) {
            if (MdaUtils.isEmpty(ccdgrpVo.getRec().getOpndat()) ||
                    MdaUtils.isEmpty(ccdgrpVo.getRec().getInr()))
//                    || sysmodService.sptIsRimLoaded(SettleContext.getUserSession().getSpt().getSta()))
            {
                return IS_ERROR;
            }
            //case "CCTADD"
            // allowed, if contract is loaded and not yet closed
            // if IsEmpty( ArgCcdGrp\\REC\\INR ) or not IsEmpty( ArgCcdGrp\\REC\\CLSDAT ) then
            // $res = FALSE
            // endif
            // case "CCTCHG"
            //not allowed, if no contract is loaded. This trancaction could be #startet from CONCHG only
            //if IsEmpty( ArgCcdGrp\\REC\\INR ) then
            //  $res = FALSE
            //  endif
            return "";
        }
        if ("CLTSEL".equals(trnNam)) {
            if ((!MdaUtils.isEmpty(ccdgrpVo.getRec().getOpndat())) &&
                    (!MdaUtils.isEmpty(ccdgrpVo.getRec().getClsdat()))) {
                return IS_ERROR;
            } else {
                if (MdaUtils.compareTo(ccdgrpVo.getRec().getModset(), "1") == 0) {
                    return IS_ERROR;
                }
            }
            return "";
        }
//        // If $Res is set to false and no errormessage is set
//        // set a default errormessage.
//        if( ! res && MdaUtils.isEmpty(argRes.value) ) {
//            argRes.value = MdaUtils.getI18NString("ccdlod","CT000046");
//        }

        String msgTxt = "Transaction not possible with this contract.";
        log.warn(msgTxt);
        return IS_ERROR;


    }

    public Bodgrp getBodgrpByBodInr(String inr) {
        Bodgrp bodgrp = new Bodgrp();
        bodgrp.reset();
        //找BRD的数据
        Bod bod = bodgrp.getRec();
        bod.setInr(inr);
        bod = bodMapper.selectByPrimaryKey(bod);
        if (bod == null) {
            throw new CommonServiceException("找不到Bod{" + inr + "}数据!");
        }
        bodgrp.setRec(bod);
        //找BOT的数据
        Bot bot = bodgrp.getBlk();
        bot.setInr(inr);
        bot = botMapper.selectByPrimaryKey(bot);
        if (bot == null) {
            throw new CommonServiceException("找不到Bot{" + inr + "}数据!");
        }
        bodgrp.setBlk(bot);
        //找liacbs数据
        Date date = Dates.add(Utils.getMaxDate(), -1);
        cbsmodService.cbsGetBalance(bodgrp.getCbs().getMax(), BOD_DATA_TYPE, inr, "MAXSUM", "AMT1", date);
        cbsmodService.cbsGetBalance(bodgrp.getCbs().getOpn1(), BOD_DATA_TYPE, inr, "OPN", "AMT1", date);
        cbsmodService.cbsGetBalance(bodgrp.getCbs().getOpnbpdisc(), BOD_DATA_TYPE, inr, "OPN", "BPDISC", date);
        cbsmodService.cbsGetBalance(bodgrp.getCbs().getRsv(), BOD_DATA_TYPE, inr, "RSVSUM", "AMT1", date);
        //找ptspta数据
        Map<String, PtsptaVo> maps = ptsptaToolComponent.getPtsptaList(inr, BOD_DATA_TYPE);
        if (maps.size() > 0) {
            maps.keySet().forEach(key -> {
                Utils.setFieldValue(bodgrp, key.toLowerCase(), maps.get(key));
            });
        }
        return bodgrp;
    }


    public Ccdgrp getCcdgrpByCcdInr(String inr) {
        Ccdgrp ccdgrpVo = new Ccdgrp();
        ccdgrpVo.reset();
        //找CCD的数据
        Ccd ccd = ccdgrpVo.getRec();
        ccd.setInr(inr);
        ccd = ccdMapper.selectByPrimaryKey(ccd);
        if (ccd == null) {
            throw new CommonServiceException("找不到Ccd{" + inr + "}数据!");
        }
        ccdgrpVo.setRec(ccd);
        //找CCT的数据
        Cct cct = ccdgrpVo.getBlk();
        cct.setInr(inr);
        cct = cctMapper.selectByPrimaryKey(cct);
        if (cct == null) {
            throw new CommonServiceException("找不到Cct{" + inr + "}数据!");
        }
        ccdgrpVo.setBlk(cct);
        //找ccacbs数据
        Date date = Dates.add(Utils.getMaxDate(), -1);
        cbsmodService.cbsGetBalance(ccdgrpVo.getCbs().getMax(), CCD_DATA_TYPE, inr, "MAXSUM", "AMT1", date);
        cbsmodService.cbsGetBalance(ccdgrpVo.getCbs().getOpn1(), CCD_DATA_TYPE, inr, "OPN", "AMT1", date);
        //找ptspta数据
        Map<String, PtsptaVo> maps = ptsptaToolComponent.getPtsptaList(inr, CCD_DATA_TYPE);
        if (maps.size() > 0) {
            maps.keySet().forEach(key -> {
                Utils.setFieldValue(ccdgrpVo, key.toLowerCase(), maps.get(key));
            });
        }
        return ccdgrpVo;
    }


    public String isBCTrnAllowed(Bcdgrp bcdgrp, String trnNam) {
        boolean res = true;
        // Initialize the variables used to assemble errormessage
        // Attention: $MsgTxt maximum size is 5 rows with 80 digits per row
        //  Errortexts
        String errSelN = MdaUtils.getI18NString("bcdlod", "CT000008");
        String errSelY = MdaUtils.getI18NString("bcdlod", "CT000004");
        String errOpnY = MdaUtils.getI18NString("bcdlod", "CT000006");
        String errOpnN = MdaUtils.getI18NString("bcdlod", "CT000009");
        String errClsY = MdaUtils.getI18NString("bcdlod", "CT000007");
        String errClsN = MdaUtils.getI18NString("bcdlod", "CT000018");
        String errMaxAmdY = MdaUtils.getI18NString("bcdlod", "CT000010");
        String errOpnAmtN = MdaUtils.getI18NString("bcdlod", "CT000011");
        String errAccY = MdaUtils.getI18NString("bcdlod", "CT000012");
        String errMaxAmtN = MdaUtils.getI18NString("bcdlod", "CT000013");
        String errOpnUscTenN = MdaUtils.getI18NString("bcdlod", "CT000014");
        String errOpnTenN = MdaUtils.getI18NString("bcdlod", "CT000015");
        String errClnColY = MdaUtils.getI18NString("bcdlod", "CT000016");
        String errOpnLoanY = MdaUtils.getI18NString("bcdlod", "CT000017");
        String errIntN = MdaUtils.getI18NString("bcdlod", "CT000047");

        trnNam = trnNam.toUpperCase();
        int cnt = 0;
        Map<String, Object> dyncMap = new HashMap<>();

        SimpleModuleVo linkModule = SimpleModuleVo.buildModule(bcdgrp.getRec().getInr(), "BCD");


        switch (trnNam) {
            case "BCTPOP":
                //$ TRNALLOWED.BCTPOP 'RF000019
                //- 'RF000020
                // not allowed, if an existing contract is selected
                if (!MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    log.warn(errSelN);
                    return IS_ERROR;
                }
                return "";
            case "BCTDAV":
                //$ TRNALLOWED.BCTDAV 'RF000021
                if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                    log.warn(errClsY);
                    return IS_ERROR;
                }
                if (!MdaUtils.isEmpty(bcdgrp.getRec().getOpndat())) {
                    log.warn(errOpnY);
                    return IS_ERROR;
                }
                return "";
            case "BCTAME":
                //$ TRNALLOWED.BCTAME 'RF000022
                //- 'RF000044
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    log.warn(errSelY);
                    return IS_ERROR;
                } else {
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                        log.warn(errClsY);
                        return IS_ERROR;
                    }
                    if (MdaUtils.isEmpty(bcdgrp.getRec().getOpndat())) {
                        log.warn(errOpnY);
                        return IS_ERROR;
                    }
                }
                if (bcdgrp.getRec().getAmenbr() >= 99) {
                    log.warn(errMaxAmdY);
                    return IS_ERROR;
                }
                return "";
            case "BCTADD":
                //$ TRNALLOWED.BCTADD 'RF000023
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    log.warn(errSelY);
                    return IS_ERROR;
                }
                return "";
            case "BCTTEN":
            case "BCTTRF":
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    log.warn(errSelY);
                    return IS_ERROR;
                } else {
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                        log.warn(errClsY);
                        return IS_ERROR;
                    }
                    if (MdaUtils.isEmpty(bcdgrp.getRec().getOpndat())) {
                        log.warn(errOpnY);
                        return IS_ERROR;
                    }
                }
                return "";
            case "BCTRAD":
                //$ TRNALLOWED.BCTRAD 'RF000026
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    log.warn(errSelN);
                    return IS_ERROR;
                } else {
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                        log.warn(errClsY);
                        return IS_ERROR;
                    }
                    if (MdaUtils.isEmpty(bcdgrp.getRec().getOpndat())) {
                        log.warn(errOpnY);
                        return IS_ERROR;
                    }
                }
                return "";
            case "BCTDOR":
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
//                    log.warn(errClsY);
                    return IS_ERROR;
                } else {
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                        return IS_ERROR;
                    }
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getAccdat()) && MdaUtils.compareTo(bcdgrp.getCbs().getOpn1().getAmt(), 0) == 0) {
                        return IS_ERROR;
                    }
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getAccdat())) {
                        return IS_ERROR;
                    }
                    if ((MdaUtils.compareTo(bcdgrp.getCbs().getMax().getAmt(), 0) == 0)) {
                        return IS_ERROR;
                    }
                }
                return "";
            case "BCTEUS":
                //$ TRNALLOWED.BCTEUS 'RF000029
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    return IS_ERROR;
                } else {
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                        return IS_ERROR;
                    }
                    if (MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "DPU" + CR + "DPZ" + CR + "AKZ"))) {
                        return IS_ERROR;
                    }
                }
                return "";
            case "BCTFEE":
            case "BCTFRE":
            case "BCTTRA":
                //$ TRNALLOWED.BCTFEE 'RF000030
                //$ TRNALLOWED.BCTFRE 'RF000031
                //$ TRNALLOWED.BCTTRA 'RF000032
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    return IS_ERROR;
                } else {
                    if (MdaUtils.isEmpty(bcdgrp.getRec().getOpndat())) {
                        return IS_ERROR;
                    }
                }
                return "";
            case "BCTPAY":
                //$ TRNALLOWED.BCTPAY 'RF000033
                //- 'RF000034
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    return IS_ERROR;
                } else {
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                        return IS_ERROR;
                    }
                    if (MdaUtils.isEmpty(bcdgrp.getRec().getOpndat())) {
                        return IS_ERROR;
                    }
                    if (MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "INT"))) {
                        return IS_ERROR;
                    }
                }
                return "";
            case "BCTACC":
                //$ TRNALLOWED.BCTPAY 'RF000045
                //- 'RF000046
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    return IS_ERROR;
                } else {
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                        return IS_ERROR;
                    }
                    if (MdaUtils.isEmpty(bcdgrp.getRec().getOpndat())) {
                        return IS_ERROR;
                    }
                    if (MdaUtils.compareTo(bcdgrp.getRec().getDoctypcod(), "P") == 0) {
                        return IS_ERROR;
                    }
                    if (MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "INT"))) {
                        return IS_ERROR;
                    }
                }
                return "";
            case "BCTSET":
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    return IS_ERROR;
                } else {
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                        return IS_ERROR;
                    }
                    if (MdaUtils.isEmpty(bcdgrp.getRec().getOpndat())) {
                        return IS_ERROR;
                    }
                    /**
                     if bcdgrpVo\\CBS\\OPN1\\AMT == 0 then
                     $MsgTxt = $MsgTxt + $CR + $ErrOpnAmt
                     $CR = CR
                     $res = FALSE
                     endif
                     )
                     {
                     if bcdgrpVo\\REC\\DOCTYPCOD <> "P" then
                     if IsEmpty( TrnmodGetTenors( bcdgrpVo, TrnmodGetUsanceCbtpfxLst ) ) then
                     $MsgTxt = $MsgTxt + $CR + $ErrOpnUscTenN
                     $CR = CR
                     $res = FALSE
                     endif
                     endif
                     **/
                    if (MdaUtils.compareTo(bcdgrp.getRec().getDoctypcod(), "P") == 0) {
                        // not allowed if no usance tenors for selected set of documents are available
                        if (MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "INT"))) {
                            return IS_ERROR;
                        }
                    } else {
                        if (MdaUtils.compareTo(bcdgrp.getRec().getDoctypcod(), "M") == 0) {
                            // not allowed if no usance tenors for selected set of documents are available
                            if (MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "DPU" + CR + "DPZ" + CR + "AKZ" + CR + "INT"))) {
                                return IS_ERROR;
                            }
                        } else {
                            if (MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "DPU" + CR + "DPZ" + CR + "AKZ"))) {
                                //  $MsgTxt = $MsgTxt + $CR + $ErrTenN
                                // $CR = CR
                                return IS_ERROR;
                            }
                        }

                    }
                }
                return "";
            case "BCTSUS":
                //$ TRNALLOWED.BCTSUS 'RF000035
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    return IS_ERROR;
                } else {
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                        return IS_ERROR;
                    }
                    if (MdaUtils.isEmpty(liagetService.trnmodGetTenorAmount(linkModule, "DPU" + CR + "DPZ" + CR + "AKZ"))) {
                        return IS_ERROR;
                    }
                }
                return "";
            case "BCTROG":
                //$ TRNALLOWED.BCTROG 'RF000036
                //- 'RF000037
                if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                    return IS_ERROR;
                }
                if (MdaUtils.compareTo(bcdgrp.getRec().getDoctypcod(), "C") == 0) {
                    return IS_ERROR;
                }
                return "";
            case "BCTCAN":
                //$ TRNALLOWED.BCTCAN 'RF000038
                //- 'RF000039
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    return IS_ERROR;
                } else {
                    if (!MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                        return IS_ERROR;
                    }
                    // 有融资没有还清的情况下也能做该交易。
                    /**
                     // not allowed, if there are contracts with open amount for TR
                     $cnt = 0
                     $sql = "select count(*) from TRD,CBB where PNTTYP = 'BCD' and PNTINR = " + SqlLit( bcdgrpVo\\REC\\INR ) + " AND " + CbsGetCbbSql( "'TRD'", "TRD.INR", "CBB", "OPN", "AMT1", Today ) + " AND CBB.AMT <> 0"
                     DBExecuteSQL( $sql )
                     DBFetchFields( "", $cnt )
                     DBCloseCursor
                     if $cnt > 0 then
                     $MsgTxt = $MsgTxt + $CR + $ErrOpnLoanY
                     $CR = CR
                     $res = FALSE
                     endif
                     **/
                }
                return "";
            case "BCTROP":
                //$ TRNALLOWED.BCTROP 'RF000040
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    return IS_ERROR;
                } else {
                    if (MdaUtils.isEmpty(bcdgrp.getRec().getClsdat())) {
                        return IS_ERROR;
                    }
                }
                return "";
            case "BCTATT":
                // Attaching incoming message
                //$ TRNALLOWED.BCTATT 'RF000041
                //- 'RF000042
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    return IS_ERROR;
                }
                return "";
            case "BCTCHG":
                //$ TRNALLOWED.BCTCHG 'RF000043
                if (MdaUtils.isEmpty(bcdgrp.getRec().getInr())) {
                    return IS_ERROR;
                }
                return "";
        }

        // If $Res is set to false and no errormessage is set
        // set a default errormessage.
        String msgTxt = "The selected transaction cannot be started under the selected contract";
        log.warn(msgTxt);
        return IS_ERROR;
    }

    public Bcdgrp getBcdgrpByBcdInr(String inr) {
        Bcdgrp bcdgrp = new Bcdgrp();
        bcdgrp.reset();
        //找BRD的数据
        Bcd bcd = bcdgrp.getRec();
        bcd.setInr(inr);
        bcd = bcdMapper.selectByPrimaryKey(bcd);
        if (bcd == null) {
            throw new CommonServiceException("找不到Bcd{" + inr + "}数据!");
        }
        bcdgrp.setRec(bcd);
        //找BOT的数据
        Bct bct = bcdgrp.getBlk();
        bct.setInr(inr);
        bct = bctMapper.selectByPrimaryKey(bct);
        if (bct == null) {
            throw new CommonServiceException("找不到Bct{" + inr + "}数据!");
        }
        bcdgrp.setBlk(bct);
        //找liacbs数据
        Date date = Dates.add(Utils.getMaxDate(), -1);
        cbsmodService.cbsGetBalance(bcdgrp.getCbs().getOpn1(), BCD_DATA_TYPE, inr, "OPN", "AMT1", date);
        cbsmodService.cbsGetBalance(bcdgrp.getCbs().getMax(), BCD_DATA_TYPE, inr, "MAXSUM", "AMT1", date);
        //找ptspta数据
        Map<String, PtsptaVo> maps = ptsptaToolComponent.getPtsptaList(inr, BCD_DATA_TYPE);
        if (maps.size() > 0) {
            maps.keySet().forEach(key -> {
                Utils.setFieldValue(bcdgrp, key.toLowerCase(), maps.get(key));
            });
        }
        return bcdgrp;
    }

    public static String trnmodGetUsanceCbtpfxLst() {
        String trnName = SettleContext.getTransName();
        switch (trnName) {
            case "BCTACC":
            case "BCTSET":
            case "BOTSEL":
            case "BRTCSG":
            case "CPTOPN":
                return "DPU" + CR + "DPZ" + CR + "AKZ";
            default:
                return NULLSTR;
        }
    }


}
