package com.yem.wm.es.storagetrans.op;

import com.alibaba.csp.sentinel.util.StringUtil;
import com.yem.wm.es.Util.BoxTypeDataGen;
import com.yem.wm.utils.YEM;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
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.botp.ConvertMetaServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;

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

/**
 * @author xwudd
 * @date 9:49
 * @Description
 **/
public class StorageTransSaveOp extends AbstractOperationServicePlugIn {
    @Override
    public void onPreparePropertys(PreparePropertysEventArgs e) {
        super.onPreparePropertys(e);
        e.getFieldKeys().add("yem_qty");
        e.getFieldKeys().add("yem_bigcabinet");
        e.getFieldKeys().add("yem_mincabinet");
        e.getFieldKeys().add("yem_bigcabinetnumbers");
        e.getFieldKeys().add("yem_mincabinetnumbers");
        e.getFieldKeys().add("yem_boxvolume1");
        e.getFieldKeys().add("yem_contractnumbers_m");
        e.getFieldKeys().add("yem_businesssort");
        e.getFieldKeys().add("yem_products");
        e.getFieldKeys().add("yem_salesmethod");
        e.getFieldKeys().add("yem_productmodel");
        e.getFieldKeys().add("yem_resourcenog");
        e.getFieldKeys().add("yem_materiel");
        e.getFieldKeys().add("yem_unit");
        e.getFieldKeys().add("yem_cubetype");
        e.getFieldKeys().add("yem_cubenumber");
        e.getFieldKeys().add("yem_remarks");
        e.getFieldKeys().add("yem_pieceqty");
        e.getFieldKeys().add("yem_piece");
        e.getFieldKeys().add("yem_weightunit");
        e.getFieldKeys().add("yem_grossweight");
        e.getFieldKeys().add("yem_lenghtunit");
        e.getFieldKeys().add("yem_long");
        e.getFieldKeys().add("yem_high");
        e.getFieldKeys().add("yem_wide");
        e.getFieldKeys().add("yem_vol");
        e.getFieldKeys().add("yem_volm3");
        e.getFieldKeys().add("yem_volm3sum");
        e.getFieldKeys().add("yem_grossweightsum");
        e.getFieldKeys().add("yem_baseunit");
        e.getFieldKeys().add("yem_baseqty");
        e.getFieldKeys().add("yem_shipmentnumbers_m");
        e.getFieldKeys().add("yem_corebilltype_e");
        e.getFieldKeys().add("yem_corebillno_d");
        e.getFieldKeys().add("yem_corebillid_d");
        e.getFieldKeys().add("yem_coreentryid");
        e.getFieldKeys().add("yem_resourceid");
        e.getFieldKeys().add("yem_material");
        e.getFieldKeys().add("yem_units");
        e.getFieldKeys().add("yem_shipmentqty");
        e.getFieldKeys().add("yem_residueqty");
        e.getFieldKeys().add("yem_packstyle");
        e.getFieldKeys().add("yem_baseunit_if");
        e.getFieldKeys().add("yem_baseqty_if");
        e.getFieldKeys().add("yem_salenumberno");
        e.getFieldKeys().add("yem_outnumberno");
        e.getFieldKeys().add("yem_sourcebillno_d");
        e.getFieldKeys().add("yem_sourcebilltype_e");
        e.getFieldKeys().add("yem_sourcebillid_d");
        e.getFieldKeys().add("yem_sourceentryid");
        e.getFieldKeys().add("yem_totalcontractno");
        e.getFieldKeys().add("yem_totalcontractno");
        e.getFieldKeys().add("yem_shipmentnumbers_m");
        e.getFieldKeys().add("yem_totalshippingno");
    }

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        super.beginOperationTransaction(e);
        DynamicObject[] storageTrans = e.getDataEntities();
        for (DynamicObject storageTran : storageTrans) {
            repairRelation(storageTran);
            repairRelationShipping(storageTran);
        }

    }

    @Override
    public void endOperationTransaction(EndOperationTransactionArgs e) {
        super.endOperationTransaction(e);
        DynamicObject[] storageTrans = e.getDataEntities();
        for (DynamicObject storageTran : storageTrans) {

            DynamicObject enCasement = BusinessDataServiceHelper.loadSingle("yem_im_encasement",
                    new QFilter[]{new QFilter("yem_sourcebillid", QCP.equals, storageTran.getPkValue()),
                            new QFilter("yem_sourcebilltype", QCP.equals, storageTran.getDynamicObjectType().getName())});
            if (YEM.isNotEmpty(enCasement)) {
                Map<Long, Map<String, Object>> map = new HashMap();
                DynamicObjectCollection materialInfos = storageTran.getDynamicObjectCollection("yem_es_materialinfo");
                for (DynamicObject materialInfo : materialInfos) {
                    Map<String, Object> entryMap = new HashMap();
                    entryMap.put("yem_businesssort", materialInfo.get("yem_businesssort"));//业务分类
                    entryMap.put("yem_products", materialInfo.get("yem_products"));//产品分类
                    entryMap.put("yem_salesmethod", materialInfo.get("yem_salesmethod"));//销售方式
                    entryMap.put("yem_productmodel", materialInfo.get("yem_productmodel"));//基础机型
                    entryMap.put("yem_resourcenog", materialInfo.get("yem_resourcenog"));//资源号
                    entryMap.put("yem_materiel", materialInfo.get("yem_materiel"));//物料编码
                    entryMap.put("yem_unit", materialInfo.get("yem_unit"));//计量单位
                    entryMap.put("yem_qty", materialInfo.get("yem_qty"));//数量
                    entryMap.put("yem_cubetype", materialInfo.get("yem_cubetype"));//箱型
                    entryMap.put("yem_cubenumber", materialInfo.get("yem_cubenumber"));//箱量
                    entryMap.put("yem_bigcabinet", materialInfo.get("yem_bigcabinet"));//大柜
                    entryMap.put("yem_bigcabinetnumbers", materialInfo.get("yem_bigcabinetnumbers"));//大柜数量
                    entryMap.put("yem_mincabinet", materialInfo.get("yem_mincabinet"));//小柜
                    entryMap.put("yem_mincabinetnumbers", materialInfo.get("yem_mincabinetnumbers"));//小柜数量
                    entryMap.put("yem_remarks", materialInfo.get("yem_remarks"));//备注
                    entryMap.put("yem_packstyle", materialInfo.get("yem_packstyle"));//包装方式
                    entryMap.put("yem_pieceqty", materialInfo.get("yem_pieceqty"));//单件数量
                    entryMap.put("yem_piece", materialInfo.get("yem_piece"));//件数
                    entryMap.put("yem_weightunit", materialInfo.get("yem_weightunit"));//重量计量单位
                    entryMap.put("yem_grossweight", materialInfo.get("yem_grossweight"));//毛重
                    entryMap.put("yem_lenghtunit", materialInfo.get("yem_lenghtunit"));//长度计量单位
                    entryMap.put("yem_long", materialInfo.get("yem_long"));//长
                    entryMap.put("yem_high", materialInfo.get("yem_high"));//宽
                    entryMap.put("yem_wide", materialInfo.get("yem_wide"));//高
                    entryMap.put("yem_vol", materialInfo.get("yem_vol"));//体积
                    entryMap.put("yem_volm3", materialInfo.get("yem_volm3"));//体积M3
                    entryMap.put("yem_volm3sum", materialInfo.get("yem_volm3sum"));//总体积M3
                    entryMap.put("yem_grossweightsum", materialInfo.get("yem_grossweightsum"));//总毛重
                    entryMap.put("yem_baseunit", materialInfo.get("yem_baseunit"));//基本计量单位
                    entryMap.put("yem_baseqty", materialInfo.get("yem_baseqty"));//基本单位数量
                    entryMap.put("yem_contractnumbers_m", materialInfo.get("yem_contractnumbers_m"));//外销合同号
                    entryMap.put("yem_shipmentnumbers_m", materialInfo.get("yem_shipmentnumbers_m"));//出运明细单号
                    entryMap.put("yem_corebilltype_e", materialInfo.get("yem_corebilltype_e"));//核心单类型
                    entryMap.put("yem_corebillno_d", materialInfo.get("yem_corebillno_d"));//核心单编号
                    entryMap.put("yem_corebillid_d", materialInfo.get("yem_corebillid_d"));//核心单据id
                    entryMap.put("yem_coreentryid", materialInfo.get("yem_coreentryid"));//核心单据分录id
                    map.put(materialInfo.getLong("id"), entryMap);
                }
//                List<Integer> sourceEntryIdList = new ArrayList<>();
                List<DynamicObject> removeList = new ArrayList();
                DynamicObjectCollection imMaterialInfos = enCasement.getDynamicObjectCollection("yem_im_materialinfo_mi");
                for (int i = 0; i < imMaterialInfos.size(); i++) {
                    DynamicObject imMaterialInfo = imMaterialInfos.get(i);
                    long sourceEntryId = imMaterialInfo.getLong("yem_sourceentryid");
                    if (map.containsKey(sourceEntryId)) {
                        //移除装箱单本地数据
                        map.remove(sourceEntryId);
                    } else {
                        removeList.add(imMaterialInfo);
                        // sourceEntryIdList.add(i);
                    }
                }
                if (removeList.size() > 0) {
//                    imMaterialInfos.removeAll(sourceEntryIdList);
                    //移除储运托单删除行内容
                    for (DynamicObject dy : removeList) {
                        imMaterialInfos.remove(dy);
                    }
                }
                Set<Long> entryIds = map.keySet();
                for (Long entryId : entryIds) {
                    Map<String, Object> stringObjectMap = map.get(entryId);
                    DynamicObject addNew = imMaterialInfos.addNew();

                    addNew.set("yem_businesssort", stringObjectMap.get("yem_businesssort"));//业务分类
                    addNew.set("yem_products", stringObjectMap.get("yem_products"));//产品分类
                    addNew.set("yem_salesmethod", stringObjectMap.get("yem_salesmethod"));//销售方式
                    addNew.set("yem_productmodel", stringObjectMap.get("yem_productmodel"));//基础机型
                    addNew.set("yem_resourceid", stringObjectMap.get("yem_resourcenog"));//资源号
                    addNew.set("yem_material", stringObjectMap.get("yem_materiel"));//物料编码
                    addNew.set("yem_units", stringObjectMap.get("yem_unit"));//计量单位
                    addNew.set("yem_shipmentqty", stringObjectMap.get("yem_qty"));//储运数量
                    addNew.set("yem_cubetype", stringObjectMap.get("yem_cubetype"));//箱型
                    addNew.set("yem_cubenumber", stringObjectMap.get("yem_cubenumber"));//箱量
                    addNew.set("yem_bigcabinet", stringObjectMap.get("yem_bigcabinet"));//大柜
                    addNew.set("yem_bigcabinetnumbers", stringObjectMap.get("yem_bigcabinetnumbers"));//大柜数量
                    addNew.set("yem_mincabinet", stringObjectMap.get("yem_mincabinet"));//小柜
                    addNew.set("yem_mincabinetnumbers", stringObjectMap.get("yem_mincabinetnumbers"));//小柜数量
                    addNew.set("yem_residueqty", stringObjectMap.get("yem_qty"));//剩余数量
                    addNew.set("yem_remarks", stringObjectMap.get("yem_remarks"));//备注
                    addNew.set("yem_packstyle", stringObjectMap.get("yem_packstyle"));//包装方式
                    addNew.set("yem_pieceqty", stringObjectMap.get("yem_pieceqty"));//单件数量
                    addNew.set("yem_piece", stringObjectMap.get("yem_piece"));//件数
                    addNew.set("yem_weightunit", stringObjectMap.get("yem_weightunit"));//重量计量单位
                    addNew.set("yem_grossweight", stringObjectMap.get("yem_grossweight"));//毛重
                    addNew.set("yem_lenghtunit", stringObjectMap.get("yem_lenghtunit"));//长度计量单位
                    addNew.set("yem_long", stringObjectMap.get("yem_long"));//长
                    addNew.set("yem_wide", stringObjectMap.get("yem_wide"));//宽
                    addNew.set("yem_high", stringObjectMap.get("yem_high"));//高
                    addNew.set("yem_vol", stringObjectMap.get("yem_vol"));//体积
                    addNew.set("yem_volm3", stringObjectMap.get("yem_volm3"));//体积M3
                    addNew.set("yem_volm3sum", stringObjectMap.get("yem_volm3sum"));//总体积M3
                    addNew.set("yem_grossweightsum", stringObjectMap.get("yem_grossweightsum"));//总毛重
                    addNew.set("yem_baseunit_if", stringObjectMap.get("yem_baseunit"));//基本计量单位
                    addNew.set("yem_baseqty_if", stringObjectMap.get("yem_baseqty"));//基本单位数量
                    addNew.set("yem_salenumberno", stringObjectMap.get("yem_contractnumbers_m"));//外销合同号
                    addNew.set("yem_outnumberno", stringObjectMap.get("yem_shipmentnumbers_m"));//出运明细单号
                    addNew.set("yem_sourcebillno_d", storageTran.getString("billno"));//源单编号
                    addNew.set("yem_sourcebilltype_e", storageTran.getDynamicObjectType().getName());//源单类型
                    addNew.set("yem_sourcebillid_d", storageTran.getPkValue());//源单id
                    addNew.set("yem_sourceentryid", entryId);//来源单据分录id
                    addNew.set("yem_corebilltype_e", stringObjectMap.get("yem_corebilltype_e"));//核心单类型
                    addNew.set("yem_corebillno_d", stringObjectMap.get("yem_corebillno_d"));//核心单编号
                    addNew.set("yem_corebillid_d", stringObjectMap.get("yem_corebillid_d"));//核心单据id
                    addNew.set("yem_coreentryid", stringObjectMap.get("yem_coreentryid"));//核心单据分录id
                    repairRelation(storageTran, "yem_es_materialinfo", addNew);
                }
                //反写装箱单数量
                DynamicObjectCollection yem_es_materialinfo = storageTran.getDynamicObjectCollection("yem_es_materialinfo");
                for (DynamicObject dt : yem_es_materialinfo) {
                    DynamicObjectCollection materialinfo_mi = enCasement.getDynamicObjectCollection("yem_im_materialinfo_mi");
                    for (DynamicObject miSon : materialinfo_mi) {
                        long aLong = miSon.getLong("yem_sourceentryid");
                        if (((long) dt.getPkValue()) == aLong) {
                            BigDecimal yemQty = dt.getBigDecimal("yem_qty");
                            BigDecimal yemQtyMi = miSon.getBigDecimal("yem_shipmentqty");
                            BigDecimal yemPackingqty = miSon.getBigDecimal("yem_packingqty");
                            //数量增加
                            if (yemQty.compareTo(yemQtyMi) > 0) {
                                miSon.set("yem_shipmentqty", yemQty);
                            }
                            //数量减少
                            if (yemQty.compareTo(yemQtyMi) < 0) {
                                if (yemQty.compareTo(yemPackingqty) > 0) {
                                    miSon.set("yem_shipmentqty", yemQty);
                                }
                            }
                        }
                    }
                }
                OperationResult save = OperationServiceHelper.executeOperate("save", enCasement.getDataEntityType().getName(), new DynamicObject[]{enCasement}, OperateOption.create());
                if (!save.isSuccess()) {
                    throw new KDBizException("下游装箱单保存失败！");
                }
                OperationServiceHelper.executeOperate("save", enCasement.getDataEntityType().getName(), new Object[]{enCasement.getPkValue()}, OperateOption.create());
            }


            if ("save".equals(e.getOperationKey())) {
                // 单据保存时根据明细信息  大柜和小柜数量不为空的明细行  的箱型箱量，去重合并拼接生成
                for (DynamicObject entity : storageTrans) {
                    BoxTypeDataGen.genBoxTypeData(entity);
                }
            }

        }
    }

    /**
     * @param storageTran 源单分录 字段汇总
     */
    private void repairRelation(DynamicObject storageTran) {
        DynamicObjectCollection materialInfos = storageTran.getDynamicObjectCollection("yem_es_materialinfo");
        Set<String> newSet = new HashSet<>();
        String no = "";
        for (DynamicObject materialInfo : materialInfos) {
            if (StringUtil.isNotEmpty(materialInfo.getString("yem_contractnumbers_m"))) {
                String yem_contractnumbers_m = materialInfo.getString("yem_contractnumbers_m");
                newSet.add(yem_contractnumbers_m);
            }
        }
        for (String s : newSet) {
            if (StringUtil.isEmpty(no)) {
                no = s;
            } else {
                no = no + ";" + s;
            }

        }
        storageTran.set("yem_totalcontractno", no);
    }

    private void repairRelationShipping(DynamicObject storageTran) {
        DynamicObjectCollection materialInfos = storageTran.getDynamicObjectCollection("yem_es_materialinfo");
        Set<String> newSet = new HashSet<>();
        String no = "";
        for (DynamicObject materialInfo : materialInfos) {
            if (StringUtil.isNotEmpty(materialInfo.getString("yem_shipmentnumbers_m"))) {
                String yem_contractnumbers_m = materialInfo.getString("yem_shipmentnumbers_m");
                newSet.add(yem_contractnumbers_m);
            }
        }
        for (String s : newSet) {
            if (StringUtil.isEmpty(no)) {
                no = s;
            } else {
                no = no + ";" + s;
            }

        }
        storageTran.set("yem_totalshippingno", no);
    }

    /**
     * 单据体-单据体修复上下游关联关系
     *
     * @param srcBill 源单
     */
    private void repairRelation(DynamicObject srcBill, String srcEntryKey, DynamicObject tarBillEntryRow) {

        String srcname = srcBill.getDataEntityType().getName();
        Long srcTableId = ConvertMetaServiceHelper.loadTableDefine(srcname, srcEntryKey).getTableId();
        DynamicObjectCollection linkRows = tarBillEntryRow.getDynamicObjectCollection("yem_im_materialinfo_mi_lk");
        DynamicObject linkRow = new DynamicObject(linkRows.getDynamicObjectType());
        linkRow.set("yem_im_materialinfo_mi_lk_stableid", srcTableId); // 源单分录表格编码：以此标识源单类型及单据体
        linkRow.set("yem_im_materialinfo_mi_lk_sbillid", srcBill.getLong("id")); // 源单内码
        linkRow.set("yem_im_materialinfo_mi_lk_sid", tarBillEntryRow.getLong("yem_sourceentryid"));
        linkRows.add(linkRow);
    }
}
