package com.yem.wm.fm.gathering.op;

import com.yem.wm.es.salesorder.utils.SalesOrderUtils;
import com.yem.wm.fm.gathering.validator.GatheringConfirmValidator;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.AddValidatorsEventArgs;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;

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

/**
 * @Classname GatheringConfirmOp
 * @Description 收款单财务确认服务插件
 * @Date 2023/12/6 14:45
 * @Created by 张子帅
 */

public class GatheringConfirmOp extends AbstractOperationServicePlugIn
{
    @Override
    public void onPreparePropertys(PreparePropertysEventArgs e)
    {
        super.onPreparePropertys(e);
        List<String> keys = e.getFieldKeys();
        keys.add("yem_salcontractamt");
        keys.add("yem_claimamt");
        keys.add("yem_salcontractno");
        keys.add("yem_org");
        keys.add("yem_comegoman");
        keys.add("yem_productclassify");
        keys.add("yem_client");
        keys.add("yem_productcategorie");
        keys.add("billstatus");
        keys.add("yem_claimdetail");
        keys.add("yem_receiptdetail");
        keys.add("yem_claimamtbase");
        keys.add("yem_currency");
    }

    @Override
    public void onAddValidators(AddValidatorsEventArgs e)
    {
        super.onAddValidators(e);
        e.addValidator(new GatheringConfirmValidator());
    }

    @Override
    public void endOperationTransaction(EndOperationTransactionArgs e)
    {
        super.endOperationTransaction(e);
        String operationKey = e.getOperationKey();
        DynamicObject[] entities = e.getDataEntities();
        // 财务确认 或 财务反确认
        if ("statusconvertcwqr".equals(operationKey) || "statusconvertcwfqr".equals(operationKey)) {
            for (DynamicObject entity : entities) {
                // 收款单 收款明细
                DynamicObjectCollection collection = entity.getDynamicObjectCollection("yem_receiptdetail");
                if (collection.isEmpty()) {
                    continue;
                }
                for (DynamicObject dynamicObject : collection) {
                    // 认领明细（子单据体）
                    DynamicObjectCollection subCollection = dynamicObject.getDynamicObjectCollection("yem_claimdetail");
                    if (subCollection.isEmpty()) {
                        continue;
                    }

                    // 合同号 - 认领金额, 认领金额本位币
                    Map<Long, Map<String, BigDecimal>> map = new LinkedHashMap<>();

                    // 获取子单据体中 合同号对应的认领金额总和
                    for (DynamicObject object : subCollection) {
                        // 合同号
                        long contractno = object.getLong("yem_salcontractno.id");
                        if (map.containsKey(contractno)) {
                            // 认领金额
                            BigDecimal claimamt = map.get(contractno).get("claimamt");
                            claimamt = claimamt.add(object.getBigDecimal("yem_claimamt"));
                            // 认领金额本位币
                            BigDecimal claimamtbase = map.get(contractno).get("claimamtbase");
                            claimamtbase = claimamtbase.add(object.getBigDecimal("yem_claimamtbase"));
                            Map<String, BigDecimal> vVewMap = new HashMap<>();
                            // 认领金额
                            vVewMap.put("claimamt", claimamt);
                            // 认领金额本位币
                            vVewMap.put("claimamtbase", claimamtbase);
                            // 合同金额
                            vVewMap.put("salcontractamt", object.getBigDecimal("yem_salcontractamt"));
                            map.put(contractno, vVewMap);
                        } else {
                            Map<String, BigDecimal> vVewMap = new HashMap<>();
                            vVewMap.put("claimamt", object.getBigDecimal("yem_claimamt"));
                            vVewMap.put("claimamtbase", object.getBigDecimal("yem_claimamtbase"));
                            vVewMap.put("salcontractamt", object.getBigDecimal("yem_salcontractamt"));
                            map.put(contractno, vVewMap);
                        }
                    }

                    // 单张合同， 认领金额
                    map.forEach((k, v) ->
                    {
                        // 根据合同号找到对应的合同金额
                        BigDecimal salcontractamt = BigDecimal.ZERO;
                        // 产品分类
                        long productsId = 0;
                        for (DynamicObject object : subCollection) {
                            if (object.getLong("yem_salcontractno.id") == k) {
                                salcontractamt = object.getBigDecimal("yem_salcontractamt");
                                productsId = object.getLong("yem_productclassify.id");
                            }
                        }

                        // 查询配件客商额度申请单
                        // 财务组织
                        long orgId = entity.getLong("org.id");
                        // 客户名称
                        long customerId = entity.getLong("yem_comegoman.id");
                        // 结算币别
                        long currency = entity.getLong("yem_currency.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));
                        // 查询配件客商额度申请单
                        DynamicObject partsmerchant = BusinessDataServiceHelper.loadSingle("yem_im_partsmerchant", qFilters.toArray());
                        if (partsmerchant != null) {
                            // 配件客商额度申请单明细
                            DynamicObjectCollection partsmerchantCollection = partsmerchant.getDynamicObjectCollection("yem_im_entryentity_m");
                            for (DynamicObject object : partsmerchantCollection) {
                                if (object.getLong("yem_cn.id") == k) {

                                    BigDecimal writenamt = object.getBigDecimal("yem_claimamt");
                                    BigDecimal locwrittenamt = object.getBigDecimal("yem_claimamtbase");

                                    // 财务确认
                                    if ("statusconvertcwqr".equals(operationKey)) {

                                        // 合同金额
                                        object.set("yem_salcontractamt", v.get("salcontractamt"));
                                        // 认领金额
                                        object.set("yem_claimamt", writenamt.add(v.get("claimamt")));
                                        // 认领金额本位币
                                        object.set("yem_claimamtbase", locwrittenamt.add(v.get("claimamtbase")));

                                    }
                                    // 财务反确认
                                    if ("statusconvertcwfqr".equals(operationKey)) {

                                        // 认领金额
                                        object.set("yem_claimamt", writenamt.subtract(v.get("claimamt")));
                                        // 认领金额本位币
                                        object.set("yem_claimamtbase", locwrittenamt.subtract(v.get("claimamtbase")));
                                    }

                                    // 合同金额 = 认领金额
                                    if (salcontractamt.compareTo(object.getBigDecimal("yem_claimamt")) <= 0) {
                                        object.set("yem_writtenamt", object.get("yem_sum"));
                                        object.set("yem_locwrittenamt", object.get("yem_localsum"));
                                        object.set("yem_pennsylvania", new Date());
                                    } else {
                                        object.set("yem_writtenamt", null);
                                        object.set("yem_locwrittenamt", null);
                                        object.set("yem_pennsylvania", null);
                                    }
                                }
                            }
                            // 将数据保存到分录
                            SaveServiceHelper.save(new DynamicObject[]{partsmerchant});
                            SalesOrderUtils.calcCreditAmount(partsmerchant.getLong("id"));
                        }
                    });
                }
            }
        }
    }
}
