package com.yem.wm.es.salesorder.validator;/*
 *
 * @auther: xwudd
 * @Description
 * @Date: 2023/7/24
 */

import com.yem.wm.es.Util.TotalUtil;
import com.yem.wm.utils.DynamicObjectUtil;
import com.yem.wm.utils.YEM;
import kd.bos.armor.core.util.StringUtil;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.validate.AbstractValidator;
import kd.bos.exception.KDBizException;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

import static com.yem.wm.es.storagetrans.op.StorageTransSubmitOp.validatorSwiftCode;


/**
 * @Description
 **/
public class SalesOrderSubmitValidator extends AbstractValidator {
    @Override
    public void validate() {
        ExtendedDataEntity[] dataEntities = this.getDataEntities();
        for (ExtendedDataEntity dataEntitie : dataEntities) {
            DynamicObject dataEntity = dataEntitie.getDataEntity();
            dataEntity = BusinessDataServiceHelper.loadSingle(dataEntity.getPkValue(), dataEntity.getDynamicObjectType().getName());

            String[] res = validatorSwiftCode(dataEntity);
            if (!res[0].isEmpty()) {
                this.addErrorMessage(dataEntitie, res[0]);
            }
            if (!res[1].isEmpty()) {
                this.addErrorMessage(dataEntitie, res[1]);
            }

            DynamicObject billType = dataEntity.getDynamicObject("yem_billtype");
            if (billType != null) {
                String yem_accamtusetype = dataEntity.getString("yem_accamtusetype");
                String number = billType.getString("number");
                if ("yem_es_salesorder_ZJ".equals(number) || "yem_es_salesorder_nmzj".equals(number)) {
                    String s = detailInfoMaterialClass(dataEntity);
                    if (YEM.isNotEmpty(s)) {
                        this.addErrorMessage(dataEntitie, s);
                    }
                    marketraiseprice(dataEntitie, dataEntity);
                }
                if ("yem_es_salesorder_PJ".equals(number) || "yem_es_salesorder_nmpj".equals(number)) {
                    String s = accUeDetailValidator(dataEntity);
                    if (YEM.isNotEmpty(s)) {
                        this.addErrorMessage(dataEntitie, s);
                    }
                    BigDecimal yem_safobamount = BigDecimal.ZERO;
                    BigDecimal fundPoolAmt = dataEntity.getBigDecimal("yem_fundpoolamt");
                    DynamicObjectCollection entrys = dataEntity.getDynamicObjectCollection("yem_es_materialinfo");
                    for (DynamicObject entry : entrys) {
                        yem_safobamount = yem_safobamount.add(entry.getBigDecimal("yem_saamtpriceclause"));
                    }
                    if ("C".equals(yem_accamtusetype)) {
                        if (!(yem_safobamount.compareTo(fundPoolAmt) == 0)) {
                            s = String.format("配件资金使用额度【%s】与明细信息价格条款金额合计值【%s】不一致，请调整数据！", fundPoolAmt, yem_safobamount);
                            if (YEM.isNotEmpty(s)) {
                                this.addErrorMessage(dataEntitie, s);
                            }
                        }
                    } else {
                        s = TotalUtil.fundPoolAmtValidator(dataEntity, "yem_es_materialinfo");
                        if (YEM.isNotEmpty(s)) {
                            this.addErrorMessage(dataEntitie, s);
                        }
                    }
                }
            }

            boolean isSinosureCon = dataEntity.getBoolean("yem_issinosurecon");
            if (isSinosureCon) {
                sinosureCheck(dataEntity, dataEntitie);
            }
            // 检查是否信保合同
            checkCreditContract(dataEntity, dataEntitie);
            // 信保合同提交时，消息提醒：【请确认，信保通中该客户的信保额度是否有效，如果点击是，继续下一步，点击否取消操作】。
            waringCreditContract(dataEntity, dataEntitie);

            calibrationPresaleMarks(dataEntitie, dataEntity);
            //校验内审预算单 佣金
            checkCnAmount(dataEntitie, dataEntity);
            //礼品赠送
            giftVerification(dataEntitie, dataEntity);
            //配件赠送
            PartsVerification(dataEntitie, dataEntity);
            //信保校验
            sinosureValidator(dataEntitie, dataEntity);
            rapAmtValidator(dataEntitie);

            // 客户信用额度校验
            checkCustomCredit(dataEntitie);
            //贷记单
            credit(dataEntitie, dataEntity);

            // 务分类为整机时，夜色必填
            checkColor(dataEntity, dataEntitie);

            // 是否佣金为是，校验付用对象 金额
            checkCommission(dataEntity, dataEntitie);

            checkPaymentType(dataEntity, dataEntitie);
            // 最新财务标准售价为空时，不允许提交
            checkNewPrice(dataEntity);
            //校验 贷记单使用币别对于的贷记单使用金额不能超过贷记单剩余额度
            accfunddetail(dataEntity, dataEntitie);

            // 配件资金池使用，使用金额需要校验
            checkUsedAmount(dataEntity, dataEntitie);
            // 收汇百分比必须为100
            checkReceiptRate(dataEntity, dataEntitie);
            //校验客户是否同步EAS
            DynamicObject yem_customer = dataEntity.getDynamicObject("yem_customer");
            if (yem_customer != null) {
                boolean yem_eassyn = yem_customer.getBoolean("yem_eassyn");
                boolean yem_issyneas = yem_customer.getBoolean("yem_issyneas");
                if (!yem_eassyn && !yem_issyneas) {
                    String msg = "客户【" + yem_customer.getString("number") + "】未同步至EAS，禁止提交！";
                    this.addErrorMessage(dataEntitie, msg);
                }
            }
            DynamicObject yem_currency = dataEntity.getDynamicObject("yem_currency");
            DynamicObject yem_currencybase = dataEntity.getDynamicObject("yem_currencybase");
            DynamicObject yem_internationalrate = dataEntity.getDynamicObject("yem_internationalrate");
            if (yem_currency != null && yem_currencybase != null) {
                if (yem_currency.getLong("id") != yem_currencybase.getLong("id")) {
                    if (yem_internationalrate == null) {
                        String msg = "结算币别不等于本位币，收款天数必录！";
                        this.addErrorMessage(dataEntitie, msg);
                    }
                }
            }
        }
    }

