package cn.ibizlab.codegen.model;

import cn.ibizlab.codegen.utils.DataObject;
import cn.ibizlab.codegen.utils.StringAdvUtils;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.ibizsys.model.database.IPSDEFDTColumn;
import net.ibizsys.model.dataentity.IPSDataEntity;
import net.ibizsys.model.dataentity.defield.IPSDEField;
import net.ibizsys.model.dataentity.defield.IPSLinkDEField;
import net.ibizsys.model.dataentity.der.*;
import net.ibizsys.model.dataentity.ds.IPSDEDataQueryCodeCond;
import net.ibizsys.model.dataentity.ds.IPSDEDataSetGroupParam;
import net.ibizsys.model.dataentity.ds.PSDEDataSetGroupParamImpl;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
public class EntityModel  extends BaseModel {

    
    private SystemModel system;
    
    
    public String getEntityName() {
        return getDataEntity().getName();
    }

    
    
    public String getTableName() {
        return getDataEntity().getTableName();
    }

    
    
    public String getLogicName() {
        return getDataEntity().getLogicName();
    }

    public String getModule() {
        if(getDataEntity().getPSSystemModule()!=null)
            return getDataEntity().getPSSystemModule().getCodeName().toLowerCase();
        return "ungroup";
    }


    public IPSDataEntity getDataEntity(){
        return (IPSDataEntity)opt;
    }

    private List<DataSetModel> queries;

    public EntityModel addQueries(DataSetModel dataSet)
    {
        if(queries==null)
            queries=new ArrayList<>();
        queries.add(dataSet);
        return this;
    }

    private Map<String,DataSetModel> dataQueries;

    public EntityModel addDataQueries(DataSetModel dataSet)
    {
        if(dataQueries==null)
            dataQueries=new LinkedHashMap<>();
        dataQueries.put(dataSet.getDatasetId(),dataSet);
        if("View".equalsIgnoreCase(dataSet.codeName)&&viewDataQuery==null)
            viewDataQuery=dataSet;
        if(getDataEntity().getDefaultPSDEDataSet().getCodeName().equalsIgnoreCase(dataSet.codeName)&&defaultDataQuery==null)
            defaultDataQuery=dataSet;
        return this;
    }

    private DataSetModel viewDataQuery;

    private DataSetModel defaultDataQuery;

    private List<DataSetModel> dataSets;

    public EntityModel addDataSet(DataSetModel dataSet)
    {
        if(dataSets==null)
            dataSets=new ArrayList<>();
        dataSets.add(dataSet);
        return this;
    }
    


    private List<FieldModel> fields;

    public EntityModel addField(FieldModel fieldModel)
    {
        if(fields==null)
            fields=new ArrayList<>();
        fields.add(fieldModel);
        return this;
    }

    private List<RelationshipModel> references;

    public EntityModel addReference(RelationshipModel relationshipModel)
    {
        if(references==null)
            references=new ArrayList<>();
        references.add(relationshipModel);
        return this;
    }

    public boolean isHasReferences()
    {
        return !ObjectUtils.isEmpty(references);
    }
    
    
    private Map<String,RelationshipModel> refMaps;
    
    
    public Map<String,RelationshipModel> getRefMaps()
    {
        if(refMaps==null)
            refMaps=new LinkedHashMap<>();
        if(references!=null)
        {
            references.forEach(ship->{
                if(!StringUtils.isEmpty(ship.getCodeName()))
                    refMaps.put(ship.getCodeName().toString(),ship);
                String fkname= DataObject.getStringValue(ship.getName(),"");
                if(!StringUtils.isEmpty(fkname))
                    refMaps.put(fkname, ship);
            });
        }
        return refMaps;
    }

    private List<RelationshipModel> nesteds;

    public EntityModel addNested(RelationshipModel relationshipModel)
    {
        if(nesteds==null)
            nesteds=new ArrayList<>();
        nesteds.add(relationshipModel);
        return this;
    }

    private Map<String,EntityModel> relEntitiesMap;

    public EntityModel addRelEntity(String codeName,EntityModel entityModel)
    {
        if(entityModel==null||StringUtils.isEmpty(codeName)||codeName.equalsIgnoreCase(this.codeName))
            return this;
        if(relEntitiesMap==null)
            relEntitiesMap=new LinkedHashMap<>();
        relEntitiesMap.put(codeName,entityModel);
        return this;
    }

