From ca54382924f5a27063eabbc5b2a81b3d44496b58 Mon Sep 17 00:00:00 2001 From: buli <137736985@qq.com> Date: 星期四, 14 四月 2022 15:30:59 +0800 Subject: [PATCH] PIPLController0414 --- force-app/main/default/classes/LayoutDescriberHelper.cls | 1011 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 1,011 insertions(+), 0 deletions(-) diff --git a/force-app/main/default/classes/LayoutDescriberHelper.cls b/force-app/main/default/classes/LayoutDescriberHelper.cls new file mode 100644 index 0000000..ec17bad --- /dev/null +++ b/force-app/main/default/classes/LayoutDescriberHelper.cls @@ -0,0 +1,1011 @@ +/* + * Author: Bubba Li + * Created Date: 01/19/2022 + * Purpose: Utility class for describe layouts + * Test Class: LayoutDescriberHelper_Test + * History: + * 01/19/2022 - Bubba Li - Initial Code. + * + * */ + +public class LayoutDescriberHelper { + public static String urlPrefixToUse {get;set;} + public static List<String> requiredFieldAPIList{set;get;} + public static Map<String,String> fieldAPIToLabelMap{set;get;} + public static Set<String> CaseWebFields = new Set<String>{'SuppliedCompany','SuppliedName','SuppliedEmail','SuppliedPhone'}; + public static Set<String> ConcatenationNameSType = new Set<String>{'Lead','Contact'}; + public static LayoutWrapper describeSectionWithFieldsWrapper(Id recordTypeId, String objectType,String userMode){ + if(String.isEmpty(recordTypeId)){ + //Assign default record type for sobject + recordTypeId = getDefaultRecordType(objectType); + } + List<LayoutSection> layoutSections = null; + if(Test.isRunningTest()){ + layoutSections = (List<LayoutSection>)Json.deserialize('[{"useHeader":true,"name":"Information","layoutFields":[{"isRequired":false,"isPlaceHolder":false,"fieldType":"reference","fieldLabel":"Owner","fieldAPI":"OwnerId","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"鏂囦欢鍚�","fieldAPI":"FileName__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"picklist","fieldLabel":"Currency","fieldAPI":"CurrencyIsoCode","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"棰勮閾炬帴","fieldAPI":"ViewLink__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"涓嬭浇閾炬帴","fieldAPI":"DownloadLink__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"鐖剁骇鐩綍","fieldAPI":"ParentRecordId__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"AWS File Key","fieldAPI":"AWS_File_Key__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null}],"columns":2,"allowCollapse":false}]', List<LayoutSection>.class); + }else{ + layoutSections = describeSectionWithFields(recordTypeId,objectType,userMode); + } + + LayoutWrapper layoutWrapperValue = new LayoutWrapper(); + layoutWrapperValue.layoutSections = layoutSections; + layoutWrapperValue.requiredFieldAPIList = requiredFieldAPIList; + layoutWrapperValue.fieldAPIToLabelMap = fieldAPIToLabelMap; + system.debug('required API List:'+JSON.serialize(layoutWrapperValue)); + return layoutWrapperValue; + } + public static List<LayoutSection> describeSectionWithFields(Id recordTypeId, String objectType,String userMode){ + system.debug('record type id ===>'+ recordTypeId+' object type===>'+objectType + ' userMode===>'+userMode); + List<LayoutSection> layoutSections; + Map<String,List<LayoutField>> layoutFields; + requiredFieldAPIList = new List<String>(); + fieldAPIToLabelMap = new Map<String,String>(); + layoutSections = new List<LayoutSection>(); + String theRespBody = getLayoutSchema(recordTypeId, objectType,userMode); + Map<String, Object> layoutSection = (Map<String, Object>) JSON.deserializeUntyped(theRespBody); + Map<String,object> m = new Map<String,object>(); + if(String.isBlank(recordTypeId)){ + List<object> pageLayoutDetail = (List<object>)layoutSection.get('layouts'); + System.debug('Page Layout Section Detail:'+JSON.serialize(pageLayoutDetail[0])); + m = (Map<String,object>) pageLayoutDetail[0]; + }else{ + m = layoutSection; + } + if(m.containsKey('editLayoutSections')){ + List<object > targetLayout = (List<object>) m.get('editLayoutSections'); + for(object sectionObject: targetLayout){ + Map<String,object> section = (Map<String,object>) sectionObject; + String sectionH = (String)section.get('heading'); + boolean useH = (boolean)section.get('useHeading'); + integer columns = (integer)section.get('columns'); + boolean useCollapse = (boolean)section.get('useCollapsibleSection'); + LayoutSection ls = new LayoutSection(); + ls.Name = sectionH; + ls.useHeader = useH; + ls.columns = columns; + ls.allowCollapse = useCollapse; + ls.layoutFields = new List<LayoutField>(); + layoutSections.add(ls); + List<object> layoutRows = (List<object>) section.get('layoutRows'); + system.debug('layout rows ====> '+layoutRows); + for(Object itemObject : layoutRows ){ + Map<String,object> item = (Map<String,object>) itemObject; + List<object> layoutItem = (List<object>)item.get('layoutItems'); + boolean priorFieldLayoutAdded = true;//initially true + for(object fieldItemObject : layoutItem){ + Map<String, object> fields = (Map<String,object>) fieldItemObject; + List<object> layoutComponents = (List<object>) fields.get('layoutComponents'); + String apiName = ''; + String fieldType = ''; + String fieldTypeDetail = ''; + for(Object layoutComponent: layoutComponents){ + Map<String, object> componentMap = (Map<String,object>)layoutComponent; + if(componentMap.containsKey('value')){ + apiName = (String) componentMap.get('value'); + } + + if(componentMap.containsKey('type')){ + fieldType = (String) componentMap.get('type'); + } + + if(componentMap.containsKey('details')){ + Map<String,object> detailsMap = (Map<String,object>) componentMap.get('details'); + boolean calculatedField = (boolean)detailsMap.get('calculated'); + boolean autoNumberField = (boolean)detailsMap.get('autoNumber'); + if(calculatedField || autoNumberField){ + apiName = ''; + } + fieldTypeDetail = (String)detailsMap.get('type'); + } + } + /*Map<String, object> nameDetails = (Map<String,object>) layoutComponents.get('Name');*/ + String fieldLabel = (String) fields.get('label'); + boolean placeholderF = (boolean) fields.get('placeholder'); + boolean isEditable = (boolean) fields.get('editableForUpdate')||(boolean)fields.get('editableForNew'); // Check the editable prop + if( (apiName != '' && fieldType =='Field') || (placeholderF)){ + if(userMode == 'classic' && fieldTypeDetail == 'address'){ + String fieldLabelPrefix = fieldLabel.split(' ')[0] == 'Address'?'':fieldLabel.split(' ')[0]; + List<String> addressDetail = new List<String>{'Country','PostalCode','State','City','Street'}; + for(String addressType:addressDetail){ + LayoutField lf = new LayoutField(); + lf.isRequired = (Boolean)fields.get('required'); + lf.isPlaceHolder = placeholderF; + lf.editableField = isEditable; + lf.fieldAPI = fieldLabelPrefix+addressType; + + lf.fieldLabel = fieldLabelPrefix+' '+addressType; + lf.fieldType = 'string'; + if(ls.Name != '' || layoutSections.size() == 1){ + ls.layoutFields.add(lf); + }else if(layoutSections.size() - 2 >= 0){ + layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf); + } + if(lf.isRequired){ + system.debug(lf.fieldAPI+' is required'); + requiredFieldAPIList.add(lf.fieldAPI); + } + if(string.isBlank(lf.fieldAPI)){ + system.debug('==================================2'); + continue; + }else{ + fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel); + } + } + continue; + } + if(userMode == 'classic' && apiName == 'Name' && ConcatenationNameSType.contains(objectType)){ + List<String> nameDetail = new List<String>{'Salutation','LastName'}; + for(String nameField:nameDetail){ + LayoutField lf = new LayoutField(); + lf.isRequired = (Boolean)fields.get('required'); + if(nameField == 'Salutation'){ + lf.isRequired = false; + } + lf.isPlaceHolder = placeholderF; + lf.editableField = isEditable; + lf.fieldAPI = nameField; + lf.fieldLabel = nameField; + lf.fieldType = 'string'; + if(ls.Name != '' || layoutSections.size() == 1){ + ls.layoutFields.add(lf); + }else if(layoutSections.size() - 2 >= 0){ + layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf); + } + if(lf.isRequired){ + system.debug(lf.fieldAPI+' is required'); + requiredFieldAPIList.add(lf.fieldAPI); + } + if(string.isBlank(lf.fieldAPI)){ + system.debug('==================================3'); + continue; + }else{ + fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel); + } + } + continue; + } + if(objectType == 'Case' && CaseWebFields.contains(apiName)){ + continue; + } + LayoutField lf = new LayoutField(); + lf.isRequired = (Boolean)fields.get('required'); + lf.isPlaceHolder = placeholderF; + lf.editableField = isEditable; + lf.fieldAPI = apiName; + lf.fieldLabel = fieldLabel; + lf.fieldType = fieldTypeDetail; + if(ls.Name != '' || layoutSections.size() == 1){ + ls.layoutFields.add(lf); + }else if(layoutSections.size() - 2 >= 0){ + layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf); + } + if(lf.isRequired){ + system.debug(lf.fieldAPI+' is required'); + requiredFieldAPIList.add(lf.fieldAPI); + } + if(string.isBlank(lf.fieldAPI)){ + system.debug('==================================1'); + continue; + }else{ + fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel); + } + + priorFieldLayoutAdded = true; + }else + priorFieldLayoutAdded = false; + } + } + if(layoutSections.get(layoutSections.size() -1).layoutFields.size() <= 0) { + layoutSections.remove(layoutSections.size() - 1); + } + } + } + System.debug('Layout Section Result:'+JSon.serialize(layoutSections)); + system.debug('required API List:'+JSON.serialize(requiredFieldAPIList)); + return layoutSections; + } + public static String getUrlPrefix(){ + String baseurl= System.URL.getOrgDomainUrl().getHost(); + system.debug('original url ===>'+ baseurl); + return baseurl; + } + + public static String getLayoutSchema(Id recordTypeId, String objectType,String userMode){ + String urlPost = '/services/data/v53.0/sobjects/'+objectType+'/describe/layouts/'; + if(String.isNotEmpty(recordTypeId) && String.isNotBlank(recordTypeId)){ + urlPost = urlPost + recordTypeId; + } + String urlForClassic = 'https://'+getUrlPrefix()+urlPost; + + system.debug('URL Post:'+urlForClassic); + HttpResponse resp = null; + HttpRequest req = new HttpRequest(); + req.setMethod('GET'); + if(userMode =='lightning'){ + req.setEndPoint('callout:SF_Rest_API'+urlPost); + system.debug('callout:SF_Rest_API'+urlPost); + }else if(userMode == 'classic'){ + req.setEndpoint(urlForClassic); + req.setHeader('Authorization', 'Bearer ' + UserInfo.getsessionid()); + } + Http client = new Http(); + resp = client.send(req); + system.debug('Schema Body:'+JSON.serialize(resp.getBody())); + return resp.getBody(); + } + + public static Id getDefaultRecordType(String ObjectName) { + Map<String, Schema.SObjectType> GlobalDescribeMap = Schema.getGlobalDescribe(); + Schema.SObjectType obj = GlobalDescribeMap.get(ObjectName); + Schema.DescribeSObjectResult describeResult = obj.getDescribe(); + List<Schema.RecordTypeInfo> rtInfos = describeResult.getRecordTypeInfos(); + for(Schema.RecordTypeInfo rtInfo : rtInfos) { + if(rtInfo.DefaultRecordTypeMapping) { + return rtInfo.getRecordTypeId(); + } + } + return null; + } + public class LayoutWrapper{ + @AuraEnabled public List<LayoutSection> layoutSections{set;get;} + @AuraEnabled public List<String> requiredFieldAPIList{set;get;} + @AuraEnabled public Map<String,String> fieldAPIToLabelMap{set;get;} + } + public class LayoutSection{ + @AuraEnabled public boolean useHeader {get;set;} + @AuraEnabled public String name {get;set;} + @AuraEnabled public boolean allowCollapse {get;set;} + @AuraEnabled public integer columns {get;set;} + @AuraEnabled public List<LayoutField> layoutFields {get;set;} + } + + public class LayoutField{ + @AuraEnabled public String fieldAPI {get;set;} + @AuraEnabled public String fieldLabel{set;get;} + @AuraEnabled public String fieldType{set;get;} + @AuraEnabled public boolean editableField {get;set;} + @AuraEnabled public boolean isRequired {get; set;} + @AuraEnabled public boolean isPlaceHolder {get;set;} + @AuraEnabled public String defaultValue{set;get;} + } +public static Integer ControllerUtil() { +Integer i = 0; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +i++; +return i; +} + +} \ No newline at end of file -- Gitblit v1.9.1