    /**
     * 信保合同提交时，消息提醒：【请确认，信保通中该客户的信保额度是否有效，如果点击是，继续下一步，点击否取消操作】。
     * @param dataEntity
     * @param dataEntitie
     */
    private void waringCreditContract(DynamicObject dataEntity, ExtendedDataEntity dataEntitie) {
        boolean issinosurecon = dataEntity.getBoolean("yem_issinosurecon");

        if (issinosurecon) {
            this.addWarningMessage(dataEntitie, "请确认，信保通中该客户的信保额度是否有效!!");
        }
    }

    /**
     * 根据信保明细检查是否信保合同
     * @param dataEntity
     * @param dataEntitie
     */
    private void checkCreditContract(DynamicObject dataEntity, ExtendedDataEntity dataEntitie) {
        boolean issinosurecon = dataEntity.getBoolean("yem_issinosurecon");

        Set<String> set = new HashSet<>();
        DynamicObjectCollection collection = dataEntity.getDynamicObjectCollection("yem_es_salescontrac_s");
        for (DynamicObject dynamicObject : collection) {
            String issinosure = dynamicObject.getString("yem_issinosure");
            set.add(issinosure);
        }
        //  A 是 | B 否
        if (set.contains("A")) {
            if (!issinosurecon) {
                throw new KDBizException("收款计划中有一行是否信保为是，合同必须为信保合同，请修改基本信息中是否信保为是后提交！");
            }
        }

        if (!set.contains("A")) {
            if (issinosurecon) {
                throw new KDBizException("收款计划中是否信保为否，合同不是信保合同，请修改基本信息中是否信保为否后提交！");
            }
        }
    }

    private void checkReceiptRate(DynamicObject dataEntity, ExtendedDataEntity dataEntitie) {
        DynamicObjectCollection collection = dataEntity.getDynamicObjectCollection("yem_es_salescontrac_s");
        if (collection.isEmpty()) return;
        BigDecimal rate = BigDecimal.ZERO;
        for (DynamicObject entry : collection) {
            BigDecimal raprate = entry.getBigDecimal("yem_raprate");
            rate = rate.add(raprate);
        }
        if (rate.compareTo(new BigDecimal("100")) != 0) {
            this.addErrorMessage(dataEntitie, "收汇百分比合计必须为100%");
        }
    }

    /**
     * 是否是变更合同
     * @param dataEntity 外销合同
     */
    private boolean isChangeContract(DynamicObject dataEntity) {
        String name = dataEntity.getDataEntityType().getName();
        if ("yem_es_xsalesorder".equals(name)) {
            return true;
        }
        return false;
    }

    /**
     * 根据贷记单使用币别+贷记单类型+借贷业务类型+集团客户，匹配对应配件资金池，
     * 【贷记单使用金额】不能超过其对应分录【实际来源金额-预计去向金额】
     * @param dataEntity
     * @param dataEntitie
     */
    private void checkUsedAmount(DynamicObject dataEntity, ExtendedDataEntity dataEntitie) {
        if (isChangeContract(dataEntity)) {return;}
        // 资金使用类型
        String fundusetype = dataEntity.getString("yem_fundusetype");
        if (!"B".equals(fundusetype)) return;
        DynamicObjectCollection collection = dataEntity.getDynamicObjectCollection("yem_accfunddetail");
        StringBuilder sb = new StringBuilder();
        for (DynamicObject dynamicObject : collection) {
            int index = collection.indexOf(dynamicObject);
            // 贷记单使用币别
            long currId = dynamicObject.getLong("yem_debcrednotecurr.id");
            // 借/贷类型
            String debcred = dynamicObject.getString("yem_debcred");
            // 借贷业务类型
            long debcredtype = dynamicObject.getLong("yem_debcredtype.id");
            DynamicObject customer = dataEntity.getDynamicObject("yem_customer");
            if (customer == null) return;
            customer = BusinessDataServiceHelper.loadSingle(customer.getPkValue(), customer.getDynamicObjectType().getName());
            // 集团客户
            long groupcustomers = customer.getLong("yem_groupcustomers.id");
            // 贷记单使用金额
            BigDecimal debcuseamt = dynamicObject.getBigDecimal("yem_debcuseamt");
            if (debcuseamt.compareTo(BigDecimal.ZERO) == 0) continue;
            QFilter qFilter = new QFilter("yem_spcapitalpool_a.yem_curr.id", QCP.equals, currId)
                    .and("yem_spcapitalpool_a.yem_debcredtype", QCP.equals, debcred)
                    .and("yem_spcapitalpool_a.yem_creditype.id", QCP.equals, debcredtype)
                    .and("yem_customer.id", QCP.equals, groupcustomers);
            DynamicObject single = BusinessDataServiceHelper.loadSingle("yem_spcapitalpool", qFilter.toArray());
            if (single == null) return;
            DynamicObjectCollection singleCollection = single.getDynamicObjectCollection("yem_spcapitalpool_a");
            for (DynamicObject object : singleCollection) {
                int subIdx = singleCollection.indexOf(object);
                long entryCurr = object.getLong("yem_curr.id");
                String entryDebcredtype = object.getString("yem_debcredtype");
                long entryCreditype = object.getLong("yem_creditype.id");
                long entryCustomer = single.getLong("yem_customer.id");
                if (
                        entryCurr == currId &&
                        entryDebcredtype.equals(debcred) &&
                        entryCreditype == debcredtype &&
                        groupcustomers == entryCustomer
                ) {
                    // 实际来源总金额
                    BigDecimal sumtotalamount = object.getBigDecimal("yem_sumtotalamount");
                    // 预计去向总金额
                    BigDecimal sumtowardamt = object.getBigDecimal("yem_sumtowardamt");
                    if (debcuseamt.compareTo(sumtotalamount.subtract(sumtowardamt)) > 0) {
                        sb.append(String.format("配件资金使用明细第 [ %s ] 行，贷记单使用金额 [ %s ] 超过其对应配件资金池 [ %s ] 分录第 [ %s ] 行，实际来源金额 [ %s ] - 预计去向金额 [ %s ] = [ %s ] !!\r\n",
                                index + 1,
                                debcuseamt.setScale(2, RoundingMode.HALF_UP),
                                single.getString("billno"),
                                subIdx + 1,
                                sumtotalamount.setScale(2, RoundingMode.HALF_UP),
                                sumtowardamt.setScale(2, RoundingMode.HALF_UP),
                                sumtotalamount.subtract(sumtowardamt).setScale(2, RoundingMode.HALF_UP)
                        ));
                    }
                }
            }
        }
        if (sb.length() > 0) {
            sb.append("不允许提交！");
            this.addErrorMessage(dataEntitie, sb.toString());
        }
    }