    public Collection<EntityModel> getRelEntities()
    {
        if(relEntitiesMap==null)
        {
            if(this.references!=null)
                references.forEach(item-> {
                    this.addRelEntity(item.getEntityCodeName(),item.getRelEntity());
                });
            if(this.nesteds!=null)
                nesteds.forEach(item-> {
                    this.addRelEntity(item.getEntityCodeName(),item.getRelEntity());
                });
            if(this.indexRelation!=null)
                this.addRelEntity(this.indexRelation.getEntityCodeName(),this.indexRelation.getRelEntity());
        }
        if(relEntitiesMap!=null)
            return relEntitiesMap.values();
        return new ArrayList<>();
    }
    
    private Map<String, FieldModel> fieldMap = null;

    
    
    public Map<String, FieldModel> getFieldMap()
    {
        if(fields!=null&&fieldMap==null)
        {
            fieldMap=new LinkedHashMap<>();
            fields.forEach(field->{
                fieldMap.put(field.getFieldName(),field);
                fieldMap.put(field.getCodeName().toString(),field);
            });
        }
        return fieldMap;
    }

    
    
    private FieldModel lastModifyField;
    
    
    public FieldModel getLastModifyField() {
        if(fields!=null&&lastModifyField==null)
            for(FieldModel fieldModel:fields)
                if(fieldModel.isLastModifyField())
				{
					lastModifyField=fieldModel;
					return lastModifyField;
				}
        return lastModifyField;
    }

    private FieldModel orgField;


    public FieldModel getOrgField() {
        if(fields!=null&&orgField==null)
            for(FieldModel fieldModel:fields)
                if(fieldModel.isOrgField())
                {
                    orgField=fieldModel;
                    return orgField;
                }
        return orgField;
    }




    public boolean isLogicValid()
    {
        return getDataEntity().isLogicValid();
    }
	
	
    private FieldModel logicValidField;
	
	
	public FieldModel getLogicValidField() {
		if(isLogicValid()&&logicValidField==null) {
			if (fields != null) {
				for (FieldModel fieldModel : fields) {
					if (fieldModel.isLogicValidField()) {
						logicValidField = fieldModel;
						return logicValidField;
					}
				}
			}
		}
		return logicValidField;
	}


	
	public String getValidLogicValue()
	{
		String validLogicValue=this.getDataEntity().getValidLogicValue();
		if(StringUtils.isEmpty(validLogicValue))
            validLogicValue="1";
		return validLogicValue;
	}
	

	public String getInvalidLogicValue()
	{
        String invalidLogicValue=this.getDataEntity().getInvalidLogicValue();
		if(StringUtils.isEmpty(invalidLogicValue))
            invalidLogicValue="0";
		return invalidLogicValue;
	}
	
	
	private FieldModel keyField;
    
    
    public FieldModel getKeyField() {
        if(fields!=null&&keyField==null) {
            for(FieldModel fieldModel:fields){
                if(fieldModel.isKeyDEField()) {
					keyField=fieldModel;
					break;
				}
            }
            if((!keyField.isPhisicalDEField())&&getUnionKeyFields().size()==1)
            {
                keyField=unionKeyFields.get(0);
            }
        }
        return keyField;
    }

	
	
    private List<FieldModel> unionKeyFields;
	
	
	public List<FieldModel> getUnionKeyFields() {
		if(fields!=null&&unionKeyFields==null) {
			unionKeyFields = new ArrayList<>();
			if(getDataEntity().getUnionKeyValuePSDEFields()!=null)
            {
                getDataEntity().getUnionKeyValuePSDEFields().forEach(def->{
                    unionKeyFields.add(getFieldMap().get(def.getCodeName()));
                });
            }
		}
		return unionKeyFields;
	}

    public boolean isUnionKeyMode(){
	    return !ObjectUtils.isEmpty(getUnionKeyFields());
    }
    
    public List<FieldModel> getKeyFields() {
        if(this.getKeyField()!=null&&this.getKeyField().isPhisicalDEField()) {
            List<FieldModel> keyFields = new ArrayList<>();
            keyFields.add(getKeyField());
            return keyFields;
        }
        else
            return getUnionKeyFields();
    }

    public List<FieldModel> getQuickSearchFields() {
	    return fields.stream().filter(s->s.getDataEntityField().isEnableQuickSearch()).collect(Collectors.toList());
    }


    private Map<String, ActionModel> actions;

    public EntityModel addAction(ActionModel action)
    {
        if(actions==null)
            actions=new LinkedHashMap<>();
        actions.put(StringAdvUtils.camelcase(action.getCodeName()),action);
        return this;
    }

