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

import com.brilliance.mda.runtime.mda.CodetableItem;
import com.brilliance.mda.runtime.mda.IStream;
import com.brilliance.mda.runtime.mda.impl.Argument;
import com.brilliance.mda.runtime.mda.impl.StreamImpl;
import com.brilliance.mda.runtime.mda.util.*;
import com.brilliance.isc.bo.Fee;
import com.brilliance.isc.bo.Pty;
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.fecmod.service.FecmodService;
import com.brilliance.isc.common.liaall.service.LiaallService;
import com.brilliance.isc.common.liaall.vo.LiaallRegisterVo;
import com.brilliance.isc.common.liaall.vo.LiaallVo;
import com.brilliance.isc.common.liaallg.service.LiaallgService;
import com.brilliance.isc.common.liaallg.vo.LiaallgVo;
import com.brilliance.isc.common.liaone.service.LiaoneService;
import com.brilliance.isc.common.setfeg.fee.Wrksum;
import com.brilliance.isc.common.setfeg.service.SetfegService;
import com.brilliance.isc.common.setgll.vo.SetgllVo;
import com.brilliance.isc.common.setmod.service.SetmodService;
import com.brilliance.isc.common.setmod.vo.SetmodVo;
import com.brilliance.isc.common.transaction.help.LiaallSet;
import com.brilliance.isc.common.transaction.help.TransactionHelpService;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.common.vo.BizInfoVo;
import com.brilliance.isc.common.vo.FecVo;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.mda.dao.FeeMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

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

/**
 *
 */
@Service
public class LiaallgServiceImpl implements LiaallgService {

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

    @Autowired
    private SetmodService setmodService;

    @Autowired
    private LiaallService liaallService;

    @Autowired
    private SetfegService setfegService;

    @Autowired
    private XrtmodService xrtmodService;

    @Autowired
    private PtsptaToolComponent ptsptaToolComponent;

    @Autowired
    private FecmodService fecmodService;

    @Autowired
    private LiaoneService liaoneService;

    @Autowired
    private TransactionHelpService transactionHelpService;

    @Autowired
    private CodetableService codetableService;

    @Autowired
    private FeeMapper feeMapper;

    @Autowired
    private PtyCacheService ptyCacheService;

    /**
     *   source:liaallg.0000.script
     */
    public void defaultAcc(LiaallgVo liaallg) {
        liaallg.setAccSet(liaallg.getAcplia().getAccSet());
        String acc = liaallg.getAcplia().getCbe().getAcc();
        if (StringUtils.isEmpty(liaallg.getOldflg())) {
            if(MdaUtils.compareTo(liaallg.getAmt(),0)>0 && (!MdaUtils.isEmpty(liaallg.getRol()))) {
                if((!liaallg.isModified("acc") ) || !liaallg.getAccSet().contains(liaallg.getAcc())) {
                    liaallg.resetModified("acc");
                    liaallg.setAcc(acc);
                }
            } else {
                liaallg.setAcc("");
                liaallg.resetModified("acc");
            }
        } else {
            liaallg.setAcc(acc);
        }
    }

    /**
     *   source:liaallg.0001.script
     */
    public void defaultAcc2(LiaallgVo liaallg){
        liaallg.setAcc2Set(liaallg.getAcplia().getAcc2Set());
        String acc2 = liaallg.getAcplia().getCbe().getAcc2();
        if (StringUtils.isEmpty(liaallg.getOldflg())) {
            if(MdaUtils.compareTo(liaallg.getAmt(),0)>0 && (!MdaUtils.isEmpty(liaallg.getRol()))) {
                if((!liaallg.isModified("acc2") ) || !liaallg.getAcc2Set().contains(liaallg.getAcc2())) {
                    liaallg.resetModified("acc2");
                    liaallg.setAcc2(acc2);
                }
            } else {
                liaallg.setAcc2("");
                liaallg.resetModified("acc2");
            }
        } else {
            liaallg.setAcc2(acc2);
        }
    }

    /**
     *   source:liaallg.0002.script
     */
    public void defaultCur(LiaallgVo liaallg){
        liaallg.setCur(liaallg.getAcplia().getCbe().getCur());
    }

    /**
     *   source:liaallg.0008.script
     */
    public void defaultAcpliaLiaptyinr(LiaallgVo liaallg){
        liaallg.getAcplia().setLiaptyinr(liaallg.getLiaptyinr());
    }