    private void calibrationPresaleMarks(ExtendedDataEntity dataEntitie, DynamicObject dataEntity) {
        DynamicObject dynamicObject = dataEntitie.getDataEntity();
        dynamicObject = BusinessDataServiceHelper.loadSingle(dynamicObject.getPkValue(), dynamicObject.getDynamicObjectType().getName());

        // 收款计划
        DynamicObjectCollection esSalescontracS = dynamicObject.getDynamicObjectCollection("yem_es_salescontrac_s");
        for (DynamicObject object : esSalescontracS) {
            int index = esSalescontracS.indexOf(object);
            // 预收标志
            boolean ispre = object.getBoolean("yem_ispre");
            // 是否生产（下单）预收
            String isprepayment = object.getString("yem_isprepayment");
            // 是否发货预收
            String isshippayment = object.getString("yem_isshippayment");
            if (ispre) {
                if ("A".equals(isprepayment) && "A".equals(isshippayment)) {
                    String message = "收款计划分录第 [" + (index + 1) + "] 行，预收标志为是时，下单预收、发货预收只能有一个为是。";
                    this.addErrorMessage(dataEntitie, message);
                }
            }

            if (!ispre) {
                if ("A".equals(isprepayment) || "A".equals(isshippayment)) {
                    String message = "收款计划分录第 [" + (index + 1) + "] 行，预收标志为否时，下单预收、发货预收必须为否";
                    this.addErrorMessage(dataEntitie, message);
                }
            }
        }
    }

