package com.yem.wm.es.shippingdetails.util;

import com.yem.wm.es.contractamtlist.util.FunUtil;
import com.yem.wm.utils.DynamicObjectUtil;
import com.yem.wm.utils.YEM;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;

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

import static com.yem.wm.es.contractamtlist.util.FunUtil.getBillStatusQFilter;
import static com.yem.wm.es.contractamtlist.util.FunUtil.getThisShippingDetails;

/**
 * @author xwudd
 * @Description
 * @date 11:34
 **/
public class PaymentControlUtil
{

    /**
     * @description 获取合同的所有收款
     * @author xwudd
     * @param[1] saleOrderId 合同id
     * return
     * @time 2023/11/9 10:08
     */

    public static BigDecimal getCollection(long saleOrderId)
    {
        BigDecimal claimAmt = BigDecimal.ZERO;
        String selectfields = DynamicObjectUtil.getSelectfields("yem_gathering", false);
        selectfields = DynamicObjectUtil.getEntrySelectfields(selectfields, "yem_gathering", "yem_receiptdetail", false);
        selectfields = DynamicObjectUtil.getEntrySelectfields(selectfields, "yem_gathering", "yem_receiptdetail", "yem_claimdetail", false);
        QFilter qFilter = new QFilter("yem_receiptdetail.yem_claimdetail.yem_salcontractno", QCP.equals, saleOrderId);
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        qFilter.and(new QFilter("yem_financeaffirm", QCP.equals, "B"));
        DynamicObject[] gatherings = BusinessDataServiceHelper.load("yem_gathering", selectfields, qFilter.toArray());
        for (DynamicObject gathering : gatherings) {
            DynamicObjectCollection receiptDetails = gathering.getDynamicObjectCollection("yem_receiptdetail");
            for (DynamicObject receiptDetail : receiptDetails) {
                DynamicObjectCollection claimDetails = receiptDetail.getDynamicObjectCollection("yem_claimdetail");
                for (DynamicObject claimDetail : claimDetails) {
                    DynamicObject salContract = claimDetail.getDynamicObject("yem_salcontractno");
                    if (YEM.isNotEmpty(salContract)) {
                        long salContractId = salContract.getLong("id");
                        if (saleOrderId == salContractId) {
                            claimAmt = claimAmt.add(claimDetail.getBigDecimal("yem_salcontractclaamt"));
                        }
                    }
                }
            }
        }
        return claimAmt;
    }

    /**
     * @description 获取合同的所有收款
     * @author xwudd
     * @param[1] saleOrder
     * @param[2] gatherings
     * return
     * @time 2023/11/17 14:19
     */

    public static BigDecimal getCollection(DynamicObject saleOrder, DynamicObject[] gatherings)
    {
        BigDecimal claimAmt = BigDecimal.ZERO;
        long saleOrderId = saleOrder.getLong("id");
        for (DynamicObject gathering : gatherings) {
            DynamicObjectCollection receiptDetails = gathering.getDynamicObjectCollection("yem_receiptdetail");
            for (DynamicObject receiptDetail : receiptDetails) {
                DynamicObjectCollection claimDetails = receiptDetail.getDynamicObjectCollection("yem_claimdetail");
                for (DynamicObject claimDetail : claimDetails) {
                    DynamicObject salContract = claimDetail.getDynamicObject("yem_salcontractno");
                    if (YEM.isNotEmpty(salContract)) {
                        long salContractId = salContract.getLong("id");
                        if (saleOrderId == salContractId) {
                            claimAmt = claimAmt.add(claimDetail.getBigDecimal("yem_salcontractclaamt"));
                        }
                    }
                }
            }
        }
        return claimAmt;
    }


    /**
     * 下单预收款的-合同认领金额，款项性质为为下单预收款的
     *
     * @param saleOrder
     * @param gatherings
     * @param prop       款项性质
     * @return
     * @author ZZSLL
     */
    public static BigDecimal getPreCollection(DynamicObject saleOrder, DynamicObject[] gatherings, String prop)
    {
        BigDecimal claimAmt = BigDecimal.ZERO;
        long saleOrderId = saleOrder.getLong("id");
        for (DynamicObject gathering : gatherings) {
            DynamicObjectCollection receiptDetails = gathering.getDynamicObjectCollection("yem_receiptdetail");
            for (DynamicObject receiptDetail : receiptDetails) {
                DynamicObjectCollection claimDetails = receiptDetail.getDynamicObjectCollection("yem_claimdetail");
                for (DynamicObject claimDetail : claimDetails) {
                    // 款项性质
                    String moneynature = claimDetail.getString("yem_moneynature");
                    if (prop.equals(moneynature)) {
                        DynamicObject salContract = claimDetail.getDynamicObject("yem_salcontractno");
                        if (YEM.isNotEmpty(salContract)) {
                            long salContractId = salContract.getLong("id");
                            if (saleOrderId == salContractId) {
                                claimAmt = claimAmt.add(claimDetail.getBigDecimal("yem_salcontractclaamt"));
                            }
                        }
                    }
                }
            }
        }
        return claimAmt;
    }

    /**
     * @description 获取合同的除去本收款单的所有收款
     * @author xwudd
     * @param[1] saleOrderId 合同id
     * return
     * @time 2023/11/9 10:08
     */

    public static BigDecimal getCollection(DynamicObject salesOrder, Long gatheringId)
    {
        BigDecimal claimAmt = BigDecimal.ZERO;
        long id = salesOrder.getLong("id");
        String selectfields = DynamicObjectUtil.getSelectfields("yem_gathering", false);
        selectfields = DynamicObjectUtil.getEntrySelectfields(selectfields, "yem_gathering", "yem_receiptdetail", false);
        selectfields = DynamicObjectUtil.getEntrySelectfields(selectfields, "yem_gathering", "yem_receiptdetail", "yem_claimdetail", false);
        QFilter qFilter = new QFilter("yem_receiptdetail.yem_claimdetail.yem_salcontractno", QCP.equals, id);
        qFilter.and(new QFilter("id", QCP.not_equals, gatheringId));
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        qFilter.and(new QFilter("yem_financeaffirm", QCP.equals, "B"));

        DynamicObject[] gatherings = BusinessDataServiceHelper.load("yem_gathering", selectfields, qFilter.toArray());
        for (DynamicObject gathering : gatherings) {
            DynamicObjectCollection receiptDetails = gathering.getDynamicObjectCollection("yem_receiptdetail");
            for (DynamicObject receiptDetail : receiptDetails) {
                DynamicObjectCollection claimDetails = receiptDetail.getDynamicObjectCollection("yem_claimdetail");
                for (DynamicObject claimDetail : claimDetails) {
                    DynamicObject salContract = claimDetail.getDynamicObject("yem_salcontractno");
                    if (YEM.isNotEmpty(salContract)) {
                        long salContractId = salContract.getLong("id");
                        if (id == salContractId) {
                            claimAmt = claimAmt.add(claimDetail.getBigDecimal("yem_salcontractclaamt"));
                        }
                    }
                }
            }
        }
        return claimAmt;
    }