    /**
     *   source:liaallg.0009.script
     */
    public void defaultExtid(LiaallgVo liaallg){
        if(StringUtils.isEmpty(liaallg.getOldflg()) ) {
            if(MdaUtils.compareTo(liaallg.getAmtchgflg(),"N") != 0) {
                if(!liaallg.isModified("extid") ) {
                    // Default Id is maturity date
                    //      EXTID = "GI"
                    // make it unique
                    //      if StreamSearch( \\LIAALL\\ALLEXTIDS, Mid( EXTID, 1, 16 ) + "/" ) > 0 then
                    //       $num = 1
                    //      while StreamSearch( \\LIAALL\\ALLEXTIDS, Mid( EXTID + Str( $num, -3 ), 1, 16 ) + "/" ) > 0 do
                    //     $num = $num + 1
                    //  wend
                    //      EXTID = EXTID + "/" + Str( $num, -3 )
                    //   endif
                }
            } else {
                liaallg.setExtid("");
            }
        } else {
            liaallg.setExtid(liaallg.getAcplia().getCbe().getExtid());
        }
        return;
    }

    /**
     *   source:liaallg.0010.script
     */
    public void defaultNam(LiaallgVo liaallgVo){
        if (StringUtils.isEmpty(liaallgVo.getLiaptyinr())) {
            liaallgVo.setNam(codetableService.getTblLabel(liaallgVo.getRol(), "ROLALL"));
        } else {
            Pty pty = ptyCacheService.getPtyById(liaallgVo.getLiaptyinr());
            if (pty != null) {
                liaallgVo.setNam(pty.getNam());
            }
        }
    }

    /**
     *   source:liaallg.0016.script
     */
    //@Default(value={"fee","fecp1.mac"},order=900)
    public void defaultFee(LiaallgVo liaallgVo){
        if (liaallgVo.getFee() != null && liaallgVo.getFee().getCod().equals(liaallgVo.getFeecod())) {
            return;
        }
        // no fee, if no amount
        if(MdaUtils.compareTo(liaallgVo.getAmt(),0) == 0
                && MdaUtils.compareTo(liaallgVo.getOldamt(),0) == 0) {
            liaallgVo.setFee(new Fee());
            return;
        }
        if(StringUtils.isEmpty(liaallgVo.getFeecod()) ) {
            liaallgVo.setFee(new Fee());
        } else {
            Fee fee = feeMapper.selectByCod(liaallgVo.getFeecod());
            if(MdaUtils.isEmpty(fee)){
                fee = new Fee();
            }
            liaallgVo.setFee(fee);
        }
    }

    /**
     *   source:liaallg.0017.script
     */
    public void defaultFeecod(LiaallgVo liaallg){
        IStream stream = setfegService.getAvbfeecod(SettleContext.getTransName(), SettleContext.getUserEtg().getExtkey());
        IStream val = new StreamImpl();
        int stmCnt = Streams.streamCount(stream);
        for(int  k = 1;k <= stmCnt;k++) {
            String line = Strings.getLine(stream, k);
            if( MdaUtils.compareTo(Strings.mid(line,1,3),Strings.mid(liaallg.getDftfeecod(),1,3)) == 0 || MdaUtils.compareTo(line,liaallg.getFeecod()) == 0 )
            {
                Streams.streamInsert(val,0,line);
            }
        }
        if( MdaUtils.isEmpty(liaallg.getPtegrp().getRec().getFeeinr()) ) {
            if(!liaallg.isModified("feecod") ) {
                liaallg.setFeecod(getDefaultFeecod(liaallg, MdaUtils.toString(val), liaallg.getPtegrp().getRec().getCovtyp()));
            }
        }
    }

    /**
     *   source:liaallg.0019.script
     */
    public void defaultPtegrpRecBegdat(LiaallgVo liaallg){
        //! the default date for start of commission calulation is OPNDAT (for guerantees: Issued on), if not set explicity by LiaallSetFeeBegdat
        //! If you want to define it differently use Default in Level 6
        // default from open date if new
        Date res = null;
        String feebegdat = NULLSTR;
        if((( MdaUtils.isEmpty(liaallg.getOldflg()) ) && (!liaallg.isModified("begdat"))) || MdaUtils.isEmpty(liaallg.getPtegrp().getRec().getBegdat())) {
            res = Dates.today();
            feebegdat = liaallService.liaallParGet ( "FEEBEGDAT", liaallg.getGrpkey() );
            if( MdaUtils.isEmpty(feebegdat) ) {
                feebegdat = liaallService.liaallParGet ( "FEEBEGDAT", "ALL" );
            }
            if(!MdaUtils.isEmpty(feebegdat)) {
                res = Utils.parseDate(feebegdat);
            } else {
                BizInfoVo rec = transactionHelpService.getLiaallSet().getRec();
                if (rec.getOpndat() == null) {
                    res = Dates.today();
                } else {
                    res = rec.getOpndat();
                }
            }
            liaallg.getPtegrp().getRec().setBegdat(res);
        }
    }