    /**
     * 校验 贷记单使用币别对于的贷记单使用金额不能超过贷记单剩余额度
     *
     * @param dataEntity
     * @param dataEntitie
     */
    public void accfunddetail(DynamicObject dataEntity, ExtendedDataEntity dataEntitie) {
        dataEntity = BusinessDataServiceHelper.loadSingle(dataEntity.getPkValue(), dataEntity.getDynamicObjectType().getName());
        String yem_billtype = dataEntity.getString("yem_billtype.number");//单据类型
        String yem_fundusetype = dataEntity.getString("yem_fundusetype");//资金使用类型
        String yem_accamtusetype = dataEntity.getString("yem_accamtusetype");//配件资金使用方式
        String yem_billbusstype = dataEntity.getString("yem_billbusstype.number");//单据业务类型
        if (yem_fundusetype.equals("B")) {
            QFilter qFilter = new QFilter("yem_contracttype", QCP.equals, yem_billtype);//
            qFilter.and(new QFilter("yem_accamtusetype", QCP.equals, yem_accamtusetype));
            qFilter.and(new QFilter("yem_billbusstype.number", QCP.equals, yem_billbusstype));
            qFilter.and(new QFilter("enable", QCP.equals, "1"));
            String selectfield = DynamicObjectUtil.getSelectfields("yem_bd_credittypeconfig", false);
            String selectfields = DynamicObjectUtil.getEntrySelectfields(selectfield, "yem_bd_credittypeconfig", "yem_credittypeentry", false);
            DynamicObjectCollection data = QueryServiceHelper.query("yem_bd_credittypeconfig",
                    selectfields, new QFilter[]{qFilter}, null);
            if (data.size() > 0) {
                Map<Long, Boolean> map = new HashMap<>();
                for (int i = 0; i < data.size(); i++) {
                    DynamicObject object = data.get(i);
                    long aLong = object.getLong("yem_credittypeentry.yem_credittype");
                    if (!map.containsKey(aLong)) {
                        map.put(aLong, object.getBoolean("yem_credittypeentry.yem_isoverage"));
                    }
                }
                DynamicObjectCollection yem_accfunddetail = dataEntity.getDynamicObjectCollection("yem_accfunddetail");
                for (int j = 0; j < yem_accfunddetail.size(); j++) {
                    int row = j + 1;
                    DynamicObject object = yem_accfunddetail.get(j);
                    DynamicObject yem_debcredtype = object.getDynamicObject("yem_debcredtype");//贷记单类型
                    long debcredtypeid = yem_debcredtype.getLong("id");
                    DynamicObject yem_debcrednotecurr = object.getDynamicObject("yem_debcrednotecurr");//贷记单使用币别
                    BigDecimal yem_creditrmbamt = object.getBigDecimal("yem_creditrmbamt");//贷记单人民币金额
                    BigDecimal yem_creditusdamt = object.getBigDecimal("yem_creditusdamt");//贷记单美元金额
                    BigDecimal yem_debcuseamt = object.getBigDecimal("yem_debcuseamt");//贷记单使用金额

                    BigDecimal yem_yzycreditrmbamt = object.getBigDecimal("yem_yzycreditrmbamt");//贷记单人民币金额（预占用）
                    BigDecimal yem_yzycreditusdamt = object.getBigDecimal("yem_yzycreditusdamt");//贷记单美元金额（预占用）

                    String yem_debcred = object.getString("yem_debcred");
                    BigDecimal bigDecimal = yem_creditusdamt.setScale(2, BigDecimal.ROUND_HALF_UP);
                    BigDecimal bigDecimal1 = yem_debcuseamt.setScale(2, BigDecimal.ROUND_HALF_UP);
                    BigDecimal bigDecimal2 = yem_creditrmbamt.setScale(2, BigDecimal.ROUND_HALF_UP);
                    if (yem_debcrednotecurr.getString("number").equals("USD")) {
                        if (yem_debcred.equals("DN")) {//借记类型
                            if (yem_debcuseamt.compareTo(yem_creditusdamt) == 1) {
                                String msg = "配件资金池使用明细第【" + row + "】行，贷记单美元金额【" + bigDecimal + "】小于贷记单使用金额【" + bigDecimal1 + "】，请修改后重试！";
                                this.addErrorMessage(dataEntitie, msg);
                            }
                            if (yem_debcuseamt.compareTo(yem_yzycreditusdamt) == 1) {
                                String msg = "配件资金池使用明细第【" + row + "】行，贷记单美元金额(预占用)【" + yem_yzycreditusdamt.setScale(2, BigDecimal.ROUND_HALF_UP) + "】小于贷记单使用金额【" + bigDecimal1 + "】，请修改后重试！";
                                this.addErrorMessage(dataEntitie, msg);
                            }
                        } else {
                            if (map.containsKey(debcredtypeid)) {
                                Boolean aBoolean = map.get(debcredtypeid);
                                if (!aBoolean) {
                                    if (yem_debcuseamt.compareTo(yem_creditusdamt) == 1) {
                                        String msg = "配件资金池使用明细第【" + row + "】行，贷记单美元金额【" + bigDecimal + "】小于贷记单使用金额【" + bigDecimal1 + "】，请修改后重试！";
                                        this.addErrorMessage(dataEntitie, msg);
                                    }
                                    if (yem_debcuseamt.compareTo(yem_yzycreditusdamt) == 1) {
                                        String msg = "配件资金池使用明细第【" + row + "】行，贷记单美元金额(预占用)【" + yem_yzycreditusdamt.setScale(2, BigDecimal.ROUND_HALF_UP) + "】小于贷记单使用金额【" + bigDecimal1 + "】，请修改后重试！";
                                        this.addErrorMessage(dataEntitie, msg);
                                    }
                                } else {
                                    if (yem_creditusdamt.compareTo(BigDecimal.ZERO) == -1) {
                                        String msg = "配件资金池使用明细第【" + row + "】行，贷记单美元金额小于0，请修改后重试！";
                                        this.addErrorMessage(dataEntitie, msg);
                                    }
                                    if (yem_yzycreditusdamt.compareTo(BigDecimal.ZERO) == -1) {
                                        String msg = "配件资金池使用明细第【" + row + "】行，贷记单美元金额（预占用）小于0，请修改后重试";
                                        this.addErrorMessage(dataEntitie, msg);
                                    }
                                }
                            }
                        }
                    } else {
                        if (yem_debcred.equals("DN")) {
                            if (yem_debcuseamt.compareTo(yem_creditrmbamt) == 1) {
                                String msg = "配件资金池使用明细第【" + row + "】行，贷记单人民币金额【" + bigDecimal2 + "】小于贷记单使用金额【" + bigDecimal1 + "】，请修改后重试！";
                                this.addErrorMessage(dataEntitie, msg);
                            }
                            if (yem_debcuseamt.compareTo(yem_yzycreditrmbamt) == 1) {
                                String msg = "配件资金池使用明细第【" + row + "】行，贷记单人民币金额（预占用）【" + yem_yzycreditrmbamt.setScale(2, BigDecimal.ROUND_HALF_UP) + "】小于贷记单使用金额【" + bigDecimal1 + "】，请修改后重试！";
                                this.addErrorMessage(dataEntitie, msg);
                            }
                        } else {
                            if (map.containsKey(debcredtypeid)) {
                                Boolean aBoolean = map.get(debcredtypeid);
                                if (!aBoolean) {
                                    if (yem_debcuseamt.compareTo(yem_creditrmbamt) == 1) {
                                        String msg = "配件资金池使用明细第【" + row + "】行，贷记单人民币金额【" + bigDecimal2 + "】小于贷记单使用金额【" + bigDecimal1 + "】，请修改后重试！";
                                        this.addErrorMessage(dataEntitie, msg);
                                    }
                                    if (yem_debcuseamt.compareTo(yem_yzycreditrmbamt) == 1) {
                                        String msg = "配件资金池使用明细第【" + row + "】行，贷记单人民币金额（预占用）【" + yem_yzycreditrmbamt.setScale(2, BigDecimal.ROUND_HALF_UP) + "】" +
                                                "小于贷记单使用金额【" + bigDecimal1 + "】，请修改后重试！";
                                        this.addErrorMessage(dataEntitie, msg);
                                    }
                                } else {
                                    if (yem_creditrmbamt.compareTo(BigDecimal.ZERO) == -1) {
                                        String msg = "配件资金池使用明细第【" + row + "】行，贷记单人民币金额小于0，请修改后重试！";
                                        this.addErrorMessage(dataEntitie, msg);
                                    }
                                    if (yem_yzycreditrmbamt.compareTo(BigDecimal.ZERO) == -1) {
                                        String msg = "配件资金池使用明细第【" + row + "】行，贷记单人民币金额（预占用）小于0，请修改后重试！";
                                        this.addErrorMessage(dataEntitie, msg);
                                    }
                                }
                            }
                        }

                    }
                }
            }
        }
    }

