package com.yem.wm.bc.change.business;

import com.yem.wm.bc.change.common.consts.BizCancelStatusEnum;
import com.yem.wm.bc.change.common.consts.BizChangeStatusEnum;
import com.yem.wm.bc.change.common.consts.BizValidStatusEnum;
import com.yem.wm.bc.change.common.consts.ChangeTypeEnum;
import com.yem.wm.bc.common.CommonUtils;
import com.yem.wm.bc.common.enums.EnableStatusEnum;
import com.yem.wm.bc.common.enums.StatusEnum;
import com.yem.wm.bc.helper.BillTypeHelper;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.dataentity.entity.MulBasedataDynamicObjectCollection;
import kd.bos.dataentity.metadata.ICollectionProperty;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.IDataEntityType;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.dataentity.metadata.clr.DataEntityType;
import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.dataentity.metadata.dynamicobject.DynamicPropertyCollection;
import kd.bos.dataentity.resource.ResManager;
import kd.bos.dataentity.serialization.DcJsonSerializer;
import kd.bos.dataentity.serialization.ListDcxmlBinder;
import kd.bos.dataentity.serialization.SerializationUtils;
import kd.bos.entity.*;
import kd.bos.entity.filter.FilterBuilder;
import kd.bos.entity.filter.FilterCondition;
import kd.bos.entity.property.EntryProp;
import kd.bos.exception.KDException;
import kd.bos.lang.Lang;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.metadata.entity.validation.ConditionValidation;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.MetadataServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;

import java.lang.reflect.Method;
import java.util.*;

/**
 * @author 夜子
 * @ClassName ChangeModelHelper
 * @description: TODO
 * @date 2023年07月19日
 * @version: 1.0
 */
public class ChangeModelHelper {
    private static final Log LOGGER = LogFactory.getLog(ChangeModelHelper.class);

    public ChangeModelHelper() {
    }

    public static DynamicObject getChangeModel4SrcBill(String srcBillEntiyId) {
        QFilter qf1 = new QFilter("srcbill", "=", srcBillEntiyId);
        QFilter qf2 = new QFilter("enable", "=", EnableStatusEnum.ENABLE.getValue());
        Map<Object, DynamicObject> map = BusinessDataServiceHelper.loadFromCache("yem_changemodel", new QFilter[]{qf1, qf2});
        if (!CommonUtils.isNull(map)) {
            ArrayList<DynamicObject> list = new ArrayList<>(map.values());
            DynamicObject changeModel = (DynamicObject)list.get(0);
            return changeModel;
        } else {
            return null;
        }
    }

    public static DynamicObject getChangeModel4XBill(String xBillEntiyId) {
        QFilter qf1 = new QFilter("xbill", "=", xBillEntiyId);
        QFilter qf2 = new QFilter("enable", "=", EnableStatusEnum.ENABLE.getValue());
        Map<Object, DynamicObject> map = BusinessDataServiceHelper.loadFromCache("yem_changemodel", new QFilter[]{qf1, qf2});
        if (!CommonUtils.isNull(map)) {
            ArrayList<DynamicObject> list = new ArrayList<>(map.values());
            DynamicObject changeModel = (DynamicObject)list.get(0);
            return changeModel;
        } else {
            return null;
        }
    }

    public static DynamicObject getChangeModel5SrcBill(String srcBillEntiyId) {
        QFilter qf1 = new QFilter("srcbill", "=", srcBillEntiyId);
        Map<Object, DynamicObject> map = BusinessDataServiceHelper.loadFromCache("yem_changemodel", new QFilter[]{qf1});
        if (!CommonUtils.isNull(map)) {
            ArrayList<DynamicObject> list = new ArrayList<>(map.values());
            DynamicObject changeModel = (DynamicObject)list.get(0);
            return changeModel;
        } else {
            return null;
        }
    }

    public static DynamicObject getChangeModel5XBill(String xBillEntiyId) {
        QFilter qf1 = new QFilter("xbill", "=", xBillEntiyId);
        Map<Object, DynamicObject> map = BusinessDataServiceHelper.loadFromCache("yem_changemodel", new QFilter[]{qf1});
        if (!CommonUtils.isNull(map)) {
            ArrayList<DynamicObject> list = new ArrayList<>(map.values());
            DynamicObject changeModel = (DynamicObject)list.get(0);
            return changeModel;
        } else {
            return null;
        }
    }