    /**
     * @description 获取合同未关闭明细信息行 销售金额（价格条款合计）
     * @author xwudd
     * @param[1] salesOrder
     * return
     * @time 2023/11/9 11:24
     */

    public static BigDecimal getContractPayment(DynamicObject salesOrder)
    {
        BigDecimal saAmtPriceClause = BigDecimal.ZERO;
        if (YEM.isNotEmpty(salesOrder)) {
            DynamicObjectCollection materialInfos = salesOrder.getDynamicObjectCollection("yem_es_materialinfo");
            for (DynamicObject materialInfo : materialInfos) {
                String lineClosstate = materialInfo.getString("yem_lineclosstate");
                if ("A".equals(lineClosstate)) {
                    saAmtPriceClause = saAmtPriceClause.add(materialInfo.getBigDecimal("yem_saamtpriceclause"));
                }
            }
//            saAmtPriceClause = saAmtPriceClause;
        }
        return saAmtPriceClause;
    }


    /**
     * @param saleOrder
     * @return
     */
    public static BigDecimal getContractPrePayment(DynamicObject saleOrder)
    {
        return null;
    }

    /**
     * 获取合同未关闭明细信息行 && 是生产预收 销售金额（价格条款合计）
     *
     * @param salesOrder
     * @return
     * @author ZZSLL
     */
    public static BigDecimal getContractProcPayment(DynamicObject salesOrder)
    {
        BigDecimal saAmtPriceClause = BigDecimal.ZERO;
        if (YEM.isNotEmpty(salesOrder)) {
            DynamicObjectCollection materialInfos = salesOrder.getDynamicObjectCollection("yem_es_materialinfo");
            for (DynamicObject materialInfo : materialInfos) {
                String lineClosstate = materialInfo.getString("yem_lineclosstate");
                String isprepayment = materialInfo.getString("yem_isprepayment");
                if ("A".equals(lineClosstate) && "A".equals(isprepayment)) {
                    saAmtPriceClause = saAmtPriceClause.add(materialInfo.getBigDecimal("yem_saamtpriceclause"));
                }
            }
        }
        return saAmtPriceClause;
    }

    /**
     * 获取合同未关闭明细信息行 && 是发货预收 销售金额（价格条款合计）
     *
     * @param salesOrder
     */
    public static BigDecimal getContractShipPayment(DynamicObject salesOrder)
    {
        BigDecimal saAmtPriceClause = BigDecimal.ZERO;
        if (YEM.isNotEmpty(salesOrder)) {
            DynamicObjectCollection materialInfos = salesOrder.getDynamicObjectCollection("yem_es_materialinfo");
            for (DynamicObject materialInfo : materialInfos) {
                String lineClosstate = materialInfo.getString("yem_lineclosstate");
                String isprepayment = materialInfo.getString("yem_isshippayment");
                if ("A".equals(lineClosstate) && "A".equals(isprepayment)) {
                    saAmtPriceClause = saAmtPriceClause.add(materialInfo.getBigDecimal("yem_saamtpriceclause"));
                }
            }
        }
        return saAmtPriceClause;
    }

    /**
     * @description 获取提交、审核的历史发运单 财务信息 金额（价格条款合计）
     * @author xwudd
     * @param[1] sourceBillType
     * @param[2] sourceBillId
     * @param[3] salesOrder
     * return
     * @time 2023/11/9 11:24
     */
    public static BigDecimal getBalancePayment(long id, String sourceBillType, long sourceBillId)
    {
        BigDecimal offerAmount = BigDecimal.ZERO;
        QFilter qFilter = new QFilter("yem_sourcebilltype", QCP.equals, sourceBillType);
        qFilter.and(new QFilter("yem_sourcebillid", QCP.equals, sourceBillId));
        qFilter.and(new QFilter("id", QCP.not_equals, id));
        qFilter.and(new QFilter("billstatus", QCP.in, new String[]{"B", "C"}));
        DynamicObject[] shippingDetails = BusinessDataServiceHelper.load("yem_shippingdetails", "id,yem_offeramount",
                qFilter.toArray());
        for (DynamicObject shippingDetail : shippingDetails) {
            offerAmount = offerAmount.add(shippingDetail.getBigDecimal("yem_offeramount"));
        }
        return offerAmount;
    }

    /**
     * @description
     * @author xwudd
     * @param[1] id
     * @param[2] shippingDetails
     * return
     * @time 2023/11/16 17:19
     */

    public static BigDecimal getBalancePayment(long id, DynamicObject[] shippingDetails)
    {
        BigDecimal offerAmount = BigDecimal.ZERO;
        for (DynamicObject shippingDetail : shippingDetails) {
            offerAmount = offerAmount.add(shippingDetail.getBigDecimal("yem_offeramount"));
        }
        return offerAmount;
    }


    /**
     * @description 获取本次发运单 财务信息 金额（价格条款合计）
     * @author xwudd
     * @param[1] dataEntitie
     * @param[2] salesOrder
     * return
     * @time 2023/11/9 11:30
     */

    public static BigDecimal getTranslateBalancePayment(DynamicObject dataEntitie)
    {
        BigDecimal offerAmount = dataEntitie.getBigDecimal("yem_offeramount");
        return offerAmount;
    }


    /**
     * @description 获取外销合同对应的已审核所有出运明细-财务信息-金额（价格条款）的合计
     * @author xwudd
     * * @param[1] sourceBillType
     * @param[2] sourceBillId
     * @param[3] salesOrder
     * return
     * @time 2023/11/10 11:09
     */

    public static BigDecimal getAllBalancePayment(String sourceBillType, long sourceBillId)
    {
        BigDecimal offerAmount = BigDecimal.ZERO;
        QFilter qFilter = new QFilter("yem_sourcebilltype", QCP.equals, sourceBillType);
        qFilter.and(new QFilter("yem_sourcebillid", QCP.equals, sourceBillId));
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        DynamicObject[] shippingDetails = BusinessDataServiceHelper.load("yem_shippingdetails", "id,yem_offeramount",
                qFilter.toArray());
        for (DynamicObject shippingDetail : shippingDetails) {
            offerAmount = offerAmount.add(shippingDetail.getBigDecimal("yem_offeramount"));
        }
        return offerAmount;
    }


    /**
     * @description 获取外销合同对应的已审核所有出运明细-财务信息-金额（价格条款）的合计
     * @author xwudd
     * @param[1] shippingDetails
     * return
     * @time 2023/11/10 11:09
     */

    public static BigDecimal getAllBalancePayment(DynamicObject[] shippingDetails)
    {
        BigDecimal offerAmount = BigDecimal.ZERO;
        for (DynamicObject shippingDetail : shippingDetails) {
            offerAmount = offerAmount.add(shippingDetail.getBigDecimal("yem_offeramount"));
        }
        return offerAmount;
    }

