package com.brilliance.isc.common.util;

import com.brilliance.isc.bo.Adr;
import com.brilliance.isc.bo.Cty;
import com.brilliance.isc.bo.Pty;
import com.brilliance.isc.common.cache.adr.AdrCacheService;
import com.brilliance.isc.common.cache.pty.PtyCacheService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.trndoc.vo.DoceotVo;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.mda.dao.CtyMapper;
import com.brilliance.isc.utils.StringUtils;
import com.brilliance.mda.runtime.mda.IStream;
import com.brilliance.mda.runtime.mda.impl.StreamImpl;
import com.brilliance.mda.runtime.mda.util.Formats;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import com.brilliance.mda.runtime.mda.util.Streams;
import com.brilliance.mda.runtime.mda.util.Strings;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

@Service
public class TemplateUtils {
    public static final String CR = "\n";

    @Resource
    private PtyCacheService ptyCacheService;
    @Resource
    private CtyMapper ctyMapper;
    @Resource
    private AdrCacheService adrCacheService;
    @Autowired
    private CodetableService codetableService;


    public int getCurrentCORLineLength(String cortyp) {
        switch (cortyp) {
            case "TLX":
                return 69;
            case "FAX":
                return 69;
            case "EML":
                return 69;
            case "BOL":
                return 79;
            case "SWT":
            case "RTG":
            case "TAR":
            case "TCO":
                return -2;
            default:
                return -1;
        }
    }


