package com.brilliance.isc.common.bop.bopdec.service.imp;

import com.brilliance.mda.runtime.mda.util.*;
import com.brilliance.isc.bo.Bch;
import com.brilliance.isc.bo.Cbb;
import com.brilliance.isc.bo.Ptc;
import com.brilliance.isc.bo.Pty;

import com.brilliance.isc.bo.model.BopObjectType;
import com.brilliance.isc.bo.model.CommetItems;
import com.brilliance.isc.common.esb.account.IAccountFeign;
import com.brilliance.isc.common.util.BopUtils;
import com.brilliance.isc.common.bopset.counter.service.CounterBopdecService;
import com.brilliance.isc.common.bopset.service.BopdecCommonService;
import com.brilliance.isc.common.bopset.service.CtlmodService;
import com.brilliance.isc.common.cache.pty.PtyCacheService;
import com.brilliance.isc.common.cbsmod.service.XrtmodService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.component.PtsptaToolComponent;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.counter.service.CounterService;
import com.brilliance.isc.common.setfeg.vo.SetfelVo;
import com.brilliance.isc.common.setfog.vo.SetfolVo;
import com.brilliance.isc.common.setgll.vo.SetgllVo;
import com.brilliance.isc.common.setmod.vo.PtsFeeDetailVo;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.config.BoprptnoConfig;
import com.brilliance.isc.counter.service.SerialCounterService;
import com.brilliance.isc.esb.model.inner.InnerReq;
import com.brilliance.isc.esb.model.inner.InnerReq8023;
import com.brilliance.isc.esb.model.inner.InnerRes;
import com.brilliance.isc.esb.model.inner.InnerRes8023;
import com.brilliance.isc.mda.dao.BchMapper;
import com.brilliance.isc.mda.dao.BopcouMapper;
import com.brilliance.isc.mda.dao.PtcMapper;
import com.brilliance.isc.vo.bop.RptnoRequestVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

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

@Service
public class BopdecCommonServiceImpl implements BopdecCommonService {

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

    @Autowired
    private PtsptaToolComponent ptsptaToolComponent;

    @Autowired
    private PtyCacheService ptyCacheService;

    @Autowired
    private XrtmodService xrtmodService;
    @Autowired
    private CounterService counterService;

    @Autowired
    private CodetableService codetableService;

    @Autowired
    private CtlmodService ctlmodService;

    @Autowired
    private BchMapper bchMapper;

    @Autowired
    private BoprptnoConfig boprptnoConfig;

    @Autowired
    private BopcouMapper bopcouMapper;

    @Autowired
    private PtcMapper ptcMapper;

    @Autowired
    private CounterBopdecService counterBopdecService;

    @Autowired
    private SerialCounterService serialCounterService;

    @Autowired(required = false)
    private IAccountFeign accountFeign;