    private static Set<String> ignoActions=new HashSet<String>(){{
        add("get");add("create");add("update");add("remove");add("save");add("getdraft");add("checkkey");
        add("createbatch");add("savebatch");add("updatebatch");add("removebatch");
    }};

    public List<ActionModel> getExtActions()
    {
        return actions.values().stream().filter(s->!ignoActions.contains(s.getCodeName().toLowerCase())).collect(Collectors.toList());
    }
    
    public String getDsName()
    {
        String dsName=this.getDataEntity().getDSLink();
        if(StringUtils.isEmpty(dsName)||"DEFAULT".equalsIgnoreCase(dsName))
            dsName=null;
        else
            dsName=dsName.toLowerCase();
        return dsName;
    }



    public String getTableName(String dsType)
    {
        return this.getStringValue("table-"+dsType.toLowerCase(),getTableName());
    }

    



	private String storage="SQL";

	public void setStorage(Integer type)
    {
        switch(type){
            case 0:
                this.storage="NONE";
                break;
            case 1:
                this.storage="SQL";
                break;
            case 2:
                this.storage="NoSQL";
                break;
            case 4:
                this.storage="ServiceAPI";
                break;
            default:
                this.storage="SQL";
                break;
        }
    }
    public void setStorage(String type)
    {
        this.storage=type;
    }



    private RelationshipModel indexRelation;

    public boolean isIndexSubDE()
    {
        if(this.getIndexRelation()!=null)
            return true;
        return false;
    }

    public boolean isLogicInherit()
    {
        if(this.getIndexRelation()==null)
            return false;
        IPSDERBase MinorPSDER = this.getIndexRelation().getDer();
        if("DERINHERIT".equals(MinorPSDER.getDERType()) && MinorPSDER instanceof IPSDERInherit)
        {
            return ((IPSDERInherit)MinorPSDER).isLogicInherit();
        }
        return false;
    }


    public boolean isHasPSDERsMapping()
    {
        if(this.getReferences()!=null)
        {
            for(RelationshipModel rel:this.getReferences())
            {

                if(rel.getRelEntity().getStorage().equals("NONE"))
                    continue;
                if(!(rel.getDer() instanceof PSDER1NImpl))
                    continue;
                if(((PSDER1NImpl)rel.getDer()).getPSDER1NDEFieldMaps()==null)
                    continue;
                for(IPSDER1NDEFieldMap derField : ((PSDER1NImpl)rel.getDer()).getPSDER1NDEFieldMaps())
                {
                    if(derField.getMapType().equals("COUNT") || derField.getMapType().equals("SUM")
                            || derField.getMapType().equals("AVG") || derField.getMapType().equals("MAX") || derField.getMapType().equals("MIN"))
                        return true;
                }
            }
        }
        return false;
    }

    public boolean isEnableES()
    {
        return "elasticsearch".equalsIgnoreCase(this.getDataEntity().getUserTag());
    }

    public boolean isHasDupCheck()
    {
        if(this.getDefaultDataQuery()==null)
            return false;
        if(getDataEntity().getStorageMode()!=1&&getDataEntity().getStorageMode()!=2)
            return false;
        for(IPSDEField field:getDataEntity().getAllPSDEFields())
        {
            if("ALL".equalsIgnoreCase(field.getDupCheckMode()))
                return true;
        }
        return false;
    }

    public boolean isNeedTypeHandler()
    {
        if(!"NONE".equalsIgnoreCase(getStorage()))
            return false;
        if(isHasReferences())
        {
            for(RelationshipModel ref:getReferences())
            {
                if(ref.getDer() instanceof IPSDER1N && ref.getRelEntity().getStorage().equalsIgnoreCase("SQL"))
                {
                    IPSDEField def=((IPSDER1N) ref.getDer()).getPSOne2ManyDataDEField();
                    if(def!=null&&def.isPhisicalDEField())
                        return true;
                }
            }
        }
        return false;
    }

    public List getMqPublishers()
    {
        List publishers=new ArrayList();
        if(getDataEntity().getAllPSDEDataSyncs()!=null)
        {
            getDataEntity().getAllPSDEDataSyncs().forEach(dataSync->{
                if(dataSync.getOutPSSysDataSyncAgent()!=null&&dataSync.getEventType()!=0)
                {
                    Map map=new HashMap();
                    map.put("dataSync",dataSync);
                    Set<String> monitors=new LinkedHashSet<>();
                    map.put("monitors",monitors);
                    if((dataSync.getEventType()&1)>0)
                        monitors.add("create");
                    if((dataSync.getEventType()&2)>0)
                        monitors.add("update");
                    if((dataSync.getEventType()&4)>0)
                        monitors.add("remove");
                    publishers.add(map);
                }
            });
        }
        return publishers;
    }