    public Map<String, Object> printAddressBlock(DoceotVo doceotVo) {
        Map map = new HashMap();
        //取得上下文
        if (this.getCurrentCORLineLength(doceotVo.getCortyp()) == -2) {
            // skip adress for SWIFT
            return map;
        }
        if (this.getCurrentCORLineLength(doceotVo.getCortyp()) == -1) {
            // for letter only
            /**
             print vertical ( 40, tdUnitmm, tdPosAbsolute )
             **/
        } else {
            // for telex
            map.put("doceot.adrlin", MdaUtils.getI18NString("doceot", "CT000073"));
        }
        String blk = NULLSTR;
        String adrFmtKey = NULLSTR;
        String zipTown = NULLSTR;
        String locCty = NULLSTR;
        IStream adrStm = new StreamImpl();
        int cnt = 0;
        String lin = NULLSTR;
        if (!MdaUtils.isEmpty(doceotVo.getRcv().getAdr().getInr())) {
            blk = "";
            // TODO
            adrFmtKey = this.getAdrFormat(doceotVo, "CN"); //ctx.absGet(Trnmod.class).getOwnpts().getAdr().getLoccty()
            if (MdaUtils.isEmpty(adrFmtKey)) {
                // use default format
                // connect zip code and town 1st to start always at a new line, also if zip code is empty
                zipTown = this.xmlGetTxtSepTxt(doceotVo.getRcv().getAdr().getLoczip(), " ", doceotVo.getRcv().getAdr().getLoctxt());
                // Do not display country, if dispatch is domestic
                locCty = "";
                if (MdaUtils.compareTo(doceotVo.getRcv().getAdr().getLoccty(), "") != 0) { //ctx.absGet(Trnmod.class).getOwnpts().getAdr().getLoccty()
                    // Output of the country in entity language
                    locCty = codetableService.getTblLabel(doceotVo.getRcv().getAdr().getLoccty(),"CTYTXT", doceotVo.getDocuil());
                }
                blk = this.xmlGetTxtSepTxt("", "", doceotVo.getRcv().getAdr().getNam1());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getNam2());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getNam3());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getStr1());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getStr2());
                blk = this.xmlGetTxtSepTxt(blk, CR, zipTown);
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getLoc2());
                blk = this.xmlGetTxtSepTxt(blk, CR, locCty);
            } else {
                blk = this.getFmtAdrBlk(doceotVo, adrFmtKey);
            }
            map.put("doceot.adrlin", blk);
            // do also output free text addresses (not stored in database)
        } else {
            if (!MdaUtils.isEmpty(doceotVo.getAdrblk())) {
                Streams.streamSet(adrStm, doceotVo.getAdrblk());
                cnt = Streams.streamCount(adrStm);
                for (int i = 1; i <= cnt; i++) {
                    lin = Strings.getLine(adrStm, i);
                    // do not output empty lines
                    if (!MdaUtils.isEmpty(lin)) {
                        map.put("doceot.adrlin", lin);
                    }
                }
            }
        }
        return map;
    }

    public String getAdrFormat(DoceotVo doceotVo, String argEtyCty) {
        //! Get address format from table CTY.
        // ArgEtyCty = Country key of current entity. Get via "GetCtyOfEty".
        if (MdaUtils.isEmpty(argEtyCty)) {
            SettleExceptionUtils.sysDump("GetAdrFormat: Called with an empty country key of entity!");
        }
        Cty cty = ctyMapper.selectByCod(doceotVo.getRcv().getAdr().getLoccty());
        if (cty == null) {
            return "";
        }
        // if receiver is situated in the same country as entity
        if (MdaUtils.compareTo(doceotVo.getRcv().getAdr().getLoccty(), argEtyCty) == 0) {
            return cty.getFmtdomadrtyp();
        }
        return cty.getFmtintadrtyp();
    }

    public String xmlGetTxtSepTxt(String argTxt1, String argSep, String argTxt2) {
        //! Bind two arguments with a passed seperator.
        //! Insert seperator between argTxt1 and argTxt2.
        //! argSep = seperator, e.g. (" "), (", "), ("\\b"), (CR), (CR + CR)
        String res = "";
        if (!MdaUtils.isEmpty(argTxt1)) {
            res = argTxt1;
        }
        if (!MdaUtils.isEmpty(argTxt2)) {
            if (MdaUtils.isEmpty(res)) {
                res = argTxt2;
            } else {
                res = res + argSep + argTxt2;
            }
        }
        return res;

    }

    public String getFmtAdrBlk(DoceotVo doceotVo, String argAdrFmt) {
        //! Function for formatting the address block of the receiver
        // ArgAdrFmt = Content of fields CTY\\FMTdomADRTYP (domestic) or
        //             CTY\\FMTintADRTYP (abroad) and
        //             is filled via "GetAdrFormat".
        // Do not display country, if dispatch is domestic
        String locCty = "";
        if (MdaUtils.compareTo(doceotVo.getRcv().getAdr().getLoccty(), "") != 0) //ctx.absGet(Trnmod.class).getOwnpts().getAdr().getLoccty()
        {
            // Output of the country in entity language
            locCty = codetableService.getTblLabel(doceotVo.getRcv().getAdr().getLoccty(),"CTYTXT", doceotVo.getDocuil());
        }
        // for postal address ("A") and all other
        String strPob = this.xmlGetTxtSepTxt(doceotVo.getRcv().getAdr().getStr1(), CR, doceotVo.getRcv().getAdr().getStr2());
        String zip = doceotVo.getRcv().getAdr().getLoczip();
        String town = doceotVo.getRcv().getAdr().getLoctxt();
        String province = "";
        if (!MdaUtils.isEmpty(doceotVo.getRcv().getAdr().getLoc2())) {
            province = Strings.formatText("($1)", doceotVo.getRcv().getAdr().getLoc2());
        }
        // Location/Destination of receiver always display in capital letters, if it is international dispatch
        if (MdaUtils.compareTo(doceotVo.getRcv().getAdr().getLoccty(), "") != 0) //ctx.absGet(Trnmod.class).getOwnpts().getAdr().getLoccty()
        {
            town = Strings.toUpper(town);
            // show province in upper case too
            province = Strings.toUpper(province);
        }
        String blk = "";
        String zipTown = NULLSTR;
        switch (Strings.toUpper(argAdrFmt)) {
            // Domestic DE ["Zip Code Location" - Address or P.O. Box]
            case "A":
                blk = this.xmlGetTxtSepTxt(blk, "", doceotVo.getRcv().getAdr().getNam1());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getNam2());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getNam3());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getPtcnam());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getDpt());
                blk = this.xmlGetTxtSepTxt(blk, CR, strPob);
                blk = this.xmlGetTxtSepTxt(blk, CR, zip);
                blk = this.xmlGetTxtSepTxt(blk, " ", town);
                // Abroad ["Location Zip Code (Province)" - only Address]
                break;
            case "B":
                blk = this.xmlGetTxtSepTxt(blk, "", doceotVo.getRcv().getAdr().getNam1());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getNam2());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getNam3());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getPtcnam());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getDpt());
                blk = this.xmlGetTxtSepTxt(blk, CR, strPob);
                blk = this.xmlGetTxtSepTxt(blk, CR, town);
                blk = this.xmlGetTxtSepTxt(blk, " ", zip);
                blk = this.xmlGetTxtSepTxt(blk, " ", province);
                blk = this.xmlGetTxtSepTxt(blk, CR, locCty);
                // Domestic GB ["Location
                //               Zip Code" - only Address]
                break;
            case "C":
                blk = this.xmlGetTxtSepTxt(blk, "", doceotVo.getRcv().getAdr().getNam1());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getNam2());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getNam3());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getPtcnam());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getDpt());
                blk = this.xmlGetTxtSepTxt(blk, CR, strPob);
                blk = this.xmlGetTxtSepTxt(blk, CR, town);
                blk = this.xmlGetTxtSepTxt(blk, CR, zip);
                blk = this.xmlGetTxtSepTxt(blk, CR, locCty);
                // Abroad ["Zip Code Location (Province)" - only Address]
                break;
            case "D":
                blk = this.xmlGetTxtSepTxt(blk, "", doceotVo.getRcv().getAdr().getNam1());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getNam2());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getNam3());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getPtcnam());
                blk = this.xmlGetTxtSepTxt(blk, CR, doceotVo.getRcv().getAdr().getDpt());
                blk = this.xmlGetTxtSepTxt(blk, CR, strPob);
                // connect zip code and town 1st to start always at a new line, also if zip code is empty
                zipTown = this.xmlGetTxtSepTxt(zip, " ", town);
                blk = this.xmlGetTxtSepTxt(blk, CR, zipTown);
                blk = this.xmlGetTxtSepTxt(blk, " ", province);
                blk = this.xmlGetTxtSepTxt(blk, CR, locCty);
                break;
            default:
                // z.Z. nix
        }
        return blk;
    }

    public String xmlGetPtyNam(PtsptaVo argGrpRol) {
        String nam = "";
        if (argGrpRol != null && StringUtils.isNotEmpty(argGrpRol.getPtainr())) {
            Adr adr = adrCacheService.selectByPtaInr(argGrpRol.getPtainr());
            if (adr != null) {
                //! Get complete name of party.
                String nam1 = adr.getNam1();
                String nam2 = adr.getNam2();
                String nam3 = adr.getNam3();
                String town = adr.getLoctxt();
                nam = xmlGetTxtSepTxt(nam1, " ", nam2);
                nam = xmlGetTxtSepTxt(nam, " ", nam3);
                nam = xmlGetTxtSepTxt(nam, ", ", town);
            }
        }
        if (MdaUtils.isEmpty(nam)) {
            nam = this.ptsmodGetAdrLine(argGrpRol);
        }
        return nam;
    }

    public String xmlPrtRefLinePty(PtsptaVo argGrpRol) {
        String pty = "";
        if (argGrpRol != null && StringUtils.isNotEmpty(argGrpRol.getPtainr())) {
            Adr adr = adrCacheService.selectByPtaInr(argGrpRol.getPtainr());
            if (adr != null) {
                if (StringUtils.isNotEmpty(adr.getNam1())) {
                    pty = pty + " " + adr.getNam1();
                }
                if (StringUtils.isNotEmpty(adr.getNam2())) {
                    pty = pty + " " + adr.getNam2();
                }
                if (StringUtils.isNotEmpty(adr.getNam3())) {
                    pty = pty + " " + adr.getNam3();
                }
                if (StringUtils.isNotEmpty(adr.getLoctxt())) {
                    pty = pty + ", " + adr.getLoctxt();
                }
            }
        }
        return pty;
    }

    public String ptsmodGetAdrLine(PtsptaVo argptspta) {
        //! returns the Addressline of address ARGPTSPTA delimited by ","
        String res = "";
        String dlm = "";
        IStream adrstm = new StreamImpl();
        Streams.streamSet(adrstm, argptspta.getPts().getAdrblk());
        int cnt = Streams.streamCount(adrstm);
        String lin = NULLSTR;
        for (int i = 1; i <= cnt; i++) {
            lin = Strings.getLine(adrstm, i);
            if (!MdaUtils.isEmpty(lin)) {
                res = res + dlm + lin;
                dlm = ", ";
            }
        }
        return res;
    }

    public String adrLine(String adrblk) {
        //! returns the Addressline of address ARGPTSPTA delimited by ","
        String res = "";
        String dlm = "";
        IStream adrstm = new StreamImpl();
        Streams.streamSet(adrstm, adrblk);
        int cnt = Streams.streamCount(adrstm);
        String lin = NULLSTR;
        for (int i = 1; i <= cnt; i++) {
            lin = Strings.getLine(adrstm, i);
            if (!MdaUtils.isEmpty(lin)) {
                res = res + dlm + lin;
                dlm = ", ";
            }
        }
        return res;
    }

    public List<String> xmlPrtAPPRUL(String apprul, String Apprultxt) {
        List list = Lists.newArrayList();
        switch (Strings.toUpper(apprul)) {
            // according to applicable rule
            // used for letters of credit
            case "UCP LATEST VERSION":
                list.add("The documentary credit is subject to the version of the ICC Uniform Customs and Practice for Documentary Credits, International Chamber of Commerce, Paris, France, which is in effect on the date of issue.");
                break;
            case "EUCP LATEST VERSION":
                list.add("The documentary credit is subject to the version of the Supplement of the ICC Uniform Customs and Practice for Documentary Credits for Electronic Presentations, International Chamber of Commerce, Paris, France, which is in effect on the date of issue.");
                break;
            case "UCPURR LATEST VERSION":
                list.add("The documentary credit is subject to the version of the ICC Uniform Customs and Practice for Documentary Credits and the version of the Uniform Rules for Bank-to-Bank Reimbursements under documentary credits, International Chamber of Commerce, Paris, France, which are in effect on the date of issue.");
                break;
            case "EUCPURR LATEST VERSION":
                list.add("The documentary credit is subject to the version of the Supplement of the ICC Uniform Customs and Practice for Documentary Credits for Electronic Presentations and the version of the Uniform Rules for Bank-to-Bank Reimbursements, International Chamber of Commerce, Paris, France, which are in effect on the date of issue.");
                break;
            case "ISP LATEST VERSION":
                list.add("The standby letter of credit is subject to the version of the ICC International Standby Practices, International Chamber of Commerce, Paris, France, which is in effect on the date of issue.");
                // used for guarantees
                break;
            case "URDG":
                list.add("The guarantee is subject to the ICC Rules for Demand Guarantees, International Chamber of Commerce, Paris, France, which is in effect on the date of issue.");
                break;
            case "URCG":
                list.add("The guarantee is subject to the ICC Rules for Contract Guarantees, International Chamber of Commerce, Paris, France, which is in effect on the date of issue.");
                break;
            case "ISPR":
                list.add("The guarantee is subject to International Standby Practices.");
                break;
            case "NONE":
                list.add("The guarantee is not subject to any set of rule.");
                break;
            default:
                if (!MdaUtils.isEmpty(Apprultxt)) {
                    list.add("The contract is subject to the following rules:");
                    list.add(Apprultxt);
                }
        }
        return list;
    }

    public Map<String, Object> xmlDocStartGI(DoceotVo doceotVo, String argTitle) {
        Map<String, Object> map = new HashMap<>();
        map.putAll(xmlPrtAdrOfReceiver(doceotVo));
        map.putAll(xmlPrintTitleBold(doceotVo, argTitle));
        map.putAll(xmlPrtRefBlkGI(doceotVo));
        map.putAll(xmlPrtSalutation(doceotVo));
        return map;
    }

    public Map<String, Object> xmlPrtRefBlkGI(DoceotVo doceotVo) {
        return null;
    }

    /**
     * Dynamic.xmlPrtSalutation
     * @param doceotVo
     * @return
     */
    public Map<String, Object> xmlPrtSalutation(DoceotVo doceotVo) {
        //! is used at ordinary letters over all transactions
        // print salutation only for LETTER and TELEX
        if( getCurrentCORLineLength(doceotVo.getCortyp()) == -1
//                ||TODO--Trndoc.getDoccur().getCortyp() MdaUtils.compareTo(this.getDoccur().getCortyp(),"TLX") == 0
        ) {
            // salutation
//            TODO Systems.printTempUsing("trndoc.salutation");
        }
        return null;
    }

    /**
     * 对应原型中Dynamic.xmlPrtAdrOfReceiver() !注意添加空行!
     * map中会添加的KEY：
     * doceot.classtrx、doceot.adrlin.rec、doceot.adrlin.blk、doceot.adrlin.lin
     * @param doceotVo 面函.
     * @return map;
     */
    public Map<String, Object> xmlPrtAdrOfReceiver(DoceotVo doceotVo) {
        Map<String, Object> map = new HashMap<>();
        String snf = "";
        if( MdaUtils.compareTo(doceotVo.getDocsnf(),"LET") != 0 ) {
            snf = codetableService.getTblLabel(doceotVo.getDocsnf(), "DOCSNF", doceotVo.getDocuil());
        }
        map.put("doceot.classtrx",snf);
        if( getCurrentCORLineLength(doceotVo.getCortyp()) != -1 ) {
            map.put("doceot.adrlin.rec", MdaUtils.getI18NString("doceot","CT000073"));
        }
        String blk = NULLSTR;
        String adrFmtKey = NULLSTR;
        String zipTown = NULLSTR;
        String locCty = NULLSTR;
        IStream adrStm = new StreamImpl();
        int cnt = 0;
        String lin = NULLSTR;
        if( ! MdaUtils.isEmpty(doceotVo.getRcv().getAdr().getInr())) {
            blk = "";
            //TODO ctx.absGet(Trnmod.class).getOwnpts().getAdr().getLoccty()
            adrFmtKey = getAdrFormat(doceotVo, "" );
            if( MdaUtils.isEmpty(adrFmtKey)){
                // use default format
                // connect zip code and town 1st to start always at a new line, also if zip code is empty
                zipTown = xmlGetTxtSepTxt( doceotVo.getRcv().getAdr().getLoczip(), " ", doceotVo.getRcv().getAdr().getLoctxt());
                // Do not display country, if dispatch is domestic
                locCty = "";
                //TODO  ctx.absGet(Trnmod.class).getOwnpts().getAdr().getLoccty()
                if( MdaUtils.compareTo(doceotVo.getRcv().getAdr().getLoccty(),"") != 0 ) {
                    // Output of the country in entity language
                    locCty = codetableService.getTblLabel(doceotVo.getRcv().getAdr().getLoccty(),"CTYTXT", doceotVo.getDocuil());
                }
                blk = xmlGetTxtSepTxt( "", "", doceotVo.getRcv().getAdr().getNam1() );
                blk = xmlGetTxtSepTxt( blk, CR, doceotVo.getRcv().getAdr().getNam2() );
                blk = xmlGetTxtSepTxt( blk, CR, doceotVo.getRcv().getAdr().getNam3() );
                blk = xmlGetTxtSepTxt( blk, CR, doceotVo.getRcv().getAdr().getStr1() );
                blk = xmlGetTxtSepTxt( blk, CR, doceotVo.getRcv().getAdr().getStr2() );
                blk = xmlGetTxtSepTxt( blk, CR, zipTown );
                blk = xmlGetTxtSepTxt( blk, CR, doceotVo.getRcv().getAdr().getLoc2() );
                blk = xmlGetTxtSepTxt( blk, CR, locCty );
            } else {
                blk = getFmtAdrBlk( doceotVo, adrFmtKey );
            }
            map.put("doceot.adrlin.blk", blk);
        }  else {
            if( ! MdaUtils.isEmpty(doceotVo.getAdrblk()) ) {
                Streams.streamSet(adrStm,doceotVo.getAdrblk());
                cnt = Streams.streamCount(adrStm);
                for(int  i = 1;i <= cnt;i++) {
                    lin = Strings.getLine(adrStm,i);
                    // do not output empty lines
                    if( ! MdaUtils.isEmpty(lin) )  {
                        map.put("doceot.adrlin.lin",lin);
                    }
                }
            }
        }
        return map;
    }


    public Map<String, Object> xmlPrintTitleBold(DoceotVo doceotVo, String argTitle) {
        Map<String, Object> map = new HashMap<>();
        //! prints a bold text with an empty line
        //! most used as titel of letters
        if( ! MdaUtils.isEmpty(argTitle) ) {
            switch( getCurrentCORLineLength(doceotVo.getCortyp())) {
                case - 1:  // for Letter
                    // the text is bold with font-size = default
                    map.put("trndoc.LineBold",argTitle);
//                  注意空行 xmlPrtEmptyLine( 1 );
                    break;
                case 69:   // for Telex, Fax and eMail
                    //TODO
//                    Systems.printTemp(argTitle);
                    break;
                default: // for Swift
                    // no output of title
            }
        }
        return map;
    }

    public Map<String, Object> xmlPrtRefLine(DoceotVo doceotVo, String argText, String argValue) {
        Map<String, Object> map = new HashMap<>();
        //! Get standard line of reference.
        //! If no argValue is passed, no line of reference will be returned.
        if( ! MdaUtils.isEmpty(argValue) ) {
            switch( getCurrentCORLineLength(doceotVo.getCortyp()) ) {
                case - 1:  // for Letter
                    //TODO
//                    Systems.printTempUsing("trndoc.refLine",argText,argValue);
                    break;
                case 69:   // for Telex, Fax and eMail
                    //TODO
//                    Systems.printTemp(Strings.mid(argText + ":",1,25),argValue);
                    break;
                default: // for Swift
                    // no output of reference lines
            }
        }
        return map;
    }

    public static String moneycnsmalltobig(String number) {
        //金额小写转换为中文大写。
        //$number = str( number )
        //if the number is empty,return the null
        if (MdaUtils.isEmpty(number)) {
            return ("");
        }
        String vnumber = number;
        String l1 = "";
        String l2 = "";
        String l3 = "";
        String l4 = "";
        String rtn = "";
        String up = "";
        String dn = "";
        if ((Strings.pos(vnumber, ".") > 0)) {
            up = Strings.mid(vnumber, 1, Strings.pos(vnumber, ".") - 1);
            dn = Strings.mid(vnumber, Strings.pos(vnumber, ".") + 1, Strings.len(vnumber) - Strings.pos(vnumber, "."));
        } else {
            up = vnumber;
            // add by wwj for error handled
            dn = "";
        }
        if ((Strings.len(up) > 16)) {
            return "-1";
        }
        for (int i = 0; i <= 3; i++) {
            if ((Strings.len(up) - i > 0)) {
                l1 = Strings.mid(vnumber, Strings.len(up) - i, 1) + l1;
            }
            if ((Strings.len(up) - 4 - i > 0)) {
                l2 = Strings.mid(vnumber, Strings.len(up) - 4 - i, 1) + l2;
            }
            if ((Strings.len(up) - 8 - i > 0)) {
                l3 = Strings.mid(vnumber, Strings.len(up) - 8 - i, 1) + l3;
            }
            if ((Strings.len(up) - 12 - i > 0)) {
                l4 = Strings.mid(vnumber, Strings.len(up) - 12 - i, 1) + l4;
            }
        }
        if (!MdaUtils.isEmpty(l4)) {
            if ((MdaUtils.compareTo(ntOC(l4), "") != 0) && (MdaUtils.compareTo(ntOC(l4), MdaUtils.getI18NString("sysmod", "CT000566")) != 0)) {
                rtn = rtn + ntOC(l4) + "兆";
            }
        }
        if (!MdaUtils.isEmpty(l3)) {
            if ((MdaUtils.compareTo(ntOC(l3), "") != 0) && (MdaUtils.compareTo(ntOC(l3), MdaUtils.getI18NString("sysmod", "CT000567")) != 0)) {
                rtn = rtn + ntOC(l3) + "亿";
            }
        }
        if (!MdaUtils.isEmpty(l2)) {
            if ((MdaUtils.compareTo(ntOC(l2), "") != 0) && (MdaUtils.compareTo(ntOC(l2), MdaUtils.getI18NString("sysmod", "CT000568")) != 0)) {
                rtn = rtn + ntOC(l2) + "万";
            }
        }
        if (!MdaUtils.isEmpty(l1)) {
            if ((MdaUtils.compareTo(ntOC(l1), "") != 0) && (MdaUtils.compareTo(ntOC(l1), MdaUtils.getI18NString("sysmod", "CT000569")) != 0)) {
                rtn = rtn + ntOC(l1);
            }
        }
        //if not IsEmpty( Val( $dn ) ) then
        //why use the function Val,if the variable $dn is null,error display
        int num = 0;
        if (!MdaUtils.isEmpty(dn)) {
            num = Strings.parseInt(dn);
        }
        if (num != 0) {
            if (!MdaUtils.isEmpty(rtn)) {
                rtn = rtn + "元";
            }
            if ((MdaUtils.compareTo(dtOC(up, dn), "整") == 0)) {
                rtn = "零元整";
            } else {
                rtn = rtn + dtOC(up, dn);
            }
        } else {
            if (!MdaUtils.isEmpty(rtn)) {
                rtn = rtn + "元整";
            } else {
                rtn = "零元整";
            }
        }
        return rtn;

    }

    public static String ntOC(String number) {
        // 整数部分转成汉字
        boolean error = Strings.len(number) > 4;
        StringBuilder rtn = new StringBuilder();
        boolean iszero = true;
        int len = Strings.len(number);
        for (int i = len + 1; i <= 4; i++) {
            number = "0" + number;
        }
        //ISZERO为真则说明循环的数字若是0则可以在返回串中写零否则不能加零
        String a1 = "";
        for (int i = 4 - len + 1; i <= 4; i++) {
            a1 = Strings.mid(number, i, 1);
            switch (a1) {
                case "1":
                    iszero = true;
                    rtn.append("壹");
                    break;
                case "2":
                    iszero = true;
                    rtn.append("贰");
                    break;
                case "3":
                    iszero = true;
                    rtn.append("叁");
                    break;
                case "4":
                    iszero = true;
                    rtn.append("肆");
                    break;
                case "5":
                    iszero = true;
                    rtn.append("伍");
                    break;
                case "6":
                    iszero = true;
                    rtn.append("陆");
                    break;
                case "7":
                    iszero = true;
                    rtn.append("柒");
                    break;
                case "8":
                    iszero = true;
                    rtn.append("捌");
                    break;
                case "9":
                    iszero = true;
                    rtn.append("玖");
                    break;
                case "0":
                    if ((iszero)) {
                        rtn.append("零");
                        iszero = false;
                    }
                    break;
                default:
                    error = true;
            }
            if (iszero) {
                switch (i) {
                    case 1:
                        rtn.append("仟");
                        break;
                    case 2:
                        rtn.append("佰");
                        break;
                    case 3:
                        rtn.append("拾");
                        break;
                }
            }
        }
        if ((MdaUtils.compareTo(Strings.mid(rtn.toString(), Strings.len(rtn.toString()) - 1, 2), "零") == 0)) {
            rtn = new StringBuilder(Strings.mid(rtn.toString(), 0, Strings.len(rtn.toString()) - 2));
        }
        if ((error)) {
            return MdaUtils.getI18NString("sysmod", "CT000570");
        }
        return rtn.toString();

    }

    public static String dtOC(String up, String number) {
        // 小数部分转成汉字
        int n3 = 0;
        if (Strings.parseInt(Strings.mid(number, 3, 1)) > 4) {
            n3 = 1;
        } else {
            n3 = 0;
        }
        StringBuilder num = new StringBuilder(Strings.mid(number, 1, 1) + MdaUtils.toString(Strings.parseInt(Strings.mid(number, 2, 1)) + n3));
        StringBuilder rtn = new StringBuilder();
        boolean iszero = true;
        int len = Strings.len(num.toString());
        for (int i = len + 1; i <= 2; i++) {
            num.insert(0, "0");
        }
        if ((MdaUtils.compareTo(up, "0") == 0) && MdaUtils.compareTo(Strings.mid(num.toString(), 1, 1), "0") == 0) {
            iszero = false;
        }
        String a1 = "";
        boolean error = false;
        for (int i = 2 - len + 1; i <= 2; i++) {
            a1 = Strings.mid(num.toString(), i, 1);
            switch (a1) {
                case "1":
                    iszero = true;
                    rtn.append("壹");
                    break;
                case "2":
                    iszero = true;
                    rtn.append("贰");
                    break;
                case "3":
                    iszero = true;
                    rtn.append("叁");
                    break;
                case "4":
                    iszero = true;
                    rtn.append("肆");
                    break;
                case "5":
                    iszero = true;
                    rtn.append("伍");
                    break;
                case "6":
                    iszero = true;
                    rtn.append("陆");
                    break;
                case "7":
                    iszero = true;
                    rtn.append("柒");
                    break;
                case "8":
                    iszero = true;
                    rtn.append("捌");
                    break;
                case "9":
                    iszero = true;
                    rtn.append("玖");
                    break;
                case "0":
                    if ((iszero)) {
                        rtn.append("零");
                        iszero = false;
                    }
                    break;
                default:
                    error = true;
            }
            if (iszero) {
                switch (i) {
                    case 1:
                        rtn.append("角");
                        break;
                    case 2:
                        rtn.append("分");
                        break;
                }
            }
        }
        if ((MdaUtils.compareTo(Strings.mid(up, Strings.len(up), 1), "0") == 0) && Strings.len(up) != 1 && MdaUtils.isEmpty(rtn.toString())) {
            rtn.insert(0, "零");
        }
        if ((MdaUtils.compareTo(Strings.mid(rtn.toString(), Strings.len(rtn.toString()) - 1, 2), "零") == 0)) {
            rtn = new StringBuilder(Strings.mid(rtn.toString(), 0, Strings.len(rtn.toString()) - 2));
        }
        return rtn.toString();

    }

    public String getAddressBnk(PtsptaVo ptsptaVo)
    {
        String adress = "";
        Adr adr = adrCacheService.selectByPtaInr(ptsptaVo.getPts().getPtainr());
        if( adr!=null && ! MdaUtils.isEmpty(adr.getInr()) )
        {
            if( ! MdaUtils.isEmpty(adr.getNam1()) )
            {
                adress = Strings.trim(adr.getNam1());
            }
            if( ! MdaUtils.isEmpty(adr.getStr1()) )
            {
                adress = adress + "<br/>"+ Strings.trim(adr.getStr1());
            }
            if( ! MdaUtils.isEmpty(adr.getStr2()) )
            {
                adress = adress + "<br/>"+ Strings.trim(adr.getStr2());
            }
            if( ! MdaUtils.isEmpty(adr.getLoczip()) || ! MdaUtils.isEmpty(adr.getLoctxt()) )
            {
                adress = adress + "<br/>" + Strings.trim(adr.getLoczip()) + " " + Strings.trim(adr.getLoctxt());
            }
        }
        return  adress;
    }


    /**
     * 获取业务当事人（客户/代理行等）的信息
     *
     * 注意：若该当事人不是我行客户，比如转开的申请人或者直开受益人不是我行客户等，取pty则是错误的。
     * 临时客户不会存pty信息，但是会存adr以及pta信息
     *
     * @param advPtspta
     * @return
     */
    public Pty getptyfields(PtsptaVo advPtspta) {
        Pty pty = new Pty();
        if (advPtspta == null) {
            return pty;
        }
        String inr = "";
        if (advPtspta.getPts() != null) {
            inr = advPtspta.getPts().getPtyinr();
        }
        if(StringUtils.isEmpty(inr)){
            inr = advPtspta.getPtyinr();
        }
        if(StringUtils.isEmpty(inr)){
            return pty;
        }
        pty = ptyCacheService.getPtyById(inr);
        return pty!=null?pty:new Pty();
    }

    public String xmlFmtDat(DoceotVo doceotVo, String argDatTyp, Date argDate){
        String docUil = doceotVo.getDocuil();
        String typ = Strings.toUpper(argDatTyp);
        switch( typ )
        {
            case "L":
                return  Formats.fmtDateLong(argDate,docUil);
            case "S":
                return  Formats.fmtDateShort(argDate,docUil);
            case "N":
                return  Formats.format(argDate,docUil);
        }
        return NULLSTR;
    }
}