    /**
     * 外销合同-基本信息:是否信保合同为是:
     * 收款计划-是否信保字段必填，且至少有一行选择是，为否时不判断;
     * 否则合同不允许提交;
     *
     * @param dataEntity
     * @param dataEntitie
     */
    private void checkPaymentType(DynamicObject dataEntity, ExtendedDataEntity dataEntitie) {
        // 是否信保合同
        boolean issinosurecon = dataEntity.getBoolean("yem_issinosurecon");
        if (Boolean.TRUE.equals(issinosurecon)) {
            DynamicObjectCollection collection = dataEntity.getDynamicObjectCollection("yem_es_salescontrac_s");

            Set<Boolean> set = new HashSet<>();

            for (DynamicObject dynamicObject : collection) {
                int index = collection.indexOf(dynamicObject);
                // 是否信保
                String issinosure = dynamicObject.getString("yem_issinosure");
                if (issinosure == null || issinosure.isEmpty()) {
                    this.addErrorMessage(dataEntitie, "收款计划第" + (index + 1) + "行，是否信保必填");
                }
                set.add("A".equals(issinosure));
            }

            if (!set.contains(Boolean.TRUE)) {
                this.addErrorMessage(dataEntitie, "合同为信保合同，收款计划中至少有一行是否信保需为是！");
            }
        }
    }

    /**
     * 是否佣金为是，校验付用对象 金额
     *
     * @param dataEntity
     * @param dataEntitie
     */
    private void checkCommission(DynamicObject dataEntity, ExtendedDataEntity dataEntitie) {
        // 是否佣金
        String incommission = dataEntity.getString("yem_incommission");
        if ("A".equals(incommission)) {
            // 付佣对象
            long cnpersonId = dataEntity.getLong("yem_cnperson.id");
            // 佣金金额
            BigDecimal commissionamt = dataEntity.getBigDecimal("yem_commissionamt");

            if (cnpersonId == 0 || commissionamt == null || commissionamt.compareTo(BigDecimal.ZERO) == 0) {
                this.addErrorMessage(dataEntitie, "外销合同有佣金，佣金金额必录，请维护数据之后重新提交！");
            }
        }
    }

    /**
     * 业务分类为整机时，夜色必填
     *
     * @param dataEntity
     * @param dataEntitie
     */
    private void checkColor(DynamicObject dataEntity, ExtendedDataEntity dataEntitie) {
        DynamicObjectCollection collection = dataEntity.getDynamicObjectCollection("yem_es_materialinfo");
        for (int i = 0; i < collection.size(); i++) {
            // 业务分类为整机
            if ("Z".equals(collection.get(i).getString("yem_businesssort"))) {
                String color = collection.get(i).getString("yem_color");
                if (color == null || color.isEmpty()) {
                    this.addMessage(dataEntitie, "商品明细第" + (i + 1) + "行，颜色必填");
                }
            }
        }
    }


    /**
     * 客户信用额度校验
     *
     * @param dataEntitie
     */
    private void checkCustomCredit(ExtendedDataEntity dataEntitie) {
        String operateKey = this.getOperateKey();
        if (!operateKey.equals("submit")) {
            return;
        }

        DynamicObject entity = dataEntitie.getDataEntity();
        // 资金使用类型
        String fundusetype = entity.getString("yem_fundusetype");
        // 资金使用类型为 = 客户信用额度
        if ("A".equals(fundusetype)) {
            // 公司
            long orgId = entity.getLong("org.id");
            // 客户ID
            long customerId = entity.getLong("yem_customer.id");
            // 客户名称
            String customerName = entity.getString("yem_customer.name");
            // 产品分类
            long productsId = entity.getLong("yem_bd_products.id");
            // 产品名称
            String productsName = entity.getString("yem_bd_products.name");
            // 配件客商/借记额度
            BigDecimal debitamount = entity.getBigDecimal("yem_debitamount");
            DynamicObject yem_currency = entity.getDynamicObject("yem_currency");
            // 结算币别
            long currency = yem_currency.getLong("id");
            // 业务组织 = 公司
            QFilter qFilters = new QFilter("org.id", QCP.equals, orgId);
            // 客户名称 = 客户名称
            qFilters.and(new QFilter("yem_client.id", QCP.equals, customerId));
            // 产品分类 = 产品分类
            qFilters.and(new QFilter("yem_productcategorie", QCP.equals, productsId));
            // 单据状态 = 已审核
            qFilters.and(new QFilter("billstatus", QCP.equals, "C"));
            // 日期降序
            // 合同上结算币别 = 额度申请上 额度币别
            qFilters.and(new QFilter("yem_currency.id", QCP.equals, currency));
//            qFilters.and(new QFilter("yem_bizdate", QCP.equals));
            // 根据组织+客户+产品分类，查询 配件客商额度申请单
            DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle("yem_im_partsmerchant", qFilters.toArray());
            if (dynamicObject != null) {
                // 剩余额度(剩余额度)
                BigDecimal balance = dynamicObject.getBigDecimal("yem_balance");
                BigDecimal exchangeRate = entity.getBigDecimal("yem_exrate");
                // 配件客商/借记额度  * 汇率
                debitamount = debitamount.multiply(exchangeRate);
                // if 配件客商/借记额度>配件客商额度申请-额度信息-剩余额度
                if (debitamount.compareTo(balance) > 0) {
                    // 当前单据使用配件/借记额度：***超出该客户的剩余可用额度：***，请检查！
                    this.addErrorMessage(dataEntitie, "当前单据使用配件/借记额度：" + debitamount.setScale(4, RoundingMode.UP) + "超出该客户的剩余可用额度：" + balance.setScale(4, RoundingMode.UP) + "，请检查！");
                }
            } else {
                // 没有找到符合条件的配件客商额度申请，不允许提交
                // 没有找到客户：***，产品分类：***的配件客商额度申请单，请确认！
                this.addErrorMessage(dataEntitie, "没有找到客户：" + customerName + "，产品分类：" + productsName + "，币别：" + yem_currency.getString("name") + "的配件客商额度申请单，请确认！");
            }
        }
    }