    /**
     * @description 获取提交、审核的历史发货单 财务信息-价税合计 合计
     * @author xwudd
     * @param[1] sourceBillType
     * @param[2] sourceBillId
     * @param[3] salesOrder
     * return
     * @time 2023/11/9 11:24
     */
    public static BigDecimal getDeliverPayment(long id, String coreBillType, long coreBillId)
    {
        BigDecimal totalAllAmount = BigDecimal.ZERO;
        QFilter qFilter = new QFilter("yem_corebilltype", QCP.equals, coreBillType);
        qFilter.and(new QFilter("yem_corebillid", QCP.equals, coreBillId));
        qFilter.and(new QFilter("id", QCP.not_equals, id));
        qFilter.and(new QFilter("billstatus", QCP.in, new String[]{"B", "C"}));
        DynamicObject[] shippingDetails = BusinessDataServiceHelper.load("yem_es_delivernotice", "id,yem_totalallamount",
                qFilter.toArray());
        for (DynamicObject shippingDetail : shippingDetails) {
            totalAllAmount = totalAllAmount.add(shippingDetail.getBigDecimal("yem_totalallamount"));
        }
        return totalAllAmount;
    }

    /**
     * @description 获取本次发货单 财务信息-价税合计 合计
     * @author xwudd
     * @param[1] dataEntitie
     * @param[2] salesOrder
     * return
     * @time 2023/11/9 11:30
     */

    public static BigDecimal getTranslateDeliverPayment(DynamicObject dataEntitie)
    {
        BigDecimal totalAllAmount = dataEntitie.getBigDecimal("yem_totalallamount");
        return totalAllAmount;
    }

    /**
     * @description 外销合同对应的所有已审核发货通知单-财务信息-价格合计 合计
     * @author xwudd
     * @param[1] coreBillType
     * @param[2] coreBillId
     * return
     * @time 2023/11/10 11:16
     */

    public static BigDecimal getAllDeliverPayment(String coreBillType, long coreBillId)
    {
        BigDecimal totalAllAmount = BigDecimal.ZERO;
        QFilter qFilter = new QFilter("yem_corebilltype", QCP.equals, coreBillType);
        qFilter.and(new QFilter("yem_corebillid", QCP.equals, coreBillId));
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        DynamicObject[] shippingDetails = BusinessDataServiceHelper.load("yem_es_delivernotice", "id,yem_totalallamount",
                qFilter.toArray());
        for (DynamicObject shippingDetail : shippingDetails) {
            totalAllAmount = totalAllAmount.add(shippingDetail.getBigDecimal("yem_totalallamount"));
        }
        return totalAllAmount;
    }


    /**
     * @description 外销合同对应的所有已审核发货通知单-财务信息-价格合计 合计
     * @author xwudd
     * @param[1] deliverNotices
     * return
     * @time 2023/11/10 11:16
     */

    public static BigDecimal getAllDeliverPayment(DynamicObject[] deliverNotices)
    {
        BigDecimal totalAllAmount = BigDecimal.ZERO;
        for (DynamicObject deliverNotice : deliverNotices) {
            totalAllAmount = totalAllAmount.add(deliverNotice.getBigDecimal("yem_totalallamount"));
        }
        return totalAllAmount;
    }


    /**
     * @description 获取合同预收的收汇百分比
     * @author xwudd
     * @param[1] salesOrder
     * return
     * @time 2023/11/9 11:22
     */

    public static BigDecimal getRapRate(DynamicObject salesOrder)
    {
        BigDecimal rapRate = BigDecimal.ZERO;
        DynamicObjectCollection paymentPlans = salesOrder.getDynamicObjectCollection("yem_es_salescontrac_s");
        for (DynamicObject paymentPlan : paymentPlans) {
            boolean isPre = paymentPlan.getBoolean("yem_ispre");
            if (isPre) {
                rapRate = rapRate.add(paymentPlan.getBigDecimal("yem_raprate"));
            }
        }
        return rapRate;
    }

    /**
     * 获取合同预收的收汇百分比 外销合同-应收计划-是生产预收-收汇比例%/100
     *
     * @param saleOrder
     * @return
     */
    public static BigDecimal getProcPreRapRate(DynamicObject saleOrder)
    {
        BigDecimal rapRate = BigDecimal.ZERO;
        DynamicObjectCollection paymentPlans = saleOrder.getDynamicObjectCollection("yem_es_salescontrac_s");
        for (DynamicObject paymentPlan : paymentPlans) {
            boolean isPre = paymentPlan.getBoolean("yem_ispre");
            String isprepayment = paymentPlan.getString("yem_isprepayment");
            if (isPre && "A".equals(isprepayment)) {
                rapRate = rapRate.add(paymentPlan.getBigDecimal("yem_raprate"));
            }
        }
        return rapRate;
    }

    /**
     * 获取合同预收的收汇百分比 发货预收汇比例
     *
     * @param saleOrder
     * @return
     */
    public static BigDecimal getShipPreRapRate(DynamicObject saleOrder)
    {
        BigDecimal rapRate = BigDecimal.ZERO;
        DynamicObjectCollection paymentPlans = saleOrder.getDynamicObjectCollection("yem_es_salescontrac_s");
        for (DynamicObject paymentPlan : paymentPlans) {
            boolean isPre = paymentPlan.getBoolean("yem_ispre");
            String isprepayment = paymentPlan.getString("yem_isshippayment");
            if (isPre && "A".equals(isprepayment)) {
                rapRate = rapRate.add(paymentPlan.getBigDecimal("yem_raprate"));
            }
        }
        return rapRate;
    }

    /**
     * @description 获取指定金额的尾款
     * @author xwudd
     * @param[1] amt
     * @param[2] rapRate
     * return
     * @time 2023/11/10 11:21
     */

    public static BigDecimal getBalancePayment(BigDecimal amt, BigDecimal rapRate)
    {
        return amt.multiply(BigDecimal.ONE.subtract(rapRate.divide(new BigDecimal(100))));
    }

    /**
     * @description 获取指定金额的预收款
     * @author xwudd
     * @param[1] amt
     * @param[2] rapRate
     * return
     * @time 2023/11/10 11:21
     */

    public static BigDecimal getAdvancePayment(BigDecimal amt, BigDecimal rapRate)
    {
        return amt.multiply(rapRate.divide(new BigDecimal(100)));
    }

    /**
     * 外销合同号向下所有已审核的下单审批-财务信息-本单金额的合计值
     *
     * @param saleOrder
     * @return
     * @author ZZSLL
     */
    public static BigDecimal getOrderedAmount(DynamicObject saleOrder, String auditOrAuditAndSubmit)
    {
        BigDecimal amount = BigDecimal.ZERO;
        Long pkValue = (Long) saleOrder.getPkValue();
        QFilter qFilter = new QFilter("yem_sourcebillid", QCP.equals, pkValue);
        qFilter = getBillStatusQFilter(qFilter, saleOrder, auditOrAuditAndSubmit);
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_placeexamine", "id, billno, yem_amount", qFilter.toArray());
        for (DynamicObject dynamicObject : load) {
            amount = amount.add(dynamicObject.getBigDecimal("yem_amount"));
        }
        return amount;
    }