    /**
     *   source:liaallg.0020.script
     */
    public void defaultPtegrpRecRolpay(LiaallVo liaallVo, LiaallgVo liaallg){
        String values = NULLSTR;
        String rol = NULLSTR;
        boolean rolSet = false;
        if(MdaUtils.isEmpty(liaallg.getRol())) {
            liaallg.getPtegrp().getRec().setRolpay("");
        } else {
            values = "";
            for (CodetableItem role : liaallVo.getRoldsc()) {
                if (!"OWN".equals(role.getValue()) && StringUtils.isNotEmpty(role.getValue())) {
                    if (StringUtils.isEmpty(values)) {
                        values = rol;
                    } else {
                        values = values + CR + rol;
                    }
                }
            }
            // default like in settlement, except if OTHROL ist set and is same prefix
            if (!liaallg.isModified("rolpay") && StringUtils.isEmpty(liaallg.getPtegrp().getRec().getInr())) {
                rolSet = false;
                List<LiaallRegisterVo> liaallRegisters = getLiaallSet().getLiaallRegisters();
                for (LiaallRegisterVo liaallRegisterVo : liaallRegisters) {
                    List<String> othrolList = liaallRegisterVo.getOthrol();
                    for (String role : othrolList) {
                        if (role.substring(0, 2).equals(liaallg.getRol().substring(0, 2))) {
                            liaallg.getPtegrp().getRec().setRolpay(liaallg.getRol());
                            rolSet = true;
                        }
                    }
                }
                if (!rolSet) {
                    liaallg.getPtegrp().getRec().setRolpay(liaallg.getWrkfee().getRol());
                    Argument<String> pathBox = new Argument<String>("", liaallg.getPtegrp().getRec().getRolpay());
                    Argument<String> ptyinrBox = new Argument<String>();
                    Argument<String> ptainrBox = new Argument<String>();
                    SetmodVo setmod = new SetmodVo();
                    setmod.setFeeclirol(liaallVo.getFeeclirol());
                    setmod.setFeecorrol(liaallVo.getFeecorrol());
                    liaallVo.getRoldsc().forEach(role -> setmod.getRoldsc().getRows().add(role.getValue() + TAB + role.getLabel()));
                    setfegService.getrolandptxinr(setmod, pathBox, ptyinrBox, ptainrBox, liaallVo.getRec().getChato(), liaallg.getRol());

                    liaallg.getPtegrp().getRec().setRolpay(pathBox.value);
                }
            }
        }
    }

    /**
     *   source:liaallg.0021.script
     */
    public void defaultPtegrpRecExtid(LiaallgVo liaallg){
        liaallg.getPtegrp().getRec().setExtid(liaallg.getExtid());
    }

    /**
     *   source:liaallg.0022.script
     *   @Default(target="ptegrp.rec.subid",order=1000)
     */
    public void defaultPtegrpRecSubid(LiaallVo liaall, LiaallgVo liaallg){
        int maxsub = 0;
        int thisid = 0;
        if( MdaUtils.isEmpty(liaallg.getOldflg()) && ( ! MdaUtils.isEmpty(liaallg.getPtegrp().getRec().getExtid()) ) && MdaUtils.isEmpty(liaallg.getPtegrp().getRec().getInr()) ) {
            String oldmaxlinStr = liaallService.liaallParGet("LIAALLMAXOLDSUBID", "");
            if( StringUtils.isEmpty(oldmaxlinStr) ) {
                maxsub = 0;
            } else {
                maxsub = Integer.parseInt(oldmaxlinStr);
            }
            if( ! MdaUtils.isEmpty(liaallg.getPtegrp().getRec().getSubid()) ) {
                thisid = Strings.parseInt(liaallg.getPtegrp().getRec().getSubid());
                if( thisid <= maxsub ) {
                    liaallg.getPtegrp().getRec().setSubid(NULLSTR);
                }
            } else {
                String newmaclinStr = liaallService.liaallParGet("LIAALLMAXNEWSUBID", "");
                if( StringUtils.isNotEmpty(newmaclinStr) ) {
                    maxsub = Integer.parseInt(newmaclinStr);
                } else {
                    maxsub = getMaxSub(liaall);
                }
                maxsub = maxsub + 1;
                liaallg.getPtegrp().getRec().setSubid(MdaUtils.toString(maxsub,-3));
                liaallService.liaallParSet(String.valueOf(maxsub), "LIAALLMAXNEWSUBID", "");
            }
        }
    }