    public static DynamicObject generateXBilll(String srcBillEntiy, long srcBillId) {
        DynamicObject changeModel = getChangeModel4SrcBill(srcBillEntiy);
        if (changeModel == null) {
            return null;
        } else {
            Map<String, Map<String, String>> entryAndOp = getXBillEntryAndOp(changeModel);
            DynamicObject srcBill = BusinessDataServiceHelper.loadSingle(srcBillId, srcBillEntiy);
            if (CommonUtils.isNull(srcBill)) {
                return null;
            } else {
                excutePluginMethod(changeModel, "beforeSrcBillChange", srcBill);
                String xbilldtstr = "";
                if (changeModel.getDynamicObject("xbill") != null && changeModel.getDynamicObject("xbill").getPkValue() != null) {
                    xbilldtstr = (String)changeModel.getDynamicObject("xbill").getPkValue();
                    MainEntityType xBillDt = MetadataServiceHelper.getDataEntityType(xbilldtstr);
                    List<EntityType> xBillentryEntitys = getChildEntities(xBillDt);
                    IDataEntityType var15 = srcBill.getDataEntityType();
                    List<EntityType> srcBillentryEntitys = getChildEntities(var15);
                    DynamicObject xBill = new DynamicObject(xBillDt);
                    DynamicObjectCollection mapplingEntitys = changeModel.getDynamicObjectCollection("mappingentity");
                    long begingenXbillTime = System.currentTimeMillis();
                    HashSet<String> notRegistedEntryInfoSet = new HashSet<>();
                    LocaleString headTitle = ResManager.getLocaleString("单据头", "ChangeModelHelper_0", "yem-yc-changemodel");

                    for (DynamicObject mapplingEntity : mapplingEntitys) {
                        try {
                            String targetFieldName = mapplingEntity.getString("targetfieldname");
                            String sourceFieldName = mapplingEntity.getString("sourcefieldname");
                            if (!CommonUtils.isNull(sourceFieldName)) {
                                String[] targetItems = targetFieldName.split("\\.");
                                String[] sourceItems = sourceFieldName.split("\\.");
                                if (headTitle.containsValue(targetItems[0])) {
                                    SetPropertyValue(xBill, mapplingEntity.getString("targetfield"), srcBill.get(mapplingEntity.getString("sourcefield")));
                                } else if (targetItems.length == 2 && sourceItems.length == 2 && !headTitle.containsValue(targetItems[0])) {
                                    EntityType xBillEntryType = getChildEntitiesByAlias(xBillentryEntitys, targetItems[0]);
                                    EntityType srcBillEntryType = getChildEntitiesByAlias(srcBillentryEntitys, sourceItems[0]);
                                    if (xBillEntryType != null && srcBillEntryType != null) {
                                        String entryTypeName = xBillEntryType.getName();
                                        if (entryAndOp.get(entryTypeName) == null) {
                                            notRegistedEntryInfoSet.add(entryTypeName);
                                        } else {
                                            String entrychangetype =  ( entryAndOp.get(xBillEntryType.getName())).get("changetype");
                                            String entrysrcid =  ( entryAndOp.get(xBillEntryType.getName())).get("srcid");
                                            DynamicObjectCollection xBillEntrys;
                                            DynamicObjectCollection srcBillEntrys;
                                            DynamicObject srcBillEntry;
                                            DynamicObject xBillEntry;
                                            if (xBillEntryType.getClass() == EntryType.class) {
                                                xBillEntrys = xBill.getDynamicObjectCollection(xBillEntryType.getName());
                                                srcBillEntrys = srcBill.getDynamicObjectCollection(srcBillEntryType.getName());
                                                if (entryAndOp.get(xBillEntryType.getName()) != null) {
                                                    if (srcBillEntrys.size() > 0 && xBillEntrys.size() == 0) {
                                                        for (DynamicObject billEntry : srcBillEntrys) {
                                                            srcBillEntry = xBillEntrys.addNew();

                                                            try {
                                                                srcBillEntry.set(entrysrcid, ((DynamicObject) billEntry).getPkValue());
                                                                srcBillEntry.set(entrychangetype, ChangeTypeEnum.UPDATE.getValue());
                                                            } catch (KDException var48) {
                                                                LOGGER.warn(var48);
                                                            }
                                                        }
                                                    }

                                                    for (int i = 0; i < srcBillEntrys.size(); ++i) {
                                                        srcBillEntry = (DynamicObject) srcBillEntrys.get(i);
                                                        xBillEntry = (DynamicObject) xBillEntrys.get(i);

                                                        try {
                                                            if (!mapplingEntity.getString("targetfield").equals(entrychangetype) && !mapplingEntity.getString("targetfield").equals(entrysrcid)) {
                                                                SetPropertyValue(xBillEntry, mapplingEntity.getString("targetfield"), srcBillEntry.get(mapplingEntity.getString("sourcefield")));
                                                            }
                                                        } catch (Exception var47) {
                                                            LOGGER.warn(var47);
                                                        }
                                                    }
                                                }
                                            } else if (xBillEntryType.getClass() == TreeEntryType.class) {

                                                xBillEntrys = xBill.getDynamicObjectCollection(xBillEntryType.getName());
                                                srcBillEntrys = srcBill.getDynamicObjectCollection(srcBillEntryType.getName());
                                                if (entryAndOp.get(xBillEntryType.getName()) != null) {
                                                    if (srcBillEntrys.size() > 0 && xBillEntrys.size() == 0) {
                                                        for (int i = 0; i < srcBillEntrys.size(); ++i) {
                                                            srcBillEntry = xBillEntrys.addNew();
                                                            ORM.create().setPrimaryKey(srcBillEntry);
                                                            try {
                                                                srcBillEntry.set("seq", ((DynamicObject) srcBillEntrys.get(i)).get("seq"));
                                                                srcBillEntry.set(entrysrcid, ((DynamicObject) srcBillEntrys.get(i)).getPkValue());
                                                                srcBillEntry.set(entrychangetype, ChangeTypeEnum.UPDATE.getValue());
                                                                long srcEntrypid = srcBillEntrys.get(i).getLong("pid");
                                                                if (srcEntrypid != 0L) {
                                                                    long xEntrypid = 0L;
                                                                    for (int j = 0; j < srcBillEntrys.size(); ++j) {
                                                                        long srcEntryid = srcBillEntrys.get(j).getLong("id");
                                                                        if(srcEntryid==srcEntrypid){
                                                                             xEntrypid = xBillEntrys.get(j).getLong("id");
                                                                        }
                                                                    }
                                                                    srcBillEntry.set("pid", xEntrypid);
                                                                }
                                                            } catch (KDException var48) {
                                                                LOGGER.warn(var48);
                                                            }
                                                        }
                                                    }

                                                    for (int i = 0; i < srcBillEntrys.size(); ++i) {
                                                        srcBillEntry = (DynamicObject) srcBillEntrys.get(i);
                                                        xBillEntry = (DynamicObject) xBillEntrys.get(i);

                                                        try {
                                                            if (!mapplingEntity.getString("targetfield").equals(entrychangetype) && !mapplingEntity.getString("targetfield").equals(entrysrcid)) {
                                                                SetPropertyValue(xBillEntry, mapplingEntity.getString("targetfield"), srcBillEntry.get(mapplingEntity.getString("sourcefield")));
                                                            }
                                                        } catch (Exception var47) {
                                                            LOGGER.warn(var47);
                                                        }
                                                    }
                                                }
                                            } else if (xBillEntryType.getClass() == SubEntryType.class) {
                                                xBillEntrys = xBill.getDynamicObjectCollection(((EntryType) srcBillEntryType.getParent()).getName());
                                                srcBillEntrys = srcBill.getDynamicObjectCollection(((EntryType) srcBillEntryType.getParent()).getName());

                                                for (int i = 0; i < srcBillEntrys.size(); ++i) {
                                                    srcBillEntry = (DynamicObject) srcBillEntrys.get(i);
                                                    xBillEntry = (DynamicObject) xBillEntrys.get(i);
                                                    DynamicObjectCollection subSrcBillEntrys = srcBillEntry.getDynamicObjectCollection(srcBillEntryType.getName());
                                                    DynamicObjectCollection subXBillEntrys = xBillEntry.getDynamicObjectCollection(xBillEntryType.getName());
                                                    DynamicObject subSrcBillEntry;
                                                    if (subSrcBillEntrys.size() > 0 && subXBillEntrys.size() == 0) {
                                                        for (DynamicObject billEntry : subSrcBillEntrys) {
                                                            subSrcBillEntry = subXBillEntrys.addNew();

                                                            try {
                                                                subSrcBillEntry.set("seq", ((DynamicObject) billEntry).get("seq"));
                                                                subSrcBillEntry.set(entrysrcid, ((DynamicObject) billEntry).getPkValue());
                                                                subSrcBillEntry.set(entrychangetype, ChangeTypeEnum.UPDATE.getValue());
                                                            } catch (Exception var46) {
                                                                LOGGER.warn(var46);
                                                            }
                                                        }
                                                    }

                                                    for (int j = 0; j < subSrcBillEntrys.size(); ++j) {
                                                        subSrcBillEntry = (DynamicObject) subSrcBillEntrys.get(j);
                                                        DynamicObject subXBillEntry = (DynamicObject) subXBillEntrys.get(j);

                                                        try {
                                                            if (!mapplingEntity.getString("targetfield").equals(entrychangetype) && !mapplingEntity.getString("targetfield").equals(entrysrcid)) {
                                                                SetPropertyValue(subXBillEntry, mapplingEntity.getString("targetfield"), subSrcBillEntry.get(mapplingEntity.getString("sourcefield")));
                                                            }
                                                        } catch (Exception var45) {
                                                            LOGGER.warn(var45);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        } catch (Exception var49) {
                            LOGGER.warn(var49);
                        }
                    }

                    if(srcBill.containsProperty("billtype")){
                        DynamicObject srcBillTypeDO = srcBill.getDynamicObject("billtype");
                        Long xBillTypeID = getXBillTypeIDFromChangeModel(changeModel, srcBillTypeDO != null ? (Long)srcBillTypeDO.getPkValue() : 0L);
                        if (xBillTypeID <= 0L) {
                            xBill.set("billtype", BillTypeHelper.getBillTypeByEntity(xBill.getDataEntityType().getName()));
                        } else {
                            xBill.set("billtype", xBillTypeID);
                        }
                    }
                    if(srcBill.containsProperty("yem_billtype")){
                        DynamicObject srcBillTypeDO = srcBill.getDynamicObject("yem_billtype");
                        Long xBillTypeID = getXBillTypeIDFromChangeModel(changeModel, srcBillTypeDO != null ? (Long)srcBillTypeDO.getPkValue() : 0L);
                        if (xBillTypeID <= 0L) {
                            xBill.set("yem_billtype", BillTypeHelper.getBillTypeByEntity(xBill.getDataEntityType().getName()));
                        } else {
                            xBill.set("yem_billtype", xBillTypeID);
                        }
                    }


                    if (changeModel.getBoolean("isnotupdateversion")) {
                        xBill.set("changebillno", srcBill.get("billno") + "_" + srcBill.get("version") + "_" + srcBill.get("subversion"));
                    } else {
                        xBill.set("changebillno", srcBill.get("billno") + "_" + srcBill.get("version"));
                    }

                    xBill.set("billstatus", StatusEnum.SAVE.getValue());
                    xBill.set("changebizdate", new Date(System.currentTimeMillis()));
                    xBill.set("sourcebillid", srcBill.getPkValue());
                    xBill.set("sourcebillentity", srcBill.getDataEntityType().getName());
                    xBill.set("validstatus", BizValidStatusEnum.UNVALID.getValue());
                    xBill.set("valider", (Object)null);
                    xBill.set("validdate", (Object)null);
                    if (xBill.getDynamicObjectType().getProperty("changecancelstatus") != null) {
                        xBill.set("changecancelstatus", BizCancelStatusEnum.UNCANCEL.getValue());
                    }

                    xBill.set("changestatus", BizChangeStatusEnum.UNCHANGE.getValue());
                    xBill.set("validstatus", BizValidStatusEnum.UNVALID.getValue());
                    DynamicObject currentUserDO = BusinessDataServiceHelper.loadSingleFromCache(UserServiceHelper.getCurrentUserId(), "bos_user");
                    xBill.set("creator", currentUserDO);
                    xBill.set("createtime", new Date(System.currentTimeMillis()));
                    xBill.set("modifier", currentUserDO);
                    xBill.set("modifytime", new Date(System.currentTimeMillis()));
                    excutePluginMethod(changeModel, "afterSrcBillChange", srcBill);
                    long endGenXbillOtherTime = System.currentTimeMillis();
                    return xBill;
                } else {
                    return null;
                }
            }
        }
    }

    public static DynamicObject[] generateXBilll(DynamicObject[] srcBills) {
        List<DynamicObject> xBills = new ArrayList<>();
        DynamicObject[] var2 = srcBills;
        int var3 = srcBills.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            DynamicObject srcBill = var2[var4];
            DynamicObject xBill = generateXBilll(srcBill.getDataEntityType().getName(), (Long)srcBill.getPkValue());
            if (!CommonUtils.isNull(xBill)) {
                xBills.add(xBill);
            }
        }

        if (xBills.size() == 0) {
            return null;
        } else {
            return (DynamicObject[])xBills.toArray(new DynamicObject[xBills.size()]);
        }
    }

    public static String[] getProperty4Entry(IDataEntityType dt, String entryName) {
        DynamicPropertyCollection dynPropColl = (DynamicPropertyCollection)dt.getProperties();
        Iterator<IDataEntityProperty> it = dynPropColl.iterator();
        ArrayList<String> arPropName = new ArrayList<>();

        while(true) {
            label54:
            while(it.hasNext()) {
                IDataEntityProperty dataEntityProp = (IDataEntityProperty)it.next();
                DataEntityPropertyCollection entry;
                Iterator itEntry;
                IDataEntityProperty dataEntityPropEntry;
                if (dataEntityProp instanceof EntryProp && dataEntityProp.getName().equals(entryName)) {
                    entry = ((EntryProp)dataEntityProp).getDynamicCollectionItemPropertyType().getProperties();
                    itEntry = entry.iterator();

                    while(itEntry.hasNext()) {
                        dataEntityPropEntry = (IDataEntityProperty)itEntry.next();
                        if (!(dataEntityPropEntry instanceof EntryProp)) {
                            arPropName.add(dataEntityPropEntry.getName());
                        }
                    }
                } else if (dataEntityProp instanceof EntryProp) {
                    entry = ((EntryProp)dataEntityProp).getDynamicCollectionItemPropertyType().getProperties();
                    itEntry = entry.iterator();

                    while(true) {
                        do {
                            do {
                                if (!itEntry.hasNext()) {
                                    continue label54;
                                }

                                dataEntityPropEntry = (IDataEntityProperty)itEntry.next();
                            } while(!(dataEntityPropEntry instanceof EntryProp));
                        } while(!dataEntityPropEntry.getName().equals(entryName));

                        DataEntityPropertyCollection subEntry = ((EntryProp)dataEntityPropEntry).getDynamicCollectionItemPropertyType().getProperties();
                        Iterator<IDataEntityProperty> itSubEntry = subEntry.iterator();

                        while(itSubEntry.hasNext()) {
                            IDataEntityProperty dataEntityPropSubEntry = (IDataEntityProperty)itSubEntry.next();
                            if (!(dataEntityPropSubEntry instanceof EntryProp)) {
                                arPropName.add(dataEntityPropSubEntry.getName());
                            }
                        }
                    }
                }
            }

            return (String[])arPropName.toArray(new String[0]);
        }
    }

    public static String[] getCanLogProperty(IDataEntityType xbillDt) {
        DynamicObjectCollection mappingEntitys = getMappingColFromXBillDT(xbillDt);
        if (mappingEntitys != null && mappingEntitys.size() >= 1) {
            ArrayList<String> arPropName = new ArrayList();
            LocaleString headTitle = ResManager.getLocaleString("单据头", "ChangeModelHelper_0", "yem-yc-changemodel");
            Iterator var4 = mappingEntitys.iterator();

            while(var4.hasNext()) {
                DynamicObject mappingEntity = (DynamicObject)var4.next();
                String targetField = mappingEntity.getString("targetfield");
                String targetFieldname = mappingEntity.getString("targetfieldname");
                Boolean canLog = mappingEntity.getBoolean("canlog");
                String[] targetItems = targetFieldname.split("\\.");
                if (headTitle != null && headTitle.containsValue(targetItems[0]) && canLog) {
                    arPropName.add(targetField);
                }
            }

            return (String[])arPropName.toArray(new String[0]);
        } else {
            return null;
        }
    }

    public static String[] getCanWritebackProperty(IDataEntityType xbillDt) {
        DynamicObjectCollection mappingEntitys = getMappingColFromXBillDT(xbillDt);
        if (mappingEntitys != null && mappingEntitys.size() >= 1) {
            ArrayList<String> arPropName = new ArrayList();
            LocaleString headTitle = ResManager.getLocaleString("单据头", "ChangeModelHelper_0", "yem-yc-changemodel");
            Iterator var4 = mappingEntitys.iterator();

            while(var4.hasNext()) {
                DynamicObject mappingEntity = (DynamicObject)var4.next();
                String targetField = mappingEntity.getString("targetfield");
                String targetFieldname = mappingEntity.getString("targetfieldname");
                Boolean canLog = mappingEntity.getBoolean("canwriteback");
                String[] targetItems = targetFieldname.split("\\.");
                if (headTitle != null && headTitle.containsValue(targetItems[0]) && canLog) {
                    arPropName.add(targetField);
                }
            }

            return (String[])arPropName.toArray(new String[0]);
        } else {
            return null;
        }
    }

    public static String[] getEnableProperty(IDataEntityType xbillDt) {
        DynamicObjectCollection mappingEntitys = getMappingColFromXBillDT(xbillDt);
        if (mappingEntitys != null && mappingEntitys.size() >= 1) {
            ArrayList<String> arPropName = new ArrayList<>();
            LocaleString headTitle = ResManager.getLocaleString("单据头", "ChangeModelHelper_0", "yem-yc-changemodel");

            for (DynamicObject mappingEntity : mappingEntitys) {
                String targetField = mappingEntity.getString("targetfield");
                String targetFieldname = mappingEntity.getString("targetfieldname");
                boolean canEnable = mappingEntity.getBoolean("canenable");
                String[] targetItems = targetFieldname.split("\\.");
                if (headTitle.containsValue(targetItems[0]) && canEnable) {
                    arPropName.add(targetField);
                    if(targetField.contains("_startdate")||targetField.contains("_enddate")){
                        targetField = targetField.replace("_startdate","");
                        targetField = targetField.replace("_enddate","");
                        arPropName.add(targetField);
                    }
                }
            }

            return (String[])arPropName.toArray(new String[0]);
        } else {
            return null;
        }
    }

    public static String[] getUnEnableProperty(IDataEntityType xbillDt) {
        DynamicObjectCollection mappingEntitys = getMappingColFromXBillDT(xbillDt);
        if (mappingEntitys != null && mappingEntitys.size() >= 1) {
            ArrayList<String> arPropName = new ArrayList<>();
            LocaleString headTitle = ResManager.getLocaleString("单据头", "ChangeModelHelper_0", "yem-yc-changemodel");

            for (DynamicObject mappingEntity : mappingEntitys) {
                String targetField = mappingEntity.getString("targetfield");
                String targetFieldname = mappingEntity.getString("targetfieldname");
                boolean canEnable = mappingEntity.getBoolean("canenable");
                String[] targetItems = targetFieldname.split("\\.");
                if (headTitle.containsValue(targetItems[0]) && !canEnable) {
                    arPropName.add(targetField);
                    if(targetField.contains("_startdate")||targetField.contains("_enddate")){
                        targetField = targetField.replace("_startdate","");
                        targetField = targetField.replace("_enddate","");
                        arPropName.add(targetField);
                    }
                }
            }

            return (String[])arPropName.toArray(new String[0]);
        } else {
            return null;
        }
    }

    public static String[] getCanLogProperty(IDataEntityType xBillDt, String entryEntity) {
        DynamicObjectCollection mappingEntitys = getMappingColFromXBillDT(xBillDt);
        if (mappingEntitys != null && mappingEntitys.size() >= 1) {
            ArrayList<String> arPropName = new ArrayList<>();
            LocaleString headTitle = ResManager.getLocaleString("单据头", "ChangeModelHelper_0", "yem-yc-changemodel");
            Iterator<DynamicObject> var5 = mappingEntitys.iterator();

            while(true) {
                String targetField;
                boolean canLog;
                String[] targetItems;
                EntityType xBillEntryType;
                do {
                    do {
                        do {
                            if (!var5.hasNext()) {
                                return (String[])arPropName.toArray(new String[0]);
                            }

                            DynamicObject mappingEntity = (DynamicObject)var5.next();
                            targetField = mappingEntity.getString("targetfield");
                            String targetFieldname = mappingEntity.getString("targetfieldname");
                            canLog = mappingEntity.getBoolean("canlog");
                            targetItems = targetFieldname.split("\\.");
                            List<EntityType> xBillentryEntitys = getChildEntities(xBillDt);
                            xBillEntryType = getChildEntitiesByAlias(xBillentryEntitys, targetItems[0]);
                        } while(xBillEntryType == null);
                    } while(targetItems.length != 2);
                } while(headTitle.containsValue(targetItems[0]));

                if (entryEntity.equalsIgnoreCase(xBillEntryType.getName()) && canLog) {
                    arPropName.add(targetField);
                }
            }
        } else {
            return null;
        }
    }

    public static String[] getCanWritebackProperty(IDataEntityType xBillDt, String entryEntity) {
        DynamicObjectCollection mappingEntitys = getMappingColFromXBillDT(xBillDt);
        if (mappingEntitys != null && mappingEntitys.size() >= 1) {
            ArrayList<String> arPropName = new ArrayList<>();
            LocaleString headTitle = ResManager.getLocaleString("单据头", "ChangeModelHelper_0", "yem-yc-changemodel");
            Iterator<DynamicObject> var5 = mappingEntitys.iterator();

            while(true) {
                String targetField;
                boolean canLog;
                String[] targetItems;
                EntityType xBillEntryType;
                do {
                    do {
                        do {
                            if (!var5.hasNext()) {
                                return (String[])arPropName.toArray(new String[0]);
                            }

                            DynamicObject mappingEntity = (DynamicObject)var5.next();
                            targetField = mappingEntity.getString("targetfield");
                            String targetFieldname = mappingEntity.getString("targetfieldname");
                            canLog = mappingEntity.getBoolean("canwriteback");
                            targetItems = targetFieldname.split("\\.");
                            List<EntityType> xBillentryEntitys = getChildEntities(xBillDt);
                            xBillEntryType = getChildEntitiesByAlias(xBillentryEntitys, targetItems[0]);
                        } while(xBillEntryType == null);
                    } while(targetItems.length != 2);
                } while(headTitle.containsValue(targetItems[0]));

                if (entryEntity.equalsIgnoreCase(xBillEntryType.getName()) && canLog) {
                    arPropName.add(targetField);
                }
            }
        } else {
            return null;
        }
    }

    public static String[] getEnableProperty(IDataEntityType xBillDt, String entryEntity) {
        DynamicObjectCollection mappingEntitys = getMappingColFromXBillDT(xBillDt);
        if (mappingEntitys != null && mappingEntitys.size() >= 1) {
            ArrayList<String> arPropName = new ArrayList<>();
            LocaleString headTitle = ResManager.getLocaleString("单据头", "ChangeModelHelper_0", "yem-yc-changemodel");
            Iterator<DynamicObject> var5 = mappingEntitys.iterator();

            while(true) {
                String targetField;
                boolean canEnable;
                String[] targetItems;
                EntityType xBillEntryType;
                do {
                    do {
                        do {
                            if (!var5.hasNext()) {
                                return (String[])arPropName.toArray(new String[0]);
                            }

                            DynamicObject mappingEntity = (DynamicObject)var5.next();
                            targetField = mappingEntity.getString("targetfield");
                            String targetFieldname = mappingEntity.getString("targetfieldname");
                            canEnable = mappingEntity.getBoolean("canenable");
                            targetItems = targetFieldname.split("\\.");
                            List<EntityType> xBillentryEntitys = getChildEntities(xBillDt);
                            xBillEntryType = getChildEntitiesByAlias(xBillentryEntitys, targetItems[0]);
                        } while(xBillEntryType == null);
                    } while(targetItems.length != 2);
                } while(headTitle.containsValue(targetItems[0]));

                if (entryEntity.equalsIgnoreCase(xBillEntryType.getName()) && canEnable) {
                    arPropName.add(targetField);
                    if(targetField.contains("_startdate")||targetField.contains("_enddate")){
                        targetField = targetField.replace("_startdate","");
                        targetField = targetField.replace("_enddate","");
                        arPropName.add(targetField);
                    }
                }
            }
        } else {
            return null;
        }
    }

    public static String[] getUnEnableProperty(IDataEntityType xBillDt, String entryEntity) {
        DynamicObjectCollection mappingEntitys = getMappingColFromXBillDT(xBillDt);
        if (mappingEntitys != null && mappingEntitys.size() >= 1) {
            ArrayList<String> arPropName = new ArrayList<>();
            LocaleString headTitle = ResManager.getLocaleString("单据头", "ChangeModelHelper_0", "yem-yc-changemodel");
            Iterator<DynamicObject> var5 = mappingEntitys.iterator();

            while(true) {
                String targetField;
                Boolean canEnable;
                String[] targetItems;
                EntityType xBillEntryType;
                do {
                    do {
                        do {
                            if (!var5.hasNext()) {
                                return (String[])arPropName.toArray(new String[0]);
                            }

                            DynamicObject mappingEntity = (DynamicObject)var5.next();
                            targetField = mappingEntity.getString("targetfield");
                            String targetFieldname = mappingEntity.getString("targetfieldname");
                            canEnable = mappingEntity.getBoolean("canenable");
                            targetItems = targetFieldname.split("\\.");
                            List<EntityType> xBillentryEntitys = getChildEntities(xBillDt);
                            xBillEntryType = getChildEntitiesByAlias(xBillentryEntitys, targetItems[0]);
                        } while(xBillEntryType == null);
                    } while(targetItems.length != 2);
                } while(headTitle.containsValue(targetItems[0]));

                if (entryEntity.equalsIgnoreCase(xBillEntryType.getName()) && !canEnable) {
                    arPropName.add(targetField);
                    if(targetField.contains("_startdate")||targetField.contains("_enddate")){
                        targetField = targetField.replace("_startdate","");
                        targetField = targetField.replace("_enddate","");
                        arPropName.add(targetField);
                    }
                }
            }
        } else {
            return null;
        }
    }

    public static List<EntityType> getChildEntities(IDataEntityType entityType) {
        List<EntityType> childEntities = new ArrayList();
        Iterator var2 = entityType.getProperties().iterator();

        while(var2.hasNext()) {
            IDataEntityProperty property = (IDataEntityProperty)var2.next();
            if (property instanceof ICollectionProperty) {
                ICollectionProperty collProp = (ICollectionProperty)property;
                if (collProp.getItemType() instanceof EntityType) {
                    EntityType childEntity = (EntityType)collProp.getItemType();
                    childEntities.add(childEntity);
                    childEntities.addAll(getChildEntities(childEntity));
                }
            }
        }

        return childEntities;
    }

    public static EntityType getChildEntitiesByAlias(List<EntityType> childEntities, String alias) {
        Iterator var2 = childEntities.iterator();

        EntityType childEntity;
        LocaleString childEntityDisName;
        do {
            if (!var2.hasNext()) {
                return null;
            }

            childEntity = (EntityType)var2.next();
            childEntityDisName = childEntity.getDisplayName();
        } while(alias == null || childEntityDisName == null || !childEntityDisName.containsValue(alias));

        return childEntity;
    }

    public static EntityType getChildEntitiesByName(List<EntityType> childEntities, String name) {
        Iterator<EntityType> var2 = childEntities.iterator();

        EntityType childEntity;
        String childEntityName;
        do {
            if (!var2.hasNext()) {
                return null;
            }

            childEntity = (EntityType)var2.next();
            childEntityName = childEntity.getName();
        } while(childEntityName == null || !childEntityName.equals(name));

        return childEntity;
    }

    public static String[] getChangeService(DynamicObject changeModel) {
        if (CommonUtils.isNull(changeModel)) {
            return null;
        } else {
            DynamicObjectCollection plugins = changeModel.getDynamicObjectCollection("pluginentity");
            if (CommonUtils.isNull(plugins)) {
                return null;
            } else {
                ArrayList<String> res = new ArrayList<>();

                for (DynamicObject plugin : plugins) {
                    boolean pluginenable = plugin.getBoolean("pluginenable");
                    String classname = plugin.getString("classname");
                    if (pluginenable && !CommonUtils.isNull(classname)) {
                        res.add(classname);
                    }
                }

                if (res.size() != 0) {
                    return (String[])res.toArray(new String[res.size()]);
                } else {
                    return null;
                }
            }
        }
    }

    public static String[] getAllWritebackProperty(IDataEntityType xbillDt) {
        String[] enablePropertys = getEnableProperty(xbillDt);
        String[] canwritebackPropertys = getCanWritebackProperty(xbillDt);
        ArrayList<String> allwritebackPropertys = new ArrayList<>();
        if (enablePropertys != null && enablePropertys.length > 0) {
            Collections.addAll(allwritebackPropertys, enablePropertys);
        }

        if (canwritebackPropertys != null && canwritebackPropertys.length > 0) {
            Collections.addAll(allwritebackPropertys, canwritebackPropertys);
        }

        return allwritebackPropertys.size() > 0 ? (String[])allwritebackPropertys.toArray(new String[0]) : null;
    }

    public static String[] getAllWritebackProperty(IDataEntityType xBillDt, String entryEntity) {
        String[] enablePropertys = getEnableProperty(xBillDt, entryEntity);
        String[] canwritebackPropertys = getCanWritebackProperty(xBillDt, entryEntity);
        ArrayList<String> allwritebackPropertys = new ArrayList<>();
        if (enablePropertys != null && enablePropertys.length > 0) {
            Collections.addAll(allwritebackPropertys, enablePropertys);
        }

        if (canwritebackPropertys != null && canwritebackPropertys.length > 0) {
            Collections.addAll(allwritebackPropertys, canwritebackPropertys);
        }

        return allwritebackPropertys.size() > 0 ? (String[])allwritebackPropertys.toArray(new String[0]) : null;
    }

    public static Map<String, Map<String, String>> getXBillEntryAndOp(DynamicObject changeModel) {
        Map<String, Map<String, String>> result = new HashMap();
        String[] plugins = getChangeService(changeModel);
        if (plugins != null && plugins.length != 0) {
            String[] var11 = plugins;
            int var4 = plugins.length;

            for(int var5 = 0; var5 < var4; ++var5) {
                String plugin = var11[var5];

                try {
                    Class<?> c = Class.forName(plugin);
                    Method m = c.getMethod("getXBillEntryAndOp");
                    Object r = m.invoke(c.newInstance());
                    if (r instanceof Map) {
                        result.putAll((Map)r);
                    }
                } catch (Exception var10) {
                    var10.printStackTrace();
                }
            }

            return result;
        } else {
            Map<String, String> value = new HashMap<>();
            value.put("entity", "billentry");
            value.put("entry_toolbar", "tbmainentry");
            value.put("btn_add", "addrow");
            value.put("btn_delete", "deleterow");
            value.put("btn_modify", "modifyrow");
            value.put("changetype", "billentrychangetype");
            value.put("srcid", "billentrysrcid");
            result.put(value.get("entity"), value);
            return result;
        }
    }

    public static Map<String, Map<String, String>> getXBillEntryAndOpFromCustpama(DynamicObject changeModel) {
        String customparameter = changeModel.getString("customparameter");
        if (customparameter != null && !customparameter.isEmpty()) {
            String xbilldtstr = "";
            if (changeModel.getDynamicObject("xbill") != null && changeModel.getDynamicObject("xbill").getPkValue() != null) {
                xbilldtstr = (String)changeModel.getDynamicObject("xbill").getPkValue();
            }

            EntityType xBillDt = MetadataServiceHelper.getDataEntityType(xbilldtstr);
            List<EntityType> xBillentryEntitys = getChildEntities(xBillDt);
            List<Map<String, String>> customparameters = new ArrayList<>(16);

            try {
                customparameters = SerializationUtils.fromJsonString(customparameter, customparameters.getClass());
                Map<String, Map<String, String>> result = new HashMap<>();

                for (Map<String, String> stringStringMap : customparameters) {
                    Map<String, String> map =  stringStringMap;

                    for (EntityType xBillentryEntity : xBillentryEntitys) {
                        if (xBillentryEntity.getName().equalsIgnoreCase((String) map.get("name"))) {
                            try {
                                Map<String, String> propertymapping =  SerializationUtils.fromJsonString((String) map.get("val"), Map.class);
                                result.put(map.get("name"), propertymapping);
                            } catch (Exception ignored) {
                            }
                        }
                    }
                }

                return result;
            } catch (Exception var13) {
                LOGGER.error(var13);
                return null;
            }
        } else {
            return null;
        }
    }

    public static void excutePluginMethod(DynamicObject changeModel, String methodName, DynamicObject arg) {
        String[] plugins = getChangeService(changeModel);
        if (plugins != null && plugins.length != 0) {
            String[] var4 = plugins;
            int var5 = plugins.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                String plugin = var4[var6];

                try {
                    Class<?> c = Class.forName(plugin);
                    Method m = c.getMethod(methodName, DynamicObject.class);
                    m.invoke(c.newInstance(), arg);
                } catch (Exception var10) {
                    var10.printStackTrace();
                }
            }

        }
    }

    public static Long getXBillTypeIDFromChangeModel(DynamicObject changeModelDO, Long srcBillTypeID) {
        Long targetXBillTypeID = 0L;
        if (changeModelDO != null && srcBillTypeID != null && srcBillTypeID > 0L) {
            DynamicObjectCollection billTypeEntryCol = changeModelDO.getDynamicObjectCollection("billtypeentity");
            if (billTypeEntryCol != null && billTypeEntryCol.size() > 0) {

                for (DynamicObject billTypeEntryDO : billTypeEntryCol) {
                    if (billTypeEntryDO.getDynamicObject("srcbilltype") != null) {
                        Long entrySrcBillTypeID = (Long) billTypeEntryDO.getDynamicObject("srcbilltype").getPkValue();
                        if (srcBillTypeID == entrySrcBillTypeID && billTypeEntryDO.getDynamicObject("xbilltype") != null) {
                            targetXBillTypeID = (Long) billTypeEntryDO.getDynamicObject("xbilltype").getPkValue();
                            break;
                        }
                    }
                }
            }

            return targetXBillTypeID;
        } else {
            return targetXBillTypeID;
        }
    }

    public static FilterBuilder convertStringToQFilter(String runcondition, String srcType) {
        if (kd.bos.util.StringUtils.isNotEmpty(runcondition)) {
            FilterCondition condition = (FilterCondition)SerializationUtils.fromJsonString(runcondition, FilterCondition.class);
            condition.createMetaData();
            FilterBuilder fb = new FilterBuilder(EntityMetadataCache.getDataEntityType(srcType), condition);
            fb.buildFilter();
            return fb;
        } else {
            return null;
        }
    }

    public static Map<Long, List<Object>> getAreaConditionArray(Long changeModel, String srcType) {
        DynamicObject changemodel = BusinessDataServiceHelper.loadSingleFromCache(changeModel, "yem_changemodel");
        String runcondition = "";
        String runconditionDesc = "";
        Map<Long, List<Object>> areaFilterMap = new HashMap<>();
        if (changemodel != null) {
            runcondition = changemodel.getString("areaconditionjson");
            runconditionDesc = (String)changemodel.getLocaleString("mul_areaconditiondesc").getItem(Lang.get().toString());
            FilterBuilder fb = convertStringToQFilter(runcondition, srcType);
            List<Object> filterlist = new ArrayList<>(2);
            if (fb != null) {
                filterlist.add(fb);
                filterlist.add(runconditionDesc);
                areaFilterMap.put(changeModel, filterlist);
            } else {
                areaFilterMap.put(changeModel, (List<Object>) null);
            }

            return areaFilterMap;
        } else {
            return null;
        }
    }

    public static ConditionValidation convertStringToValidate(String validconditionjson) {
        if (kd.bos.util.StringUtils.isNotEmpty(validconditionjson)) {
            List<IDataEntityType> dTypes = new ArrayList<>();
            dTypes.add(DataEntityType.getDataEntityType(ConditionValidation.class));
            ListDcxmlBinder binder = new ListDcxmlBinder(false, dTypes);
            Map<String, Object> parameter = SerializationUtils.fromJsonString(validconditionjson, Map.class);
            DcJsonSerializer ds = new DcJsonSerializer(binder);
            ds.setIsLocaleValueFull(true);
            ConditionValidation validation = (ConditionValidation)((ConditionValidation)ds.deserializeFromMap(parameter, (Object)null));
            if (validation.getDescription() == null && kd.bos.dataentity.utils.StringUtils.isNotBlank(parameter.get("Description")) && parameter.get("Description") instanceof String) {
                validation.setDescription(new LocaleString((String)parameter.get("Description")));
            }

            if (validation.getMessage() == null && kd.bos.dataentity.utils.StringUtils.isNotBlank(parameter.get("Message")) && parameter.get("Message") instanceof String) {
                validation.setMessage(new LocaleString((String)parameter.get("Message")));
            }

            return validation;
        } else {
            return null;
        }
    }

    public static List<ConditionValidation> getValidConditionList(String xBillEntiyId) {
        DynamicObject changmodel = getChangeModel4XBill(xBillEntiyId);
        if (changmodel != null) {
            DynamicObjectCollection validcol = changmodel.getDynamicObjectCollection("validentity");
            List<ConditionValidation> vallist = new ArrayList<>();

            for (DynamicObject valid : validcol) {
                ConditionValidation validation = convertStringToValidate(valid.getString("validconditionjson_tag"));
                if (validation != null && validation.getEnabled()) {
                    vallist.add(validation);
                }
            }

            return vallist;
        } else {
            return null;
        }
    }

    public static List<ConditionValidation> getValidConditionList(String xBillEntiyId, String opkey) {
        DynamicObject changmodel = getChangeModel4XBill(xBillEntiyId);
        if (changmodel != null) {
            DynamicObject changemodelDO = changmodel;
            String validoptype = changemodelDO.getString("validoptype");
            if (kd.bos.dataentity.utils.StringUtils.isNotEmpty(validoptype) && validoptype.contains(opkey)) {
                DynamicObjectCollection validcol = changemodelDO.getDynamicObjectCollection("validentity");
                List<ConditionValidation> vallist = new ArrayList<>();

                for (DynamicObject valid : validcol) {
                    ConditionValidation validation = convertStringToValidate(valid.getString("validconditionjson_tag"));
                    if (validation != null && validation.getEnabled()) {
                        vallist.add(validation);
                    }
                }

                return vallist;
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    private static DynamicObjectCollection getMappingColFromXBillDT(IDataEntityType xBillDt) {
        if (xBillDt == null) {
            return null;
        } else {
            DynamicObject changeModel = getChangeModel4XBill(xBillDt.getName());
            if (changeModel == null) {
                return null;
            } else {
                return changeModel.getDynamicObjectCollection("mappingentity");
            }
        }
    }

    public static void SetPropertyValue(DynamicObject xBill, String propertyName, Object value) {
        if(value  instanceof MulBasedataDynamicObjectCollection) {//多选基础资料
            DynamicObjectCollection portnewcol = xBill.getDynamicObjectCollection(propertyName);
            DynamicObjectCollection portcol = (DynamicObjectCollection) value;
            portnewcol.clear();
            DynamicObjectType typeLoad = portnewcol.getDynamicObjectType();
            if (portcol.size() > 0) {
                for (DynamicObject port : portcol) {
                    DynamicObject fbasedataid = port.getDynamicObject("fbasedataid");
                    DynamicObject dynamicLoad = new DynamicObject(typeLoad);
                    dynamicLoad.set("fbasedataid", fbasedataid);
                    portnewcol.add(dynamicLoad);
                }
                xBill.set(propertyName,portnewcol);
            }
        }else {
            xBill.set(propertyName, value);
        }
    }
}