    public static BigDecimal getCalcShipAmount(DynamicObject saleOrder)
    {
        BigDecimal resultAmo = BigDecimal.ZERO;
        Long pkValue = (Long) saleOrder.getPkValue();
        QFilter qFilter = new QFilter("yem_sourcebillid", QCP.equals, pkValue);
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));

        // 发运明细单
        DynamicObject[] shippingdetails = BusinessDataServiceHelper.load("yem_shippingdetails", "id, billno", qFilter.toArray());

        for (DynamicObject shippingdetail : shippingdetails) {
            DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(shippingdetail.getPkValue(), shippingdetail.getDataEntityType().getName());
            BigDecimal contractClaimAmount = getContractClaimAmount(dynamicObject);
            BigDecimal offeramount = dynamicObject.getBigDecimal("yem_offeramount");
            BigDecimal calcOfferamount = PaymentControlUtil.getAdvancePayment(offeramount, PaymentControlUtil.getShipPreRapRate(saleOrder));
            BigDecimal subtract = contractClaimAmount.subtract(calcOfferamount);
            if (subtract.compareTo(BigDecimal.ZERO) < 0) {
                resultAmo = resultAmo.add(subtract);
            }
        }
        return resultAmo;
    }

    /**
     * @param shippingDetails
     * @param shipPreRapRate
     * @return
     */
    public static BigDecimal getNewCalcShipAmount(DynamicObject[] shippingDetails, BigDecimal shipPreRapRate)
    {
        BigDecimal resultAmo = BigDecimal.ZERO;
        for (DynamicObject shippingdetail : shippingDetails) {
            DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(shippingdetail.getPkValue(), shippingdetail.getDataEntityType().getName());
            BigDecimal contractClaimAmount = getContractClaimAmount(dynamicObject);
//            BigDecimal offeramount = dynamicObject.getBigDecimal("yem_offeramount");
            BigDecimal offeramount = getShipedAmount(dynamicObject);
            BigDecimal calcOfferamount = PaymentControlUtil.getAdvancePayment(offeramount, shipPreRapRate);
            BigDecimal subtract = contractClaimAmount.subtract(calcOfferamount);
            if (subtract.compareTo(BigDecimal.ZERO) < 0) {
                resultAmo = resultAmo.add(subtract);
            }
        }
        return resultAmo;
    }

    public static BigDecimal getHistoryCalcShipAmount(DynamicObject[] shippingDetails, BigDecimal shipPreRapRate)
    {
        BigDecimal resultAmo = BigDecimal.ZERO;
        for (DynamicObject shippingdetail : shippingDetails) {
            DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(shippingdetail.getPkValue(), shippingdetail.getDataEntityType().getName());
            BigDecimal contractClaimAmount = getContractClaimAmount(dynamicObject);
            BigDecimal offeramount = dynamicObject.getBigDecimal("yem_offeramount");
            BigDecimal calcOfferamount = PaymentControlUtil.getAdvancePayment(offeramount, shipPreRapRate);
            BigDecimal subtract = contractClaimAmount.subtract(calcOfferamount);
            if (subtract.compareTo(BigDecimal.ZERO) < 0) {
                resultAmo = resultAmo.add(subtract);
            }
        }
        return resultAmo;
    }

    private static BigDecimal getShipedAmount(DynamicObject dynamicObject)
    {
        BigDecimal resultAmo = BigDecimal.ZERO;
        Long pkValue = (Long) dynamicObject.getPkValue();
        QFilter qFilter = new QFilter("yem_sourcebillid", QCP.equals, pkValue);
        getBillStatusQFilter(qFilter, dynamicObject, "B");
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_es_delivernotice", "id, billno, yem_totalallamount", qFilter.toArray());
        for (DynamicObject object : load) {
            resultAmo = resultAmo.add(object.getBigDecimal("yem_totalallamount"));
        }
        return resultAmo;
    }


    /**
     * 收款单-款项性质发货预收款对应发运单号的合同认领金额--Dd*（(外销合同-应收计划-是否发货预收-收汇比例%/100)是否大于0，大于0 不参与计算
     *
     * @param saleOrder
     * @param thisAmt
     * @param obj
     * @return
     */
    public static BigDecimal getHistoryCalcShipAmount(DynamicObject saleOrder, BigDecimal thisAmt, DynamicObject obj)
    {
        BigDecimal resultAmo = BigDecimal.ZERO;
        Long pkValue = (Long) saleOrder.getPkValue();
        QFilter qFilter = new QFilter("yem_sourcebillid", QCP.equals, pkValue);
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));

        Map<Long, DynamicObject> map = new HashMap<>();

        // 发运明细单
        DynamicObject[] shippingdetails = BusinessDataServiceHelper.load("yem_shippingdetails", "id, billno", qFilter.toArray());
        BigDecimal amountClaimed = PaymentControlUtil.getAmountClaimed(getThisShippingDetails(shippingdetails, obj), "D");
        BigDecimal shipPreRapRate = PaymentControlUtil.getShipPreRapRate(saleOrder);

        QFilter filter = new QFilter("yem_receiptdetail.yem_claimdetail.yem_salcontractno", QCP.equals, saleOrder.getPkValue());
        filter.and(new QFilter("billstatus", QCP.equals, "C"));
        qFilter.and(new QFilter("yem_financeaffirm", QCP.equals, "B"));
        DynamicObject[] gatherings = BusinessDataServiceHelper.load("yem_gathering", "id, billno", filter.toArray());

        for (DynamicObject gathering : gatherings) {
            Long value = (Long) gathering.getPkValue();
            if (!map.containsKey(value)) {
                map.put(value, gathering);
            }
        }

        Set<Map.Entry<Long, DynamicObject>> entries = map.entrySet();
        for (Map.Entry<Long, DynamicObject> entry : entries) {
            DynamicObject gathering = entry.getValue();
            DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(gathering.getPkValue(), gathering.getDataEntityType().getName());
            DynamicObjectCollection collection = dynamicObject.getDynamicObjectCollection("yem_receiptdetail");
            for (DynamicObject object : collection) {
                DynamicObjectCollection subCollection = object.getDynamicObjectCollection("yem_claimdetail");
                for (DynamicObject subObject : subCollection) {
                    // 款项性质
                    String moneynature = subObject.getString("yem_moneynature");
                    if ("E".equals(moneynature)) {
                        // 合同认领金额
                        BigDecimal subtract = amountClaimed.subtract(PaymentControlUtil.getAdvancePayment(thisAmt, shipPreRapRate));
                        if (subtract.compareTo(BigDecimal.ZERO) > 0) {
                            resultAmo = resultAmo.add(BigDecimal.ZERO);
                        } else {
                            resultAmo = resultAmo.add(subtract);
                        }
                    }
                }
            }
        }
        return resultAmo;
    }

    public static BigDecimal getHistoryDeliverShipAmount(DynamicObject saleOrder, BigDecimal thisShipAmt)
    {

        BigDecimal resultAmo = BigDecimal.ZERO;
        Long pkValue = (Long) saleOrder.getPkValue();
        QFilter qFilter = new QFilter("yem_sourcebillid", QCP.equals, pkValue);
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));

        // 发运明细单
        DynamicObject[] shippingdetails = BusinessDataServiceHelper.load("yem_shippingdetails", "id, billno", qFilter.toArray());

        for (DynamicObject shippingdetail : shippingdetails) {
            Object id = shippingdetail.getPkValue();
            QFilter filter = new QFilter("yem_receiptdetail.yem_claimdetail.yem_salcontractno", QCP.equals, id);
            filter.and(new QFilter("billstatus", QCP.equals, "C"));
            qFilter.and(new QFilter("yem_financeaffirm", QCP.equals, "B"));
            DynamicObject[] gatherings = BusinessDataServiceHelper.load("yem_gathering", "id, billno", filter.toArray());
            for (DynamicObject gathering : gatherings) {
                DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(gathering.getPkValue(), gathering.getDataEntityType().getName());
                DynamicObjectCollection collection = dynamicObject.getDynamicObjectCollection("yem_receiptdetail");
                for (DynamicObject object : collection) {
                    DynamicObjectCollection subCollection = object.getDynamicObjectCollection("yem_claimdetail");
                    for (DynamicObject subObject : subCollection) {
                        // 款项性质
                        String moneynature = subObject.getString("yem_moneynature");
                        if ("E".equals(moneynature)) {
                            // 合同认领金额
                            BigDecimal salcontractclaamt = subObject.getBigDecimal("yem_salcontractclaamt");
                            resultAmo = resultAmo.add(salcontractclaamt);
                        }
                    }
                }
            }
        }
        BigDecimal shipPreRapRate = PaymentControlUtil.getShipPreRapRate(saleOrder);
        BigDecimal subtract = resultAmo.subtract(PaymentControlUtil.getAdvancePayment(thisShipAmt, shipPreRapRate));
        if (subtract.compareTo(BigDecimal.ZERO) < 0) {
            return subtract;
        }
        return BigDecimal.ZERO;
    }

    /**
     * 是否大于0，大于0 返回0 的累计值
     *
     * @param calcShipAmount
     * @return
     */
    public static BigDecimal formatCalcShipAmount(BigDecimal calcShipAmount)
    {
        if (calcShipAmount.compareTo(BigDecimal.ZERO) > 0) {
            return BigDecimal.ZERO;
        }
        return calcShipAmount;
    }

    /**
     * @param saleOrder
     * @return
     * @author ZZSLL
     */
    public static BigDecimal getCalcDeliverAmount(DynamicObject saleOrder)
    {
        BigDecimal resultAmo = BigDecimal.ZERO;
        Long pkValue = (Long) saleOrder.getPkValue();
        QFilter qFilter = new QFilter("yem_sourcebillid", QCP.equals, pkValue);
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));

        // 发运明细单
        DynamicObject[] shippingdetails = BusinessDataServiceHelper.load("yem_shippingdetails", "id, billno", qFilter.toArray());

        for (DynamicObject shippingdetail : shippingdetails) {
            DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(shippingdetail.getPkValue(), shippingdetail.getDataEntityType().getName());
            BigDecimal contractClaimAmount = getContractClaimAmount(dynamicObject);

            QFilter filter = new QFilter("yem_sourcebillid", QCP.equals, shippingdetail.getPkValue());
            filter.and(new QFilter("billstatus", QCP.equals, "C"));
            // 当前发运明细单向下的 发货通知单(销售出库)
            DynamicObject[] delivernotices = BusinessDataServiceHelper.load("yem_es_delivernotice", "yem_amount", filter.toArray());

            BigDecimal currAmountSum = BigDecimal.ZERO;

            for (DynamicObject delivernotice : delivernotices) {
                BigDecimal amount = delivernotice.getBigDecimal("yem_amount");
                currAmountSum = currAmountSum.add(amount);
            }

            BigDecimal shipPreRapRate = PaymentControlUtil.getShipPreRapRate(saleOrder);
            BigDecimal calcAmount = PaymentControlUtil.getAdvancePayment(currAmountSum, shipPreRapRate);
            BigDecimal subtractRes = contractClaimAmount.subtract(calcAmount);
            if (subtractRes.compareTo(BigDecimal.ZERO) < 0) {
                resultAmo = resultAmo.add(subtractRes);
            }
        }
        return resultAmo;
    }

    /**
     * 查询发运明细单对应的合同认领金额
     *
     * @param dynamicObject 发运明细单
     * @author ZZSLL
     */
    private static BigDecimal getContractClaimAmount(DynamicObject dynamicObject)
    {
        BigDecimal resultAmo = BigDecimal.ZERO;
        Long pkValue = (Long) dynamicObject.getPkValue();
        QFilter qFilter = new QFilter("yem_receiptdetail.yem_claimdetail.yem_shippingdetailsno.id", QCP.equals, pkValue);

        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        qFilter.and(new QFilter("yem_financeaffirm", QCP.equals, "B"));
        // 收款单
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_gathering", "id, billno", qFilter.toArray());

        for (DynamicObject object : load) {
            object = BusinessDataServiceHelper.loadSingle(object.getPkValue(), object.getDataEntityType().getName());
            // 收款明细
            DynamicObjectCollection collection = object.getDynamicObjectCollection("yem_receiptdetail");

            for (DynamicObject entity : collection) {
                DynamicObjectCollection subCollection = entity.getDynamicObjectCollection("yem_claimdetail");
                for (DynamicObject subObject : subCollection) {
                    DynamicObject salcontractno = subObject.getDynamicObject("yem_shippingdetailsno");
                    if (salcontractno == null) continue;
                    long shippingdetail = salcontractno.getLong("id");
                    if (shippingdetail == pkValue) {
                        resultAmo = resultAmo.add(subObject.getBigDecimal("yem_salcontractclaamt"));
                    }
                }
            }
        }

        return resultAmo;
    }

    /**
     * 外销合同对应国贸欠款欠条的剩余未核销金额累计
     *
     * @param saleOrder
     * @return
     * @author ZZSLL
     */
    public static BigDecimal getIOUResidueAmount(DynamicObject saleOrder)
    {
        BigDecimal resultAmo = BigDecimal.ZERO;
        String billno = saleOrder.getString("billno");
        QFilter qFilter = new QFilter("yem_im_tradeapp.yem_im_tradeapp_em.yem_contractno", QCP.equals, billno);
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        DynamicObject[] tradeapps = BusinessDataServiceHelper.load("yem_im_tradeapp", "id, billno, yem_remainunwamount", qFilter.toArray());
        for (DynamicObject tradeapp : tradeapps) {
            resultAmo = resultAmo.add(tradeapp.getBigDecimal("yem_remainunwamount"));
        }
        return resultAmo;
    }

    public static BigDecimal getAllShipPayment(DynamicObject[] shippingDetails)
    {
        BigDecimal resAmt = BigDecimal.ZERO;
        for (DynamicObject shippingDetail : shippingDetails) {
            Long pkValue = (Long) shippingDetail.getPkValue();
            QFilter qFilter = new QFilter("yem_sourcebillid", QCP.equals, pkValue);
            qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
            DynamicObject[] delivernotices = BusinessDataServiceHelper.load("yem_es_delivernotice", "id, billno, yem_totalallamount", qFilter.toArray());
            resAmt = resAmt.add(getAllDeliverPayment(delivernotices));
        }
        return resAmt;
    }

    public static BigDecimal calcIOUAmount(DynamicObject dataEntity)
    {
        // 剩余未核销金额
        BigDecimal thisshipiouamt = BigDecimal.ZERO;

        String billno = dataEntity.getString("billno");
        QFilter qFilter = new QFilter("yem_shippingdetailsno", QCP.equals, billno);
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        // 整机配件货款延付申请
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_im_tradeapp", "id, billno", qFilter.toArray());
        if (load.length < 1) return thisshipiouamt;

        for (DynamicObject object : load) {
            DynamicObject single = BusinessDataServiceHelper.loadSingle(object.getPkValue(), object.getDynamicObjectType().getName());
            if (single == null) return thisshipiouamt;
            thisshipiouamt = thisshipiouamt.add(single.getBigDecimal("yem_thisshipiouamt"));
        }
        return thisshipiouamt;
    }


    /**
     * 合同号下单认领金额合计
     * 合同下 发运下 合同号对应 收款单 下单预收款的
     *
     * @param saleOrder 合同
     * @return
     * @author ZZSLL
     */
    public static BigDecimal getTotalClaimedAmount(DynamicObject saleOrder)
    {
        BigDecimal res = BigDecimal.ZERO;
        // 合同下发运明细单
        DynamicObject[] shippingdetails = getShipDetailsBySaleOrder(saleOrder);

        Set<String> saleOrderNo = new HashSet<>();
        // 发运明细单对应合同
        for (DynamicObject shippingdetail : shippingdetails) {
            saleOrderNo.add(shippingdetail.getString("yem_saleorderno"));
        }

        List<DynamicObject> receipt = new ArrayList<>();

        // 查合同下收款单
        for (String billno : saleOrderNo) {
            QFilter qFilter = new QFilter("yem_receiptdetail.yem_claimdetail.yem_salcontractno.billno", QCP.equals, billno);
            qFilter.and(new QFilter("yem_financeaffirm", QCP.equals, "B"));
            DynamicObject[] load = BusinessDataServiceHelper.load("yem_gathering", "id, billno", qFilter.toArray());
            for (DynamicObject dynamicObject : load) {
                if (receipt.contains(dynamicObject)) continue;
                receipt.add(dynamicObject);
            }
        }

        // 收款单下中下单预收款的认领金额
        for (DynamicObject dynamicObject : receipt) {
            dynamicObject = BusinessDataServiceHelper.loadSingle(dynamicObject.getPkValue(), dynamicObject.getDataEntityType().getName());
            DynamicObjectCollection receiptdetail = dynamicObject.getDynamicObjectCollection("yem_receiptdetail");
            for (DynamicObject object : receiptdetail) {
                DynamicObjectCollection claimdetail = object.getDynamicObjectCollection("yem_claimdetail");
                for (DynamicObject claim : claimdetail) {
                    String moneynature = claim.getString("yem_moneynature");
                    if ("D".equals(moneynature)) {
                        DynamicObject salcontractno = claim.getDynamicObject("yem_salcontractno");
                        if (salcontractno == null) continue;
                        long id = salcontractno.getLong("id");
                        if (id == (long) saleOrder.getPkValue()) {
                            res = res.add(claim.getBigDecimal("yem_salcontractclaamt"));
                        }
                    }
                }
            }
        }
        return res;
    }

    /**
     * 获取合同下所有的发运明细
     *
     * @param saleOrder 合同
     * @return
     * @author ZZSLL
     */
    public static DynamicObject[] getShipDetailsBySaleOrder(DynamicObject saleOrder)
    {
        Long pkValue = (Long) saleOrder.getPkValue();
        QFilter qFilter = new QFilter("yem_sourcebillid", QCP.equals, pkValue);
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_shippingdetails", "id, billno, yem_saleorderno, yem_offeramount", qFilter.toArray());
        return load == null ? new DynamicObject[]{} : load;
    }

    /**
     * 本合同历史已发运金额合计
     *
     * @param saleOrder      合同
     * @param shippingDetail 本次发运
     * @return
     * @author ZZSLL
     */
    public static BigDecimal getShipAmt(DynamicObject saleOrder, DynamicObject shippingDetail)
    {
        BigDecimal res = BigDecimal.ZERO;
        DynamicObject[] shipDetails = getShipDetailsBySaleOrder(saleOrder);
        for (DynamicObject object : shipDetails) {
            Long pkValue = (Long) object.getPkValue();
            if (shippingDetail != null) {
                Long detailPkValue = (Long) shippingDetail.getPkValue();
                if (!pkValue.equals(detailPkValue)) {
                    res = res.add(object.getBigDecimal("yem_offeramount"));
                }
            } else {
                res = res.add(object.getBigDecimal("yem_offeramount"));
            }
        }
        return res;
    }

    /**
     * 本次发运欠款金额，具体计算逻辑看报表
     *
     * @return
     */
    public static BigDecimal getThisRealityAmt(DynamicObject saleOrder, DynamicObject[] shippingDetails, DynamicObject[] gatherings, DynamicObject shippingDetail)
    {
        BigDecimal preCollection = PaymentControlUtil.getPreCollection(saleOrder, gatherings, "D");//合同下单已认领金额 C change
        BigDecimal allBalancePayment = FunUtil.getAllBalancePayment(shippingDetails, shippingDetail, "yem_offeramount");//已发运占用金额 D
        BigDecimal procPreRapRate = PaymentControlUtil.getProcPreRapRate(saleOrder);//生产预收汇比例
        BigDecimal shipPreRapRate = PaymentControlUtil.getShipPreRapRate(saleOrder);//发货预收汇比例
        BigDecimal thisAmt = FunUtil.getThisAmt(shippingDetail);//本次出运/发货金额

        BigDecimal newThisDeliverDebtAmt;
        BigDecimal formulaTwo = BigDecimal.ZERO;
        BigDecimal formulaOne = preCollection.subtract(PaymentControlUtil.getAdvancePayment(allBalancePayment, procPreRapRate));//400 - 1224 *0.3
        if (formulaOne.compareTo(BigDecimal.ZERO) > 0) {
            BigDecimal subtract = formulaOne.subtract(PaymentControlUtil.getAdvancePayment(thisAmt, procPreRapRate));
            if (subtract.compareTo(BigDecimal.ZERO) > 0) {
                formulaTwo = BigDecimal.ZERO;
            } else {
                formulaTwo = subtract;
            }
        } else {
            formulaTwo = BigDecimal.ZERO.subtract(PaymentControlUtil.getAdvancePayment(thisAmt, procPreRapRate));
        }

        BigDecimal formulaThreeRes = BigDecimal.ZERO;
        BigDecimal formulaThree = PaymentControlUtil.getThisCalcShipAmount(shippingDetail, thisAmt, shipPreRapRate, saleOrder);

        if (formulaThree.compareTo(BigDecimal.ZERO) > 0) {
            formulaTwo = BigDecimal.ZERO;
        } else {
            formulaThreeRes = formulaThree;
        }

        newThisDeliverDebtAmt = formulaTwo.add(formulaThreeRes);
        return newThisDeliverDebtAmt;
    }

    /**
     * 发运明细对应收款单中以认领金额合计
     *
     * @param shippingDetails
     * @param moneynature
     * @return
     */
    public static BigDecimal getAmountClaimed(DynamicObject[] shippingDetails, String moneynature)
    {
        BigDecimal res = BigDecimal.ZERO;
        for (DynamicObject shippingDetail : shippingDetails) {
            List<DynamicObject> gatherings = getGatheringByShipDetail(shippingDetail);
            for (DynamicObject gathering : gatherings) {
                DynamicObjectCollection collection = gathering.getDynamicObjectCollection("yem_receiptdetail");
                for (DynamicObject object : collection) {
                    DynamicObjectCollection subCollection = object.getDynamicObjectCollection("yem_claimdetail");
                    for (DynamicObject subObject : subCollection) {
                        String currMoneynature = subObject.getString("yem_moneynature");
                        DynamicObject shippingdetailsno = subObject.getDynamicObject("yem_shippingdetailsno");
                        if (moneynature.equals(currMoneynature) && shippingdetailsno != null && shippingdetailsno.getPkValue().equals(shippingDetail.getPkValue())) {
                            res = res.add(subObject.getBigDecimal("yem_salcontractclaamt"));
                        }
                    }
                }
            }
        }
        return res;
    }

    /**
     * 查找所有有认款的收款单
     * @param shippingDetail
     */
    private static List<DynamicObject> getGatheringByShipDetailSubmit(DynamicObject shippingDetail)
    {
        QFilter qFilter = new QFilter("yem_receiptdetail.yem_claimdetail.yem_shippingdetailsno.id", QCP.equals, shippingDetail.getPkValue());
        qFilter.and(new QFilter("billstatus",QCP.in,new String[]{"B","C"}));
        qFilter.and(new QFilter("yem_financeaffirm", QCP.equals, "B"));
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_gathering", "id, billno", qFilter.toArray());
        List<DynamicObject> dynamicObjects = new ArrayList<>();
        for (DynamicObject dynamicObject : load) {
            dynamicObjects.add(BusinessDataServiceHelper.loadSingle(dynamicObject.getPkValue(), dynamicObject.getDataEntityType().getName()));
        }
        return dynamicObjects;
    }

    /**
     * 查找所有有认款的收款单
     * @param shippingDetail
     */
    private static List<DynamicObject> getGatheringByShipDetail(DynamicObject shippingDetail)
    {
        QFilter qFilter = new QFilter("yem_receiptdetail.yem_claimdetail.yem_shippingdetailsno.id", QCP.equals, shippingDetail.getPkValue());
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        qFilter.and(new QFilter("yem_financeaffirm", QCP.equals, "B"));
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_gathering", "id, billno", qFilter.toArray());
        List<DynamicObject> dynamicObjects = new ArrayList<>();
        for (DynamicObject dynamicObject : load) {
            dynamicObjects.add(BusinessDataServiceHelper.loadSingle(dynamicObject.getPkValue(), dynamicObject.getDataEntityType().getName()));
        }
        return dynamicObjects;
    }

    /**
     * 本次发运欠款金额
     * @param shipdetail
     * @param thisAmt
     * @param shipPreRapRate
     * @param saleOrder
     * @return
     */
    public static BigDecimal getThisCalcShipAmount(DynamicObject shipdetail, BigDecimal thisAmt, BigDecimal shipPreRapRate, DynamicObject saleOrder)
    {
        BigDecimal resultAmo = BigDecimal.ZERO;
        BigDecimal claimAmount = BigDecimal.ZERO;
        long shipdetailPkValue = (long) shipdetail.getPkValue();
        List<DynamicObject> gathering = getGatheringByShipDetailSubmit(shipdetail);
        for (DynamicObject dynamicObject : gathering) {
            dynamicObject = BusinessDataServiceHelper.loadSingle(dynamicObject.getPkValue(), dynamicObject.getDataEntityType().getName());
            DynamicObjectCollection collection = dynamicObject.getDynamicObjectCollection("yem_receiptdetail");
            for (DynamicObject object : collection) {
                DynamicObjectCollection subCollection = object.getDynamicObjectCollection("yem_claimdetail");
                for (DynamicObject subObject : subCollection) {
                    DynamicObject shippingdetailsno = subObject.getDynamicObject("yem_shippingdetailsno");
                    if (shippingdetailsno == null) continue;
                    long pkValue = (long) shippingdetailsno.getPkValue();
                    if (pkValue == shipdetailPkValue) {
                        claimAmount = claimAmount.add(subObject.getBigDecimal("yem_salcontractclaamt"));
                    }
                }
            }
        }
        resultAmo = claimAmount.subtract(PaymentControlUtil.getAdvancePayment(thisAmt, shipPreRapRate));
        return resultAmo;
    }

    /**
     * 认领到该合同的合同认领金额合计值
     * @param salcontractno
     * @return
     */
    public static BigDecimal getContractClimeAmt(DynamicObject salcontractno, String moneynature)
    {
        BigDecimal res = BigDecimal.ZERO;
        QFilter qFilter = new QFilter("yem_receiptdetail.yem_claimdetail.yem_salcontractno", QCP.equals, salcontractno.getPkValue());
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        qFilter.and(new QFilter("yem_financeaffirm", QCP.equals, "B"));
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_gathering", "id, billno", qFilter.toArray());
        for (DynamicObject dynamicObject : load) {
            dynamicObject = BusinessDataServiceHelper.loadSingle(dynamicObject.getPkValue(), dynamicObject.getDataEntityType().getName());
            DynamicObjectCollection collection = dynamicObject.getDynamicObjectCollection("yem_receiptdetail");
            for (DynamicObject object : collection) {
                DynamicObjectCollection subCollection = object.getDynamicObjectCollection("yem_claimdetail");
                for (DynamicObject subObject : subCollection) {
                    DynamicObject claimContractNo = subObject.getDynamicObject("yem_salcontractno");
                    if (claimContractNo == null) continue;
                    long pkValue = (long) claimContractNo.getPkValue();
                    if (pkValue != (long) salcontractno.getPkValue()) continue;
                    if (YEM.isNotEmpty(moneynature)) {
                        String moneyNature = subObject.getString("yem_moneynature");
                        if (YEM.isEmpty(moneyNature)) continue;
                        if (moneynature.equals(moneyNature)) {
                            res = res.add(subObject.getBigDecimal("yem_salcontractclaamt"));
                        }
                    } else {
                        res = res.add(subObject.getBigDecimal("yem_salcontractclaamt"));
                    }
                }
            }
        }
        return res;
    }

    /**
     * 该合同向下的下单审批（不区分单据状态）总金额
     * @param salcontractno
     * @return
     */
    public static BigDecimal getContractOrderApprovalAmt(DynamicObject salcontractno)
    {
        BigDecimal amount = BigDecimal.ZERO;
        Long pkValue = (Long) salcontractno.getPkValue();
        QFilter qFilter = new QFilter("yem_sourcebillid", QCP.equals, pkValue);
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_placeexamine", "id, billno, yem_amount", qFilter.toArray());
        for (DynamicObject dynamicObject : load) {
            amount = amount.add(dynamicObject.getBigDecimal("yem_amount"));
        }
        return amount;
    }

    /**
     * 领到该发运向下的所有销售出库
     * @param shippingdetailsno
     * @return
     */
    public static BigDecimal getContractShipApprovalAmt(DynamicObject shippingdetailsno)
    {
        BigDecimal amount = BigDecimal.ZERO;
        Long pkValue = (Long) shippingdetailsno.getPkValue();
        QFilter qFilter = new QFilter("yem_sourcebillid", QCP.equals, pkValue);
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_es_delivernotice", "id, billno, yem_amount", qFilter.toArray());
        for (DynamicObject dynamicObject : load) {
            amount = amount.add(dynamicObject.getBigDecimal("yem_amount"));
        }
        return amount;
    }

    /**
     * 发运单号对应的收款的认领明细的-款项性质：moneynature的合同认领金额
     * @param shippingDetail
     * @param moneynature
     * @return
     */
    public static BigDecimal getShipClaimContractClimeAmt(DynamicObject shippingDetail, String moneynature)
    {
        BigDecimal res = BigDecimal.ZERO;
        QFilter qFilter = new QFilter("yem_receiptdetail.yem_claimdetail.yem_shippingdetailsno", QCP.equals, shippingDetail.getPkValue());
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        qFilter.and(new QFilter("yem_financeaffirm", QCP.equals, "B"));
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_gathering", "id, billno", qFilter.toArray());
        for (DynamicObject dynamicObject : load) {
            dynamicObject = BusinessDataServiceHelper.loadSingle(dynamicObject.getPkValue(), dynamicObject.getDataEntityType().getName());
            DynamicObjectCollection collection = dynamicObject.getDynamicObjectCollection("yem_receiptdetail");
            for (DynamicObject object : collection) {
                DynamicObjectCollection subCollection = object.getDynamicObjectCollection("yem_claimdetail");
                for (DynamicObject subObject : subCollection) {
                    DynamicObject claimShipDetailNo = subObject.getDynamicObject("yem_shippingdetailsno");
                    if (claimShipDetailNo == null) continue;
                    long pkValue = (long) claimShipDetailNo.getPkValue();
                    if (pkValue != (long) shippingDetail.getPkValue()) continue;
                    if (YEM.isNotEmpty(moneynature)) {
                        String moneyNature = subObject.getString("yem_moneynature");
                        if (YEM.isEmpty(moneyNature)) continue;
                        if (moneynature.equals(moneyNature)) {
                            res = res.add(subObject.getBigDecimal("yem_salcontractclaamt"));
                        }
                    } else {
                        res = res.add(subObject.getBigDecimal("yem_salcontractclaamt"));
                    }
                }
            }
        }
        return res;
    }

    /**
     * 合同下所有收款单
     * @param saleOrder
     * @param status
     * @return
     */
    public static BigDecimal getAllContractClimeAmt(DynamicObject saleOrder, String status)
    {
        DynamicObject[] gatherings = getGatheringBySalesOrder(saleOrder, status);
        BigDecimal res = BigDecimal.ZERO;
        for (DynamicObject gathering : gatherings) {
            DynamicObjectCollection collection = gathering.getDynamicObjectCollection("yem_receiptdetail");
            for (DynamicObject object : collection) {
                DynamicObjectCollection subCollection = object.getDynamicObjectCollection("yem_claimdetail");
                for (DynamicObject subObject : subCollection) {
                    DynamicObject salcontractno = subObject.getDynamicObject("yem_salcontractno");
                    if (salcontractno == null) continue;
                    long pkValue = (long) salcontractno.getPkValue();
                    if (pkValue != (long) saleOrder.getPkValue()) continue;
                    res = res.add(subObject.getBigDecimal("yem_salcontractclaamt"));
                }
            }
        }
        return res;
    }

    private static DynamicObject[] getGatheringBySalesOrder(DynamicObject saleOrder, String status)
    {
        String selectfields = DynamicObjectUtil.getSelectfields("yem_gathering", false);
        selectfields = DynamicObjectUtil.getEntrySelectfields(selectfields,"yem_gathering","yem_receiptdetail",false);
        selectfields = DynamicObjectUtil.getEntrySelectfields(selectfields,"yem_gathering","yem_receiptdetail","yem_claimdetail",false);

        QFilter qFilter = new QFilter("yem_comegoman.id",QCP.equals,saleOrder.getLong("yem_customer.id"));
        qFilter.and(new QFilter("yem_financeaffirm", QCP.equals, "B"));
        if ("A".equals(status)) {
            qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        } else {
            qFilter.and(new QFilter("billstatus", QCP.in, new String[]{"B", "C"}));
        }
        return BusinessDataServiceHelper.load("yem_gathering", selectfields, qFilter.toArray());
    }

    /**
     * 获取合同下所有销售出库
     * @param salesorder
     * @return
     */
    public static DynamicObject[] getContractStockOut(DynamicObject salesorder) {
        String billno = salesorder.getString("billno");
        QFilter qFilter = new QFilter("yem_contractnum", QCP.equals, billno);
        qFilter.and(new QFilter("billstatus", QCP.equals, "C"));
        String selectfields = DynamicObjectUtil.getSelectfields("yem_es_delivernotice");
        return BusinessDataServiceHelper.load("yem_es_delivernotice", selectfields, qFilter.toArray());
    }

    /**
     * 排除本次销售出库
     * @param stackOut
     * @param thisStack
     * @return
     */
    public static List<DynamicObject> excludeThisShipment(DynamicObject[] stackOut, DynamicObject thisStack) {
        List<DynamicObject> list = new ArrayList<>();
        Long thisId = (Long) thisStack.getPkValue();
        for (DynamicObject object : stackOut) {
            object = BusinessDataServiceHelper.loadSingle(object.getPkValue(), object.getDynamicObjectType().getName());
            Long id = (Long) object.getPkValue();
            if (thisId.equals(id)) continue;
            list.add(object);
        }
        return list;
    }
}