    /**
     * 如果外贸整机：已经生成内审预算单，调整佣金金额，提交时，需提示：明细信息行的单车佣金是否与内审预算单中的佣金一致，如果否，给出提示：“明细信息**行，单车佣金【明细信息-单车佣金】跟其对应的内审预算单佣金**不一致，请检查数据！！”
     * 如果是外贸配件：已经生成内审预算单，调整佣金金额，提交时，需要提示：外销合同总佣金【佣金信息-佣金金额】与内审预算单的佣金是否一致，如果否，给出提示：“外销合同总佣金【佣金信息-佣金金额】与内审预算单的佣金**不一致，请检查数据！！”
     */
    private void checkCnAmount(ExtendedDataEntity dataEntitie, DynamicObject dataEntity) {
        DynamicObject billtype = dataEntity.getDynamicObject("yem_billtype");
        if (billtype != null) {
            String billNumber = billtype.getString("number");
            StringBuffer info = new StringBuffer();
            int infoRow = 1;
            DynamicObjectCollection yemesmaterialinfo = dataEntity.getDynamicObjectCollection("yem_es_materialinfo");
            if ("yem_es_salesorder_ZJ".equals(billNumber)) {
                for (DynamicObject tempZj : yemesmaterialinfo) {
                    long aLong = tempZj.getLong("yem_intauditbusaid");
                    if (YEM.isNotEmpty(aLong)) {
                        BigDecimal yemOnecarcom = tempZj.getBigDecimal("yem_onecarcom");
                        DynamicObject datas = BusinessDataServiceHelper.loadSingle(aLong, "yem_im_intauditbusa");
                        if (datas != null) {
                            datas = BusinessDataServiceHelper.loadSingle(datas.getPkValue(), datas.getDynamicObjectType().getName());
                            BigDecimal yemCommissionamt = datas.getBigDecimal("yem_commissionamt");
                            if (!Objects.equals(yemCommissionamt, yemOnecarcom)) {
                                info.append("明细信息第" + infoRow + "行,单车佣金跟其对应的内审预算单佣金" + yemCommissionamt.setScale(2) + "不一致，请检查数据！！\r\n");
                            }
                        }
                    }
                    infoRow++;
                }

            }
            if ("yem_es_salesorder_PJ".equals(billNumber)) {
                if (yemesmaterialinfo != null && yemesmaterialinfo.size() > 0) {
                    BigDecimal Commissionamt = dataEntity.getBigDecimal("yem_commissionamt");
                    long aLong = yemesmaterialinfo.get(0).getLong("yem_intauditbusaid");
                    if (YEM.isNotEmpty(aLong)) {
                        DynamicObject datas = BusinessDataServiceHelper.loadSingle(aLong, "yem_im_intauditbusa");
                        if (datas != null) {
                            datas = BusinessDataServiceHelper.loadSingle(datas.getPkValue(), datas.getDynamicObjectType().getName());
                            BigDecimal yemCommissionamt = datas.getBigDecimal("yem_commissionamt");
                            if (!Objects.equals(yemCommissionamt, Commissionamt)) {
                                info.append("外销合同总佣金与内审预算单的佣金" + yemCommissionamt.setScale(2) + "不一致，请检查数据!!\r\n");
                            }
                        }

                    }
                }
            }
            if (info.length() > 0) {
                this.addErrorMessage(dataEntitie, info.toString());
            }

        }
    }

    /**
     * @description 整机物料分类校验
     * @author xwudd
     * @param[1] dataEntity
     * return 返回校验信息
     * @time 2023/8/4 11:49
     */

    public String detailInfoMaterialClass(DynamicObject dataEntity) {
        Boolean flag = false;
        DynamicObjectCollection materialInfos = dataEntity.getDynamicObjectCollection("yem_es_materialinfo");
        for (DynamicObject materialInfo : materialInfos) {
            String materialClass = materialInfo.getString("yem_businesssort");
            if ("Z".equals(materialClass)) {
                flag = true;
            }
        }
        if (!flag) {
            return "整机合同，明细信息至少要有一条物料分类为整机的信息！";
        } else {
            return null;
        }
    }

    /**
     * 弱控制 标准销售加价（结算币别）
     *
     * @param dataEntity
     * @return
     */
    public void marketraiseprice(ExtendedDataEntity dataEntitie, DynamicObject dataEntity) {
        StringBuffer info = new StringBuffer();
        boolean flags = false;
        DynamicObjectCollection detailedinfor = dataEntity.getDynamicObjectCollection("yem_es_materialinfo");
        int row = 1;
        if (detailedinfor != null && detailedinfor.size() > 0) {
            for (DynamicObject dy : detailedinfor) {
                int sonRow = 1;
                DynamicObjectCollection dynamicObjects = dy.getDynamicObjectCollection("yem_multiconfig");
                for (DynamicObject temp1 : dynamicObjects) {
                    BigDecimal marketraiseprice = temp1.getBigDecimal("yem_marketraiseprice");
                    if (BigDecimal.ZERO.compareTo(marketraiseprice) == 0) {
                        flags = true;
                        info.append("明细信息第" + row + "行对应的多功能配置页签 第" + sonRow + "行的【标准销售加价（结算币别）】为空 请填写！" + "\r\n");
                    }
                    sonRow++;
                }
                row++;
            }
        }
        if (flags) {
            this.addWarningMessage(dataEntitie, info.toString());
        }

    }