    public List<OptionItem> getDataScopes()
    {
        List<OptionItem> dataScopes=new ArrayList<>();
        dataScopes.add(new OptionItem().setId("all").setName("全部数据"));
        boolean hasOrgId=false,hasDetpId=false,hasCreateBy=false;
        for(FieldModel field:getFields())
        {
            if("ORGID".equalsIgnoreCase(field.getDataEntityField().getPredefinedType()))
                hasOrgId=true;
            else if("ORGSECTORID".equalsIgnoreCase(field.getDataEntityField().getPredefinedType()))
                hasDetpId=true;
            else if("CREATEMAN".equalsIgnoreCase(field.getDataEntityField().getPredefinedType()))
                hasCreateBy=true;
        }
        if(hasOrgId)
        {
            dataScopes.add(new OptionItem().setId("curorg").setName("当前单位"));
            dataScopes.add(new OptionItem().setId("porg").setName("上级单位"));
            dataScopes.add(new OptionItem().setId("sorg").setName("下级单位"));
        }
        if(hasDetpId)
        {
            dataScopes.add(new OptionItem().setId("curorgdept").setName("当前部门"));
            dataScopes.add(new OptionItem().setId("porgdept").setName("上级部门"));
            dataScopes.add(new OptionItem().setId("sorgdept").setName("下级部门"));
        }
        if(hasCreateBy)
            dataScopes.add(new OptionItem().setId("createman").setName("创建人"));
        return dataScopes;
    }

    private Map<String, POSchema> poSchemas;

    public POSchema getDefaultPOSchema()
    {
        return getPOSchema("default");
    }
    public EntityModel addPOSchema(String name, POSchema poSchema)
    {
        if(poSchema!=null)
        {
            if(poSchemas==null)
                poSchemas=new LinkedHashMap<>();
            poSchemas.put(name,poSchema.build());
        }

        return this;
    }
    public POSchema getPOSchema(String name)
    {

        if(StringUtils.isEmpty(name)&&(!StringUtils.isEmpty(this.getDsName())))
            name=this.getDsName();
        if(StringUtils.isEmpty(name))
            name="mysql";

        if(poSchemas==null)
            poSchemas=new LinkedHashMap<>();
        if(poSchemas.containsKey(name))
        {
            return poSchemas.get(name);
        }
        String vendorProvider=POSchema.provider.get(name.toLowerCase());
        if((!StringUtils.isEmpty(vendorProvider))&&(!name.equalsIgnoreCase(vendorProvider))&&poSchemas.containsKey(vendorProvider))
            return poSchemas.get(vendorProvider);

        if(poSchemas.size()>0)
            return poSchemas.values().iterator().next();

        return null;
    }



    public String getStringValue(String key,String defaultVal)
    {
        return extParams.getStringValue(key,defaultVal);
    }

    private boolean hasResetField=false;