    @Override
    public Pty getPtyByTransname(String transName, List<PtsptaVo> ptsList,String rol,String payTyp,String hndtyp) {
        PtsptaVo ptsptaVo = null;
        Pty pty = null;
        transName = transName.toUpperCase();
        //有个别收单行交易
        transName = Strings.mid(transName,1,6);
        if( MdaUtils.compareTo(Strings.mid(transName,4,3),"FRE") == 0 ) {
            ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "OTHCC");
            if (MdaUtils.isEmpty(ptsptaVo)) {
                ptsptaVo = new PtsptaVo();
                ptsptaVo.reset();
            }
        }else {
            switch (transName) {
                case "BRTSET":
                case "BRTPAY":
                case "BRTUTL":
                case "BRTSUS":
                case "DFTSET":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "APL");
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    break;
                case "LITROG":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, rol);
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    break;
                case "BCTSET":
                case "BCTPAY":
                case "BCTSUS":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "DRE");
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    break;
                case "BOTSET":
                case "BOTPAY":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "DRR");
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    break;
                case "BTTSET":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "BE1");
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    break;
                case "BETSET":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "BEN");
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    break;
                case "CPTSET":
                    if (MdaUtils.compareTo(payTyp, "I") == 0 || MdaUtils.compareTo(payTyp, "T") == 0) {
                        ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "PYE");
                        if (MdaUtils.isEmpty(ptsptaVo)) {
                            ptsptaVo = new PtsptaVo();
                            ptsptaVo.reset();
                        }
                    } else {
                        ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "ORC");
                        if (MdaUtils.isEmpty(ptsptaVo)) {
                            ptsptaVo = new PtsptaVo();
                            ptsptaVo.reset();
                        }
                    }
                    break;
                case "GITSET":
                case "GITPSE":
                case "NITSET":
                case "NITPSE":
                    String flg = BopUtils.judgeGIType(transName, hndtyp);
                    switch (flg) {
                        case "GI":
                        case "NI":
                            ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "APL");
                            break;
                        case "GE":
                        case "NE":
                            ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "BEN");
                            break;
                    }
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    break;
                case "GETSET":
                case "NETSET":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "BEN");
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    break;
                case "TRTOPN":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "FIP");
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    //--光大汇入汇款---
                    break;
                case "CPTADV":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "PYE");
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    //--光大汇出汇款---
                    break;
                case "CPTOPN":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "ORC");
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    //--光大光票托收---
                    break;
                case "CCTSET":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "PRE");
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    break;
                case "BPTOPN":
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, "FIA");
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
                    break;
                default:
                    ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, rol);
                    if (MdaUtils.isEmpty(ptsptaVo)) {
                        ptsptaVo = new PtsptaVo();
                        ptsptaVo.reset();
                    }
            }
        }
        if (!MdaUtils.isEmpty(ptsptaVo.getPtyinr())) {
            pty = ptyCacheService.getPtyById(ptsptaVo.getPtyinr());
        }
        return pty;
    }

    @Override
    public String getTranRol(String transName) {
        transName = transName.toUpperCase();
        //有个别收单行交易
        transName = Strings.mid(transName,1,6);
        String rol = NULLSTR;
        switch(transName) {
            case "BRTSET":
            case "BRTSUS":
            case "BRTPAY":
            case "GITSET":
            case "GITPSE":
            case "NITSET":
            case "NITPSE":
            case "BRTUTL":
                rol = "APL";
                break;
            case "BCTSET":
            case "BCTSUS":
            case "BCTPAY":
                rol = "DRE";
                break;
            case "BOTSET":
            case "BOTPAY":
                rol = "DRR";
                break;
            case "BETSET":
                rol = "BEN";
                break;
            case "CCTSET":
                rol = "PRE";
                break;
            case "BPTOPN":
                rol = "FIA";
                break;
            case "BTTSET":
            case "BTTPAY":
                rol = "BE1";
                break;
            case "CPTOPN":
                rol = "ORC";
                break;
            case "CPTADV":
                rol = "PYE";
                break;
            case "GETSET":
            case "NETSET":
                rol = "BEN";
                break;
            case "CPTSET":
                break;
        }
        return rol;
    }

    @Override
    public String getTranCur(String transName, Map<String, Cbb> cbsMap) {
        String bus = Strings.mid(transName,1,2);
        String cur = NULLSTR;
        switch( bus ) {
            case "BR":
            case "BC":
            case "BO":
                cur = cbsMap.get("OPN1").getCur();
                break;
            case "BP":
            case "CP":
            case "TR":
            case "GI":
            case "GE":
            case "NE":
            case "NI":
                cur = cbsMap.get("MAX").getCur();
                break;
            default:
                cur = cbsMap.get("OPN1").getCur();
        }
        return cur;
    }

    @Override
    public BigDecimal getInchargeAmt(String transName,String cur,List<SetfelVo> setFelList,List<PtsFeeDetailVo> ptydet) {
        BigDecimal outAmt = new BigDecimal("0.00");
        String eot = NULLSTR;
        String rolStr = NULLSTR;
        String curStr = NULLSTR;
        BigDecimal amt = null;
        String dspStr = NULLSTR;
        String cPRolC = NULLSTR;
        String cPRolB = NULLSTR;
        if( MdaUtils.compareTo(cur,xrtmodService.sysiso()) != 0 ) {
            for(SetfelVo setFel : setFelList){
                rolStr = setFel.getRol();
                curStr = setFel.getCur();
                amt = setFel.getAmt();
                dspStr = setFel.getDsp();
                cPRolC = "";
                cPRolB = "";
                switch( Strings.mid(transName,1,2) ) {
                    case "BO":
                        //  if $CurStr <> SYSISO and $DspStr = "X" and $RolStr = "DRR" and not isSeperateFEE( $RolStr ) then
                        //        if $CurStr = GetTranCur( $TranName ) and $DspStr = "X" and $RolStr = "DRR" and not isSeperateFEE( $RolStr ) then
                        if( MdaUtils.compareTo(curStr,cur) == 0 && MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"DRR") == 0 || MdaUtils.compareTo(rolStr,"COL") == 0 ) && !this.isSeperateFEE(rolStr,ptydet) ) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                    case "BE":
                        //  if $CurStr <> SYSISO and $DspStr = "X" and $RolStr = "BEN" and not isSeperateFEE( $RolStr ) then
                        //        if $CurStr = GetTranCur( $TranName ) and $DspStr = "X" and ( $RolStr = "BEN" or $RolStr = "PRB" ) and not isSeperateFEE( $RolStr ) then
                        if( MdaUtils.compareTo(curStr,cur) == 0 && MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"BEN") == 0 || MdaUtils.compareTo(rolStr,"PRB") == 0 || MdaUtils.compareTo(rolStr,"ISS") == 0 || MdaUtils.compareTo(rolStr,"RMB") == 0 || MdaUtils.compareTo(rolStr,"OTH") == 0 ) && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                    case "CC":
                        //  if $CurStr <> SYSISO and $DspStr = "X" and ( $RolStr = "COL" or $RolStr = "PRE" ) and not isSeperateFEE( $RolStr ) then
                        if( MdaUtils.compareTo(curStr,cur) == 0 && MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"COL") == 0 || MdaUtils.compareTo(rolStr,"PRE") == 0 ) && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                    case "BT":
                        // if $CurStr <> SYSISO and $DspStr = "X" and $RolStr = "BE1" and not isSeperateFEE( $RolStr ) then
                        //      if $CurStr = GetTranCur( $TranName ) and $DspStr = "X" and $RolStr = "BE1" and not isSeperateFEE( $RolStr ) then
                        if( MdaUtils.compareTo(curStr,cur) == 0 && MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"BE1") == 0 || MdaUtils.compareTo(rolStr,"ISS") == 0 || MdaUtils.compareTo(rolStr,"OTH") == 0 || MdaUtils.compareTo(rolStr,"PRB") == 0 ) && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                    case "BP":
                        // if $CurStr <> SYSISO and $DspStr = "X" and ( $RolStr = "DRR" or $RolStr = "BEN" or $RolStr = "FIA" ) and not isSeperateFEE( $RolStr ) then
                        if( MdaUtils.compareTo(curStr,cur) == 0 && MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"DRR") == 0 || MdaUtils.compareTo(rolStr,"BEN") == 0 || MdaUtils.compareTo(rolStr,"FIA") == 0 ) && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                    case "GE":
                    case "NE":
                        // if $CurStr <> SYSISO and $DspStr = "X" and ( $RolStr = "ISS" or $RolStr = "BEN" ) and not isSeperateFEE( $RolStr ) then
                        //     if $CurStr = GetTranCur( $TranName ) and $DspStr = "X" and ( $RolStr = "ISS" or $RolStr = "BEN" ) and not isSeperateFEE( $RolStr ) then
                        if( MdaUtils.compareTo(curStr,cur) == 0 && MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"ISS") == 0 || MdaUtils.compareTo(rolStr,"BEN") == 0 || MdaUtils.compareTo(rolStr,"OTH") == 0 || MdaUtils.compareTo(rolStr,"PRB") == 0 ) && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                }
                if( MdaUtils.compareTo(transName,"CPTADV") == 0 ) {
                    if( ! MdaUtils.isEmpty(dspStr) ) {
                        // if $CurStr <> SYSISO and GetTranCur( $TranName ) = $CurStr and not isSeperateFEE( getDefaultCUSTROL ) then
                        if( MdaUtils.compareTo(curStr,cur) == 0 && MdaUtils.compareTo(dspStr,"X") == 0 && MdaUtils.compareTo(cur,curStr) == 0 && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                    }
                }
            }
        }else{
            for(SetfelVo setFel : setFelList){
                rolStr = setFel.getRol();
                curStr = setFel.getCur();
                amt = setFel.getAmt();
                dspStr = setFel.getDsp();
                //将此处的错误进行了修改，应该截取TranName的前两位
                switch( Strings.mid(transName,1,2) ) {
                    case "PC":
                        if( MdaUtils.compareTo(dspStr,"X") == 0 && MdaUtils.compareTo(rolStr,"ISS") == 0 && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                    case "BO":
                        //  if $DspStr = "X" and $RolStr = "DRR" and not isSeperateFEE( $RolStr ) then
                        if( MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"DRR") == 0 || MdaUtils.compareTo(rolStr,"COL") == 0 ) && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                    case "BE":
                        // if $DspStr = "X" and $RolStr = "BEN" and not isSeperateFEE( $RolStr ) then
                        if( MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"BEN") == 0 || MdaUtils.compareTo(rolStr,"PRB") == 0 || MdaUtils.compareTo(rolStr,"ISS") == 0 || MdaUtils.compareTo(rolStr,"RMB") == 0 || MdaUtils.compareTo(rolStr,"OTH") == 0 ) && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                    case "CC":
                        if( MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"COL") == 0 || MdaUtils.compareTo(rolStr,"PRE") == 0 ) && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                    case "BT":
                        //  if $DspStr = "X" and $RolStr = "BE1" and not isSeperateFEE( $RolStr ) then
                        if( MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"BE1") == 0 || MdaUtils.compareTo(rolStr,"ISS") == 0 || MdaUtils.compareTo(rolStr,"OTH") == 0 || MdaUtils.compareTo(rolStr,"PRB") == 0 ) && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                    case "BP":
                        // if $DspStr = "X" and ( $RolStr = "ISS" or $RolStr = "BEN" or $RolStr = "INT" ) and not isSeperateFEE( $RolStr ) then
                        if( MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"ISS") == 0 || MdaUtils.compareTo(rolStr,"BEN") == 0 || MdaUtils.compareTo(rolStr,"FIA") == 0 ) && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                    case "GE":
                    case "NE":
                        // if $DspStr = "X" and ( $RolStr = "ISS" or $RolStr = "BEN" ) and not isSeperateFEE( $RolStr ) then
                        if( MdaUtils.compareTo(dspStr,"X") == 0 && ( MdaUtils.compareTo(rolStr,"ISS") == 0 || MdaUtils.compareTo(rolStr,"BEN") == 0 || MdaUtils.compareTo(rolStr,"OTH") == 0 || MdaUtils.compareTo(rolStr,"PRB") == 0 ) && !this.isSeperateFEE(rolStr,ptydet)) {
                            outAmt = amt.add(outAmt);
                        }
                        break;
                }
                if( MdaUtils.compareTo(transName,"CPTADV") == 0 ) {
                    if( ! MdaUtils.isEmpty(dspStr) ) {
                        if( MdaUtils.compareTo(cur,curStr) == 0 && MdaUtils.compareTo(dspStr,"X") == 0 ) {
                            outAmt = amt.add(outAmt);
                        }
                    }
                }
            }
        }
        return Numerics.round(outAmt,0);
    }

    @Override
    public void getBasic(String transName, List<SetgllVo> setGllList,String cur,String ffaacc,Map<String, BigDecimal> amtList, Map<String, String> accList) {
        amtList.put("exrate",BigDecimal.ZERO);
        amtList.put("lcyamt",BigDecimal.ZERO);
        amtList.put("fcyamt",BigDecimal.ZERO);
        amtList.put("othamt",BigDecimal.ZERO);

        accList.put("lcyacc",NULLSTR);
        accList.put("fcyacc",NULLSTR);
        accList.put("othacc",NULLSTR);
        // 如果party为CLI应与APL的金额合并处理
        BigDecimal ghAplAmt = new BigDecimal("0.0000");
        BigDecimal ghCliAmt = new BigDecimal("0.0000");
        BigDecimal maxlcyamt = new BigDecimal("0.0000");
        BigDecimal maxfcyamt = new BigDecimal("0.0000");
        BigDecimal vfcyamt = new BigDecimal("0.0000");
        BigDecimal maxothamt = new BigDecimal("0.0000");

        String accCurStr = NULLSTR;
        String curStr = NULLSTR;
        String rolStr = NULLSTR;
        BigDecimal amt = BigDecimal.ZERO;
        String actStr = NULLSTR;
        BigDecimal ratCeb = BigDecimal.ZERO;
        String dspStr = NULLSTR;
        String gllGrp = NULLSTR;

        for(SetgllVo setGll : setGllList){
            accCurStr = setGll.getAcccur();
            curStr = setGll.getCur();
            rolStr = setGll.getRol();
            amt = setGll.getAmt();
            actStr = setGll.getAct();
            ratCeb = setGll.getRat();
            dspStr = setGll.getDsp();
            gllGrp = setGll.getGllgrp();
            //国内费用、国外费用，如果选择了seperate,在收支申报信息中不体现---刘文青
            //选中seperte时，$GllGrp为F
            if( this.bopCheckRol( transName, rolStr ) ) {
                if( MdaUtils.compareTo(cur,xrtmodService.sysiso()) != 0 ) {
                    //结售汇
                    //  if $AccCurStr = SYSISO and $CurStr <> SYSISO then
                    if( MdaUtils.compareTo(accCurStr,xrtmodService.sysiso()) == 0 && MdaUtils.compareTo(curStr,xrtmodService.sysiso()) != 0 && MdaUtils.compareTo(gllGrp,"F") != 0 ) {
                        if(Numerics.abs(amt).compareTo(maxlcyamt) > 0) {
                            maxlcyamt = Numerics.abs(amt);
                            accList.put("lcyacc",actStr);
                            amtList.put("exrate",ratCeb);
                        }
                        ghAplAmt = ghAplAmt.add(Numerics.abs(amt));
                    }else {
                        //   if $AccCurStr <> SYSISO and $CurStr <> SYSISO and $AccCurStr = GetTranCur( $TranName ) then  #原币
                        if( MdaUtils.compareTo(accCurStr,xrtmodService.sysiso()) != 0 && MdaUtils.compareTo(curStr,xrtmodService.sysiso()) != 0 && MdaUtils.compareTo(accCurStr,cur) == 0 && MdaUtils.compareTo(gllGrp,"F") != 0 ) {
                            if( bopCheckDSP( transName, dspStr ) && Numerics.abs(amt).compareTo(BigDecimal.ZERO) > 0 )
                            {
                                if(Numerics.abs(amt).compareTo(maxfcyamt) > 0) {
                                    maxfcyamt = Numerics.abs(amt);
                                    accList.put("fcyacc",actStr);
                                    if( ! MdaUtils.isEmpty(ffaacc) ) {
                                        accList.put("fcyacc",ffaacc);
                                    }
                                }
                                vfcyamt = vfcyamt.add(Numerics.abs(amt));
                            }
                        }
                    }
                } else {
                    //   if $AccCurStr = SYSISO and $CurStr = SYSISO then #人名币
                    if( MdaUtils.compareTo(accCurStr,xrtmodService.sysiso()) == 0 && MdaUtils.compareTo(curStr,xrtmodService.sysiso()) == 0 && MdaUtils.compareTo(gllGrp,"F") != 0 ) {
                        if(Numerics.abs(amt).compareTo(maxothamt) > 0) {
                            maxothamt = Numerics.abs(amt);
                            accList.put("othacc",actStr);
                        }
                        ghCliAmt = ghCliAmt.add(Numerics.abs(amt));
                    }
                }
            }
        }
        //取整放到这个函数的外面进行。
        amtList.put("lcyamt",ghAplAmt);
        amtList.put("fcyamt",vfcyamt);
        amtList.put("othamt",ghCliAmt);
        if(Numerics.round(ghAplAmt,0).compareTo(BigDecimal.ZERO) == 0) {
            amtList.put("exrate",BigDecimal.ZERO);
            accList.put("lcyacc",NULLSTR);
        }
    }

    @Override
    public boolean bopCheckRol(String transName, String rol) {
        boolean ret = false;
        String bus = Strings.mid(transName,1,2);
        switch( bus ) {
            case "LI":
            case "BR":
                if( MdaUtils.compareTo(rol,"APL") == 0 ) {
                    //BRTSET,GITSET,BCTSET交易中国内扣费只对我方客户收取--刘文青
                    //   if Rol = "APL" or Rol = "CLI" or Rol = "PRB" or Rol = "ADV" then
                    ret = true;
                }
                break;
            case "BC":
                if( MdaUtils.compareTo(rol,"DRE") == 0 ) {
                    ret = true;
                }
                break;
            case "LE":
                ret = true;
                break;
            case "BO":
                if( MdaUtils.compareTo(rol,"DRR") == 0 || MdaUtils.compareTo(rol,"LO1") == 0 || MdaUtils.compareTo(rol,"FIA") == 0 ) {
                    ret = true;
                }
                break;
            case "BE":
                //  if Rol = "BEN" or Rol = "COL" or Rol = "FIA" then
                if( MdaUtils.compareTo(rol,"BEN") == 0 || MdaUtils.compareTo(rol,"COL") == 0 || MdaUtils.compareTo(rol,"FIA") == 0 || MdaUtils.compareTo(rol,"ADV") == 0 ) {
                    ret = true;
                }
                break;
            case "CC":
                if( MdaUtils.compareTo(rol,"CLI") == 0 || MdaUtils.compareTo(rol,"PRE") == 0 ) {
                    ret = true;
                }
                break;
            case "GI":
            case "NI":
                //  if Rol = "APL" or Rol = "CLI" then
                /**
                 if Rol == "APL" then

                 **/
                if( MdaUtils.compareTo(rol,"APL") == 0 || MdaUtils.compareTo(rol,"CTR") == 0 ) {
                    ret = true;
                }
                break;
            case "BT":
                if( MdaUtils.compareTo(rol,"BE1") == 0 ) {
                    ret = true;
                }
                break;
            case "GE":
            case "NE":
                if( MdaUtils.compareTo(rol,"BEN") == 0 ) {
                    ret = true;
                }
                break;
            case "BP":
                if( MdaUtils.compareTo(rol,"FIA") == 0 || MdaUtils.compareTo(rol,"LO1") == 0 ) {
                    ret = true;
                }
                break;
        }
        switch( transName ) {
            case "CPTOPN":
                if( MdaUtils.compareTo(rol,"ORC") == 0 || MdaUtils.compareTo(rol,"ORI") == 0 ) {
                    ret = true;
                }
                break;
            case "CPTADV":
                if( MdaUtils.compareTo(rol,"PYE") == 0 ) {
                    ret = true;
                }
                break;
        }
        return ret;
    }

    @Override
    public boolean bopCheckDSP(String transName, String dsp) {
        boolean ret = false;
        String bus = Strings.mid(transName,1,2);
        switch( bus ) {
            case "LI":
            case  "BR":
            case  "BC":
                if( MdaUtils.compareTo(dsp,"LOD") == 0 || MdaUtils.compareTo(dsp,"SPD") == 0 || MdaUtils.compareTo(dsp,"ARD") == 0 || MdaUtils.compareTo(dsp,"BF") == 0 || MdaUtils.compareTo(dsp,"TPD") == 0 || MdaUtils.compareTo(dsp,"CCD") == 0 || MdaUtils.compareTo(dsp,"NOD") == 0 ) {
                    ret = true;
                }
                break;
            case "GI":
            case "NI":
                if( MdaUtils.compareTo(dsp,"LOD") == 0 || MdaUtils.compareTo(dsp,"TPD") == 0 || MdaUtils.compareTo(dsp,"SPD") == 0 || MdaUtils.compareTo(dsp,"SCD") == 0 || MdaUtils.compareTo(dsp,"ARD") == 0 || MdaUtils.compareTo(dsp,"CCD") == 0 ) {
                    ret = true;
                }
                break;
            case "BO":
            case "BE":
                if( MdaUtils.compareTo(dsp,"LOC") == 0 || MdaUtils.compareTo(dsp,"TPC") == 0 || MdaUtils.compareTo(dsp,"SPC") == 0 || MdaUtils.compareTo(dsp,"ARC") == 0 || MdaUtils.compareTo(dsp,"BF") == 0 || MdaUtils.compareTo(dsp,"INC") == 0 ) {
                    ret = true;
                }
                break;
            case "CC":
                if( MdaUtils.compareTo(dsp,"LOC") == 0 || MdaUtils.compareTo(dsp,"TPC") == 0 || MdaUtils.compareTo(dsp,"SPC") == 0 || MdaUtils.compareTo(dsp,"ARC") == 0 || MdaUtils.compareTo(dsp,"FIC") == 0 ) {
                    ret = true;
                }
                break;
            case "BT":
                if( MdaUtils.compareTo(dsp,"LOC") == 0 || MdaUtils.compareTo(dsp,"TPC") == 0 || MdaUtils.compareTo(dsp,"SPC") == 0 || MdaUtils.compareTo(dsp,"ARC") == 0 || MdaUtils.compareTo(dsp,"PAC") == 0 ) {
                    ret = true;
                }
                break;
            case "GE":
            case "NE":
                if( MdaUtils.compareTo(dsp,"LOC") == 0 || MdaUtils.compareTo(dsp,"TPC") == 0 || MdaUtils.compareTo(dsp,"SPC") == 0 || MdaUtils.compareTo(dsp,"ARC") == 0 ) {
                    ret = true;
                }
                break;
            case "BP":
                if( MdaUtils.compareTo(dsp,"LOC") == 0 || MdaUtils.compareTo(dsp,"TPC") == 0 || MdaUtils.compareTo(dsp,"SPC") == 0 || MdaUtils.compareTo(dsp,"ARC") == 0 || MdaUtils.compareTo(dsp,"BF") == 0 ) {
                    ret = true;
                }
                break;
        }
        switch( transName ) {
            case "CPTOPN":
                if( MdaUtils.compareTo(dsp,"LOD") == 0 || MdaUtils.compareTo(dsp,"TPD") == 0 || MdaUtils.compareTo(dsp,"SPD") == 0 || MdaUtils.compareTo(dsp,"SCD") == 0 || MdaUtils.compareTo(dsp,"ARD") == 0 || MdaUtils.compareTo(dsp,"FID") == 0 || MdaUtils.compareTo(dsp,"BF") == 0 ) {
                    ret = true;
                }
                break;
            case "CPTADV":
                if( MdaUtils.compareTo(dsp,"LOC") == 0 || MdaUtils.compareTo(dsp,"TPC") == 0 || MdaUtils.compareTo(dsp,"SPC") == 0 || MdaUtils.compareTo(dsp,"CCC") == 0 || MdaUtils.compareTo(dsp,"ARC") == 0 || MdaUtils.compareTo(dsp,"FIC") == 0 ) {
                    ret = true;
                }
                break;
        }
        return ret;
    }

    @Override
    public BigDecimal gettxccy(String transName, List<SetgllVo> setGllList,String accmod,String payrol) {
        BigDecimal ghAplAmt = null;
        String rolStr = NULLSTR;
        String dspStr = NULLSTR;
        String actStr = NULLSTR;
        BigDecimal amt = null;
        String deb = NULLSTR;
        String gllGrp = NULLSTR;
        switch( Strings.mid(transName,1,2) ) {
            case "BR":
            case "BC":
            case "GI":
            case "NI":
                //  $GhAplAmt = \\BOPMOD\\BOPGRP\\REC\\LCYAMT + \\BOPMOD\\BOPGRP\\REC\\FCYAMT + \\BOPMOD\\BOPGRP\\REC\\OTHAMT
                break;
            case "BO":
            case "BE":
            case "CC":
            case "CP":
            case "GE":
            case "NE":
            case "BT":
            case "BP":
                ghAplAmt = new BigDecimal("0.00");
                for(SetgllVo setGll : setGllList){
                    rolStr = setGll.getRol();
                    dspStr = setGll.getDsp();
                    actStr = setGll.getAct();
                    amt = setGll.getAmt();
                    deb = setGll.getDebcdtflg();
                    gllGrp = setGll.getGllgrp();
                    //国内费用如果选择了seperate,在收支申报信息中不体现
                    //选中seperte时，$GllGrp为F
                    switch( Strings.mid(transName,1,2) ) {
                        case "BO":
                        case "BE":
                        case "CC":
                        case "GE":
                        case "NE":
                            //  if TXTCheckRol( $TranName, $RolStr ) and Mid( $ActStr, 7, 4 ) = "2120" and TXTCheckDSP( $TranName, $DspStr ) then
                            if( this.txtCheckRol(transName, rolStr,accmod,payrol) && MdaUtils.compareTo(Strings.mid(actStr,7,4),"2120") == 0 && txtCheckDSP( transName, dspStr ) && MdaUtils.compareTo(gllGrp,"F") != 0 ) {
                                ghAplAmt = ghAplAmt.add(Numerics.abs(amt));
                            }
                            break;
                        case "BT":
                        case "BP":
                            // if TXTCheckRol( $TranName, $RolStr ) and TXTCheckDSP( $TranName, $DspStr ) then
                            if( txtCheckRol( transName, rolStr,accmod,payrol ) && txtCheckDSP( transName, dspStr ) && MdaUtils.compareTo(gllGrp,"F") != 0 ) {
                                ghAplAmt = ghAplAmt.add(Numerics.abs(amt));
                            }
                            break;
                        case "CP":
                            switch(transName) {
                                case "CPTOPN":
                                    /**
                                     if TXTCheckRol( $TranName, $RolStr ) and Mid( $ActStr, 7, 4 ) == "2120" and $Deb == "C" then

                                     **/
                                    // if ( $RolStr = "BU2" or $RolStr = "BU1" ) and Mid( $ActStr, 7, 4 ) = "2120" and $Deb = "C" then
                                    if( txtCheckRol( transName, rolStr ,accmod,payrol) && ( MdaUtils.compareTo(Strings.mid(actStr,7,4),"2120") == 0 || MdaUtils.compareTo(Strings.mid(actStr,7,4),"2149") == 0 ) && MdaUtils.compareTo(deb,"C") == 0 && MdaUtils.compareTo(gllGrp,"F") != 0 ) {
                                        ghAplAmt = ghAplAmt.add(Numerics.abs(amt));
                                    }
                                    break;
                                case "CPTADV":
                                    //  if TXTCheckRol( $TranName, $RolStr ) and Mid( $ActStr, 7, 4 ) = "2120" and $Deb = "D" then
                                    //accmod为G时为原td CPTREP交易
                                    if("G".equals(accmod)){
                                        if( txtCheckRol( transName, rolStr,accmod,payrol ) && MdaUtils.compareTo(Strings.mid(actStr,7,4),"2149") == 0 && MdaUtils.compareTo(deb,"D") == 0 && MdaUtils.compareTo(gllGrp,"F") != 0 ) {
                                            ghAplAmt = ghAplAmt.add(Numerics.abs(amt));
                                        }
                                    }else {
                                        if (txtCheckRol(transName, rolStr, accmod,payrol) && MdaUtils.compareTo(Strings.mid(actStr, 7, 4), "2120") == 0 && MdaUtils.compareTo(deb, "D") == 0 && MdaUtils.compareTo(gllGrp, "F") != 0) {
                                            ghAplAmt = ghAplAmt.add(Numerics.abs(amt));
                                        }
                                    }
                                    break;
                            }
                            break;
                    }
                }
                break;
        }
        return Numerics.round(ghAplAmt,0);
    }

    @Override
    public BigDecimal getactuccy(String transName, List<SetgllVo> setGllList,String docprbrol) {
        String rolStr = NULLSTR;
        BigDecimal amt = new BigDecimal("0.00");
        for(SetgllVo setGll : setGllList){
            rolStr = setGll.getRol();
            BigDecimal setGllAmt = setGll.getAmt();
            if( this.actCheckRol ( transName, rolStr, docprbrol) ) {
                amt = amt.add(setGllAmt);
            }
        }
        return  Numerics.round(Numerics.abs(amt),0);
    }

    @Override
    public BigDecimal getoutchargeccy(String transName, List<SetfelVo> setFelList, List<SetfolVo> setFolList,String cur,List<PtsFeeDetailVo> ptydet) {
        transName = transName.toUpperCase();
        BigDecimal outAmt = new BigDecimal("0.00");
        String rolStr = NULLSTR;
        String curStr = NULLSTR;
        BigDecimal amt = null;
        String dspStr = NULLSTR;
        if( MdaUtils.compareTo(transName,"CPTADV") == 0 || MdaUtils.compareTo(transName,"CPTOPN") == 0 ) {
            // 境内外收入bopgat模型里需要手填，境内外汇款boprem不涉及扣费
//            return  Platform.round(Platform.abs(Platform.getContentNumeric(this,"\\CPDGRP\\REC\\FEEAMT")),0);
            return BigDecimal.ZERO;
        } else {
            switch( Strings.mid(transName,1,2) ) {
                case "BR":
                case "BC":
                case "GI":
                case "NI":
                    for(SetfelVo setfelVo : setFelList){
                        rolStr = setfelVo.getRol();
                        curStr = setfelVo.getCur();
                        amt = setfelVo.getAmt();
                        dspStr = setfelVo.getDsp();
                        if( outCHCheck( transName, rolStr, curStr, dspStr, amt,cur,ptydet) ) {
                            outAmt = outAmt.add(amt);
                        }
                    }
                    break;
                default:
                    for(SetfolVo setfolVo : setFolList){
                        rolStr = setfolVo.getPtydbt();
                        curStr = setfolVo.getCur();
                        amt = setfolVo.getAmt();
                        dspStr = setfolVo.getDsp();
                        if( outCHCheck( transName, rolStr, curStr, dspStr, amt,cur,ptydet) ) {
                            outAmt = outAmt.add(amt);
                        }
                    }
            }
        }
        return  Numerics.round(outAmt,0);
    }

    @Override
    public boolean outCHCheck(String transName, String rol, String curr, String dsp, BigDecimal amt,String cur,List<PtsFeeDetailVo> ptydet) {
        transName = transName.toUpperCase();
        BigDecimal zero = BigDecimal.ZERO;
        boolean ret = false;
        String bus = Strings.mid(transName.toUpperCase(),1,2);
        switch( bus ) {
            case "LI":
            case "BR":
            case "BC":
                if( this.bopCheckRol(transName, rol) && MdaUtils.compareTo(dsp,"X") == 0 && amt.compareTo(zero) != 0 && MdaUtils.compareTo(curr,cur) == 0  && !isSeperateFEE(rol,ptydet)) {
                    ret = true;
                }
                break;
                /**
                 case "BO", "BE", "CC", "GE"
                 if dsp == "X" and amt <> 0 and curr == GetTranCur( trnnam ) and not isSeperateFEE( Rol ) then
                 $ret = TRUE
                 endif

                 **/
                //----xxf与程秋敏对国外收费角色重新核对后修改----
            case "BO":
                if( MdaUtils.compareTo(rol,"DRR") == 0 && MdaUtils.compareTo(dsp,"X") == 0 && amt.compareTo(zero) != 0 && MdaUtils.compareTo(curr,cur) == 0 && !isSeperateFEE(rol,ptydet)) {
                    ret = true;
                }
                break;
            case "BE":
            case "GE":
            case "NE":
                if( MdaUtils.compareTo(rol,"BEN") == 0 && MdaUtils.compareTo(dsp,"X") == 0 && amt.compareTo(zero) != 0 && MdaUtils.compareTo(curr,cur) == 0 && !isSeperateFEE(rol,ptydet)) {
                    ret = true;
                }
                break;
            case "CC":
                if( MdaUtils.compareTo(rol,"PRE") == 0 && MdaUtils.compareTo(dsp,"X") == 0 && amt.compareTo(zero) != 0 && MdaUtils.compareTo(curr,cur) == 0 && !isSeperateFEE(rol,ptydet)) {
                    ret = true;
                }
                //-----------------
                //程秋敏的需求，转让信用证中只对BE1收国外费用
                break;
            case "BT":
                if( MdaUtils.compareTo(rol,"BE1") == 0 && MdaUtils.compareTo(dsp,"X") == 0 && amt.compareTo(zero) != 0 && MdaUtils.compareTo(curr,cur) == 0 && !isSeperateFEE(rol,ptydet)) {
                    ret = true;
                }
                break;
            case "GI":
            case "NI":
                if( MdaUtils.compareTo(rol,"APL") == 0 && MdaUtils.compareTo(dsp,"X") == 0 && amt.compareTo(zero) != 0 && MdaUtils.compareTo(curr,cur) == 0 && !isSeperateFEE(rol,ptydet)) {
                    ret = true;
                }
                break;
        }
        return ret;
    }

    @Override
    public boolean isSeperateFEE(String rol,List<PtsFeeDetailVo> ptydet) {
        PtsFeeDetailVo ptsFeeDetailInfo = null;
        for(PtsFeeDetailVo ptsFeeDetailVo : ptydet){
            if(MdaUtils.compareTo(ptsFeeDetailVo.getRol(),rol) == 0){
                ptsFeeDetailInfo = ptsFeeDetailVo;
                break;
            }
        }
        if(!MdaUtils.isEmpty(ptsFeeDetailInfo)){
            if(MdaUtils.compareTo(ptsFeeDetailInfo.getGlggrpflg(),"F") == 0){
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean actCheckRol(String transName, String rol,String docprbrol) {
        boolean ret = false;
        String bus = Strings.mid(transName.toUpperCase(),1,2);
        switch( bus ) {
            case "LI":
                if( MdaUtils.compareTo(rol,"PRB") == 0 ) {
                    ret = true;
                }
                break;
            case "BR":
            case "GI":
            case "NI":
                if( MdaUtils.compareTo(rol,docprbrol) == 0 ) {
                    ret = true;
                }
                break;
            case "BC":
                /**
                 if Rol == "DRR" then

                 **/
                if( MdaUtils.compareTo(rol,"RMI") == 0 ) {
                    ret = true;
                }
                break;
        }
        return ret;
    }

    @Override
    public boolean txtCheckRol(String transName, String rol,String accmod,String payrol) {
        boolean ret = false;
        String bus = Strings.mid(transName,1,2);
        switch( bus ) {
            case "BO":
            case "CC":
                if( MdaUtils.compareTo(rol,"COL") == 0 ) {
                    ret = true;
                }
                break;
            case "BE":
                //  if Rol = "ISS" or Rol = "AVB" or Rol = "OTH" then
                if( MdaUtils.compareTo(rol,"ISS") == 0 || MdaUtils.compareTo(rol,"AVB") == 0 || MdaUtils.compareTo(rol,"OTH") == 0 || MdaUtils.compareTo(rol,"ADV") == 0 ) {
                    ret = true;
                }
                break;
            case "BT":
                if( MdaUtils.compareTo(rol,"BE1") == 0 ) {
                    ret = true;
                }
                break;
            case "CP":
                if( MdaUtils.compareTo(transName,"CPTADV") == 0 ) {
                    /**
                     if Rol == "SND" then

                     **/
                    //accmod为G时为原td CPTREP交易
                    if("G".equals(accmod)){
                        if( MdaUtils.compareTo(rol,"ORC") == 0 ) {
                            ret = true;
                        }
                    }else {
                        if (MdaUtils.compareTo(rol, "SND") == 0 || MdaUtils.compareTo(rol, "ORC") == 0) {
                            ret = true;
                        }
                    }
                }
                if( MdaUtils.compareTo(transName,"CPTOPN") == 0 ) {
                    if( MdaUtils.compareTo(rol,"PYE") == 0 || MdaUtils.compareTo(rol,"DFF") == 0 ) {
                        ret = true;
                    }
                }
                break;
            case "BP":
                //   if Rol = "FIA" or Rol = "BU1" or Rol = "BU2" then
                if( MdaUtils.compareTo(rol,"BU1") == 0 || MdaUtils.compareTo(rol,"BU2") == 0 ) {
                    ret = true;
                }
                break;
            case "GE":
            case "NE":
                if(MdaUtils.compareTo(rol,payrol) == 0){
                    ret = true;
                }
                break;
        }
        return ret;
    }

    @Override
    public boolean txtCheckDSP(String transName, String dsp) {
        boolean ret = false;
        String bus = Strings.mid(transName,1,2);
        switch( bus ) {
            case "PC":
            case "BO":
            case "BE":
            case "GE":
            case "NE":
                if( MdaUtils.compareTo(dsp,"LOD") == 0 || MdaUtils.compareTo(dsp,"TPD") == 0 || MdaUtils.compareTo(dsp,"SPD") == 0 ) {
                    ret = true;
                }
                break;
            case "BT":
                if( MdaUtils.compareTo(dsp,"LOC") == 0 || MdaUtils.compareTo(dsp,"TPC") == 0 || MdaUtils.compareTo(dsp,"SPC") == 0 ) {
                    ret = true;
                }
                break;
            case "CC":
                if( MdaUtils.compareTo(dsp,"LOD") == 0 || MdaUtils.compareTo(dsp,"TPD") == 0 || MdaUtils.compareTo(dsp,"SPD") == 0 || MdaUtils.compareTo(dsp,"NOD") == 0 ) {
                    ret = true;
                }
                break;
            case "BP":
                if( MdaUtils.compareTo(dsp,"LOD") == 0 || MdaUtils.compareTo(dsp,"TPD") == 0 || MdaUtils.compareTo(dsp,"SPD") == 0 || MdaUtils.compareTo(dsp,"BF") == 0 ) {
                    ret = true;
                }
                break;
        }
        return ret;
    }

    @Override
    public BigDecimal getchargeFamt(String transName, BigDecimal outChargeAmt) {
        BigDecimal outAmt = BigDecimal.ZERO;
        if(MdaUtils.isEmpty(outChargeAmt)){
            outChargeAmt = BigDecimal.ZERO;
        }
        if( MdaUtils.compareTo(transName,"CPTADV") == 0 || MdaUtils.compareTo(transName,"CPTOPN") == 0 ) {
            outAmt = Numerics.round(Numerics.abs(outChargeAmt),0);
        }else {
            switch( Strings.mid(transName,1,2) ) {
                case "BE":
                case "BO":
                case "GE":
                case "NE":
                case "CC":
                    outAmt = Numerics.round(Numerics.abs(outChargeAmt),0);
                    break;
            }
        }
        return outAmt;
    }

    @Override
    public String getBopTmpRef() {
        String bustyp = "DVP";
        String etyExtkey = SettleContext.getUserSession().getEty().getExtkey();
        String couNam = etyExtkey + bustyp;
        String couVal = MdaUtils.toString(counterService.dbCounter(couNam),-6);
        String ownRef = couNam + Strings.mid(MdaUtils.toString(Dates.getYear(Dates.today()),-4),3,2) + couVal;
        return ownRef;
    }

    @Override
    public Date getCoreSysDay() {
        return Dates.today();
    }

    @Override
    public int tenortext(String transName, int tenmaxday) {
        if( this.checkTenorBool(transName.toUpperCase())) {
            return tenmaxday;
        }else{
            return 0;
        }

    }

    @Override
    public boolean checkTenorBool(String transName) {
        boolean ret = false;
        String bus = Strings.mid(transName.toUpperCase(),1,2);
        /**
         #There have no tenor days in standard 505version
         TenorDir = ""
         return $ret

         **/
        switch( bus ) {
            case "BR":
                ret = true;
                break;
            case "BC":
                ret = true;
                break;
            default:
                ret = false;
        }
        return ret;
    }

    @Override
    public boolean ischeckacc(CommetItems commetItems, String lcyacc, String fcyacc, String othacc) {
        boolean ischeck = false;
        String lcyacclen = Strings.toUpper(Strings.mid(lcyacc,1,3));
        String fcyacclen = Strings.toUpper(Strings.mid(fcyacc,1,3));
        String othacclen = Strings.toUpper(Strings.mid(othacc,1,3));
        String acchea = "-NRA-FTN-FTF-FTU-";
        if( Strings.pos(acchea,lcyacclen) > 0 || Strings.pos(acchea,fcyacclen) > 0 || Strings.pos(acchea,othacclen) > 0 ) {
            return true;
        }else {
            //防止空对象
            if(!MdaUtils.isEmpty(commetItems.getV72())){
                String v72 = Strings.trim(this.getBlockText(commetItems.getV72()));
                if(this.ispospayment(v72)){
                    return true;
                }
            }

            if(!MdaUtils.isEmpty(commetItems.getCommet())){
                if(this.ispospayment(commetItems.getCommet())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getFuynh2())){
                if(this.ispospayment(commetItems.getFuynh2())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getFuynh3())){
                if(this.ispospayment(commetItems.getFuynh3())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getFuynh4())){
                if(this.ispospayment(commetItems.getFuynh4())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getFuyns1())){
                if(this.ispospayment(commetItems.getFuyns1())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getFuyns2())){
                if(this.ispospayment(commetItems.getFuyns2())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getFuyns3())){
                if(this.ispospayment(commetItems.getFuyns3())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getFuyns4())){
                if(this.ispospayment(commetItems.getFuyns4())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getCovfuy1())){
                if(this.ispospayment(commetItems.getCovfuy1())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getCovfuy2())){
                if(this.ispospayment(commetItems.getCovfuy2())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getCovfuy3())){
                if(this.ispospayment(commetItems.getCovfuy3())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getCovfuy4())){
                if(this.ispospayment(commetItems.getCovfuy4())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getFecomm())){
                if(this.ispospayment(commetItems.getFecomm())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getAttcommet())){
                if(this.ispospayment(commetItems.getAttcommet())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getAttcommet72())){
                if(this.ispospayment(commetItems.getAttcommet72())){
                    return true;
                }
            }
            if(!MdaUtils.isEmpty(commetItems.getContag72())){
                if(this.ispospayment(commetItems.getContag72())){
                    return true;
                }
            }
        }
        return ischeck;
    }

    @Override
    public String getCorNM(List<PtsptaVo> ptsList, String feecorrol) {
        String rolName = "";
        PtsptaVo ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(ptsList, feecorrol);
        if (!MdaUtils.isEmpty(ptsptaVo)) {
            rolName = ptsptaVo.getNam();
        }
        return rolName;
    }

    @Override
    public String getact(String transName, String orcact) {
        if( MdaUtils.isEmpty(orcact) ) {
            if( MdaUtils.compareTo(transName,"CCTSET") == 0 || MdaUtils.compareTo(transName,"BOTSET") == 0 ) {
                orcact = "000000";
            }
        }
        return orcact;
    }

//    @Override
//    public String getBopdecRptno(RptnoRequestVo rptnoRequestVo) {
//        String rptno = rptnoRequestVo.getRptno();
//        String ref = "";
//        //!产生业务编号
//        String gs = NULLSTR;
//        String custype = rptnoRequestVo.getCustype();
//        String ownextkey = rptnoRequestVo.getOwnextkey();
//        String typ = rptnoRequestVo.getTyp();
//        String transName = rptnoRequestVo.getTransname().toUpperCase();
//        String dectyp = ctlmodService.setDectyp(transName);
//        String hndtyp = rptnoRequestVo.getHndtyp();
//        if( MdaUtils.isEmpty(custype)) {
//            return  ref;
//        }else {
//            if( MdaUtils.compareTo(custype,"C") == 0 ) {
//                gs = "C";
//            }else {
//                gs = "F";
//            }
//            if( MdaUtils.isEmpty(ownextkey)) {
//                return ref;
//            }
//        }
//        Date reldat = null;
//        if( MdaUtils.compareTo(dectyp,"I") == 0 || MdaUtils.compareTo(dectyp,"P") == 0 ) {
//            //交易为info
//            reldat = rptnoRequestVo.getCtlmod().getWrkdbl().getReldat();
//        }else {
//            reldat = rptnoRequestVo.getCtlmod().getDbl().getReldat();
//            if( Dates.diff(reldat,MdaUtils.today())<0 && ! MdaUtils.isEmpty(reldat) && MdaUtils.compareTo(dectyp,"V") == 0 ) {
//                //repair回来的交易的处理
//                //新增交易要去选的日期，不用这样处理
//                reldat = MdaUtils.today();
//            }
//        }
//        if(MdaUtils.compareTo(dectyp,"V") == 0 ) {
//            if( MdaUtils.isEmpty(reldat) ) {
//                reldat = this.getCoreSysDay();
//                rptnoRequestVo.getCtlmod().getDbl().setReldat(reldat);
//            }
//        }
//        String dat = NULLSTR;
//        BopObjectType bopObjectType = this.getBOPInfobyType(transName,hndtyp,typ);
//        if( ( MdaUtils.isEmpty(rptno) || ( !MdaUtils.isEmpty(rptno) && ! validRefenence(rptnoRequestVo) ) ) && ( MdaUtils.compareTo(custype,"A") == 0 || MdaUtils.compareTo(dectyp,"M") == 0 || MdaUtils.compareTo(dectyp,"P") == 0 || MdaUtils.compareTo(dectyp,"V") == 0 ) ) {
//            dat = this.format(reldat,"YYYYMMDD");
//            if( MdaUtils.compareTo(dat,"20141009")<=0 ) {
//                ref = this.getRefmod().getBopRefold20141009 ( reldat, objtyp, gs, this.getOwnextkey(), false, "" );
//            }else{
//                ref = this.getRefmod().getBopRef ( reldat, objtyp, gs, this.getOwnextkey(), false, "" );
//            }
//            if( !MdaUtils.isEmpty(ref) ) {
//                this.setRptno( ref);
//            }
//            if( MdaUtils.isEmpty(ref) )
//            {
//                MdaUtils.exitRule();
//            }
//            if( Platform.pos(ref,"#") > 0 )
//            {
//                ctx.setFieldError(this,"rptno",MdaUtils.getI18NString("baspp","CT000037"));
//                MdaUtils.exitRule();
//                return false;
//            }
//        }
//        return null;
//    }

    public String format(Date date, String pattern) {
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        if (date != null) {
            return dateFormat.format(date);
        }else {
            return null;
        }
    }

//    public boolean validRefenence(RptnoRequestVo rptnoRequestVo) {
//        //取得上下文
//        IContext ctx = MdaEnv.getContext();
//        ctx.setErrorCode(NO_ERROR);
//        //!校验业务编号
//        if( MdaUtils.isEmpty(this.getRptno()) )
//        {
//            return  false;
//        }
//        String gs = NULLSTR;
//        if( MdaUtils.isEmpty(this.getCustype()) )
//        {
//            return  false;
//        }
//        else
//        {
//            if( Platform.compareTo(this.getCustype(),"C") == 0 )
//            {
//                gs = "C";
//            }
//            else
//            {
//                gs = "F";
//            }
//            if( MdaUtils.isEmpty(this.getOwnextkey()) )
//            {
//                return  false;
//            }
//        }
//        Date reldat = null;
//        if( Platform.compareTo(ctx.absGet(Ctlmod.class).getDectyp(),"I") == 0 || Platform.compareTo(ctx.absGet(Ctlmod.class).getDectyp(),"P") == 0 )
//        {  //交易为info
//            reldat = ctx.absGet(Ctlmod.class).getWrkdbl().getReldat();
//        }
//        else
//        {
//            reldat = ctx.absGet(Ctlmod.class).getDbl().getReldat();
//            if( MdaUtils.diff(reldat,MdaUtils.today())<0 && ! MdaUtils.isEmpty(reldat) && Platform.compareTo(ctx.absGet(Ctlmod.class).getDectyp(),"V") == 0 )
//            {
//                reldat = MdaUtils.today();
//            }
//        }
//        String typ = NULLSTR;
//        if( Platform.compareTo(ctx.absGet(Ctlmod.class).getDectyp(),"V") == 0 )
//        {
//            typ = Platform.getContent(this,"\\BOPMOD\\TYP");
//            if( MdaUtils.isEmpty(reldat) )
//            {
//                return  false;
//            }
//        }
//        else
//        {
//            typ = Platform.getContent(this,"\\TYP");
//        }
//        String objtyp = NULLSTR;
//        String path = NULLSTR;
//        String bastyp = NULLSTR;
//        String dcltyp = NULLSTR;
//        String vrftyp = NULLSTR;
//        String dat = NULLSTR;
//        String ref = NULLSTR;
//        if( ctx.getErrorCode() == 0 )
//        {
//            Argument<String> objtypBox = new Argument<String>();
//            Argument<String> pathBox = new Argument<String>();
//            Argument<String> bastypBox = new Argument<String>();
//            Argument<String> dcltypBox = new Argument<String>();
//            Argument<String> vrftypBox = new Argument<String>();
//            ctx.absGet(Ctlmod.class).getBOPInfobyType ( typ, objtypBox, pathBox, bastypBox, dcltypBox, vrftypBox );
//
//            objtyp = objtypBox.value;
//            path = pathBox.value;
//            bastyp = bastypBox.value;
//            dcltyp = dcltypBox.value;
//            vrftyp = vrftypBox.value;
//
//            dat = MdaUtils.format(reldat,"YYYYMMDD");
//            if( Platform.compareTo(dat,"20141009")<=0 )
//            {
//                ref = this.getRefmod().getBopRefold20141009 ( reldat, objtyp, gs, this.getOwnextkey(), true, this.getRptno() );
//            }
//            else
//            {
//                ref = this.getRefmod().getBopRef ( reldat, objtyp, gs, this.getOwnextkey(), true, this.getRptno() );
//            }
//            if( Platform.compareTo(ref,this.getRptno()) == 0 )
//            {
//                return  true;
//            }
//            else
//            {
//                return  false;
//            }
//        }
//        else
//        {
//            this.setRptno(NULLSTR);
//            return  false;
//        }
//
//    }

    @Override
    public Map<String, BopObjectType> registerBOPObjectTypes(String transName, String hndtyp) {
        Map<String,BopObjectType> output = new HashMap<>();
        String sname = Strings.mid(transName,1,2);
        //判断保函为进口类业务还是出口类业务
        sname = BopUtils.judgeGIType(transName,hndtyp);
        switch( sname ) {
            case  "BO":
            case  "BE":
            case  "BT":
            case  "GE":
            case  "NE":
            case  "CC":
            case  "BP":
            case  "CP":
                output.put("GAT1",new BopObjectType("GAT1","DBA","E","N","N","涉外收入申报单－基础信息"));
                output.put("GAT2",new BopObjectType("GAT2","DBA","E","E","N","涉外收入申报单－基础信息&申报信息(境外)"));
                output.put("GAT3",new BopObjectType("GAT3","DBA","E","N","E","涉外收入申报单－基础信息&核销信息(境外)"));
                output.put("GAT4",new BopObjectType("GAT4","DBA","E","E","E","涉外收入申报单－基础信息&申报信息(境外)//出口收汇核销专用联（境外收入）核销信息"));
                output.put("GAT5",new BopObjectType("GAT5","DBD","E","N","N","出口收汇核销专用联（境内收入）基础信息"));
                output.put("GAT6",new BopObjectType("GAT6","DBD","E","N","E","出口收汇核销专用联（境内收入）基础信息&核销信息"));
                break;
        }
        return output;
    }

    @Override
    public Map<String, BopObjectType> registerBoppayObjectTypes(String transName, String hndtyp) {
        Map<String,BopObjectType> output = new HashMap<>();
        String sname = Strings.mid(transName,1,2);
        //判断保函为进口类业务还是出口类业务
        sname = BopUtils.judgeGIType(transName,hndtyp);
        switch( sname ) {
            case "BR":
            case "BC":
            case "GI":
            case "NI":
                output.put("PAY1",new BopObjectType("PAY1","DBC", "E", "N", "N", "对外付款/承兑通知书－基础信息" ));
                output.put("PAY2",new BopObjectType("PAY2","DBC", "E", "E", "N", "对外付款/承兑通知书－基础信息&申报信息(特殊经济区域企业/境外)" ));
                output.put("PAY3",new BopObjectType("PAY3","DBC", "E", "N", "E", "对外付款/承兑通知书－基础信息&核销信息(特殊经济区域企业/境外)" ));
                output.put("PAY4",new BopObjectType("PAY4","DBC", "E", "E", "E", "对外付款/承兑通知书(非特殊经济区域企业/境外)" ));
                output.put("PAY5",new BopObjectType("PAY5","DBF", "E", "N", "N", "境内付款/承兑通知书－基础信息(特殊经济区域企业/境内)" ));
                output.put("PAY6",new BopObjectType("PAY6","DBF", "E", "N", "E", "境内付款/承兑通知书(非特殊经济区域企业/境内)" ));
                break;
        }
        return output;
    }

    @Override
    public Map<String, BopObjectType> registerBopremObjectTypes(String transName, String hndtyp) {
        Map<String,BopObjectType> output = new HashMap<>();
        output.put("REM1",new BopObjectType("REM1","DBB", "E", "N", "N", "境外汇款申请书－基础信息" ));
        output.put("REM2",new BopObjectType("REM2","DBB", "E", "E", "N", "境外汇款申请书－基础信息&申报信息" ));
        output.put("REM3",new BopObjectType("REM3","DBB", "E", "E", "E", "境外汇款申请书－基础信息&申报信息&核销信息" ));
        output.put("REM4",new BopObjectType("REM4","DBE", "E", "N", "E", "境内汇款申请书－基础信息&核销信息" ));
        output.put("REM5",new BopObjectType("REM5","DBE", "E", "N", "N", "境内汇款申请书－基础信息" ));
        return output;
    }

    @Override
    public String getBopdecTyp(String boptyp,String szflg, String basflg, String dclflg, String vrfflg) {
        String typ = "";
        if("BOPGAT".equals(boptyp)) {
            if("1".equals(szflg)) {
                if ("X".equals(basflg) && "X".equals(dclflg) && "X".equals(vrfflg)) {
                    typ = "GAT4";
                } else if ("X".equals(basflg) && "".equals(dclflg) && "X".equals(vrfflg)) {
                    typ = "GAT3";
                } else if ("X".equals(basflg) && "X".equals(dclflg) && "".equals(vrfflg)) {
                    typ = "GAT2";
                } else if ("X".equals(basflg) && "".equals(dclflg) && "".equals(vrfflg)) {
                    typ = "GAT1";
                }
            }
            if("2".equals(szflg)){
                if("X".equals(basflg) && "".equals(dclflg) && "X".equals(vrfflg)){
                    typ = "GAT6";
                }else if("X".equals(basflg) && "".equals(dclflg) && "".equals(vrfflg)){
                    typ = "GAT5";
                }
            }
        }
        if("BOPREM".equals(boptyp)) {
            if("1".equals(szflg)) {
                if ("X".equals(basflg) && "X".equals(dclflg) && "X".equals(vrfflg)) {
                    typ = "REM3";
                } else if ("X".equals(basflg) && "X".equals(dclflg) && "".equals(vrfflg)) {
                    typ = "REM2";
                } else if ("X".equals(basflg) && "".equals(dclflg) && "".equals(vrfflg)) {
                    typ = "REM1";
                }
            }
            if("2".equals(szflg)){
                if("X".equals(basflg) && "".equals(dclflg) && "X".equals(vrfflg)){
                    typ = "REM4";
                }else if("X".equals(basflg) && "".equals(dclflg) && "".equals(vrfflg)){
                    typ = "REM5";
                }
            }
        }
        if("BOPPAY".equals(boptyp)) {
            if("1".equals(szflg)) {
                if ("X".equals(basflg) && "X".equals(dclflg) && "X".equals(vrfflg)) {
                    typ = "PAY4";
                } else if ("X".equals(basflg) && "".equals(dclflg) && "X".equals(vrfflg)) {
                    typ = "PAY3";
                } else if ("X".equals(basflg) && "X".equals(dclflg) && "".equals(vrfflg)) {
                    typ = "PAY2";
                } else if ("X".equals(basflg) && "".equals(dclflg) && "".equals(vrfflg)) {
                    typ = "PAY1";
                }
            }
            if("2".equals(szflg)){
                if("X".equals(basflg) && "".equals(dclflg) && "X".equals(vrfflg)){
                    typ = "PAY6";
                }else if("X".equals(basflg) && "".equals(dclflg) && "".equals(vrfflg)){
                    typ = "PAY5";
                }
            }
        }
        return typ;
    }

    @Override
    public BopObjectType getBOPInfobyType(String transName,String hndtyp,String typ) {
        Map<String,BopObjectType> map = this.registerBOPObjectTypes(transName,hndtyp);
        return map.get(typ);
    }

    @Override
    public BopObjectType getBoppayInfobyType(String transName, String hndtyp, String typ) {
        Map<String,BopObjectType> map = this.registerBoppayObjectTypes(transName,hndtyp);
        return map.get(typ);
    }

    @Override
    public BopObjectType getBopremInfobyType(String transName, String hndtyp, String typ) {
        Map<String,BopObjectType> map = this.registerBopremObjectTypes(transName,hndtyp);
        return map.get(typ);
    }

    //!生成正式流水号
    //!===================================
    //!        Dat 生成流水号的日期
    //!        Typ 申报单的类型
    //!        Gs  对公/对私
    //!	  OwnExtKey 地区机构号
    //!        valid  验证编号标志
    //!        validref 待验证编号
    //!===================================
//    @Override
//    public String getBopRefold20141009(Date dat, String typ, String gs, String ownExtKey, boolean valid, String validref) {
//        String bnkCod = "";
//        String wgbm = "";
//        //! 取外管编码: 首先取传入得地区机构号的外管编码，如果不为12位,那么取上级机构
//        //! 如果上级机构的外管编码也不为12位，提示柜员维护正确的外管编码!
//        if( MdaUtils.isEmpty(dat) ) {
//            return  "";
//        }
//        //! 取本机构的外管编码
//        Bch bch = bchMapper.selectByBranch(ownExtKey);
//        if(!MdaUtils.isEmpty(bch)){
//            wgbm = bch.getDecnum();
//        }else{
//            return "";
//        }
////        String sql = " select decnum from bch where branch='" + ownExtKey + "' ";
//        if(MdaUtils.isEmpty(wgbm)) {
//            return  "";
//        }else {
//            if(Strings.trim(wgbm).length() != 12 ) {
//                return  "";
//            }
//        }
//        String vtyp = NULLSTR;
//        if( MdaUtils.compareTo(typ.length(),1) == 0 ) {
//            vtyp = typ;
//        }else {
//            //ex:DBA DBB....
//            vtyp = Strings.mid(typ,typ.length(),1);
//        }
//        String couVal = NULLSTR;
//        String couNam = NULLSTR;
//        int counum = 0;
//        if( valid ) {
//            couVal = Strings.mid(validref,19,4);
//        }else{
//            couVal = "";
//            couNam = wgbm + typ + gs;
//            counum = Platform.dbBopCounter(couNam,dat);
//            while( Platform.compareTo(Platform.numMul(Platform.round(Platform.numDiv(counum,100),0),100),counum) == 0 )
//            {
//                counum = Platform.dbBopCounter(couNam,dat);
//            }
//            couVal = MdaUtils.toString(counum,-4);
//        }
//        String bopref = wgbm + MdaUtils.format(dat,"YYMMDD") + bopMapNumber( couVal, vtyp, gs, valid );
//        return bopref;
//        return null;
//    }

    @Override
    public String dbBopCounter(String name) {
        int counterValue = (int)counterService.dbCounter(name);
        double dCounterValue = counterValue / 100;
        int iAmt = (int)(dCounterValue + 0.5);
        while(iAmt * 100 == counterValue)
        {
            counterValue = (int)counterService.dbCounter(name);
            dCounterValue = counterValue / 100;
            iAmt = (int)(dCounterValue + 0.5);
        }
        return String.format("%04d",counterValue);
    }

    @Override
    public int dbCounterBopcou(String counam, Date dat) {
        String vcounam = Strings.trim(counam);
        return (int) serialCounterService.genSerialNumberByDb("bopcou",vcounam,dat);
    }

    @Override
    public String getNewRef(RptnoRequestVo rptnoRequestVo) {
        String rptno = rptnoRequestVo.getRptno();
        String ref = "";
        //!产生业务编号
        // dba dbd
        String bopobjtyp = rptnoRequestVo.getBopobjtyp().toLowerCase();
        String gs = "F";
        String custype = rptnoRequestVo.getCustype();
        String ownextkey = rptnoRequestVo.getOwnextkey();
        String typ = rptnoRequestVo.getTyp();
        String transName = rptnoRequestVo.getTransname().toUpperCase();
        String dectyp = ctlmodService.setDectyp(transName);
        String hndtyp = rptnoRequestVo.getHndtyp();
        if (MdaUtils.isEmpty(ownextkey)) {
            return ref;
        }
        if (MdaUtils.isEmpty(custype)) {
            return ref;
        }
        if ("C".equals(custype)) {
            gs = "C";
        }
        //判断申报日期是否填写

        Date paydat = rptnoRequestVo.getPaydat();
        if(MdaUtils.isEmpty(paydat)) {
            return ref;
        }
        //金融机构标识码
        String decnumStr="";
        Bch bch = bchMapper.selectByBranch(ownextkey);
        if(!MdaUtils.isEmpty(bch)){
            if(!MdaUtils.isEmpty(bch.getDecnum())){
                decnumStr = bch.getDecnum().trim();
            }else {
                return ref;
            }
        }else{
            return ref;
        }
        if(MdaUtils.isEmpty(rptno) || ((!MdaUtils.isEmpty(rptno) && (!this.validRptno(rptno,paydat,decnumStr))))) {
            ref = this.getBopReference(transName, decnumStr, paydat, bopobjtyp, gs);
        }else{
            ref = rptno;
        }

        //String ref = $refmod.getBopReference($\\sysmod\\bch\\decnum.getValue(), $\\mtabut\\paydat.getValue(), Platform.getTransBaseName(), gs);
        if (MdaUtils.isEmpty(ref)) {
            return ref;
        }
        //todo 需要放到别的地方
//        this.setRptno(ref);
//        MdaUtils.setEmptyImpl(this,"rptno");
//        MdaUtils.setEmptyImpl(this,"rptno");
//        ctx.absGet(Ctlmod.class).setOthRptno(ref);
        return ref;
    }


    @Override
    public String getRef(RptnoRequestVo rptnoRequestVo) {
        String rptno = rptnoRequestVo.getRptno();
        String ref = "";
        Date reldat = NULLDATE;
        //!产生业务编号
        // dba dbd
        String bopobjtyp = rptnoRequestVo.getBopobjtyp().toUpperCase();
        String gs = "F";
        String custype = rptnoRequestVo.getCustype();
        String ownextkey = rptnoRequestVo.getOwnextkey();
        String typ = rptnoRequestVo.getTyp();
        String transName = rptnoRequestVo.getTransname().toUpperCase();
        String dectyp = ctlmodService.setDectyp(transName);
        String hndtyp = rptnoRequestVo.getHndtyp();
        String dat = NULLSTR;
        Date wrkDblReldat = rptnoRequestVo.getWrkDblReldat();
        if (MdaUtils.isEmpty(ownextkey)) {
            return ref;
        }
        if (MdaUtils.isEmpty(custype)) {
            return ref;
        }
        if ("C".equals(custype)) {
            gs = "C";
        }

        if( MdaUtils.compareTo(dectyp,"I") == 0 || MdaUtils.compareTo(dectyp,"P") == 0 ) {
            //交易为info
            reldat = wrkDblReldat;
        }else if(MdaUtils.compareTo(dectyp,"A") == 0){
            reldat = rptnoRequestVo.getPaydat();
        }else {
            if(MdaUtils.compareTo(dectyp,"V") == 0){
                reldat = this.getCoreSysDay();
            }
//            reldat = ctx.absGet(Ctlmod.class).getDbl().getReldat();
//            if( Dates.diff(reldat,MdaUtils.today())<0 && ! MdaUtils.isEmpty(reldat) && MdaUtils.compareTo(dectyp,"V") == 0 ) {
//                //repair回来的交易的处理
//                //新增交易要去选的日期，不用这样处理
//                reldat = MdaUtils.today();
//            }
        }
        if( ( MdaUtils.isEmpty(rptno) || ( !MdaUtils.isEmpty(rptno) && !this.validRefenence(rptnoRequestVo) ) ) && ( MdaUtils.compareTo(dectyp,"A") == 0 || MdaUtils.compareTo(dectyp,"M") == 0 || MdaUtils.compareTo(dectyp,"P") == 0 || MdaUtils.compareTo(dectyp,"V") == 0 ) ){
            dat = this.format(reldat, "YYYYMMdd");
            if( MdaUtils.compareTo(dat,"20141009")<=0 ){
                ref = this.getBopRefold20141009(reldat,bopobjtyp,gs,ownextkey,false,"");
            }else{
                ref = this.getBopRef(reldat,bopobjtyp,gs,ownextkey,false,"");
            }
        }
        return ref;
    }

    public boolean validRefenence(RptnoRequestVo rptnoRequestVo) {
        String transName = rptnoRequestVo.getTransname().toUpperCase();
        String rptno = rptnoRequestVo.getRptno();
        String custype = rptnoRequestVo.getCustype();
        String ownextkey = rptnoRequestVo.getOwnextkey();
        String dectyp = ctlmodService.setDectyp(transName);
        Date reldat = NULLDATE;
        Date wrkDblReldat = rptnoRequestVo.getWrkDblReldat();
        String bopobjtyp = rptnoRequestVo.getBopobjtyp().toUpperCase();
        String dat = NULLSTR;
        String ref = "";
        //!校验业务编号
        if(MdaUtils.isEmpty(rptno)) {
            return  false;
        }
        String gs = NULLSTR;
        if(MdaUtils.isEmpty(custype)) {
            return  false;
        }else {
            if( MdaUtils.compareTo(custype,"C") == 0 ) {
                gs = "C";
            }else {
                gs = "F";
            }
            if(MdaUtils.isEmpty(ownextkey)) {
                return  false;
            }
        }
        if( MdaUtils.compareTo(dectyp,"I") == 0 || MdaUtils.compareTo(dectyp,"P") == 0 ) {
            //交易为info
            reldat = wrkDblReldat;
        }else {
            if(MdaUtils.compareTo(dectyp,"V") == 0){
                reldat = this.getCoreSysDay();
            }
        }
            dat = this.format(reldat,"YYYYMMdd");
            if( MdaUtils.compareTo(dat,"20141009")<=0 ) {
                ref = this.getBopRefold20141009 ( reldat, bopobjtyp, gs, ownextkey, true, rptno);
            }else {
                ref = this.getBopRef ( reldat, bopobjtyp, gs, ownextkey, true, rptno);
            }
            if( MdaUtils.compareTo(ref,rptno) == 0 ) {
                return  true;
            }else{
                return  false;
            }
    }
    /**

    /**
     * 生成正式流水号
     * Dat 生成流水号的日期
     * Typ 申报单的类型
     * Gs  对公/对私
     * OwnExtKey 地区机构号
     * valid  验证编号标志
     * validref 待验证编号
     **/
    public String getBopRefold20141009(Date dat,String typ,String gs,String ownExtKey,boolean valid,String validref){
        String bnkCod = "";
        String wgbm = "";
        String ref = "";
        String couVal = NULLSTR;
        String couNam = NULLSTR;
        int counum = 0;
        if(MdaUtils.isEmpty(dat)){
            return ref;
        }
        Bch bch = bchMapper.selectByBranch(ownExtKey);
        if(!MdaUtils.isEmpty(bch)){
            if(!MdaUtils.isEmpty(bch.getDecnum())){
                wgbm = bch.getDecnum().trim();
            }else {
                return ref;
            }
        }else{
            return ref;
        }
        if(typ.length() != 1){
            typ = Strings.mid(typ,typ.length());
        }
        if( valid ) {
            couVal = Strings.mid(validref,19,4);
        }else{
            couNam = wgbm + typ + gs;
//            counum = this.dbCounterBopcou(couNam,dat);
            counum = counterBopdecService.dbBopdecCounter(couNam,dat);
            couVal = MdaUtils.toString(counum,-4);
        }
        ref = wgbm + this.format(dat,"YYMMdd") + bopMapNumber( couVal, typ, gs, valid );
        return ref;
    }

    /**
     * 生成正式流水号
     * Dat 生成流水号的日期
     * Typ 申报单的类型
     * Gs  对公/对私
     * OwnExtKey 地区机构号
     * valid  验证编号标志
     * validref 待验证编号
     **/
    public String getBopRef(Date dat,String typ,String gs,String ownExtKey,boolean valid,String validref){
        String bnkCod = "";
        String wgbm = "";
        String ref = "";
        String couVal = NULLSTR;
        String couNam = NULLSTR;
        int counum = 0;
        if(MdaUtils.isEmpty(dat)){
            return ref;
        }
        Bch bch = bchMapper.selectByBranch(ownExtKey);
        if(!MdaUtils.isEmpty(bch)){
            if(!MdaUtils.isEmpty(bch.getDecnum())){
                wgbm = bch.getDecnum().trim();
            }else {
                return ref;
            }
        }else{
            return ref;
        }
        if(typ.length() != 1){
            typ = Strings.mid(typ,typ.length());
        }
        if( valid ) {
            couVal = Strings.mid(validref,19,4);
        }else{
            couNam = wgbm + typ + gs;
//            counum = this.dbCounterBopcou(couNam,dat);
            counum = counterBopdecService.dbBopdecCounter(couNam,dat);
            //18号文需求，允许申报号流水中使用部分字母
            switch(typ) {
                case "D":
                    couVal = this.changetypeD10to33( counum,4);
                    break;
                case "E":
                case "F":
                    couVal = this.changetypeEF10to33( counum, 4 );
                    break;
                case "A":
                case "B":
                case "C":
                    couVal = this.tdchange10to33( counum, 4 );
                    break;
                case "J":
                case "W":
                    couVal = this.changetypeJW10to33( counum, 4 );
                    break;
                default:
                    couVal = MdaUtils.toString(counum,-4);
            }
            //----------X000时候，流水顺延+1-------------
            while( MdaUtils.compareTo(Strings.mid(couVal,2),"000") == 0 ) {
//                counum = this.dbCounterBopcou(couNam,dat);
                counum = counterBopdecService.dbBopdecCounter(couNam,dat);
                switch(typ) {
                    case "D":
                        couVal = this.changetypeD10to33( counum, 4 );
                        break;
                    case "E":
                    case "F":
                        couVal = this.changetypeEF10to33( counum, 4 );
                        break;
                    case "A":
                    case "B":
                    case "C":
                        couVal = this.tdchange10to33( counum, 4 );
                        break;
                    case "J":
                    case "W":
                        couVal = this.changetypeJW10to33( counum, 4 );
                        break;
                    default:
                        couVal = MdaUtils.toString(counum,-4);
                }
            }
        }
        ref = wgbm + this.format(dat,"YYMMdd") + bopMapNumberNew( couVal, typ, gs, valid );
        return ref;
    }

    /**
     * 按照外管规定生成申报号码的后四位(根据18号文修正)
     * @param bnno 获取的流水号(4位)
     * @param typ 业务编号的类型
     * @param gs 对公/对私
     * @param valid
     * @return 业务流水号的后四位
     * 1.根据申报类型和gs得到当前类型可用的标志位$bopstr
     * 2.调整收支申报流水号产生规则
     * AC 涉外收入申报单对公：P001-PYYY
     * A  涉外收入申报单对私：U001-U2YY
     * DC 境内收入申报单对公：0001-0YY9
     * D  境内收入申报单对私：4001-49Y9
     * BC 境外汇款申请书对公：A001-AYYY
     * B  境外汇款申请书对私：J001-J9YY
     * EC 境内汇款申请书对公：001A-9YYA
     * E  境内汇款申请书对私：001E-9YYE
     * CC 对外付款/承兑申请书对公：E001-EYYY
     * C  对外付款/承兑申请书对私：L001-L1YY
     * FC 境内付款/承兑申请书对公：001K-9YYK
     * F  境内付款/承兑申请书对私：001Q-9YYE
     * J  账户内结汇:001W-199W
     * W  账户内售汇:001Y-199Y
     */
    public String bopMapNumberNew(String bnno,String typ,String gs,boolean valid) {
        String bopstr = NULLSTR;
        switch( typ ) {
            case "A":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "P";
                }else {
                    bopstr = "U";
                }
                break;
            case "B":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "A";
                }else {
                    bopstr = "J";
                }
                break;
            case "C":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "EFG";
                }else {
                    bopstr = "L";
                }
                break;
            case "D":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "0";
                }else {
                    bopstr = "4";
                }
                break;
            case "E":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "A";
                }else {
                    bopstr = "E";
                }
                break;
            case "F":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "KLMN";
                }else {
                    bopstr = "QRS";
                }
                break;
            case "J":
                bopstr = "W";
                break;
            case "W":
                bopstr = "Y";
                break;
        }
        //2.根据当前流水判断该取第几个标志位$bnno
        String str = " ";
        String returnstr = "";
        String v1stNum = Strings.mid(bnno,1,1);
        if(!valid) {
            if( Strings.pos("0123456789",v1stNum) == 0 ) {
                return "";
            }
        }
        //非数字默认返回0
        if(Strings.pos("0123456789",v1stNum) == 0){
            v1stNum = "0";
        }
        BigDecimal vbnno = Strings.parseDecimal(v1stNum).add(new BigDecimal(1));
        //3.得到流水号$returnstr
        if(valid) {
            if( MdaUtils.compareTo(typ,"E") == 0 || MdaUtils.compareTo(typ,"F") == 0 ) {
                if( Strings.pos(bopstr,Strings.mid(bnno,4,1)) > 0 ) {
                    returnstr = bnno;
                }else {
                    returnstr = "####";
                }
            }else {
                if( Strings.pos(bopstr,Strings.mid(bnno,1,1)) > 0 ) {
                    returnstr = bnno;
                }else {
                    returnstr = "####";
                }
            }
        }else {
            str = bopNumToStrNew( bopstr, vbnno );
            if( MdaUtils.compareTo(typ,"E") == 0 || MdaUtils.compareTo(typ,"F") == 0 || MdaUtils.compareTo(typ,"J") == 0 || MdaUtils.compareTo(typ,"W") == 0 ) {
                returnstr = Strings.mid(bnno,2,3) + str;
            }else {
                returnstr = str + Strings.mid(bnno,2,3);
            }
        }
        /*
        //!涉外收入申报单对公流水号分配值为P001-PUYY
        if( MdaUtils.compareTo(Strings.mid(returnstr,1,1),"P") == 0 ) {
            if( Strings.pos("0123456789ABCDEFGHJKLMNPQRSTU",Strings.mid(returnstr,2,1)) == 0 ) {
                //number >31580
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000034"));
                MdaUtils.exitRule();
            }
        }
        //!涉外收入申报单对私流水号分配值为U001-U0YY
        if( MdaUtils.compareTo(Strings.mid(returnstr,1,1),"U") == 0 ) {
            if( Strings.pos("0",Strings.mid(returnstr,2,1)) == 0 ) {
                //number >1088
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000035"));
                MdaUtils.exitRule();
            }
        }
        //!境内收入申报单对公流水号分配值为0001-0MY9
        if( MdaUtils.compareTo(typ,"D") == 0 && MdaUtils.compareTo(gs,"C") == 0 && MdaUtils.compareTo(Strings.mid(returnstr,1,1),"0") == 0 ) {
            if( Strings.pos("0123456789ABCDEFGHJKLM",Strings.mid(returnstr,2,1)) == 0 ) {
                //number >7259
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000036"));
                MdaUtils.exitRule();
            }
        }
        //!境内收入申报单对私流水号分配值为4001-45Y9
        if( MdaUtils.compareTo(typ,"D") == 0 && MdaUtils.compareTo(gs,"F") == 0 && MdaUtils.compareTo(Strings.mid(returnstr,1,1),"4") == 0 ) {
            if( Strings.pos("012345",Strings.mid(returnstr,2,1)) == 0 ) {
                //number >1979
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000037"));
                MdaUtils.exitRule();
            }
        }
        //!境外汇款申报单对公流水号分配值为A001-AUYY
        if( MdaUtils.compareTo(Strings.mid(returnstr,1,1),"A") == 0 ) {
            if( Strings.pos("0123456789ABCDEFGHJKLMNPQRSTU",Strings.mid(returnstr,2,1)) == 0 ) {
                //number >31580
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000038"));
                MdaUtils.exitRule();
            }
        }
        //!境外汇款申报单对私流水号分配值为J001-J5YY
        if( MdaUtils.compareTo(Strings.mid(returnstr,1,1),"J") == 0 ) {
            if( Strings.pos("012345",Strings.mid(returnstr,2,1)) == 0 ) {
                //number >6533
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000039"));
                MdaUtils.exitRule();
            }
        }
        //!境内汇款申报单对公流水号分配值为001A-5YYA
        // 加报文类型判断
        if( MdaUtils.compareTo(typ,"E") == 0 && MdaUtils.compareTo(gs,"C") == 0 ) {
            if( Strings.pos("012345",Strings.mid(returnstr,1,1)) == 0 ) {
                //number >6533
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000040"));
                MdaUtils.exitRule();
            }
        }
        //!境内汇款申报单对私流水号分配值为001E-5YYE
        // 加报文类型判断
        if( MdaUtils.compareTo(typ,"E") == 0 && MdaUtils.compareTo(gs,"F") == 0 ) {
            if( Strings.pos("012345",Strings.mid(returnstr,1,1)) == 0 ) {
                //number >6533
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000041"));
                MdaUtils.exitRule();
            }
        }
        //!对外付款/承兑申报单对公流水号分配值为E001-EYYY
        if( MdaUtils.compareTo(typ,"C") == 0 && MdaUtils.compareTo(gs,"C") == 0 ) {
            if( Strings.pos("E",Strings.mid(returnstr,1,1)) == 0 ) {
                //number >35936
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000043"));
                MdaUtils.exitRule();
            }
        }
        //!对外付款/承兑申报单对私流水号分配值为L001-L1YY
        if( MdaUtils.compareTo(Strings.mid(returnstr,1,1),"L") == 0 ) {
            if( Strings.pos("01",Strings.mid(returnstr,2,1)) == 0 ) {
                //number >2177
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000046"));
                MdaUtils.exitRule();
            }
        }
        //!境内付款/承兑申报单对公流水号分配值为001K-9YYK
        if( MdaUtils.compareTo(typ,"F") == 0 && MdaUtils.compareTo(gs,"C") == 0 ) {
            if( Strings.pos("K",Strings.mid(returnstr,4,1)) == 0 ) {
                //number >10889
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000044"));
                MdaUtils.exitRule();
            }
        }
        //!境内付款/承兑申报单对私流水号分配值为001Q-9YYQ
        if( MdaUtils.compareTo(typ,"F") == 0 && MdaUtils.compareTo(gs,"F") == 0 ) {
            if( Strings.pos("Q",Strings.mid(returnstr,4,1)) == 0 ) {
                //number >10889
                Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000045"));
                MdaUtils.exitRule();
            }
        }
        //! 账户内结汇： 001W-199W
        if( MdaUtils.compareTo(typ,"J") == 0 && Strings.pos("01",Strings.mid(returnstr,1,1)) == 0 ) {
            //number >199
            Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000047"));
            MdaUtils.exitRule();
        }
        //!账户内售汇：001Y-199Y
        if( MdaUtils.compareTo(typ,"W") == 0 && Strings.pos("01",Strings.mid(returnstr,1,1)) == 0 ) {
            //number >199
            Platform.errorMessage(MdaUtils.getI18NString("refmod","CT000048"));
            MdaUtils.exitRule();
        }

         */
        return returnstr;
    }

    /**
     * 申报号码中数字与字母的对应
     * @param bopstr 字母对应表
     * @param num 对应数字
     * @return 申报号码的字母位
     */
    public String bopNumToStrNew(String bopstr,BigDecimal num) {
        String posstr = Strings.mid(bopstr,num.intValue(),1);
        if( MdaUtils.isEmpty(posstr) )
        {
            posstr = "#";
        }
        return posstr;

    }

    public String changetypeD10to33(int num,int numLen) {
        String a = "0123456789ABCDEFGHJKLMNPQRSTUVWXY";
        int vnum = num;
        int v01 = 1;
        int v02 = 10;
        int v03 = 330;
        int v04 = 10890;
        int a1 = 0;
        int a2 = 0;
        int a3 = 0;
        int a4 = 0;
        String v3301 = "0";
        String v3302 = "0";
        String v3303 = "0";
        String v3304 = "";
        if(vnum / v04 >= 1 ) {
            a4 = (int)(vnum / v04);
            vnum = vnum - v04 * a4;
            v3304 = Strings.mid(a,a4 + 1,1);
        }
        if( vnum / v03 >= 1 ) {
            a3 = (int)(vnum / v03);
            vnum = vnum - v03 * a3;
            v3303 = Strings.mid(a,a3 + 1,1);
        }
        if(vnum / v02 >= 1 ) {
            a2 = (int)(vnum / v02);
            vnum = vnum - v02 * a2;
            v3302 = Strings.mid(a,a2 + 1,1);
        }
        if(vnum / v01 >= 1 ) {
            a1 = (int)(vnum / v01);
            vnum = vnum - v01 * a1;
            v3301 = Strings.mid(a,a1 + 1,1);
        }
        if( MdaUtils.compareTo(v3304,"") == 0 ) {
            v3304 = "0";
        }
        String result = v3304 + v3303 + v3302 + v3301;
        return result;
    }

    public String changetypeEF10to33(int num,int numLen) {
        String a = "0123456789ABCDEFGHJKLMNPQRSTUVWXY";
        int vnum = num;
        int v01 = 1;
        int v02 = 33;
        int v03 = 1089;
        int v04 = 10890;
        int a1 = 0;
        int a2 = 0;
        int a3 = 0;
        int a4 = 0;
        String v3301 = "0";
        String v3302 = "0";
        String v3303 = "0";
        String v3304 = "";
        if(vnum / v04 >= 1 ) {
            a4 = (int)(vnum / v04);
            vnum = vnum - v04 * a4;
            v3304 = Strings.mid(a,a4 + 1,1);
        }
        if( vnum / v03 >= 1 ) {
            a3 = (int)(vnum / v03);
            vnum = vnum - v03 * a3;
            v3303 = Strings.mid(a,a3 + 1,1);
        }
        if(vnum / v02 >= 1 ) {
            a2 = (int)(vnum / v02);
            vnum = vnum - v02 * a2;
            v3302 = Strings.mid(a,a2 + 1,1);
        }
        if(vnum / v01 >= 1 ) {
            a1 = (int)(vnum / v01);
            vnum = vnum - v01 * a1;
            v3301 = Strings.mid(a,a1 + 1,1);
        }
        if( MdaUtils.compareTo(v3304,"") == 0 ) {
            v3304 = "0";
        }
        String result = v3304 + v3303 + v3302 + v3301;
        return result;
    }

    /**
     * 将10进制数转换为33进制数的txt形式
     * @param num 10进制数num
     * @param numLen 目标text的位数，此处默认为4
     * @return num的33进制数的txt形式
     * description 采用除数取余法，将num除以33，直到商数为0,后将余数倒序排列
     */
    public String tdchange10to33(int num,int numLen) {
        int quoNum = 0; //商数
        int remNum = 0; //余数
        numLen = 4;
        quoNum = (int)(num / 33);
        remNum = num - quoNum * 33;
        String result = get33HexNum( remNum );
        int quoNum1 = 0;
        while( quoNum != 0 ) {
            quoNum1 = (int)(quoNum / 33);
            remNum = quoNum - quoNum1 * 33;
            result = get33HexNum( remNum ) + result;
            quoNum = quoNum1;
        }
        String txt = NULLSTR;
        if( MdaUtils.compareTo(result.length(),numLen)>0 ) {
            result = "####";
        }else{
            txt = "0000" + result;
            result = Strings.mid(txt,txt.length() - 3);
        }
        return result;
    }

    /**
     * 得到32以内的数字对应的33进制数
     * @param num 十进制数num
     * @return num对应的33进制数
     */
    public String get33HexNum(int num) {
        String v33HexNums = "0123456789ABCDEFGHJKLMNPQRSTUVWXY";
        String v33num = Strings.mid(v33HexNums,num+1,1);
        return v33num;
    }

    public String changetypeJW10to33(int num,int numLen) {
        String a = "0123456789ABCDEFGHJKLMNPQRSTUVWXY";
        int vnum = num;
        int v01 = 1;
        int v02 = 33;
        int v03 = 1089;
        int v04 = 10890;
        int a1 = 0;
        int a2 = 0;
        int a3 = 0;
        int a4 = 0;
        String v3301 = "0";
        String v3302 = "0";
        String v3303 = "0";
        String v3304 = "";
        if(vnum / v04 >= 1 ) {
            a4 = (int)(vnum / v04);
            vnum = vnum - v04 * a4;
            v3304 = Strings.mid(a,a4 + 1,1);
        }
        if( vnum / v03 >= 1 ) {
            a3 = (int)(vnum / v03);
            vnum = vnum - v03 * a3;
            v3303 = Strings.mid(a,a3 + 1,1);
        }
        if(vnum / v02 >= 1 ) {
            a2 = (int)(vnum / v02);
            vnum = vnum - v02 * a2;
            v3302 = Strings.mid(a,a2 + 1,1);
        }
        if(vnum / v01 >= 1 ) {
            a1 = (int)(vnum / v01);
            vnum = vnum - v01 * a1;
            v3301 = Strings.mid(a,a1 + 1,1);
        }
        if( MdaUtils.compareTo(v3304,"") == 0 ) {
            v3304 = "0";
        }
        String result = v3304 + v3303 + v3302 + v3301;
        return result;
    }

    /**
     * 按照外管规定生成申报号码的后四位
     * @param bnno 获取的流水号(4位)
     * @param typ 业务编号的类型
     * @param gs 对公/对私
     * @param valid
     * @return 业务流水号的后四位
     */
    public String bopMapNumber(String bnno,String typ,String gs,boolean valid) {
        String str = " ";
        String returnstr = "";
//        BigDecimal vbnno = Platform.numAdd(Strings.parseDecimal(Strings.mid(bnno,1,1)),1);
        BigDecimal vbnno = Strings.parseDecimal(Strings.mid(bnno,1,1)).add(new BigDecimal(1));
        String bopstr = NULLSTR;
        switch( typ ) {
            case "A":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "PQRS";
                }else {
                    bopstr = "U";
                }
                break;
            case "B":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "AB";
                }else{
                    bopstr = "J";
                }
                break;
            case "C":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "EFG";
                }else{
                    bopstr = "L";
                }
                break;
            case "D":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "0123";
                }else{
                    bopstr = "4";
                }
                break;
            case "E":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "ABC";
                }else{
                    bopstr = "EF";
                }
                break;
            case "F":
                if( MdaUtils.compareTo(gs,"C") == 0 ) {
                    bopstr = "KLMN";
                }else {
                    bopstr = "QRS";
                }
                break;
            case "J":
                bopstr = "W";
                break;
            case "W":
                bopstr = "Y";
                break;
        }
        if( valid ) {
            if( MdaUtils.compareTo(typ,"E") == 0 || MdaUtils.compareTo(typ,"F") == 0 ) {
                if( Strings.pos(bopstr,Strings.mid(bnno,4,1)) > 0 ) {
                    returnstr = bnno;
                }else{
                    returnstr = "####";
                }
            }else {
                if( Strings.pos(bopstr,Strings.mid(bnno,1,1)) > 0 ) {
                    returnstr = bnno;
                }else {
                    returnstr = "####";
                }
            }
        }else {
            str = bopNumToStr( bopstr, vbnno );
            if( MdaUtils.compareTo(typ,"E") == 0 || MdaUtils.compareTo(typ,"F") == 0 || MdaUtils.compareTo(typ,"J") == 0 || MdaUtils.compareTo(typ,"W") == 0 ) {
                returnstr = Strings.mid(bnno,2,3) + str;
            }else {
                returnstr = str + Strings.mid(bnno,2,3);
            }
        }
        //外收入申报单-对私部分的流水号由U001-U999,调整为U001-U499
        if( MdaUtils.compareTo(Strings.mid(returnstr,1,1),"U") == 0 ) {
            if( MdaUtils.compareTo(Strings.parseDecimal(Strings.mid(returnstr,2,1)),5)>=0 ) {
                //number >=500
                return "";
            }
        }
        return returnstr;
    }

    /**
     * 申报号码中数字与字母的对应
     * @param bopstr 字母对应表
     * @param num 对应数字
     * @return 申报号码的字母位
     */
    public String bopNumToStr(String bopstr,BigDecimal num) {
        String posstr = Strings.mid(bopstr,num.intValue(),1);
        return posstr;

    }

    /**
          * 生成收支申报号码
          - finCode 外管编码
          - bopDate 生成流水日期
          - bopType 申报类型
          - custType 对公/对私
          @ String 收支申报号码
     **/
    public String getBopReference(String transName,String finCode,Date bopDate,String bopType,String custType){
        String bopobjtyp = bopType;
//        if(bopType.length() > 1)
//            bopType = bopType.substring(bopType.length() - 1,bopType.length());
//        bopType = bopType.toUpperCase();
////        String counterName = finCode + bopType + custType;
//        String counterName = finCode.substring(0,5) + bopType + custType;
//        String counterValue = this.dbBopCounter(counterName);
        String str = getBopRptFlowNumber(bopobjtyp,custType, bopDate, finCode);
        if(MdaUtils.isEmpty(str)) {
            return "";
        }else {
            return finCode + this.format(bopDate, "yyMMdd") + str;
        }
    }

    /**
			  * 按照外管局规定生成申报号码后四位
			  - transName 交易名称
			  - custType C:对公  D,F：对私
			  - flowDate 流水号记号日期
			  @ String 申报号码后四位
     **/
    @Override
    public String getBopRptFlowNumber(String bopobjtyp, String custType, Date flowDate, String finCode) {
        String transType = bopobjtyp.toLowerCase();
        String key = NULLSTR;
        String limit = NULLSTR;
        switch (transType){
            case "dba":
                key = boprptnoConfig.getDbakey();
                limit = boprptnoConfig.getDbalimit();
                break;
            case "dbb":
                key = boprptnoConfig.getDbbkey();
                limit = boprptnoConfig.getDbblimit();
                break;
            case "dbc":
                key = boprptnoConfig.getDbckey();
                limit = boprptnoConfig.getDbclimit();
                break;
            case "dbd":
                key = boprptnoConfig.getDbdkey();
                limit = boprptnoConfig.getDbdlimit();
                break;
            case "dbe":
                key = boprptnoConfig.getDbekey();
                limit = boprptnoConfig.getDbelimit();
                break;
            case "dbf":
                key = boprptnoConfig.getDbfkey();
                limit = boprptnoConfig.getDbflimit();
                break;
            case "dbj":
                key = boprptnoConfig.getDbjkey();
                break;
            case "dbw":
                key = boprptnoConfig.getDbwkey();
                break;
        }
        //0721
        // 由于报送平台系统对结售汇、收支申报的申报编号流水号，仅仅是以日期为单位计数，现根据外管局文档要求需要以机构号+日期为单位计数，应此调整流水对应CNT中的NAM生成规则：
        //'$'+objtyp(小写)+pub/pri(小写，对公对私说明，可选，如果存在)+金融机构代码（申报号1-12位）+6位日期（YYMMDD）
        //String flowKey = transType + "-rptno" + Platform.format(flowDate,"yyyyMMdd");
        String flowKey = "|$" + transType;
        //带逗号的为对公对私分开记流水号的项目
        if(!MdaUtils.isEmpty(key) && key.contains(",")) {
            if("C".equals(custType)) {
                flowKey += "pub";
            } else {
                flowKey += "pri";
            }
        }
        flowKey += finCode;
        flowKey += this.format(flowDate,"yyMMdd");

//        int flowId = this.dbCounterBopcou(flowKey,flowDate);
        int flowId = counterBopdecService.dbBopdecCounter(flowKey,flowDate);
        //申报号码应该从001开始，平台会从000开始
        //if(flowId%1000 == 0)
        // flowId = Platform.dbCounter(flowKey);
        //通过配置文件获取起始值
        if(key.contains(",")) {
            String[] words = key.split(",");
            // 对公
            if("C".equals(custType)) {
                key = words[0];
            }else {
                key = words[1];
            }
        }
        //获取最大值
        if(limit.contains(",")) {
            String[] words = limit.split(",");
            // 对公
            if("C".equals(custType)) {
                limit = words[0];
            }else {
                limit = words[1];
            }
        }
        //DBA  DBB  DBC 可以用起始值的四位进行转换
        if("dba".equals(transType)||"dbb".equals(transType)||"dbc".equals(transType)) {
            //将起始值转换为 10 进制
            int starnum = Strings.parseInt(this.change33to10(key));
            //将最大值 转换为 10 进制
            int limitnum = Strings.parseInt(this.change33to10(limit));
            //将最小值加上流水号，判断是否超过最大值
            int maxnum = starnum + flowId;
            if(maxnum >= limitnum) {
                return "";
            }
            //将增量后的 10 进制转为 33 进制
            String lastnum = this.change10to33(maxnum);
            return lastnum;
        }
        //单独处理 DBD
        if("dbd".equals(transType)) {
            //将起始值转换为 10 进制
            int dbdstarnum = Strings.parseInt(this.change33to10fordbd(key));
            //将最大值 转换为 10 进制
            int dbdlimitnum = Strings.parseInt(this.change33to10fordbd(limit));
            //将最小值加上流水号，判断是否超过最大值
            int dbdmaxnum = dbdstarnum + flowId;
            if(dbdmaxnum >= dbdlimitnum) {
                return "";
            }
            //将增量后的 10 进制转为 33 进制
            String dbdlastnum = this.change10to33fordbd(dbdmaxnum);
            return dbdlastnum;
        }
        //DBE  DBF  单独处理，只能用前三位进行 转换
        if("dbe".equals(transType)||"dbf".equals(transType)) {
            //截取前三位以及最后一位
            String subkey = key.substring(0,3);
            String endkey = key.substring(3,4);
            String sublimit = limit.substring(0,3);
            int efstarnum = Strings.parseInt(this.change33to10(subkey));
            //将最大值 转换为 10 进制
            int eflimitnum = Strings.parseInt(this.change33to10(sublimit));
            //将最小值加上流水号，判断是否超过最大值
            int efmaxnum = efstarnum + flowId;
            if(efmaxnum >= eflimitnum) {
                return "";
            }
            //将增量后的 10 进制转为 33 进制,返回值加上最后一位 截取后四位
            String eflastnum = this.change10to33(efmaxnum);
            eflastnum = eflastnum + endkey;
            String subeflastnum = eflastnum.substring(eflastnum.length() - 4,eflastnum.length());
            return subeflastnum;
        }
        return "";
    }

    @Override
    public boolean validRptno(String rptno, Date flowDate, String finCode) {
        if(MdaUtils.isEmpty(rptno) || rptno.length() != 22){
            return false;
        }
        String str = rptno.substring(rptno.length()-4);
        String ref = finCode + this.format(flowDate, "yyMMdd") + str;
        if(MdaUtils.compareTo(ref,rptno) == 0){
            return true;
        }
        return false;
    }

    @Override
    public Ptc getPtcInfo(String ptyinr, String boptyp) {
        if((!MdaUtils.isEmpty(ptyinr)) && (!MdaUtils.isEmpty(boptyp))){
            Ptc ptc = ptcMapper.selectByPtyinrAndTyp(ptyinr,boptyp);
            return ptc;
        }
        return null;
    }

    @Override
    public boolean isAccountZbxm(String account) {
        boolean res = false;
        if(MdaUtils.isEmpty(account)){
            return res;
        }
        InnerReq8023 req8023 = new InnerReq8023(account);
        InnerReq<InnerReq8023> innerReq8023 = new InnerReq<>(req8023);
        //调用接口
        try {
            InnerRes<InnerRes8023> innerRes8023 = accountFeign.call8023(innerReq8023);
            //分析接口返回码
            if (innerRes8023 == null) {
                log.error("查询Account8023接口结果为空, 账号为{}", account);
                return res;
            }
            if (!"AAAAAAA".equals(innerRes8023.header.code)) {
                log.error("查询Account8023接口出错{}, {}", account, innerRes8023.header.description);
                return res;
            }
            //获取接口返回信息,组装liaccvAcctVo
            if (innerRes8023.DATA != null) {
                String zhuzzh = innerRes8023.DATA.zhuzzh;
                String wjzhxz = innerRes8023.DATA.wjzhxz;
                if(MdaUtils.compareTo(zhuzzh,account) == 0 || this.isZbxm(wjzhxz)){
                    res = true;
                }
            } else {
                log.error("查询Account8023接口结果DATA为空!");
                return res;
            }
        } catch (Throwable e) {
            log.error("查询Account8023接口出错", e);
            return res;
        }
        return res;
    }

    @Override
    public boolean isValidAct(String act) {
        String actlen = Strings.toUpper(Strings.mid(act, 1, 3));
        String acchea = "-NRA-FTN-EFN_OSA";
        if (Strings.pos(acchea, actlen) > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean isValidCommet(CommetItems commetItems) {
        if(!MdaUtils.isEmpty(commetItems)) {
            if (!MdaUtils.isEmpty(commetItems.getV72())) {
                String v72 = Strings.trim(this.getBlockText(commetItems.getV72()));
                if (this.commetHasTxt(v72)) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getCommet())) {
                if (this.commetHasTxt(commetItems.getCommet())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getFuynh2())) {
                if (this.commetHasTxt(commetItems.getFuynh2())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getFuynh3())) {
                if (this.commetHasTxt(commetItems.getFuynh3())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getFuynh4())) {
                if (this.commetHasTxt(commetItems.getFuynh4())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getFuyns1())) {
                if (this.commetHasTxt(commetItems.getFuyns1())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getFuyns2())) {
                if (this.commetHasTxt(commetItems.getFuyns2())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getFuyns3())) {
                if (this.commetHasTxt(commetItems.getFuyns3())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getFuyns4())) {
                if (this.commetHasTxt(commetItems.getFuyns4())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getCovfuy1())) {
                if (this.commetHasTxt(commetItems.getCovfuy1())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getCovfuy2())) {
                if (this.commetHasTxt(commetItems.getCovfuy2())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getCovfuy3())) {
                if (this.commetHasTxt(commetItems.getCovfuy3())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getCovfuy4())) {
                if (this.commetHasTxt(commetItems.getCovfuy4())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getFecomm())) {
                if (this.commetHasTxt(commetItems.getFecomm())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getAttcommet())) {
                if (this.commetHasTxt(commetItems.getAttcommet())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getAttcommet72())) {
                if (this.commetHasTxt(commetItems.getAttcommet72())) {
                    return true;
                }
            }
            if (!MdaUtils.isEmpty(commetItems.getContag72())) {
                if (this.commetHasTxt(commetItems.getContag72())) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean commetHasTxt(String commet){
        boolean ispos = false;
        String vcommet = Strings.toUpper(commet);
        if( Strings.pos(vcommet,"NONRESIDENT") > 0 || Strings.pos(vcommet,"非居民机构账户间划转") > 0 ) {
            return true;
        }
        return  ispos;
    }

    private boolean isZbxm(String wjzhxz){
        String[] arr = {"2101","2102","2103","2104","2108","2109","2110","2111","2112","2113","2202","2301","2302","2303","2403","2410","2412","2416","2417","2418","2421","2499"};
        List<String> list = Arrays.asList(arr);
        if(list.contains(wjzhxz)){
            return true;
        }
        return false;
    }

    public String change33to10(String arg) {
        //starnum 33进制数值
        String hexnum ="0123456789ABCDEFGHJKLMNPQRSTUVWXY";
        int num = 0;
        for (int i = 0 ; i < arg.length(); i++) {
            int mi = arg.length()- i - 1;
            double pow33 = java.lang.Math.pow(33,mi);
            num += (hexnum.indexOf(arg.charAt(i))) * pow33;
        }
        String lastnum = String.valueOf(num);
        return lastnum;
    }

    public String change10to33(int sum) {
        //lastnum 10进制数据值
        String hexnum ="0123456789ABCDEFGHJKLMNPQRSTUVWXY";
        int shang =0;
        int yushu =0;
        String str = "";
        yushu = sum % 33;
        shang = (int)sum / 33;
        str = hexnum.charAt(yushu) + str;
        sum =  shang ;
        while (shang != 0) {
            yushu = sum % 33;
            shang = (int)sum / 33;
            str = hexnum.charAt(yushu) + str;
            sum = shang;
        }
        str = "0000" + str;
        String liushui = str.substring(str.length() - 4, str.length());
        return liushui;
    }

    public String change33to10fordbd(String arg) {
        //starnum 33进制数值
        //dbd 交易要求最后一位必须为0-9
        String hexnum ="0123456789ABCDEFGHJKLMNPQRSTUVWXY";
        int num = 0;
        for (int i = 0 ; i < arg.length() - 1 ; i++) {
            int mi = arg.length()- i - 2;
            double pow33 = java.lang.Math.pow(33,mi);
            num += (hexnum.indexOf(arg.charAt(i))) * pow33 * 10;
        }
        num += hexnum.indexOf(arg.charAt(arg.length() - 1));
        String lastnum = String.valueOf(num);
        return lastnum;
    }

    public String change10to33fordbd(int sum) {
        //lastnum 10进制数据值
        //dbd 交易要求最后一位必须为0-9
        String hexnum ="0123456789ABCDEFGHJKLMNPQRSTUVWXY";
        int shang =0;
        int yushu =0;
        String str = "";
        yushu = sum % 10;
        shang = (int)sum / 10;
        str = hexnum.charAt(yushu) + str;
        sum =  shang ;
        while (shang != 0) {
            yushu = sum % 33;
            shang = (int)sum / 33;
            str = hexnum.charAt(yushu) + str;
            sum = shang;
        }
        str = "0000" + str;
        String liushui = str.substring(str.length() - 4, str.length());
        return liushui;
    }

//    public int dbcounterBopCou(String counam,Date dat){
//        String vcounam = Strings.trim(counam);
//        int count = 0;
//        int cou = 0;
//    }

    //!判断附言中是否为境内非居民付款
    //!条件：附言中出现-NRA-FTN-FTF-FTU-
    //!条件：附言中出现“非居民机构账户间划转”
    public boolean ispospayment(String commet) {
        boolean ispos = false;
        String vcommet = Strings.toUpper(commet);
        if( Strings.pos(vcommet,"NRA") > 0 ) {
            return true;
        }
        if( Strings.pos(vcommet,"FTN") > 0 ) {
            return true;
        }
        if( Strings.pos(vcommet,"FTF") > 0 ) {
            return true;
        }
        if( Strings.pos(vcommet,"FTU") > 0 ) {
            return true;
        }
        if( Strings.pos(vcommet,"非居民机构账户间划转") > 0 ) {
            return true;
        }
        return  ispos;

    }

    public String getBlockText(String name){
        String vname = "";
        BufferedReader reader = new BufferedReader(new StringReader(name));
        String line;
        try {
            while ((line = reader.readLine()) != null){
                vname += line;
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return vname;
    }
}