    /**
     *   source:liaallg.0023.script
     */
    public String getObjMod(int index) {
        return "//LIAALL//LIAALLG("+index+")//PTEGRP";
    }

    /**
     *   source:liaallg.0029.script
     */
    public void defaultAmtchgflg(LiaallgVo liaallg){
        if( MdaUtils.compareTo(Strings.mid(SettleContext.getTransName(),4,3),"EUS") == 0 ) {
            liaallg.setAmtchgflg( "N");
        }
    }
    /**
     *   source:liaallg.0073.script
     */
    public void defaultAcpliaCbeDat(LiaallgVo liaallgVo){
        //! Set booking date for CBE-Entry to Value date by default
        if(!liaallgVo.isModified("cbe.dat") && !MdaUtils.isEmpty(liaallgVo.getValdat()) ) {
            liaallgVo.getAcplia().getCbe().setDat(liaallgVo.getValdat());
        }
    }
    /**
     *   source:liaallg.0076.script
     */
    public void defaultTenday(LiaallgVo liaallg){
        if(!liaallg.isModified("tenday") && liaallg.getPtegrp().getRec().getTenday() > 0 ) {
            liaallg.setTenday( liaallg.getPtegrp().getRec().getTenday());
        }
    }

    /**
     *   source:liaallg.0077.script
     */
    public void defaultMatdat(LiaallVo liaall, LiaallgVo liaallg){
        //到期日默认到单时到期日
        String path = NULLSTR;
        Date matdat = null;
        int ignore = 0;
        if((!liaallService.liaallCBTPFXIsBalance(liaallg.getCbtpfx())) && !liaallService.tenorSettleIncludePteinr(liaall.getTenorSettles(), liaallg.getPtegrp().getRec().getInr())) {
            // if GetFramename = "BRTUDP" or GetFramename = "BDTUDP" then
            //    $matdat = GetContentDate( $path + "\\\\matdat" )
            //    $ignore = ErrorCode
            //    = $matdat
            //  else
            if(!liaallg.isModified("matdat") && MdaUtils.isEmpty(liaallg.getMatdat()) ) {
                liaallg.setMatdat(transactionHelpService.getLiaallSet().getRec().getMatdat());
                //   endif
            }
        }
    }
    /**
     *   source:liaallg.0015.script
     */
    public void calcFec(LiaallgVo liaallg, LiaallVo liaall) {
        //! FEC is reread if not modified or not mathcing with fee code
        String feeinr = liaallg.getFee().getInr();
        String fecfeeinr = liaallg.getFec().getFeeinr();
        // if no engagement, clear commission condition
        BigDecimal tirbca = null;
        String fecPtyInr = NULLSTR;
        String rolpath = NULLSTR;
        String feeKey = NULLSTR;
        Date expdat = null;
        IStream valblk = new StreamImpl();
        IStream valstm = new StreamImpl();
        int endidx = 0;
        if( ( MdaUtils.compareTo(liaallg.getAmt(),0) == 0 && MdaUtils.compareTo(liaallg.getOldamt(),0) == 0 ) ) {
            liaallg.resetModified("fec");
            liaallg.setFec(new FecVo());
        } else {
            if(!MdaUtils.isEmpty(liaallg.getLiaptyinr())) {
                if(((!liaallg.isModified("fec")) && MdaUtils.isEmpty(liaallg.getFecold()) ) || MdaUtils.compareTo(feeinr,fecfeeinr) != 0 ) {
                    BeanUtils.copyProperties(liaallg.getFee(), liaallg.getWrkfee());
                    liaallg.resetModified("fec");
                    liaallg.getWrkfee().setCod(NULLSTR);
                    tirbca = xrtmodService.sysCurEqu(liaallg.getCur(), Decimals.add(liaallg.getOldamt(),liaallg.getAmt()), Dates.today());
                    fecPtyInr = liaallg.getLiaptyinr();
                    if( MdaUtils.compareTo(liaallg.getPtegrp().getRec().getRolpay(),liaallg.getRol()) != 0 ) {
                        PtsptaVo ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(liaall.getPtsList(), liaallg.getRol());
                        if (ptsptaVo != null) {
                            fecPtyInr = ptsptaVo.getPtyinr();
                        }
                    }
                    FecVo fec = fecmodService.getFec(liaall.getRec(), null, tirbca, fecPtyInr, liaallg.getWrkfee());
                    if (fec != null) {
                        fec.setInr("");
                        liaallg.setFec(fec);
                    }
                } else {
                    MdaUtils.clear(liaallg.getFeclst());
                    Streams.streamInsert(liaallg.getFeclst(),0,liaallg.getFec().getInr() + TAB + liaallg.getFec().getFeepri() + TAB);
                }
                liaallg.getFec().setFeeinr(liaallg.getFee().getInr());
            }
            setFecIsm(liaallg);
        }

    }
    /**
     *   source:liaallg.0033.script
     */
    public String getDefaultFeecod(LiaallgVo liaallg, String valuelist,String covertyp)
    {
        String res = "";
        // if read from old PTE the old value is the default
        String feecod = NULLSTR;
        if(StringUtils.isNotEmpty(liaallg.getPtegrp().getRec().getFeeinr()) ) {
            res = liaallg.getFee().getCod();
        } else {
            // .. if no default is set by transaction, there is no default
            if(StringUtils.isEmpty(liaallg.getDftfeecod())) {
                res = "";
            } else {
                // else derive it from code set by transaction:
                if(StringUtils.isEmpty(liaallg.getFeecodaddcov())) {
                    feecod = liaallg.getDftfeecod();
                } else {
                    feecod = liaallg.getDftfeecod() + covertyp;
                }
                if( Strings.searchBlock(valuelist,feecod) == 0 ) {
                    feecod = Strings.mid(feecod,1,3) + "X" + Strings.mid(feecod,5);
                }
                res = feecod;
            }
        }
        return  res;

    }
    /**
     *   source:liaallg.0038.script
     */
    public void calcValdat(LiaallgVo liaallg, LiaallVo liaall) {
        String vallin = NULLSTR;
        String relRol = NULLSTR;
        int gridcnt = 0;
        if(!liaallg.isModified("valdat")) {
            // if no amount to be booked, clear value date
            if( MdaUtils.isEmpty(liaallg.getAmt()) ) {
                liaallg.setValdat(null);
            } else {
                // no value date for internal bookings
                if(!isCbtRelevantForLia(liaallg.getCbtpfx())) {
                    liaallg.setValdat(null);
                } else {
                    // take main default from  LiaallSetValdat
                    vallin = liaallService.liaallParGet("VALDAT", liaallg.getGrpkey() );
                    if( MdaUtils.isEmpty(vallin) ) {
                        vallin = liaallService.liaallParGet ( "VALDAT", "*" );
                    }
                    if( ! MdaUtils.isEmpty(vallin) ) {
                        liaallg.setValdat(Strings.parseDate(vallin));
                    } else {
                        //TODO SetmodVo setmod = liaallService.getLiaallSet().getSetmod();
                        SetmodVo setmod = new SetmodVo();
                        setmod.reset();
                        // otherwise, if a fix settlementdate is set for settlement, use it
                        if(!MdaUtils.isEmpty(setmod.getSetglg().getAllvaldat())) {
                            liaallg.setValdat(setmod.getSetglg().getAllvaldat());
                        } else {
                            // otherwise get relevant role for debit booking
                            relRol = "";
                            if( MdaUtils.compareTo(liaallg.getAmt(),0)<0 ) { // only for outbookings the replacing booking is to be found
                                if( liaallService.liaallParFound ( "SETMOD", "" ) ) { // if liaall defaults settlement, current role is relevant
                                    relRol = liaallg.getRol();
                                } else {                                            // otherwise role which is debited with an document amount (if any) is relevant
                                    // check if tenors are created, i.e. amounts for group TNR are booked in
                                    // If so, no defaulting from settlement tenor inbooking is the replacing booking
                                    List<LiaallRegisterVo> liaallRegisters = getLiaallSet().getLiaallRegisters();
                                    int tnrIdx = -1;
                                    for (int i = 0; i < liaallRegisters.size(); i++) {
                                        if ("TNR".equals(liaallRegisters.get(i).getGrpKey())) {
                                            tnrIdx = i;
                                            break;
                                        }
                                    }
                                    if (tnrIdx > -1) {
                                        LiaallRegisterVo liaallRegisterVo = getLiaallSet().getLiaallRegisters().get(tnrIdx);
                                        BigDecimal amt = liaallRegisterVo.getNewAmt();
                                        if (amt.compareTo(BigDecimal.ZERO) <= 0) {
                                            tnrIdx = -1;
                                        }
                                    }
                                    if (tnrIdx == -1) {
                                        List<Wrksum> wrksumList = setfegService.getFeeSet().getWrksumByBlurKey("*SET");
                                        if (wrksumList != null && wrksumList.size() > 0) {
                                            for (Wrksum wrksum : wrksumList) {
                                                if (wrksum.getAmt().compareTo(BigDecimal.ZERO) > 0) {
                                                    relRol = wrksum.getRol();
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            // default of value date is latest value date of debit bookings of relevant role
                            if( MdaUtils.isEmpty(relRol) ) {
                                // Valuta für Finanzierung
                                if( MdaUtils.compareTo("FIN",liaallg.getRol()) == 0 || MdaUtils.compareTo("FIA",liaallg.getRol()) == 0 ) {
                                    liaallg.setValdat(setmod.getRefdat());
                                } else {
                                    liaallg.setValdat(Dates.today());
                                }
                            } else {
                                liaallg.setValdat( NULLDATE);
                                gridcnt = setmod.getSetglg().getSetgll().size();
                                for(int  i = 0;i < gridcnt;i++) {
                                    SetgllVo setgll = setmod.getSetglg().getSetgll().get(i);
                                    if( MdaUtils.compareTo(setgll.getRol(),relRol) == 0
                                            && MdaUtils.compareTo(setgll.getCur(),liaallg.getCur()) == 0
                                            && MdaUtils.compareTo(setgll.getAmt(),0)>0
                                            && Dates.diff(setgll.getValdat(),liaallg.getValdat())>0 ) {
                                        liaallg.setValdat(setgll.getValdat());
                                    }
                                }
                                // set value date, if not found in settlement
                                if( MdaUtils.isEmpty(liaallg.getValdat()) ) {
                                    liaallg.setValdat(Dates.today());
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    /**
     *   source:liaallg.0046.script
     */
    public String getGroupKey(LiaallgVo liaallg, LiaallVo liaall) {
        //! This functions returns the groupkey of the line.
        //! lines where the amounts may be interchanged by the user have the same groupkey
        // The group is given by object, role and available CBTPFX
        String res = liaallg.getObjmodpath() + TAB + liaallg.getGrpkey();
        String ownGrp = liaallService.liaallParGet ( "ROLESOWNGRP", "" );
        String newrol = NULLSTR;
        if(!MdaUtils.isEmpty(ownGrp)) {
            // respect movement with LiallSetMoveAmounts
            newrol = liaallService.liaallParGet ( "MOVAMT", liaallg.getRol() );
            if( MdaUtils.isEmpty(newrol) ) {
                res = res + TAB + liaallg.getRol() + liaallg.getCdtrol();
            } else {
                res = res + TAB + newrol + liaallg.getCdtrol();
            }
        }
        // That is the key for transactions allowing free changes as xxTTEN
        // The following extensions are valid only in other cases
        String tenCbtVal = NULLSTR;
        boolean cbtok = false;
        if(!liaallService.liaallParFound("ENABLE.AMTFLG", "*" )) {
            // If old amount and maturity date is set, the maturity date is added to define an own group
            if( MdaUtils.compareTo(liaallg.getOldflg(),"X") == 0 && ! MdaUtils.isEmpty(liaallg.getMatdat()) ) {
                res = res + TAB + Utils.fmtDate(liaallg.getMatdat());
            }
            tenCbtVal = liaallService.liaallParGet ( "TENCBT", "CBTPFX" );
            if( ! MdaUtils.isEmpty(tenCbtVal) ) {
                cbtok = true;
                if( MdaUtils.compareTo(tenCbtVal,"*ALL*MATCBT*") == 0 ) {
                    cbtok = false;
                    res = Formats.format(liaallg.getMatdat(),"YYYY/MM/DD") + liaallg.getCbtpfx();
                }
                if( MdaUtils.compareTo(Strings.mid(liaallg.getGrpkey(),1,2),"TN") == 0 && liaallService.tenorSettleIncludePteinr(liaall.getTenorSettles(), liaallg.getPtegrp().getRec().getInr()) && cbtok ) {
                    res = "TNR";
                }
            }
        }
        // if Exchange is allowed, return OBJMODPATH only
        String excIds = liaallService.liaallParGet ( "ALWEXC", liaallg.getObjmodpath() );
        if (liaallg.getCbtpfx().equals(excIds)) {
            res = liaallg.getObjmodpath() + TAB + excIds;
        }
        return  res;

    }
    /**
     *   source:liaallg.0047.script
     */
    public void calcMatdat(LiaallgVo liaallg) {
        //! set maturity date
        //! For old tenors the default Maturity date is taken from the maturity in the database
        //! For balances the definition by LiaallSetDefaultMaturity has priority.
        String cacVal = NULLSTR;
        if (MdaUtils.compareTo(liaallg.getCbtpfx(), "AKZ") != 0 && MdaUtils.compareTo(liaallg.getCbtpfx(), "DPZ") != 0 && MdaUtils.compareTo(liaallg.getCbtpfx(), "DPU") != 0) {
            liaallg.setMatdat(null);
            liaallg.resetModified("matdat");
        } else {
            // no old or new amount is set, reset maturity date
            if (liaallg.getAmt().compareTo(BigDecimal.ZERO) == 0 && liaallg.getOldamt().compareTo(BigDecimal.ZERO) == 0) {
                liaallg.setMatdat(null);
                liaallg.resetModified("matdat");
            } else {
                // else redefault it, if not modified
                if (!liaallg.isModified("matdat")) {
                    if (!liaallService.liaallCBTPFXIsBalance(liaallg.getCbtpfx())) {
                        if (StringUtils.isNotEmpty(liaallg.getOldflg())) {
                            liaallg.setMatdat(liaallg.getPtegrp().getRec().getMatdat());
                        } else {
                            cacVal = liaallService.liaallParGet("DFTMATDAT", liaallg.getCbtpfxlst() + "." + liaallg.getObjmodpath());
                            if (StringUtils.isEmpty(cacVal)) {
                                cacVal = liaallService.liaallParGet("DFTMATDAT", liaallg.getCbtpfx() + "." + liaallg.getObjmodpath());
                            }
                            if (StringUtils.isNotEmpty(cacVal)) {
                                liaallg.setMatdat(Strings.parseDate(cacVal));
                            }
                        }
                    } else {
                        cacVal = liaallService.liaallParGet("DFTMATDAT", liaallg.getCbtpfx() + "." + liaallg.getObjmodpath());
                        if (StringUtils.isNotEmpty(cacVal)) {
                            liaallg.setMatdat(Strings.parseDate(cacVal));
                        } else {
                            if (StringUtils.isNotEmpty(liaallg.getOldflg())) {
                                liaallg.setMatdat(liaallg.getPtegrp().getRec().getMatdat());
                            } else {
                                // do not clear maturity date if engagement is moved in transaction
                                String newrol = liaallService.liaallParGet("MOVAMT", liaallg.getRol());
                                if (StringUtils.isEmpty(newrol)) {
                                    liaallg.setMatdat(null);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    /**
     *   source:liaallg.0049.script
     */
    public String getAvailAcc(LiaallgVo liaallg) {
        return liaoneService.getAvailAcc(liaallg.getAcplia());
    }
    /**
     *   source:liaallg.0055.script
     */
    public String getTenorId(LiaallgVo liaallg) {
        // used to identify tenor for diary system
        if( MdaUtils.isEmpty(liaallg.getObjmodpath())) {
            return  "";
        }
        // EXTID contains CBTPFX and business sector
        return  liaallg.getExtid() + "/" + liaallg.getPtegrp().getRec().getSubid();

    }
    /**
     *   source:liaallg.0056.script
     */
    public int getMaxSub(LiaallVo liaall) {
        List<LiaallgVo> liaallgList = liaall.getLiaallg().parallelStream()
                .filter(liaallg -> StringUtils.isNotEmpty(liaallg.getPtegrp().getRec().getSubid()))
                .sorted(Comparator.comparingInt(o -> Integer.parseInt(o.getPtegrp().getRec().getSubid())))
                .collect(Collectors.toList());
        if (liaallgList != null && liaallgList.size() > 0) {
            return Integer.parseInt(liaallgList.get(liaallgList.size()-1).getPtegrp().getRec().getSubid());
        }
        return 0;
    }
    /**
     *   source:liaallg.0058.script
     */

    public String getTnrId(LiaallVo liaall, LiaallgVo liaallg) {
        //! reads ID of tenor to allow summing up of lines for same tenor
        //! selected tenors have same ID, otherwise tenors are defined by maturity dates
        if(liaallService.tenorSettleIncludePteinr(liaall.getTenorSettles(), liaallg.getPtegrp().getRec().getInr()) && ! MdaUtils.isEmpty(liaallg.getPtegrp().getRec().getInr()) ) {
            return  "SELECTED";
        } else {
            switch(liaallg.getGrpkey()) {
                case "TNR":
                case  "TN1":
                case  "TN2":
                case  "DPU":
                case  "DPZ":
                case  "AKZ":
                    return  Utils.fmtDate(liaallg.getMatdat(),"dd/MM/yyyy") + Utils.fmtDate(liaallg.getAcplia().getWrkcbe().getOptdat(),"dd/MM/yyyy");
                default:
                    return  "";
            }
        }
    }
    /**
     *   source:liaallg.0060.script
     */
    public boolean hasOldAccountToBeValid(LiaallgVo liaallg) {
        //! Function to decide if an account of the line has still to be a valid account in account defaulting
        //! TRUE means if old account is not longer in list, the amount is automatically booked out and a new line is created
        //! The example in product does the check for AVL/AVS and omits it for all other types
        boolean res = false;
        switch(liaallg.getCbtpfx()) {
            case "AVL":
            case "AVS":
                res = true;
                break;
            default:
                res = false;
        }
        return  res;
    }
    /**
     *   source:liaallg.0062.script
     */
    public boolean isIsfChg() {
        return  false;

    }
    /**
     *   source:liaallg.0069.script
     */
    public void setFecIsm(LiaallgVo liaallg) {
        //! sub to set installation specific defualts for condition
        //! (to be created from Default FEC\\...-rules that are setting fields)
        // From Default FEC\\SETFLG
        if( MdaUtils.isEmpty(liaallg.getFec().getSetflg()) ) {
            liaallg.getFec().setSetflg( "A");
        }
        // From default FEC\\SETTYP
        if( MdaUtils.isEmpty(liaallg.getFec().getSettyp()) ) {
            liaallg.getFec().setSettyp( "A");
        }
    }

    public boolean isCbtRelevantForLia(String cbt) {
        //! determines if the passed CBT is relevant for Liabilities
        //! Only the first three characters are evaluated.
        //! Thus the function may be called with the prefix or the complete booking type
        switch( Strings.mid(cbt,1,3) ) {
            case "AVL":
            case  "AKZ":
            case  "DPZ":
            case  "FIN":
            case  "AVS":
            case  "FOR":
            case  "REP":
            case  "AVG":
            case  "FIP":
            case  "CCV":
                return  true;
            default:
                return  false;
        }
    }

    //@default ("dftfeecod", "feecodaddcov", "fee")
    public void defaultDftfeecod(LiaallgVo liaallgVo) {
        if(liaallgVo.getFeehndidx() == 0) {
            String feeKey = liaallService.liaallGetFeecodFucKey(liaallgVo.getBussec(), liaallgVo.getCbtpfx());
            if(StringUtils.isNotEmpty(feeKey)) {
                liaallgVo.setDftfeecod(liaallService.liaallParGet(feeKey, "COD." + liaallgVo.getCbtpfx()));
                liaallgVo.setFeecodaddcov(liaallService.liaallParGet(feeKey, "ADDCOVFLG." + liaallgVo.getCbtpfx()));
                String expdatStr = liaallService.liaallParGet(feeKey, "EXPDAT." + liaallgVo.getCbtpfx());
                if (StringUtils.isNotEmpty(expdatStr)) {
                    Date expdat = Utils.parseDate(expdatStr,"dd/MM/yyyy");
                    liaallgVo.setFeecodExpdat(expdat);
                }
            } else {
                liaallgVo.setDftfeecod(NULLSTR);
                liaallgVo.setFeecodaddcov(NULLSTR);
            }
        } else {
            liaallgVo.setDftfeecod(NULLSTR);
            liaallgVo.setFeecodaddcov(NULLSTR);
        }
    }

    public void defaultTrntyp(LiaallVo liaallVo, LiaallgVo liaallgVo) {
        if (StringUtils.isNotEmpty(liaallgVo.getBussec())) {
            if ("GI".equalsIgnoreCase(liaallgVo.getBussec())) {
                liaallgVo.setTrntyp("GJBH");
            } else if ("NI".equalsIgnoreCase(liaallgVo.getBussec())) {
                String segtyp = Utils.getFieldValue(liaallVo.getRec(), "segtyp");
                if ("02".equals(segtyp)) {
                    liaallgVo.setTrntyp("HGBH");
                } else {
                    liaallgVo.setTrntyp("GNBH");
                }
            } else {
                liaallgVo.setTrntyp(liaallgVo.getBussec());
            }
        }
    }

    /**
     * 设置 tilmat feeinccod setmodFactory 应用于费用账务
     * @param liaallgVo
     */
    public void setLiaallgInfo4Setmod(LiaallgVo liaallgVo) {
        String tilmat = liaallService.liaallParGet("TILMAT", liaallgVo.getCbtpfx());
        liaallgVo.setTilmat(tilmat);
        String feeinccod = liaallService.liaallParGet("FEEINCCOD", liaallgVo.getCbtpfx());
        liaallgVo.setFeeinccod(feeinccod);
        String factorx = liaallService.liaallParGet("SETMOD", liaallgVo.getGrpkey());
        if (StringUtils.isNotEmpty(factorx)) {
            liaallgVo.setSetmodFactory(new BigDecimal(factorx));
        }
    }

    public LiaallSet getLiaallSet() {
        return transactionHelpService.getLiaallSet();
    }
}