    /**
     * @description 信保额度校验
     * @author xwudd
     * @param[1] dataEntity
     * return 返回校验信息
     * @time 2023/8/4 11:49
     */

    public void sinosureCheck(DynamicObject dataEntity, ExtendedDataEntity dataEntitie) {
        DynamicObject customer = dataEntity.getDynamicObject("yem_customer");
        if (YEM.isNotEmpty(customer)) {
            BigDecimal total = BigDecimal.ZERO;
            DynamicObjectCollection salesContracs = dataEntity.getDynamicObjectCollection("yem_es_salescontrac_s");
            for (DynamicObject salesContrac : salesContracs) {
                String isSinosure = salesContrac.getString("yem_issinosure");
                if ("A".equals(isSinosure)) {
                    total = total.add(salesContrac.getBigDecimal("yem_suminsured"));
                }
            }
            DynamicObject method = TotalUtil.getSettlementMethod(dataEntity);
            DynamicObject company = dataEntity.getDynamicObject("yem_company.yem_erporg");
            String swiftCode = TotalUtil.getSwiftCode(dataEntity);
            DynamicObject csrCreditLine = TotalUtil.getCsrCreditLine(customer, method, company, swiftCode);
            if (YEM.isNotEmpty(csrCreditLine)) {
                BigDecimal balance = csrCreditLine.getBigDecimal("yem_balance");//yem_suminsured
                if (total.compareTo(balance) > 0) {
                    this.addWarningMessage(dataEntitie, String.format("当前合同的信保额度{%s}超出其剩余限额{%s}，请检查数据！", total, balance));
                }
                String status = csrCreditLine.getString("yem_limitstatus");
                if ("B".equals(status)) {
                    this.addErrorMessage(dataEntitie, "当前客户信保额度申请失效，请联系单证确认！！");
                }
            } else {
                this.addErrorMessage(dataEntitie, "该客户找不到信保额度申请，不可参与信保！");
            }
        }
    }


    public String accUeDetailValidator(DynamicObject dataEntity) {
        String fundUseType = dataEntity.getString("yem_fundusetype");
        if (!"B".equals(fundUseType)) {
            return null;
        }
        BigDecimal orderUseAmtTotal = BigDecimal.ZERO;
        BigDecimal fundPoolAmt = dataEntity.getBigDecimal("yem_fundpoolamt");
        DynamicObjectCollection accFundDetails = dataEntity.getDynamicObjectCollection("yem_accfunddetail");
        for (DynamicObject accFundDetail : accFundDetails) {
            BigDecimal orderUseAmt = accFundDetail.getBigDecimal("yem_orderuseamt");
            orderUseAmtTotal = orderUseAmtTotal.add(orderUseAmt);
        }
        if (!(orderUseAmtTotal.compareTo(fundPoolAmt) == 0)) {
            return String.format("配件资金使用明细的合同使用金额{%s}不等于使用额度/资金池额度{%s}，请检查数据！", orderUseAmtTotal.setScale(2, BigDecimal.ROUND_HALF_UP), fundPoolAmt.setScale(2, BigDecimal.ROUND_HALF_UP));
        } else {
            return null;
        }
    }

    /**
     * @description 整机时是否礼品赠送为是 校验礼品金额是否为0
     * @author power
     * @time 2023/10/13
     */
    public void giftVerification(ExtendedDataEntity dataEntitie, DynamicObject dataEntity) {
        DynamicObject billType = dataEntity.getDynamicObject("yem_billtype");
        if (billType != null) {
            String number = billType.getString("number");
            if ("yem_es_salesorder_ZJ".equals(number) || "yem_es_salesorder_nmzj".equals(number)) {
                if (StringUtil.isNotEmpty(dataEntity.getString("yem_isgiftgive"))) {
                    if ("A".equals(dataEntity.getString("yem_isgiftgive"))) {
                        BigDecimal giftamountsum = dataEntity.getBigDecimal("yem_giftamountsum");
                        if (giftamountsum.compareTo(BigDecimal.ZERO) == 0) {
                            this.addErrorMessage(dataEntitie, "合同存在礼品赠送，需要在礼品赠送信息中维护礼品赠送明细，请维护数据后在操作");
                        }
                    }
                }
            }
        }
    }

    /**
     * @description 整机时是否礼品赠送为是 校验礼品金额是否为0
     * @author power
     * @time 2023/10/13
     */
    public void PartsVerification(ExtendedDataEntity dataEntitie, DynamicObject dataEntity) {
        DynamicObject billType = dataEntity.getDynamicObject("yem_billtype");
        if (billType != null) {
            String number = billType.getString("number");
            if ("yem_es_salesorder_ZJ".equals(number) || "yem_es_salesorder_nmzj".equals(number)) {
                if (StringUtil.isNotEmpty(dataEntity.getString("yem_isgiftgiveparts"))) {
                    if ("A".equals(dataEntity.getString("yem_isgiftgiveparts"))) {
                        BigDecimal giftamountsum = dataEntity.getBigDecimal("yem_giveamountsum");
                        if (giftamountsum.compareTo(BigDecimal.ZERO) == 0) {
                            this.addErrorMessage(dataEntitie, "合同存在配件赠送，需要在配件赠送信息中维护配件赠送明细，请维护数据后在操作");
                        }
                    }
                }
            }
        }
    }