    public EntityModel(SystemModel systemModel,IPSDataEntity dataEntity)
    {
        Assert.notNull(dataEntity,"未找到对应的实体模型:"+dataEntity.getId());
        this.opt=dataEntity;
        this.system=systemModel;
        this.setCodeName(dataEntity.getCodeName());
        this.setName(dataEntity.getName());
        this.setStorage(dataEntity.getStorageMode());
        List<String> dsTypes=new ArrayList<>();

        if(dataEntity.getAllPSDEDBConfigs()!=null)
        {
            dataEntity.getAllPSDEDBConfigs().forEach(item->{
                String dbType=item.getDBType().toLowerCase().replace("mysql5","mysql");
                if("mysql".equals(dbType))
                    system.setEnableMysql(true);
                else if("oracle".equals(dbType))
                    system.setEnableOracle(true);
                else if("postgresql".equals(dbType))
                    system.setEnablePostgreSQL(true);
                else if("dameng".equals(dbType)||"dm".equals(dbType))
                    system.setEnableDameng(true);
                dsTypes.add(dbType);
                if(this.getTableName()!=null && (!this.getTableName().equalsIgnoreCase(item.getTableName())))
                    this.set("table-"+item.getDBType().toLowerCase().replace("mysql5","mysql"),item.getTableName());
            });
        }




        if(dataEntity.getMinorPSDERs()!=null)
        {
            for(IPSDERBase der : dataEntity.getMinorPSDERs())
            {
                RelationshipModel rel=new RelationshipModel(this,der);
                rel.setRelationType("reference").setCodeName(der.getCodeName()).setEntityId(der.getMajorPSDataEntity().getId())
                        .setEntityCodeName(der.getMajorPSDataEntity().getCodeName()).setEntityName(der.getMajorPSDataEntity().getName())
                        .setEntityLogicName(der.getMajorPSDataEntity().getLogicName()).setTableName(der.getMajorPSDataEntity().getTableName());
                if(der.getMajorPSDataEntity().getPSSystemModule()!=null)
                    rel.setModule(der.getMajorPSDataEntity().getPSSystemModule().getCodeName().toLowerCase());



                if(der instanceof IPSDER1N)
                {
                    IPSDER1N der1n=(IPSDER1N)der;
                    String refFieldName=der1n.getPSPickupDEField().getObjectNode().get("getRelatedPSDEField").get("name").asText();
                    String refCodeName=refFieldName;
                    if(der1n.getPSPickupDEField().getObjectNode().get("getRelatedPSDEField").get("codeName")!=null)
                        refCodeName=der1n.getPSPickupDEField().getObjectNode().get("getRelatedPSDEField").get("codeName").asText();

                    LookupModel lookupModel=new LookupModel().setRelationid(der.getId())
                            .setFieldname(der1n.getPickupDEFName()).setCodeName(der1n.getPSPickupDEField().getCodeName()).setReffieldname(refFieldName).setRefCodeName(refCodeName);
                    rel.addLookup(lookupModel);
                }
                else if (der instanceof IPSDERIndex || der instanceof IPSDERInherit)
                {
                    if(der.getMajorPSDataEntity().getKeyPSDEField()!=null)
                    {
                        LookupModel lookupModel = new LookupModel().setRelationid(der.getId())
                                .setFieldname(this.getDataEntity().getKeyPSDEField().getName()).setCodeName(this.getDataEntity().getKeyPSDEField().getCodeName())
                                .setReffieldname(der.getMajorPSDataEntity().getKeyPSDEField().getName()).setRefCodeName(der.getMajorPSDataEntity().getKeyPSDEField().getCodeName());
                        rel.addLookup(lookupModel);
                    }
                    if(der.getMajorPSDataEntity().getMajorPSDEField()!=null)
                    {
                        LookupModel lookupModel = new LookupModel().setRelationid(der.getId())
                                .setFieldname(this.getDataEntity().getMajorPSDEField().getName()).setCodeName(this.getDataEntity().getMajorPSDEField().getCodeName())
                                .setReffieldname(der.getMajorPSDataEntity().getMajorPSDEField().getName()).setRefCodeName(der.getMajorPSDataEntity().getMajorPSDEField().getCodeName());
                        rel.addLookup(lookupModel);
                    }
                    List<IPSDERIndexDEFieldMap> map = ((IPSDERIndex) der).getPSDERIndexDEFieldMaps();
                    if(!ObjectUtils.isEmpty(map))
                    {
                        map.forEach(item->{
                            LookupModel lookupModel=new LookupModel().setRelationid(der.getId())
                                    .setFieldname(item.getMinorPSDEField().getName()).setCodeName(item.getMinorPSDEField().getCodeName())
                                    .setReffieldname(item.getMajorPSDEField().getName()).setRefCodeName(item.getMajorPSDEField().getCodeName());
                            rel.addLookup(lookupModel);
                        });
                    }
                }
                //聚合关系 暂时忽略
                else if (der instanceof IPSDERAggData){
                    continue;
                }

                if("DERINHERIT".equals(der.getDERType()))
                {
                    rel.setRelationType("inherit");
                    this.setIndexRelation(rel);
                }
                else if("DERINDEX".equals(der.getDERType())//&& der.getMajorPSDataEntity().getVirtualMode()!=3
                        && der.getMajorPSDataEntity().getIndexTypePSDEField()!=null)
                {
                    rel.setRelationType("index");
                    this.setIndexRelation(rel);
                }
                else {
                    rel.setRelationType("reference");
                    this.addReference(rel);
                }
            }

        }

        if(dataEntity.getMajorPSDERs()!=null)
        {
            for(IPSDERBase der : dataEntity.getMajorPSDERs())
            {
                if(der instanceof IPSDER1N)
                {
                    IPSDER1N der1n=(IPSDER1N)der;
                    String codeName=der.getMinorCodeName();
                    boolean nestedRS=false;
                    if(der1n.isNestedRS())
                        nestedRS=true;
                    else if(der1n.getPSOne2ManyDataDEField()!=null)
                    {
                        nestedRS=true;
                    }
                    else if(der1n.getMinorPSDataEntity().getPSSubSysServiceAPIDE()!=null&&der1n.getMinorPSDataEntity().getPSSubSysServiceAPIDE().isNested())
                    {
                        nestedRS=true;
                    }
                    if(!nestedRS)
                        continue;

                    if(StringUtils.isEmpty(codeName))
                        codeName=der.getMinorPSDataEntity().getCodeName();

                    RelationshipModel rel=new RelationshipModel(this,der);
                    rel.setRelationType("nested").setCodeName(codeName).setEntityId(der.getMinorPSDataEntity().getId())
                            .setEntityCodeName(der.getMinorPSDataEntity().getCodeName()).setEntityName(der.getMinorPSDataEntity().getName())
                            .setEntityLogicName(der.getMinorPSDataEntity().getLogicName()).setTableName(der.getMinorPSDataEntity().getTableName());

                    if(der.getMinorPSDataEntity().getPSSystemModule()!=null)
                        rel.setModule(der.getMinorPSDataEntity().getPSSystemModule().getCodeName().toLowerCase());

                    if(der1n.getPSOne2ManyDataDEField()!=null&&der1n.getPSOne2ManyDataDEField().isPhisicalDEField()&&der1n.getMinorPSDataEntity().getStorageMode()==0)
                    {
                        rel.setColumnName(der1n.getPSOne2ManyDataDEField().getName().toLowerCase());
                    }

                    rel.setFkFieldCodeName(der1n.getPSPickupDEField().getCodeName());
                    String refFieldName=der1n.getPSPickupDEField().getObjectNode().get("getRelatedPSDEField").get("name").asText();
                    String refCodeName=refFieldName;
                    if(der1n.getPSPickupDEField().getObjectNode().get("getRelatedPSDEField").get("codeName")!=null)
                        refCodeName=der1n.getPSPickupDEField().getObjectNode().get("getRelatedPSDEField").get("codeName").asText();

                    LookupModel lookupModel=new LookupModel().setRelationid(der.getId())
                            .setFieldname(der1n.getPickupDEFName()).setCodeName(der1n.getPSPickupDEField().getCodeName()).setReffieldname(refFieldName).setRefCodeName(refCodeName);
                    rel.addLookup(lookupModel);

                    this.addNested(rel);
                }


            }
        }

        Map<String,FieldModel> fieldMaps=new LinkedHashMap<>();
        for(IPSDEField defield:dataEntity.getAllPSDEFields())
        {

           

            if(defield.isPasteReset())
                this.hasResetField=true;

            FieldModel fieldModel=new FieldModel(this,defield);

            try { 
                fieldModel.setDict(defield.getPSCodeList()!=null?defield.getPSCodeList().getCodeName():null);                 
            } catch (Exception ex){}

            if(defield.getAllPSDEFDTColumns()!=null)
            {
                defield.getAllPSDEFDTColumns().forEach(col->{
                    if(!fieldModel.getFieldName().equalsIgnoreCase(col.getColumnName()))
                        fieldModel.set("column-"+col.getDBType().toLowerCase().replace("mysql5","mysql"),col.getColumnName());
                    if(StringUtils.isEmpty(fieldModel)&&defield.isFormulaDEField()&&(!StringUtils.isEmpty(col.getQueryCodeExp())))
                        fieldModel.setExpression(col.getQueryCodeExp().replace("`","").replace("[","").replace("]",""));
                });
            }

            if(defield.isLinkDEField() && defield instanceof IPSLinkDEField)
            {
                IPSLinkDEField linkDEField = (IPSLinkDEField)defield;
                String relfieldname=linkDEField.getObjectNode().get("getRelatedPSDEField").get("name").asText();
                String relfieldcodename=linkDEField.getObjectNode().get("getRelatedPSDEField").get("codeName").asText();
                linkDEField.getRelatedPSDEField();
                fieldModel.setRefFieldName(relfieldname).setRefFieldCodeName(relfieldcodename);

                if(!StringUtils.isEmpty(linkDEField.getPSDER().getCodeName()))
                {
                    RelationshipModel relationshipModel=this.getRefMaps().get(linkDEField.getPSDER().getCodeName());
                    if(relationshipModel!=null&&(!StringUtils.isEmpty(relationshipModel.getCodeName()))) {
                        relationshipModel.addField(fieldModel);
                        fieldModel.setReference(relationshipModel);
                        if("PICKUP".equalsIgnoreCase(defield.getDataType())) {
                            relationshipModel.setFkField(fieldModel);
                            relationshipModel.setFkFieldCodeName(fieldModel.getCodeName().toString());
                        }
                    }
                }

            }



            fieldMaps.put(fieldModel.getFieldName(),fieldModel);
            this.addField(fieldModel);
        }



        if(dataEntity.getAllPSDEDataQueries()!=null)
        {
            dataEntity.getAllPSDEDataQueries().forEach(dataQuery->{

                try {
                    if(dataQuery.getAllPSDEDataQueryCodes()!=null)
                    {
                        dataQuery.getAllPSDEDataQueryCodes().forEach(dq->{
                            if(StringUtils.isEmpty(dq.getQueryCode()))
                                return;
                            String select=TransUtils.contextParamConvert(dq.getQueryCode());
                            String where=null;
                            if(dq.getPSDEDataQueryCodeConds()!=null)
                            {
                                int i=0;
                                boolean b=TransUtils.checkIgnoreNullvalueCond(dq.getPSDEDataQueryCodeConds());
                                for(IPSDEDataQueryCodeCond cond:dq.getPSDEDataQueryCodeConds())
                                {
                                    if(i==0)
                                        where=" where ";
                                    else if(i>0)
                                        where=where.concat(" and ");

                                    where=where.concat(b?TransUtils.checkNullContextParamConvert(cond.getCustomCond()):TransUtils.contextParamConvert(cond.getCustomCond()));
                                    i++;
                                }
                            }

                            DataSetModel dsModel=new DataSetModel();
                            dsModel.setEntity(this);
                            dsModel.setName(dataQuery.getName());
                            dsModel.setDatasetId(this.getEntityName().toLowerCase()+"-dq-"+dataQuery.getCodeName()+"-"+dq.getDBType().toLowerCase().replace("mysql5","mysql"))
                                    .setDsType(dq.getDBType().toLowerCase().replace("mysql5","mysql"))
                                    .setDatasetName(dataQuery.getLogicName()).setCodeName(dataQuery.getCodeName())
                                    .setSelect(select).setWhere(where)
                                    .setDsCode(select.concat(where==null?"":where));

                            this.addQueries(dsModel);
                            this.addDataQueries(dsModel);
                        });
                    }
                } catch (Exception exception) {

                }

            });
        }

        if(dataEntity.getAllPSDEDataSets()!=null)
        {
            dataEntity.getAllPSDEDataSets().forEach(dataSet->{

                String select="select t1.*";

                String from=" from ( %s ) t1 ";

                String where=null;

                String groupBy=null;

                String orderBy=null;

                if(dataSet.getGroupMode()==1||dataSet.getMajorSortPSDEField()!=null)
                {

                    if(dataSet.getGroupMode()==1&&(!ObjectUtils.isEmpty(dataSet.getPSDEDataSetGroupParams())))
                    {
                        select="select ";
                        int i=0;
                        for(IPSDEDataSetGroupParam obj:dataSet.getPSDEDataSetGroupParams())
                        {
                            if(!(obj instanceof PSDEDataSetGroupParamImpl))
                                continue;
                            PSDEDataSetGroupParamImpl groupParam=(PSDEDataSetGroupParamImpl)obj;
                            if(i>0)select=select.concat(",");
                            if(groupParam.isEnableGroup())
                            {
                                if(!StringUtils.isEmpty(groupParam.getGroupCode()))
                                    select=select.concat(groupParam.getGroupCode());
                                else
                                    select=select.concat(groupParam.getName());
                            }
                            else
                                select=select.concat(groupParam.getGroupCode());
                            select=select.concat(" as ").concat(groupParam.getName().toLowerCase());
                            i++;
                        }
                    }


                    if(dataSet.getGroupMode()==1&&(!ObjectUtils.isEmpty(dataSet.getPSDEDataSetGroupParams())))
                    {
                        groupBy= " group by ";
                        int i=0;
                        for(IPSDEDataSetGroupParam obj:dataSet.getPSDEDataSetGroupParams())
                        {
                            if(!(obj instanceof PSDEDataSetGroupParamImpl))
                                continue;
                            PSDEDataSetGroupParamImpl groupParam=(PSDEDataSetGroupParamImpl)obj;
                            if(groupParam.isEnableGroup())
                            {
                                if(i>0)groupBy=groupBy.concat(",");

                                if(!StringUtils.isEmpty(groupParam.getGroupCode()))
                                    groupBy=groupBy.concat(groupParam.getGroupCode());
                                else
                                    groupBy=groupBy.concat(groupParam.getName());
                                i++;
                            }
                        }
                    }


                }

                try {



                    if(dataSet.getPSDEDataQueries()!=null)
                    {
                        DataSetModel dsModel=new DataSetModel(this,dataSet);
                        dsModel.setDatasetId(dataSet.getCodeName())
                                .setDatasetName(dataSet.getLogicName()).setCodeName(dataSet.getCodeName()).setSelect(select).setFrom(from).setGroupBy(groupBy);
                        this.addDataSet(dsModel);

                        Map<String, String> map =new HashMap<>();
                        dataSet.getPSDEDataQueries().forEach(dataQuery->{

                            try {
                                if(dataQuery.getAllPSDEDataQueryCodes()!=null)
                                {
                                    dsModel.addQueries(dataQuery.getCodeName());
                                    dataQuery.getAllPSDEDataQueryCodes().forEach(dq->{
                                        String code="";
                                        if(!map.containsKey(dq.getDBType())) {
                                            map.put(dq.getDBType(), "");
                                            code="";
                                        }
                                        else {
                                            code = map.get(dq.getDBType());
                                            code = code+"\r\n union all \r\n";
                                        }
                                        code = code+ TransUtils.getQueryCode(dq);
                                        ;//"<include refid=\""+this.getEntityName().toLowerCase()+"_dq_"+dataQuery.getCodeName()+"_"+dq.getDBType().toLowerCase()+"\"/>";
                                        map.put(dq.getDBType(),"select t1.* from ("+code+") t1");
                                    });
                                }
                            } catch (Exception exception) {

                            }

                        });

                        for(Map.Entry<String, String> entry:map.entrySet())
                        {
                            if(dataSet.getMajorSortPSDEField()!=null)
                            {
                                IPSDEFDTColumn column = dataSet.getMajorSortPSDEField().getPSDEFDTColumn(entry.getKey().toLowerCase().replace("mysql5","mysql"),false);

                                orderBy=" order by ".concat(column==null?dataSet.getMajorSortPSDEField().getName():column.getColumnName());
                                if(!StringUtils.isEmpty(dataSet.getMajorSortDir()))
                                    orderBy=orderBy.concat(" ").concat(dataSet.getMajorSortDir());
                                if(dataSet.getMinorSortPSDEField()!=null)
                                {
                                    IPSDEFDTColumn subCol = dataSet.getMinorSortPSDEField().getPSDEFDTColumn(entry.getKey().toLowerCase().replace("mysql5","mysql"),false);

                                    orderBy=orderBy.concat(",").concat(subCol==null?dataSet.getMinorSortPSDEField().getName():subCol.getColumnName());
                                    if(!StringUtils.isEmpty(dataSet.getMinorSortDir()))
                                        orderBy=orderBy.concat(" ").concat(dataSet.getMinorSortDir());

                                }
                            }

                            String sqlFormat=select.concat(from).concat(where==null?"":where).concat(groupBy==null?"":groupBy).concat(orderBy==null?"":orderBy);
                            DataSetModel dqModel=new DataSetModel(this,dataSet);
                            dqModel.setDatasetId(this.getEntityName().toLowerCase()+"-ds-"+dataSet.getCodeName()+"-"+entry.getKey().toLowerCase().replace("mysql5","mysql"))
                                    .setDsType(entry.getKey().toLowerCase().replace("mysql5","mysql"))
                                    .setDatasetName(dataSet.getLogicName()).setCodeName(dataSet.getCodeName())
                                    .setDsCode(entry.getValue()).setDsModel(sqlFormat);
                            this.addQueries(dqModel);

                            dsModel.setOrderBy(orderBy).setDsModel(sqlFormat);
                        }



                    }
                } catch (Exception exception) {

                }



            });


        }

        for (String dsType : dsTypes) {
            POSchema poSchema = TransUtils.EntityModelModel2PO(this, dsType);
            if (poSchema != null) {
                this.addPOSchema(dsType, poSchema);
            }
        }



        if(this.getDataEntity().getAllPSDEActions()!=null)
        {
            this.getDataEntity().getAllPSDEActions().forEach(item->{
                String tag=item.getCodeName().toLowerCase();
                addAction(new ActionModel(this,item));
            });
        }

    }

}