    public void sinosureValidator(ExtendedDataEntity dataEntitie, DynamicObject dataEntity) {
        boolean isSinosureCon = dataEntity.getBoolean("yem_issinosurecon");
        if (isSinosureCon) {
            Boolean flag = true;
            DynamicObjectCollection payEntrys = dataEntity.getDynamicObjectCollection("yem_es_salescontrac_s");
            for (DynamicObject payEntry : payEntrys) {
                String isSinosure = payEntry.getString("yem_issinosure");
                if ("A".equals(isSinosure)) {
                    flag = false;
                }
            }
            if (flag) {
                this.addErrorMessage(dataEntitie, "该合同为信保合同，收款计划中至少有一行是否信保需为是！");
            }
        }

    }

    /**
     * @description 收汇金额合计与表头金额（价格条款）是否一致校验
     * @author xwudd
     * @param[1] dataEntitie
     * return
     * @time 2023/11/9 16:14
     */

    public void rapAmtValidator(ExtendedDataEntity dataEntitie) {
        DynamicObject dataEntity = dataEntitie.getDataEntity();
        BigDecimal rapAmt = BigDecimal.ZERO;
        BigDecimal offerAmount = BigDecimal.ZERO;
        DynamicObjectCollection payPlans = dataEntity.getDynamicObjectCollection("yem_es_salescontrac_s");
        for (DynamicObject payPlan : payPlans) {
            rapAmt = rapAmt.add(payPlan.getBigDecimal("yem_rapamt").setScale(2, RoundingMode.HALF_UP));
        }
        DynamicObjectCollection collection = dataEntity.getDynamicObjectCollection("yem_es_materialinfo");


        for (DynamicObject dynamicObject : collection) {
            offerAmount = offerAmount.add(dynamicObject.getBigDecimal("yem_saamtpriceclause").setScale(2, RoundingMode.HALF_UP));
        }
        if (rapAmt.compareTo(offerAmount) != 0) {
            this.addErrorMessage(dataEntitie, String.format("外销合同的合同金额{财务信息-金额（价格条款）{%s}跟其 收款计划-收汇金额合计{%s}不一致，请调整数据后重试！", offerAmount, rapAmt));
        }
    }


    /**
     * @description 贷记单校验
     * @author power
     * @param[1] dataEntity
     * @time 2023/12/6
     */
    public void credit(ExtendedDataEntity dataEntitie, DynamicObject dataEntity) {
        DynamicObject billtype = dataEntity.getDynamicObject("yem_billtype");
        if (billtype != null) {
            String number = billtype.getString("number");
            if ("yem_es_salesorder_PJ".equals(number)) {
                if (StringUtil.isNotEmpty(dataEntity.getString("yem_fundusetype"))) {
                    String isgiftgiveparts = dataEntity.getString("yem_fundusetype");
                    if ("B".equals(isgiftgiveparts)) {
                        DynamicObjectCollection accfunddetails = dataEntity.getDynamicObjectCollection("yem_accfunddetail");
                        for (DynamicObject accfunddetail : accfunddetails) {
                            if (accfunddetail.getDynamicObject("yem_debcredtype") != null) {
                                DynamicObject debcredtype = accfunddetail.getDynamicObject("yem_debcredtype");
                                String debcredtypenum = debcredtype.getString("number");
                                if ("JDJLX-1001".equals(debcredtypenum)) {
                                    if (accfunddetail.getDynamicObject("yem_usedebcrednoteno") != null) {
                                        DynamicObject yem_usedebcrednoteno = accfunddetail.getDynamicObject("yem_usedebcrednoteno");
                                        String usedebcrednoteno = yem_usedebcrednoteno.getString("billno");
                                        DynamicObject giftamountss = BusinessDataServiceHelper.loadSingle("yem_spcapitalpool",
                                                new QFilter[]{new QFilter("yem_spcapitalpool_o.yem_originno", QCP.equals, usedebcrednoteno),});
                                        DynamicObjectCollection spcapitalpoolos = giftamountss.getDynamicObjectCollection("yem_spcapitalpool_o");
                                        for (DynamicObject spcapitalpoolo : spcapitalpoolos) {
                                            if (StringUtil.isNotEmpty(spcapitalpoolo.getString("yem_originno"))) {
                                                String originno = spcapitalpoolo.getString("yem_originno");
                                                if (originno.equals(usedebcrednoteno)) {
                                                    //贷记单使用金额
                                                    BigDecimal debcuseamt = accfunddetail.getBigDecimal("yem_debcuseamt");
                                                    //控制额度
                                                    BigDecimal limitcontrol = debcredtype.getBigDecimal("yem_limitcontrol");
                                                    //剩余可用
                                                    BigDecimal residueavaamt = spcapitalpoolo.getBigDecimal("yem_residueavaamt");
                                                    BigDecimal sum = limitcontrol.add(residueavaamt);
                                                    if (sum.compareTo(debcuseamt) == -1) {
                                                        this.addErrorMessage(dataEntitie, "贷记单" + usedebcrednoteno + "允许超额的剩余额度:" + sum.stripTrailingZeros().toPlainString() + ",本次使用额度:" + debcuseamt + ",已超额,请确认");
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 最新财务标准售价为空时，不允许提交
     */
    private void checkNewPrice(DynamicObject dataEntity) {
        String name = dataEntity.getDynamicObject("yem_billtype").getString("number");
        if ("yem_es_salesorder_nmpj".equals(name) || "yem_es_salesorder_PJ".equals(name)) {
            DynamicObjectCollection collection = dataEntity.getDynamicObjectCollection("yem_es_materialinfo");
            for (DynamicObject dynamicObject : collection) {
                int index = collection.indexOf(dynamicObject);
                BigDecimal newprice = dynamicObject.getBigDecimal("yem_newprice");
                if (newprice.compareTo(BigDecimal.ZERO) == 0) {
                    throw new KDBizException("商品明细第 " + (index + 1) + " 行物料未获取财务售价，请确认！");
                }
            }
        }
    }
}
