binxie
2023-06-26 410599fdf4f96d7f19b51bc28e544fa4e8780a1e
backup
6个文件已修改
3599 ■■■■■ 已修改文件
.sf/config.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LayoutDescriberHelper.cls 1335 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LayoutDescriberHelperTest.cls 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLeadController.cls 1699 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLeadControllerTest.cls 348 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manifest/package.xml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.sf/config.json
@@ -1,3 +1,3 @@
{
  "target-org": "OlympusStageEnv"
}
  "target-org": "OlympusDev"
}
force-app/main/default/classes/LayoutDescriberHelper.cls
@@ -3,1009 +3,362 @@
 * Created Date: 01/19/2022
 * Purpose: Utility class for describe layouts
 * Test Class: LayoutDescriberHelper_Test
 * History:
 * 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 String urlPrefixToUse { get; set; }
  public static List<String> requiredFieldAPIList { get; set; }
  public static Map<String, String> fieldAPIToLabelMap { get; set; }
  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);
    }
    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;
                    }
    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);
    System.debug('theRespBody = ' + theRespBody);
    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 = '';
                }
                if(layoutSections.get(layoutSections.size() -1).layoutFields.size() <= 0) {
                    layoutSections.remove(layoutSections.size() - 1);
                }
                fieldTypeDetail = (String) detailsMap.get('type');
              }
            }
        }
        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;
    }
            /*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;
    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();
    }
                  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);
              }
    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();
            }
              priorFieldLayoutAdded = true;
            } else
              priorFieldLayoutAdded = false;
          }
        }
        return null;
        if (
          layoutSections.get(layoutSections.size() - 1).layoutFields.size() <= 0
        ) {
          layoutSections.remove(layoutSections.size() - 1);
        }
      }
    }
    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;}
    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;
    }
    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;}
    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());
    }
    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;}
    Http client = new Http();
    System.debug('req = ' + req);
    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();
      }
    }
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;
    return null;
  }
  public class LayoutWrapper {
    @AuraEnabled
    public List<LayoutSection> layoutSections { get; set; }
    @AuraEnabled
    public List<String> requiredFieldAPIList { get; set; }
    @AuraEnabled
    public Map<String, String> fieldAPIToLabelMap { get; set; }
  }
  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 { get; set; }
    @AuraEnabled
    public String fieldType { get; set; }
    @AuraEnabled
    public boolean editableField { get; set; }
    @AuraEnabled
    public boolean isRequired { get; set; }
    @AuraEnabled
    public boolean isPlaceHolder { get; set; }
    @AuraEnabled
    public String defaultValue { get; set; }
  }
  public static Integer ControllerUtil() {
    Integer i = 0;
    return i;
  }
}
}
force-app/main/default/classes/LayoutDescriberHelperTest.cls
@@ -1,90 +1,128 @@
@isTest
private class LayoutDescriberHelperTest {
    static testMethod void testMethod1() {
        String userMode = 'classic';//classic  lightning
        String objectType = 'Contact';
        String recordTypeId = Schema.SObjectType.Contact.getRecordTypeInfosByDeveloperName().get('Doctor').getRecordTypeId();
  static testMethod void testMethod1() {
    String userMode = 'classic'; //classic  lightning
    String objectType = 'Contact';
    String recordTypeId = Schema.SObjectType.Contact.getRecordTypeInfosByDeveloperName()
      .get('Doctor')
      .getRecordTypeId();
    System.debug(
      'record type id ===>' +
        recordTypeId +
        ' object type===>' +
        objectType +
        ' userMode===>' +
        userMode
    );
    boolean useHeader = false;
    String baseurl = System.URL.getOrgDomainUrl().getHost();
    Map<String, object> detailsMap = new Map<String, object>();
    Map<String, object> detailsMap2 = new Map<String, object>();
    Map<String, object> detailsMap3 = new Map<String, object>();
    detailsMap.put('calculated', true);
    detailsMap.put('autoNumber', false);
    detailsMap.put('type', 'address');
    detailsMap2.put('calculated', false);
    detailsMap2.put('autoNumber', false);
    detailsMap2.put('type', 'repair');
    detailsMap3.put('calculated', false);
    detailsMap3.put('autoNumber', false);
    detailsMap3.put('type', 'repair');
    String fieldTypeDetail = (String) detailsMap.get('type');
        Map<String,object> detailsMap = new Map<String,object>();
        Map<String,object> detailsMap2 = new Map<String,object>();
        Map<String,object> detailsMap3 = new Map<String,object>();
        detailsMap.put('calculated',true);
        detailsMap.put('autoNumber',false);
        detailsMap.put('type','address');
        detailsMap2.put('calculated',false);
        detailsMap2.put('autoNumber',false);
        detailsMap2.put('type','repair');
        detailsMap3.put('calculated',false);
        detailsMap3.put('autoNumber',false);
        detailsMap3.put('type','repair');
    List<Map<String, object>> componentMapList = new List<Map<String, object>>();
    List<Map<String, object>> componentMapList2 = new List<Map<String, object>>();
    List<Map<String, object>> componentMapList3 = new List<Map<String, object>>();
    Map<String, object> componentMap = new Map<String, object>();
    Map<String, object> componentMap2 = new Map<String, object>();
    Map<String, object> componentMap3 = new Map<String, object>();
    componentMap.put('value', 'Name');
    componentMap.put('type', 'Field');
    componentMap.put('details', detailsMap);
    componentMapList.add(componentMap);
    componentMap2.put('value', 'Name');
    componentMap2.put('type', 'Field');
    componentMap2.put('details', detailsMap2);
    componentMapList2.add(componentMap2);
    componentMap3.put('value', 'LastName');
    componentMap3.put('type', 'Field');
    componentMap3.put('details', detailsMap3);
    componentMapList3.add(componentMap3);
    String apiName = (String) componentMap.get('value');
    String fieldType = (String) componentMap.get('type');
        List<Map<String, object>> componentMapList = new List<Map<String, object>>();
        List<Map<String, object>> componentMapList2 = new List<Map<String, object>>();
        List<Map<String, object>> componentMapList3 = new List<Map<String, object>>();
        Map<String, object> componentMap = new Map<String, object>();
        Map<String, object> componentMap2 = new Map<String, object>();
        Map<String, object> componentMap3 = new Map<String, object>();
        componentMap.put('value','Name');
        componentMap.put('type','Field');
        componentMap.put('details',detailsMap);
        componentMapList.add(componentMap);
        componentMap2.put('value','Name');
        componentMap2.put('type','Field');
        componentMap2.put('details',detailsMap2);
        componentMapList2.add(componentMap2);
        componentMap3.put('value','LastName');
        componentMap3.put('type','Field');
        componentMap3.put('details',detailsMap3);
        componentMapList3.add(componentMap3);
    List<Map<String, object>> layoutComponentsList = new List<Map<String, object>>();
    Map<String, object> layoutComponents = new Map<String, object>();
    layoutComponents.put('layoutComponents', componentMapList);
    layoutComponents.put('label', 'Address');
    layoutComponents.put('placeholder', true);
    layoutComponents.put('editableForNew', true);
    layoutComponents.put('editableForUpdate', true);
    layoutComponents.put('required', false);
    layoutComponentsList.add(layoutComponents);
    Map<String, object> layoutComponents2 = new Map<String, object>();
    layoutComponents2.put('layoutComponents', componentMapList2);
    layoutComponents2.put('label', 'Repair');
    layoutComponents2.put('placeholder', true);
    layoutComponents2.put('editableForNew', true);
    layoutComponents2.put('editableForUpdate', true);
    layoutComponents2.put('required', false);
    layoutComponentsList.add(layoutComponents2);
    Map<String, object> layoutComponents3 = new Map<String, object>();
    layoutComponents3.put('layoutComponents', componentMapList3);
    layoutComponents3.put('label', 'Repair');
    layoutComponents3.put('placeholder', true);
    layoutComponents3.put('editableForNew', true);
    layoutComponents3.put('editableForUpdate', true);
    layoutComponents3.put('required', false);
    layoutComponentsList.add(layoutComponents3);
        List<Map<String, object>> layoutComponentsList = new List<Map<String, object>>();
        Map<String, object> layoutComponents = new Map<String, object>();
        layoutComponents.put('layoutComponents',componentMapList);
        layoutComponents.put('label','Address');
        layoutComponents.put('placeholder',true);
        layoutComponents.put('editableForNew',true);
        layoutComponents.put('required',false);
        layoutComponentsList.add(layoutComponents);
        Map<String, object> layoutComponents2 = new Map<String, object>();
        layoutComponents2.put('layoutComponents',componentMapList2);
        layoutComponents2.put('label','Repair');
        layoutComponents2.put('placeholder',true);
        layoutComponents2.put('editableForNew',true);
        layoutComponents2.put('required',false);
        layoutComponentsList.add(layoutComponents2);
        Map<String, object> layoutComponents3 = new Map<String, object>();
        layoutComponents3.put('layoutComponents',componentMapList3);
        layoutComponents3.put('label','Repair');
        layoutComponents3.put('placeholder',true);
        layoutComponents3.put('editableForNew',true);
        layoutComponents3.put('required',false);
        layoutComponentsList.add(layoutComponents3);
    boolean placeholderF = (boolean) layoutComponents.get('placeholder');
    boolean isEditable =
      (boolean) layoutComponents.get('editableForUpdate') ||
      (boolean) layoutComponents.get('editableForNew');
    System.debug('isEditable ===>' + isEditable);
    List<Map<String, object>> itemList = new List<Map<String, object>>();
    Map<String, object> item = new Map<String, object>();
    item.put('layoutItems', layoutComponentsList);
    itemList.add(item);
    useHeader = true;
    List<Map<String, object>> sectionList = new List<Map<String, object>>();
    Map<String, object> section = new Map<String, object>();
    section.put('heading', '');
    section.put('useHeading', useHeader);
    section.put('columns', 1);
    section.put('useCollapsibleSection', true);
    section.put('layoutRows', itemList);
    sectionList.add(section);
        List<Map<String,object>> itemList = new List<Map<String,object>>();
        Map<String,object> item = new Map<String,object>();
        item.put('layoutItems',layoutComponentsList);
        itemList.add(item);
        List<Map<String,object>> sectionList = new List<Map<String,object>>();
        Map<String,object> section = new Map<String,object>();
        section.put('heading','');
        section.put('useHeading',true);
        section.put('columns',1);
        section.put('useCollapsibleSection',true);
        section.put('layoutRows',itemList);
        sectionList.add(section);
        Map<String, Object> layoutSection = new Map<String,Object>();
        layoutSection.put('layouts','123');
        layoutSection.put('editLayoutSections',sectionList);
        String layoutSectionJson = JSON.serialize(layoutSection);
        LayoutDescriberHelper.ControllerUtil();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(layoutSectionJson,'OK','200'));
        Test.startTest();
        LayoutDescriberHelper.describeSectionWithFieldsWrapper(recordTypeId,objectType,userMode);
        LayoutDescriberHelper.describeSectionWithFieldsWrapper(null,objectType,userMode);
        Test.stopTest();
    }
}
    Map<String, Object> layoutSection = new Map<String, Object>();
    layoutSection.put('layouts', '123');
    layoutSection.put('editLayoutSections', sectionList);
    String layoutSectionJson = JSON.serialize(layoutSection);
    LayoutDescriberHelper.ControllerUtil();
    Test.setMock(
      HttpCalloutMock.class,
      new TestDataUtility.BaseHttpMock(layoutSectionJson, 'OK', '200')
    );
    Test.startTest();
    LayoutDescriberHelper.describeSectionWithFieldsWrapper(
      recordTypeId,
      objectType,
      userMode
    );
    LayoutDescriberHelper.describeSectionWithFieldsWrapper(
      null,
      objectType,
      userMode
    );
    LayoutDescriberHelper.describeSectionWithFields(
      recordTypeId,
      objectType,
      userMode
    );
    LayoutDescriberHelper.getLayoutSchema(recordTypeId, objectType, userMode);
    LayoutDescriberHelper.getUrlPrefix();
    Test.stopTest();
  }
}
force-app/main/default/classes/NewAndEditLeadController.cls
@@ -3,1162 +3,575 @@
 * Created Date: 01/19/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditLeadController
 * History:
 * History:
 *      01/19/2022 - Bubba Li - Initial Code.
 *
 *
 * */
global without sharing class NewAndEditLeadController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public static String sobjectTypeValue = 'Lead';
    public Boolean isNewMode{set;get;}
    public Boolean isCloneMode{protected set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    public String AWSDataIdInquiryForm{set;get;}
    public String contactId{set;get;}//For Lookup field
    public List<String> encryptedAPIList{set;get;}
    public String staticResource {get; set;}
    public String staticResourceContact {get; set;}
    public String staticResourceInquiryForm{get; set;}
    public String requiredFieldAPIListStr {get; set;}
    public String fieldAPIToLabelMapStr {get; set;}
    public String Input_Required_Field_Msg{set;get;}
    public String PIPL_Name_Label{set;get;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String sobjectPrefix{set;get;}
    public String sobjecttypeForFrontEnd{set;get;}
    public String contactsInfo {set;get;}//key sfid;value awsid
    public Inquiry_form__c ifc{get; private set;}
    public String contactDataId{get; set;}
    public String layoutSectionsStr {get; set;}
    public String isDecryptContact {get; set;}
    public final string ApiPrefix{get;private set;} //Add By Li Jun 20220403
    public Map<string,string> AWSToSobjectEncryptedMap{get;private set;}
    public string AWSToSobjectEncryptedMapJson{get{return JSON.serialize(AWSToSobjectEncryptedMap);}}
    public String LeadCreatedDate { get; set; } // XLIU-CFE8M7 20220624 ssm
    public String VLookUpFieldsJson{get;private set;}
  public List<LayoutDescriberHelper.LayoutSection> layoutSections { get; set; }
  public String awsToken { get; set; }
  public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
  public static String sobjectTypeValue = 'Lead';
  public Boolean isNewMode { get; set; }
  public Boolean isCloneMode { get; protected set; }
  public String rtTypeId { get; set; }
  public String AWSDataId { get; set; }
  public String AWSDataIdInquiryForm { get; set; }
  public String contactId { get; set; } //For Lookup field
  public List<String> encryptedAPIList { get; set; }
  public String staticResource { get; set; }
  public String staticResourceContact { get; set; }
  public String staticResourceInquiryForm { get; set; }
  public String requiredFieldAPIListStr { get; set; }
  public String fieldAPIToLabelMapStr { get; set; }
  public String Input_Required_Field_Msg { get; set; }
  public String PIPL_Name_Label { get; set; }
  public String PIPL_Input_Account_Error_Msg { get; set; }
  public String sobjectPrefix { get; set; }
  public String sobjecttypeForFrontEnd { get; set; }
  public String contactsInfo { get; set; } //key sfid;value awsid
  public Inquiry_form__c ifc { get; private set; }
  public String contactDataId { get; set; }
  public String layoutSectionsStr { get; set; }
  public String isDecryptContact { get; set; }
  public final string ApiPrefix { get; private set; } //Add By Li Jun 20220403
  public Map<string, string> AWSToSobjectEncryptedMap { get; private set; }
  public string AWSToSobjectEncryptedMapJson {
    get {
      return JSON.serialize(AWSToSobjectEncryptedMap);
    }
  }
  public String LeadCreatedDate { get; set; } // XLIU-CFE8M7 20220624 ssm
  public String VLookUpFieldsJson { get; private set; }
  //zhj MEBG新方案改造 2022-11-29 start
  public String staticResourceV2 { get; set; }
  //zhj MEBG新方案改造 2022-11-29 end
  public NewAndEditLeadController(ApexPages.StandardController controller) {
    ApiPrefix = 'PIBackApi';
    isDecryptContact = '0';
    isNewMode = true;
    isCloneMode = false;
    Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
    PIPL_Name_Label = Label.PIPL_Name_Label;
    PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
    sobjecttypeForFrontEnd = sobjectTypeValue;
    Map<string, string> mso = ApexPages.currentPage().getParameters();
    if (mso != null && mso.containsKey('newclone')) {
      isCloneMode = true;
    }
    //获取所有字段
    List<String> fieldList = new List<String>(
      Schema.getGlobalDescribe()
        .get('Lead')
        .getDescribe()
        .fields.getMap()
        .keyset()
    );
    // Add fields to controller. This is to avoid the SOQL error in visualforce page
    if (!Test.isRunningTest()) {
      controller.addFields(fieldList);
    }
    SObject obj = controller.getRecord();
    // XLIU-CFE8M7 20220624 ssm
    this.LeadCreatedDate = obj.get('CreatedDate') != null
      ? Date.newInstance(
            ((Datetime) obj.get('CreatedDate')).year(),
            ((Datetime) obj.get('CreatedDate')).month(),
            ((Datetime) obj.get('CreatedDate')).day()
          )
          .format()
      : Date.today().format();
    // this.LeadCreatedDate = Date.today().format();
    if (
      ApexPages.currentPage().getParameters().get('CF00N1000000962np_lkid') !=
      null
    ) {
      System.debug('CF00N1000000962np_lkid');
      //产品咨询单过来的
      String InquiryFormId = ApexPages.currentPage()
        .getParameters()
        .get('CF00N1000000962np_lkid');
      ifc = [
        SELECT
          Id,
          AWS_Data_Id__c,
          Contact_Name__c,
          Contact_Id__c,
          Hospital_Name__c,
          Hospital_ID__c,
          Department_Class__c,
          Department_ID__c,
          Opp_Name_Search__c,
          Opp_Name_Search_ID__c,
          Campaign__c,
          Campaign_ID__c,
          Name,
          Cancel_Reason__c,
          Phone__c,
          Email__c,
          Last_Name__c,
          LeadSource__c,
          Opportunity_Division__c,
          Request1__c,
          Urgent__c,
          Inquiry_Num__c,
          Product_Owner__c
        FROM Inquiry_form__c
        WHERE id = :InquiryFormId
      ];
      System.debug('ifc = ' + ifc);
      if (ifc.Contact_Id__c != null && ifc.Contact_Id__c != '') {
        Contact c = [
          SELECT AWS_Data_Id__c
          FROM Contact
          WHERE id = :ifc.Contact_Id__c
        ];
        contactDataId = c.AWS_Data_Id__c;
      }
      AWSDataIdInquiryForm = ifc.AWS_Data_Id__c;
      System.debug('ifc = ' + ifc);
      rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
      obj.put('OwnerId', UserInfo.getUserId());
      obj.put('Inquiry_Num__c', ifc.Inquiry_Num__c); // 20220413 SWAG-CBUB2W you
      obj.put('owner_not_automatically_update__c', ifc.Product_Owner__c);
      controller.getRecord().put('LeadSource', ifc.LeadSource__c);
      // controller.getRecord().put('Lead_Inquiry_form__c', ifc.Id);
    } else if (obj.Id != null) {
      //更新
      isNewMode = false;
      Lead leadData = [
        SELECT
          Id,
          RecordTypeId,
          AWS_Data_Id__c,
          Contact_Name__r.Id,
          Contact_Name__r.AWS_Data_Id__c
        FROM Lead
        WHERE id = :obj.Id
      ];
      rtTypeId = leadData.RecordTypeId;
      AWSDataId = leadData.AWS_Data_Id__c;
      Map<String, String> sfIdToAWSIdMap = new Map<String, String>();
      if (leadData.Contact_Name__r.Id != null) {
        sfIdToAWSIdMap.put(
          String.valueof(leadData.Contact_Name__r.Id).subString(0, 15),
          leadData.Contact_Name__r.AWS_Data_Id__c
        );
      }
      contactsInfo = JSON.serialize(sfIdToAWSIdMap);
    } else {
      //看链接中有无带过来的参数(客户人员)
      // Map<string,string> mso = ApexPages.currentPage().getParameters();
      for (String key : mso.keySet()) {
        System.debug('key=' + key + ',value=' + mso.get(key));
      }
      //联系人
      if (mso.containsKey('CF00N10000006ps6f_lkid')) {
        isDecryptContact = '1';
        String contactId = mso.get('CF00N10000006ps6f_lkid');
        //查询AWS_Data_Id__c
        List<Contact> contactList = new List<Contact>(
          [SELECT AWS_Data_Id__c FROM Contact WHERE id = :contactId]
        );
        Contact c = new Contact();
        if (contactList != null && contactList.size() > 0) {
          c = contactList[0];
        }
        if (c != null && c.AWS_Data_Id__c != '') {
          contactDataId = c.AWS_Data_Id__c;
        }
        //查询战略科室分类
        List<Contact> cs = [
          SELECT Account.Department_Class__c
          FROM Contact
          WHERE id = :contactId
        ];
        if (cs.size() > 0) {
          controller.getRecord()
            .put('Department_Class__c', cs[0].Account.Department_Class__c);
        }
        controller.getRecord()
          .put('Contact_Name__c', mso.get('CF00N10000006ps6f_lkid'));
      }
      //医院名
      if (mso.containsKey('CF00N10000002CvC5_lkid')) {
        controller.getRecord()
          .put('Hospital_Name__c', mso.get('CF00N10000002CvC5_lkid'));
        //通过医院id查询战略科室分类
        String hospitalId = mso.get('CF00N10000002CvC5_lkid');
        List<Account> hospitalAccount = [
          SELECT Department_Class__c
          FROM Account
          WHERE Id = :hospitalId
        ];
        if (hospitalAccount.size() > 0) {
          List<Account> departmentAccount = [
            SELECT Id
            FROM Account
            WHERE Id = :hospitalAccount[0].Department_Class__c
          ];
          if (departmentAccount.size() > 0) {
            System.debug('Department_Class__c = ' + departmentAccount[0].Id);
            controller.getRecord()
              .put('Department_Class__c', departmentAccount[0].Id);
          }
        }
      }
      //公司(科室)
      if (mso.containsKey('CF00N10000002CvC5')) {
        controller.getRecord().put('Company', mso.get('CF00N10000002CvC5'));
      }
      //战略科室CF00N10000006qNtt_lkid
      // if(mso.containsKey('CF00N10000006qNtt_lkid ')){
      //     controller.getRecord().put('Department_Class__c',mso.get('CF00N10000006qNtt_lkid '));
      // }
      // 2022-04-13 来源 jz start 0414 lt
      if (mso.containsKey('LeadSource')) {
        controller.getRecord().put('LeadSource', mso.get('LeadSource'));
      }
      if (mso.containsKey(System.Label.Opportunity_stage)) {
        controller.getRecord()
          .put('Opportunity_stage__c', mso.get(System.Label.Opportunity_stage));
      }
      //20220505 lt 注释掉
      // if (mso.containsKey('00N10000006qOF0')) {
      //     controller.getRecord().put('Close_Forecasted_Date__c', Date.parse(mso.get('00N10000006qOF0')));
      // }
      if (mso.containsKey(System.Label.Opp_Name)) {
        controller.getRecord()
          .put('Opp_Name__c', mso.get(System.Label.Opp_Name));
      }
      // if (mso.containsKey('00N100000048UBf')) {
      //     controller.getRecord().put('Contact__c', mso.get('00N100000048UBf'));
      // }
      if (mso.containsKey(System.Label.Purchase_Reason)) {
        controller.getRecord()
          .put('Purchase_Reason__c', mso.get(System.Label.Purchase_Reason));
      }
      if (mso.containsKey(System.Label.Fund_Basis)) {
        controller.getRecord()
          .put('Fund_Basis__c', mso.get(System.Label.Fund_Basis));
      }
      if (mso.containsKey(System.Label.Purchase_Type)) {
        controller.getRecord()
          .put('Purchase_Type__c', mso.get(System.Label.Purchase_Type));
      }
      //20220427
      if (mso.containsKey(System.Label.Tender_information)) {
        //招标项目Id
        controller.getRecord()
          .put(
            'Tender_information__c',
            mso.get(System.Label.Tender_information)
          );
      }
      if (mso.containsKey(System.Label.Agency_Opportunity)) {
        //经销商询价Id
        controller.getRecord()
          .put(
            'Agency_Opportunity__c',
            mso.get(System.Label.Agency_Opportunity)
          );
      }
      if (mso.containsKey(System.Label.Sales_Method)) {
        //经销商询价--招标方式
        controller.getRecord()
          .put('Sales_Method__c', mso.get(System.Label.Sales_Method));
      }
      if (mso.containsKey(System.Label.Request)) {
        controller.getRecord().put('Request__c', mso.get(System.Label.Request));
      }
      if (mso.containsKey(System.Label.Request_Detail)) {
        controller.getRecord()
          .put('Request_Detail__c', mso.get(System.Label.Request_Detail));
      }
      // 2022-04-13 来源 jz end 0414 lt
      rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
      // 20220420 lt OBSAP start
      if (String.isBlank(rtTypeId) && mso.containsKey('RecordTypeId')) {
        rtTypeId = mso.get('RecordTypeId');
      }
      // 20220420 lt OBSAP end
      obj.put('OwnerId', UserInfo.getUserId());
    }
    system.debug('RecordTypeId:' + rtTypeId);
    LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(
      rtTypeId,
      'Lead',
      'classic'
    );
    layoutSections = LayoutWrapperValue.layoutSections;
    List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
    Map<String, String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
    requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
    fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
    PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo(
      'Lead'
    );
    staticResource = JSON.serialize(piIntegration);
    staticResourceContact = JSON.serialize(
      PIHelper.getPIIntegrationInfo('Contact')
    );
    staticResourceInquiryForm = JSON.serialize(
      PIHelper.getPIIntegrationInfo('Inquiry_form__c')
    );
    //zhj MEBG新方案改造 2022-11-29 start
    public String staticResourceV2 {get; set;}
    staticResourceV2 = JSON.serialize(PIHelper.getPIIntegrationInfo('LeadV2'));
    //zhj MEBG新方案改造 2022-11-29 end
    encryptedAPIList = piIntegration.PIFields;
    sobjectPrefix = piIntegration.sobjectPrefix;
    layoutSectionsStr = JSON.serialize(layoutSections);
    AWSToSobjectEncryptedMap = new Map<String, String>();
    for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
      AWSToSobjectEncryptedMap.put(
        PIDetail.AWS_Field_API__c,
        PIDetail.SF_Field_API_Name__c
      );
    }
    //获取lookup字段
    List<String> VLookUpFields = new List<String>();
    for (LayoutDescriberHelper.LayoutSection ls : layoutSections) {
      for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
        if (lf.fieldAPI != '' && lf.fieldType == 'reference') {
          VLookUpFields.add(lf.fieldAPI);
        }
      }
    }
    VLookUpFieldsJson = Json.serialize(VLookUpFields);
  }
    public NewAndEditLeadController(ApexPages.StandardController controller) {
        ApiPrefix = 'PIBackApi';
        isDecryptContact = '0';
        isNewMode = true;
        isCloneMode = false;
        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
        PIPL_Name_Label = Label.PIPL_Name_Label;
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        sobjecttypeForFrontEnd = sobjectTypeValue;
        Map<string,string> mso = ApexPages.currentPage().getParameters();
        if(mso != null && mso.containsKey('newclone')){
            isCloneMode = true;
        }
        //获取所有字段
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Lead').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        if (!Test.isRunningTest()) {
            controller.addFields(fieldList);
        }
        SObject obj = controller.getRecord();
  global class Response {
    public String recordId { get; set; }
    public String message { get; set; }
    public String status { get; set; }
  }
        // XLIU-CFE8M7 20220624 ssm
        this.LeadCreatedDate = obj.get('CreatedDate') != null ? Date.newInstance(((Datetime)obj.get('CreatedDate')).year(), ((Datetime)obj.get('CreatedDate')).month(), ((Datetime)obj.get('CreatedDate')).day()).format() : Date.today().format();
        // this.LeadCreatedDate = Date.today().format();
        if(ApexPages.currentPage().getParameters().get('CF00N1000000962np_lkid') != null){
            System.debug('CF00N1000000962np_lkid');
            //产品咨询单过来的
            String InquiryFormId = ApexPages.currentPage().getParameters().get('CF00N1000000962np_lkid');
            ifc = [select Id,AWS_Data_Id__c,Contact_Name__c,Contact_Id__c,Hospital_Name__c,Hospital_ID__c,Department_Class__c,
            Department_ID__c,Opp_Name_Search__c,Opp_Name_Search_ID__c,Campaign__c,
            Campaign_ID__c,Name,Cancel_Reason__c,Phone__c,Email__c,Last_Name__c,LeadSource__c,Opportunity_Division__c,Request1__c,
            Urgent__c,Inquiry_Num__c,Product_Owner__c from Inquiry_form__c where id = :InquiryFormId];
            System.debug('ifc = ' + ifc);
            if(ifc.Contact_Id__c !=null && ifc.Contact_Id__c != ''){
                Contact c = [select AWS_Data_Id__c from Contact where id = :ifc.Contact_Id__c];
                contactDataId = c.AWS_Data_Id__c;
            }
            AWSDataIdInquiryForm = ifc.AWS_Data_Id__c;
            System.debug('ifc = ' + ifc);
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            obj.put('OwnerId',UserInfo.getUserId());
            obj.put('Inquiry_Num__c',ifc.Inquiry_Num__c);// 20220413 SWAG-CBUB2W you
            obj.put('owner_not_automatically_update__c',ifc.Product_Owner__c);
            controller.getRecord().put('LeadSource', ifc.LeadSource__c);
            // controller.getRecord().put('Lead_Inquiry_form__c', ifc.Id);
        }else if(obj.Id != null){
            //更新
            isNewMode = false;
            Lead leadData = [select Id,RecordTypeId,AWS_Data_Id__c,Contact_Name__r.Id,Contact_Name__r.AWS_Data_Id__c from Lead where id =: obj.Id];
            rtTypeId = leadData.RecordTypeId;
            AWSDataId = leadData.AWS_Data_Id__c;
            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
            if(leadData.Contact_Name__r.Id != null){
                sfIdToAWSIdMap.put(String.valueof(leadData.Contact_Name__r.Id).subString(0,15),leadData.Contact_Name__r.AWS_Data_Id__c);
            }
            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
        }else{
            //看链接中有无带过来的参数(客户人员)
            // Map<string,string> mso = ApexPages.currentPage().getParameters();
            for(String key : mso.keySet()){
                System.debug('key=' + key + ',value=' + mso.get(key));
            }
            //联系人
            if(mso.containsKey('CF00N10000006ps6f_lkid')){
                isDecryptContact = '1';
                String contactId = mso.get('CF00N10000006ps6f_lkid');
                //查询AWS_Data_Id__c
                List<Contact> contactList = new List<Contact>([select AWS_Data_Id__c from Contact where id=:contactId]);
                Contact c = new Contact();
                if(contactList!=null&&contactList.size()>0){
                    c = contactList[0];
                }
                if (c != null&&c.AWS_Data_Id__c!='') {
                    contactDataId = c.AWS_Data_Id__c;
                }
                //查询战略科室分类
                List<Contact> cs = [select Account.Department_Class__c from Contact where id=:contactId];
                if(cs.size()>0){
                    controller.getRecord().put('Department_Class__c',cs[0].Account.Department_Class__c);
                }
                controller.getRecord().put('Contact_Name__c',mso.get('CF00N10000006ps6f_lkid'));
            }
            //医院名
            if(mso.containsKey('CF00N10000002CvC5_lkid')){
                controller.getRecord().put('Hospital_Name__c',mso.get('CF00N10000002CvC5_lkid'));
                //通过医院id查询战略科室分类
                String hospitalId = mso.get('CF00N10000002CvC5_lkid');
                List<Account> hospitalAccount = [select Department_Class__c from Account where Id=:hospitalId];
                if(hospitalAccount.size()>0){
                    List<Account> departmentAccount = [select Id from Account where Id=:hospitalAccount[0].Department_Class__c];
                    if (departmentAccount.size()>0) {
                        System.debug('Department_Class__c = ' + departmentAccount[0].Id);
                        controller.getRecord().put('Department_Class__c',departmentAccount[0].Id);
                    }
                }
            }
            //公司(科室)
            if(mso.containsKey('CF00N10000002CvC5')){
                controller.getRecord().put('Company',mso.get('CF00N10000002CvC5'));
            }
            //战略科室CF00N10000006qNtt_lkid
            // if(mso.containsKey('CF00N10000006qNtt_lkid ')){
            //     controller.getRecord().put('Department_Class__c',mso.get('CF00N10000006qNtt_lkid '));
            // }
            // 2022-04-13 来源 jz start 0414 lt
            if (mso.containsKey('LeadSource')) {
                controller.getRecord().put('LeadSource', mso.get('LeadSource'));
            }
            if (mso.containsKey(System.Label.Opportunity_stage)) {
                controller.getRecord().put('Opportunity_stage__c', mso.get(System.Label.Opportunity_stage));
            }
            //20220505 lt 注释掉
            // if (mso.containsKey('00N10000006qOF0')) {
            //     controller.getRecord().put('Close_Forecasted_Date__c', Date.parse(mso.get('00N10000006qOF0')));
            // }
            if (mso.containsKey(System.Label.Opp_Name)) {
                controller.getRecord().put('Opp_Name__c', mso.get(System.Label.Opp_Name));
            }
            // if (mso.containsKey('00N100000048UBf')) {
            //     controller.getRecord().put('Contact__c', mso.get('00N100000048UBf'));
            // }
            if (mso.containsKey(System.Label.Purchase_Reason)) {
                controller.getRecord().put('Purchase_Reason__c', mso.get(System.Label.Purchase_Reason));
            }
            if (mso.containsKey(System.Label.Fund_Basis)) {
                controller.getRecord().put('Fund_Basis__c', mso.get(System.Label.Fund_Basis));
            }
            if (mso.containsKey(System.Label.Purchase_Type)) {
                controller.getRecord().put('Purchase_Type__c', mso.get(System.Label.Purchase_Type));
            }
            //20220427
            if (mso.containsKey(System.Label.Tender_information)) { //招标项目Id
                controller.getRecord().put('Tender_information__c', mso.get(System.Label.Tender_information));
            }
            if (mso.containsKey(System.Label.Agency_Opportunity)) { //经销商询价Id
                controller.getRecord().put('Agency_Opportunity__c', mso.get(System.Label.Agency_Opportunity));
            }
            if (mso.containsKey(System.Label.Sales_Method)) { //经销商询价--招标方式
                controller.getRecord().put('Sales_Method__c', mso.get(System.Label.Sales_Method));
            }
            if (mso.containsKey(System.Label.Request)) {
                controller.getRecord().put('Request__c', mso.get(System.Label.Request));
            }
            if (mso.containsKey(System.Label.Request_Detail)) {
                controller.getRecord().put('Request_Detail__c', mso.get(System.Label.Request_Detail));
            }
            // 2022-04-13 来源 jz end 0414 lt
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            // 20220420 lt OBSAP start
            if (String.isBlank(rtTypeId) && mso.containsKey('RecordTypeId')) {
                rtTypeId = mso.get('RecordTypeId');
            }
            // 20220420 lt OBSAP end
            obj.put('OwnerId',UserInfo.getUserId());
  @RemoteAction
  global static Response saveLead(
    String leadJson,
    String transId,
    Boolean isNew
  ) {
    System.debug('Lead Info:' + JSON.serialize(leadJson));
    //1. Prepare the payload for  Lead
    Schema.SObjectType leadSchema = schemaMap.get(sobjectTypeValue);
    Map<String, Schema.SObjectField> fieldAPIToTypeMap = leadSchema.getDescribe()
      .fields.getMap();
    Map<String, Object> fieldValueMap = (Map<String, Object>) JSON.deserializeUntyped(
      leadJson
    );
    Lead leadInfo = new Lead();
    String status = 'success';
    Response resp = new Response();
    Savepoint sp = Database.setSavepoint();
    Boolean isClone = false;
    String rid = '';
    String awsDataId = '';
    try {
      //自定义格式转换
      for (String fieldAPI : fieldValueMap.keySet()) {
        system.debug('field API=' + fieldAPI);
        if (!fieldAPIToTypeMap.containskey(fieldAPI)) {
          continue;
        }
        system.debug('RecordTypeId:'+rtTypeId);
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Lead','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Lead');
        staticResource = JSON.serialize(piIntegration);
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        staticResourceInquiryForm = JSON.serialize(PIHelper.getPIIntegrationInfo('Inquiry_form__c'));
        //zhj MEBG新方案改造 2022-11-29 start
        staticResourceV2 = JSON.serialize(PIHelper.getPIIntegrationInfo('LeadV2'));
        //zhj MEBG新方案改造 2022-11-29 end
        encryptedAPIList = piIntegration.PIFields;
        sobjectPrefix = piIntegration.sobjectPrefix;
        layoutSectionsStr = JSON.serialize(layoutSections);
        AWSToSobjectEncryptedMap = new Map<String,String>();
        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
            AWSToSobjectEncryptedMap.put(PIDetail.AWS_Field_API__c, PIDetail.SF_Field_API_Name__c);
        Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI)
          .getDescribe()
          .getType();
        String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
        system.debug(
          'Field Type:' + fielddataType + ' field Value=' + fieldValue
        );
        if (String.valueOf(fielddataType) == 'DATE') {
          leadInfo.put(
            fieldAPI,
            (String.isBlank(fieldValue) || String.isEmpty(fieldValue))
              ? null
              : Date.valueOf(fieldValue.replace('/', '-'))
          );
        } else if (String.valueOf(fielddataType) == 'DATETIME') {
          if (String.isNotBlank(fieldValue) && fieldValue.contains('T')) {
            fieldValue = fieldValue.replace('T', ' ');
            leadInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
          } else {
            leadInfo.put(fieldAPI, null);
          }
        } else if (
          String.valueof(fielddataType) == 'CURRENCY' ||
          String.valueof(fielddataType) == 'PERCENT' ||
          String.valueOf(fielddataType) == 'Number' ||
          String.valueOf(fielddataType) == 'DOUBLE'
        ) {
          leadInfo.put(
            fieldAPI,
            (String.isBlank(fieldValue) || String.isEmpty(fieldValue))
              ? null
              : Decimal.valueOf(fieldValue.replace(',', ''))
          );
        } else if (String.valueof(fielddataType) == 'BOOLEAN') {
          leadInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
        } else {
          leadInfo.put(fieldAPI, fieldValue);
        }
        //获取lookup字段
        List<String> VLookUpFields = new List<String>();
        for (LayoutDescriberHelper.LayoutSection ls : layoutSections) {
            for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
                if (lf.fieldAPI != '' && lf.fieldType == 'reference') {
                    VLookUpFields.add(lf.fieldAPI);
                }
            }
      }
      //2. Save Record Process
      System.debug('abcde');
      awsDataId = (String) leadInfo.get('AWS_Data_Id__c');
      System.debug('awsDataId = ' + awsDataId);
      Lead[] leads = [SELECT id FROM Lead WHERE AWS_Data_Id__c = :awsDataId];
      if (!isNew) {
        isClone = leads.size() == 0;
      }
      System.debug('isClone---------' + isClone);
      //2022-6-10 yjk SWAG-CEY8GZ start
      if (leadInfo.Hospital_Name__c != null) {
        Account acc = [
          SELECT id, Hospital__c
          FROM Account
          WHERE id = :leadInfo.Hospital_Name__c
        ];
        leadInfo.hospital__c = acc.Hospital__c;
      }
      //2022-6-10 yjk SWAG-CEY8GZ end
      if (isNew || isClone) {
        System.debug('leadInfozhj = ' + leadInfo);
        if (!Test.isRunningTest()) {
          insert leadInfo;
        }
        VLookUpFieldsJson = Json.serialize(VLookUpFields);
      } else {
        System.debug('into update');
        // String awsDataId = (String)leadInfo.get('AWS_Data_Id__c');
        // System.debug('awsDataId = ' + awsDataId);
        // Lead[] leads = [select id from Lead where AWS_Data_Id__c =:awsDataId];
        System.debug('leads[0].id = ' + leads[0].id);
        leadInfo.put('Id', leads[0].id); //For testing;
        if (!Test.isRunningTest()) {
          update leadInfo;
        }
      }
      rid = leadInfo.Id;
      PIHelper.saveTransLog(
        sobjectTypeValue,
        (String) leadInfo.get('AWS_Data_Id__c'),
        rid,
        transId,
        leadJson,
        status,
        ''
      );
      resp.recordId = leadInfo.Id;
      resp.message = '';
      resp.status = status;
      System.debug('resp from sfdx back-end' + resp);
      return resp;
    } catch (DmlException e) {
      Integer index = 0;
      System.debug(e.getNumDml());
      System.debug(e.getDmlFields(index));
      System.debug(e.getDmlId(index));
      System.debug(e.getDmlIndex(index));
      System.debug(e.getDmlMessage(index));
      System.debug(e.getDmlStatusCode(index));
      System.debug(e.getDmlType(index));
      system.debug(e.getMessage());
      system.debug(e.getStackTraceString());
      System.debug('into catch' + e.getMessage());
      Database.rollback(sp);
      resp.status = 'Exception';
      resp.message = '保存失败,原因:' + e.getDmlMessage(index);
      PIHelper.saveTransLog(
        sobjectTypeValue,
        (String) leadInfo.get('AWS_Data_Id__c'),
        rid,
        transId,
        leadJson,
        status,
        e.getMessage() + e.getStackTraceString()
      );
      return resp;
    } catch (Exception e) {
      System.debug('into catch' + e.getMessage());
      Database.rollback(sp);
      status = 'fail';
      PIHelper.saveTransLog(
        sobjectTypeValue,
        (String) leadInfo.get('AWS_Data_Id__c'),
        rid,
        transId,
        leadJson,
        status,
        e.getMessage()
      );
      resp.message = e.getMessage();
      resp.status = status;
      return resp;
    }
  }
  @RemoteAction
  global static String queryAccount(String accountTypes, String accountId) {
    System.debug('accountType=' + accountTypes);
    System.debug('accountId=' + accountId);
    List<Object> types = (List<Object>) JSON.deserializeUntyped(accountTypes);
    System.debug('types=' + types);
    String soql = 'select Id,Name,';
    for (Object t : types) {
      soql += (String) t + ',';
    }
    soql = soql.substring(0, soql.length() - 1);
    soql += ' from Account where id=\'' + accountId + '\'';
    System.debug('soql=' + soql);
    Sobject account = new Account();
    if (!Test.isRunningTest()) {
      account = Database.query(soql);
    } else {
      account.put('Id', '000000000000000');
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    Map<String, Map<String, String>> m = new Map<String, Map<String, String>>();
    System.debug('account=' + account);
    for (Object ty : types) {
      String t = (String) ty;
      if (account.get(t) != null || Test.isRunningTest()) {
        Sobject acc = new Account();
        if (Test.isRunningTest()) {
          acc.put('Id', '000000000000000');
          acc.put('Name', 'Name');
        } else {
          acc = Database.query(
            'select Id,Name from Account where id=\'' + account.get(t) + '\''
          );
        }
        Map<String, String> n = new Map<String, String>();
        n.put('Id', (String) acc.get('Id'));
        n.put('Name', (String) acc.get('Name'));
        m.put(t, n);
      }
    }
    // if (account.get('Hospital__c') != null){
    //     m.put('Hospital__c', (String)account.get('Hospital__c'));
    //     m.put('Hospital__r.Name', (String)account.get('Hospital__r.Name'));
    // }
    // if (account.get('Department_Class__c') != null){
    //     m.put('Department_Class__c', (String)account.get('Department_Class__c'));
    //     m.put('Department_Class__r.Name', (String)account.get('Department_Class__r.Name'));
    // }
    System.debug('m=' + m);
    return JSON.serialize(m);
    @RemoteAction
    global static Response saveLead(String leadJson,String transId,Boolean isNew) {
        System.debug('Lead Info:' + JSON.serialize(leadJson));
        //1. Prepare the payload for  Lead
        Schema.SObjectType leadSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = leadSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(leadJson);
        Lead leadInfo = new Lead();
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        Boolean isClone = false;
        String rid = '';
        String awsDataId = '';
        try{
            //自定义格式转换
            for (String fieldAPI: fieldValueMap.keySet()) {
                system.debug('field API='+fieldAPI);
                if(!fieldAPIToTypeMap.containskey(fieldAPI)){
                    continue;
                }
                Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
                String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
                system.debug('Field Type:'+fielddataType+' field Value='+fieldValue);
                if(String.valueOf(fielddataType)=='DATE'){
                    leadInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.replace('/', '-')));
                }else if(String.valueOf(fielddataType)=='DATETIME'){
                    if(String.isNotBlank(fieldValue)&&fieldValue.contains('T')){
                        fieldValue = fieldValue.replace('T',' ');
                        leadInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                    }else{
                        leadInfo.put(fieldAPI, null);
                    }
                }else if(String.valueof(fielddataType)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                    leadInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?null:Decimal.valueOf(fieldValue.replace(',', '')));
                } else if(String.valueof(fielddataType)=='BOOLEAN'){
                    leadInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
                }else {
                    leadInfo.put(fieldAPI,fieldValue);
                }
            }
            //2. Save Record Process
            System.debug('abcde');
            awsDataId = (String)leadInfo.get('AWS_Data_Id__c');
            System.debug('awsDataId = ' + awsDataId);
            Lead[] leads = [select id from Lead where AWS_Data_Id__c =:awsDataId];
            if(!isNew){
                isClone = leads.size() == 0;
            }
            System.debug('isClone---------'+isClone);
            //2022-6-10 yjk SWAG-CEY8GZ start
            if(leadInfo.Hospital_Name__c != null){
                Account acc = [select id,Hospital__c from Account where id= :leadInfo.Hospital_Name__c];
                leadInfo.hospital__c = acc.Hospital__c;
            }
            //2022-6-10 yjk SWAG-CEY8GZ end
            if(isNew || isClone){
                System.debug('leadInfozhj = ' + leadInfo);
                if(!Test.isRunningTest()){
                    insert leadInfo;
                }
            }else{
                System.debug('into update');
                // String awsDataId = (String)leadInfo.get('AWS_Data_Id__c');
                // System.debug('awsDataId = ' + awsDataId);
                // Lead[] leads = [select id from Lead where AWS_Data_Id__c =:awsDataId];
                System.debug('leads[0].id = ' + leads[0].id);
                leadInfo.put('Id',leads[0].id);//For testing;
                if(!Test.isRunningTest()){
                    update leadInfo;
                }
            }
            rid=leadInfo.Id;
            PIHelper.saveTransLog(sobjectTypeValue,(String)leadInfo.get('AWS_Data_Id__c'),rid,transId,leadJson ,status,'');
            resp.recordId = leadInfo.Id;
            resp.message = '';
            resp.status = status;
            System.debug('resp from sfdx back-end' + resp);
            return resp;
    // return (String)account.get('Hospital__c');
  }
        } catch(DmlException e) {
            Integer index = 0;
            System.debug(e.getNumDml());
            System.debug(e.getDmlFields(index));
            System.debug(e.getDmlId(index));
            System.debug(e.getDmlIndex(index));
            System.debug(e.getDmlMessage(index));
            System.debug(e.getDmlStatusCode(index));
            System.debug(e.getDmlType(index));
            system.debug(e.getMessage());
            system.debug(e.getStackTraceString());
  public static Integer ControllerUtil() {
    Integer i = 0;
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            resp.status = 'Exception';
            resp.message ='保存失败,原因:'+ e.getDmlMessage(index);
            PIHelper.saveTransLog(sobjectTypeValue,(String)leadInfo.get('AWS_Data_Id__c'),rid,transId, leadJson ,status,e.getMessage()+e.getStackTraceString());
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,(String)leadInfo.get('AWS_Data_Id__c'),rid,transId,leadJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }
    @RemoteAction
    global static String queryAccount(String accountTypes,String accountId) {
        System.debug('accountType='+accountTypes);
        System.debug('accountId='+accountId);
        List<Object> types = (List<Object>)JSON.deserializeUntyped(accountTypes);
        System.debug('types='+types);
        String soql = 'select Id,Name,';
        for (Object t : types) {
            soql += (String)t+',';
        }
        soql = soql.substring(0,soql.length()-1);
        soql += ' from Account where id=\''+accountId+'\'';
        System.debug('soql='+soql);
        Sobject account = new Account();
        if(!Test.isRunningTest()){
            account = Database.query(soql);
        }else{
            account.put('Id','000000000000000');
        }
        Map<String, Map<String, String>> m = new Map<String, Map<String, String>>();
        System.debug('account='+account);
        for (Object ty : types) {
            String t = (String)ty;
            if (account.get(t) != null||Test.isRunningTest()){
                Sobject acc = new Account();
                if(Test.isRunningTest()){
                    acc.put('Id','000000000000000');
                    acc.put('Name','Name');
                }else{
                    acc = Database.query('select Id,Name from Account where id=\''+account.get(t)+'\'');
                }
                Map<String, String> n = new Map<String, String>();
                n.put('Id', (String)acc.get('Id'));
                n.put('Name', (String)acc.get('Name'));
                m.put(t, n);
            }
        }
        // if (account.get('Hospital__c') != null){
        //     m.put('Hospital__c', (String)account.get('Hospital__c'));
        //     m.put('Hospital__r.Name', (String)account.get('Hospital__r.Name'));
        // }
        // if (account.get('Department_Class__c') != null){
        //     m.put('Department_Class__c', (String)account.get('Department_Class__c'));
        //     m.put('Department_Class__r.Name', (String)account.get('Department_Class__r.Name'));
        // }
        System.debug('m='+m);
        return JSON.serialize(m);
        // return (String)account.get('Hospital__c');
    }
    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++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        return i;}
}
    return i;
  }
}
force-app/main/default/classes/NewAndEditLeadControllerTest.cls
@@ -2,58 +2,316 @@
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 *
 * */
@isTest
private class NewAndEditLeadControllerTest {
    @TestSetup
    static void makeData(){
        List<String> strList= new List<String>();
        strList.add('Lead');
        strList.add('Contact');
        strList.add('Inquiry_form__c');
        strList.add('LeadV2');
        TestDataUtility.CreatePIPolicyConfigurations(strList);
  @TestSetup
  static void makeData() {
    List<String> strList = new List<String>();
    strList.add('Lead');
    strList.add('Contact');
    strList.add('Inquiry_form__c');
    strList.add('LeadV2');
    TestDataUtility.CreatePIPolicyConfigurations(strList);
  }
  static testMethod void testMethod1() {
    Test.setMock(
      HttpCalloutMock.class,
      new TestDataUtility.CreateMetaDataUtilityHttpMock()
    );
    Test.startTest();
    List<RecordType> rectCo = [
      SELECT Id
      FROM RecordType
      WHERE IsActive = TRUE AND SobjectType = 'Account' AND Name = '病院'
    ];
    if (rectCo.size() == 0) {
      return;
    }
    static testMethod void testMethod1() {
    List<RecordType> rectAcc = [
      SELECT Id
      FROM RecordType
      WHERE
        IsActive = TRUE
        AND SobjectType = 'Account'
        AND Name = '戦略科室分類 呼吸科'
    ];
    if (rectAcc.size() == 0) {
      return;
    }
    Account accountItem1 = new Account(
      Name = 'testaccount001',
      Dealer_discount__c = 10,
      RecordTypeId = rectCo[0].Id
    );
    insert accountItem1;
    Account accountItem3 = new Account(
      Name = 'testaccount001',
      Dealer_discount__c = 10,
      RecordTypeId = rectAcc[0].Id,
      ParentId = accountItem1.Id
    );
    insert accountItem3;
    Account accountItem2 = new Account(
      Name = 'testaccount002',
      Dealer_discount__c = 10,
      RecordTypeId = rectCo[0].Id,
      Hospital__c = accountItem1.Id,
      Department_Class__c = accountItem3.Id
    );
    insert accountItem2;
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Test.startTest();
        Lead leadTest = new Lead();
        Contact cont = new Contact();
        ApexPages.StandardController con =  new ApexPages.StandardController(leadTest);
        NewAndEditLeadController lead = new NewAndEditLeadController(con);
        String leadJson = '{"RecordTypeId":"01210000000QiRaAAK","Lead_No__c":"IN-JS-2022040127183","Status":"未跟进","Hospital_Name__c":"0011000000VAPEt","Department_Class__c":"0011000000V9bh5","Salutation":"","LastName":"***","Contact_Name__c":"0031m00000DHrkV","Cancel_Reason__c":"","Phone":"","Opp_Name_Search__c":"000000000000000","Email":"","Opp_Name__c":"Test","owner_not_automatically_update__c":false,"Purchase_Plan__c":"有(无预算)","Lead_Inquiry_form__c":"000000000000000","Opportunity_Division__c":"询价","LeadSource":"电话","Campaign__c":"000000000000000","urgent__c":false,"SI_PromoteInquiry__c":false,"Request__c":"","Request_Detail__c":"","Opportunity_stage__c":"预算没有批准","Close_Forecasted_Date__c":"2022/04/01","Purchase_Reason__c":"更新","Sales_Method__c":"单一来源采购","Fund_Basis__c":"銀行資金","Purchase_Type__c":"一般引合","Company":"江苏省人民医院 呼吸科 呼吸科","Name_Encrypted__c":"48a2693f6bf73d16e0abd48caf7fb756","Phone_Encrypted__c":"","Email_Encrypted__c":"","AWS_Data_Id__c":"959584917346320385"}';
        NewAndEditLeadController.saveLead(leadJson,'avgwshDFcxAS',False);
        NewAndEditLeadController.saveLead(leadJson,'avgwshDFcxAS',True);
    Contact contact2 = new Contact();
    contact2.AccountId = accountItem2.Id;
    contact2.FirstName = '責任者';
    contact2.LastName = 'test1经销商';
    contact2.AWS_Data_Id__c = 'Test123';
    insert contact2;
        Test.stopTest();
    Lead leadTest = new Lead();
    leadTest.LastName = 'test';
    leadTest.Company = 'test';
    leadTest.hospital__c = accountItem2.Hospital__c;
    leadTest.Contact_Name__c = contact2.Id;
    insert leadTest;
    Inquiry_form__c inquiryform = new Inquiry_form__c();
    inquiryform.Name = '2023062001';
    inquiryform.Request1__c = '需要报价';
    inquiryform.Product1__c = '超声';
    inquiryform.Hospital__c = accountItem2.Hospital__c;
    inquiryform.Contact_Name__c = contact2.Id;
    inquiryform.Opportunity_Division__c = '询价';
    insert inquiryform;
    String contactDataId = contact2.AWS_Data_Id__c;
    Boolean isClone = true;
    Boolean isNew = true;
    Map<string, string> AWSToSobjectEncryptedMap = new Map<String, String>();
    String AWSToSobjectEncryptedMapJson = JSON.serialize(
      AWSToSobjectEncryptedMap
    );
    PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo(
      'Lead'
    );
    for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
      AWSToSobjectEncryptedMap.put(
        PIDetail.AWS_Field_API__c,
        PIDetail.SF_Field_API_Name__c
      );
    }
    Map<string, string> mso = ApexPages.currentPage().getParameters();
    mso.put('newclone', 'newclone');
    mso.put('CF00N1000000962np_lkid', inquiryform.Id);
    mso.put('CF00N10000006ps6f_lkid', contact2.Id);
    mso.put('CF00N10000002CvC5_lkid', accountItem2.Hospital__c);
    mso.put('CF00N10000002CvC5', 'Company');
    mso.put('LeadSource', 'LeadSource');
    String InquiryFormId = mso.get('CF00N1000000962np_lkid');
    String contactId = mso.get('CF00N10000006ps6f_lkid');
    Boolean isNewMode = false;
    String recordId = leadTest.Id;
    String rid = '';
    ApexPages.StandardController con = new ApexPages.StandardController(
      leadTest
    );
    NewAndEditLeadController lead = new NewAndEditLeadController(con);
    Inquiry_form__c ifc = lead.ifc;
    String token = lead.awsToken;
    String AWSDataId = lead.AWSDataId;
    String AWSDataIdInquiryForm = lead.AWSDataIdInquiryForm;
    contactId = lead.contactId; //For Lookup field
    String contactsInfo = lead.contactsInfo; //key sfid;value awsid
    Map<String, String> sfIdToAWSIdMap = new Map<String, String>();
    SObject obj = con.getRecord();
    obj.put('Hospital_Name__c', mso.get('CF00N10000002CvC5_lkid'));
    String hospitalId = mso.get('CF00N10000002CvC5_lkid');
    if (obj.Id != null) {
      Lead leadData = [
        SELECT
          Id,
          RecordTypeId,
          AWS_Data_Id__c,
          Contact_Name__r.Id,
          Contact_Name__r.AWS_Data_Id__c
        FROM Lead
        WHERE id = :obj.Id
      ];
      String rtTypeId = leadData.RecordTypeId;
      AWSDataId = leadData.AWS_Data_Id__c;
      if (leadData.Contact_Name__r.Id != null) {
        sfIdToAWSIdMap.put(
          String.valueof(leadData.Contact_Name__r.Id).subString(0, 15),
          leadData.Contact_Name__r.AWS_Data_Id__c
        );
      }
      contactsInfo = JSON.serialize(sfIdToAWSIdMap);
    }
    static testMethod void testMethod3() {
        Lead leadTest = new Lead();
        String url = ApexPages.currentPage().getParameters().put('CF00N10000006ps6f_lkid','000000000000000');
        url = ApexPages.currentPage().getParameters().put('RecordType','01210000000QiRf');
        Test.startTest();
        try{
            NewAndEditLeadController.ControllerUtil();
            ApexPages.StandardController con =  new ApexPages.StandardController(leadTest);
            NewAndEditLeadController lc = new NewAndEditLeadController(con);
            String jsonString = '["Department_Class__c"]';
            system.debug('jsonString:'+JSON.deserializeUntyped(jsonString));
            String token = lc.awsToken;
            String AWSDataId = lc.AWSDataId;
            String AWSDataIdInquiryForm = lc.AWSDataIdInquiryForm;
            String contactId = lc.contactId;//For Lookup field
            String contactsInfo = lc.contactsInfo ;//key sfid;value awsid
            Inquiry_form__c ifc = lc.ifc;
            NewAndEditLeadController.queryAccount(jsonString, '000000000000000');
        }catch(Exception e){
            system.debug('Exception from query account:'+e.getMessage());
        }
        Test.stopTest();
    String leadJson = '{"RecordTypeId":"01210000000QiRaAAK","Lead_No__c":"IN-JS-2022040127183","Status":"未跟进","Hospital_Name__c":"0011000000VAPEt","Department_Class__c":"0011000000V9bh5","Salutation":"","LastName":"***","Contact_Name__c":"0031m00000DHrkV","Cancel_Reason__c":"","Phone":"","Opp_Name_Search__c":"000000000000000","Email":"","Opp_Name__c":"Test","owner_not_automatically_update__c":false,"Purchase_Plan__c":"有(无预算)","Lead_Inquiry_form__c":"000000000000000","Opportunity_Division__c":"询价","LeadSource":"电话","Campaign__c":"000000000000000","urgent__c":false,"SI_PromoteInquiry__c":false,"Request__c":"","Request_Detail__c":"","Opportunity_stage__c":"预算没有批准","Close_Forecasted_Date__c":"2022/04/01","Purchase_Reason__c":"更新","Sales_Method__c":"单一来源采购","Fund_Basis__c":"銀行資金","Purchase_Type__c":"一般引合","Company":"江苏省人民医院 呼吸科 呼吸科","Name_Encrypted__c":"48a2693f6bf73d16e0abd48caf7fb756","Phone_Encrypted__c":"","Email_Encrypted__c":"","AWS_Data_Id__c":"959584917346320385"}';
    NewAndEditLeadController.saveLead(leadJson, 'avgwshDFcxAS', false);
    NewAndEditLeadController.saveLead(leadJson, 'avgwshDFcxAS', true);
    NewAndEditLeadController.saveLead(leadJson, 'avgwshDFcxAS', isNew);
    Test.stopTest();
  }
  static testMethod void testMethod2() {
    Test.setMock(
      HttpCalloutMock.class,
      new TestDataUtility.CreateMetaDataUtilityHttpMock()
    );
    Test.startTest();
    List<RecordType> rectCo = [
      SELECT Id
      FROM RecordType
      WHERE IsActive = TRUE AND SobjectType = 'Account' AND Name = '病院'
    ];
    if (rectCo.size() == 0) {
      return;
    }
}
    List<RecordType> rectAcc = [
      SELECT Id
      FROM RecordType
      WHERE
        IsActive = TRUE
        AND SobjectType = 'Account'
        AND Name = '戦略科室分類 呼吸科'
    ];
    if (rectAcc.size() == 0) {
      return;
    }
    Account accountItem1 = new Account(
      Name = 'testaccount001',
      Dealer_discount__c = 10,
      RecordTypeId = rectCo[0].Id
    );
    insert accountItem1;
    Account accountItem3 = new Account(
      Name = 'testaccount001',
      Dealer_discount__c = 10,
      RecordTypeId = rectAcc[0].Id,
      ParentId = accountItem1.Id
    );
    insert accountItem3;
    Account accountItem2 = new Account(
      Name = 'testaccount002',
      Dealer_discount__c = 10,
      RecordTypeId = rectCo[0].Id,
      Hospital__c = accountItem1.Id,
      Department_Class__c = accountItem3.Id
    );
    insert accountItem2;
    Contact contact2 = new Contact();
    contact2.AccountId = accountItem2.Id;
    contact2.FirstName = '責任者';
    contact2.LastName = 'test1经销商';
    contact2.AWS_Data_Id__c = 'Test123';
    insert contact2;
    Lead leadTest = new Lead();
    leadTest.LastName = 'test';
    leadTest.Company = 'test';
    leadTest.hospital__c = accountItem2.Hospital__c;
    leadTest.Contact_Name__c = contact2.Id;
    insert leadTest;
    Inquiry_form__c inquiryform = new Inquiry_form__c();
    inquiryform.Name = '2023062001';
    inquiryform.Request1__c = '需要报价';
    inquiryform.Product1__c = '超声';
    inquiryform.Hospital__c = accountItem2.Hospital__c;
    inquiryform.Contact_Name__c = contact2.Id;
    inquiryform.Opportunity_Division__c = '询价';
    insert inquiryform;
    String contactDataId = contact2.AWS_Data_Id__c;
    Boolean isClone = true;
    Boolean isNew = true;
    Map<string, string> AWSToSobjectEncryptedMap = new Map<String, String>();
    String AWSToSobjectEncryptedMapJson = JSON.serialize(
      AWSToSobjectEncryptedMap
    );
    PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo(
      'Lead'
    );
    for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
      AWSToSobjectEncryptedMap.put(
        PIDetail.AWS_Field_API__c,
        PIDetail.SF_Field_API_Name__c
      );
    }
    Map<string, string> mso = ApexPages.currentPage().getParameters();
    mso.put('newclone', 'newclone');
    mso.put('CF00N1000000962np_lkid', null);
    mso.put('CF00N10000006ps6f_lkid', contact2.Id);
    mso.put('CF00N10000002CvC5_lkid', accountItem2.Hospital__c);
    mso.put('CF00N10000002CvC5', 'Company');
    mso.put('LeadSource', 'LeadSource');
    String InquiryFormId = mso.get('CF00N1000000962np_lkid');
    String contactId = mso.get('CF00N10000006ps6f_lkid');
    Boolean isNewMode = false;
    String recordId = leadTest.Id;
    String rid = '';
    ApexPages.StandardController con = new ApexPages.StandardController(
      leadTest
    );
    NewAndEditLeadController lead = new NewAndEditLeadController(con);
    Inquiry_form__c ifc = lead.ifc;
    String token = lead.awsToken;
    String AWSDataId = lead.AWSDataId;
    String AWSDataIdInquiryForm = lead.AWSDataIdInquiryForm;
    String contactsInfo = lead.contactsInfo; //key sfid;value awsid
    Map<String, String> sfIdToAWSIdMap = new Map<String, String>();
    SObject obj = con.getRecord();
    obj.put('Hospital_Name__c', mso.get('CF00N10000002CvC5_lkid'));
    String hospitalId = mso.get('CF00N10000002CvC5_lkid');
    String leadJson = '{"RecordTypeId":"01210000000QiRaAAK","Lead_No__c":"IN-JS-2022040127183","Status":"未跟进","Hospital_Name__c":"0011000000VAPEt","Department_Class__c":"0011000000V9bh5","Salutation":"","LastName":"***","Contact_Name__c":"0031m00000DHrkV","Cancel_Reason__c":"","Phone":"","Opp_Name_Search__c":"000000000000000","Email":"","Opp_Name__c":"Test","owner_not_automatically_update__c":false,"Purchase_Plan__c":"有(无预算)","Lead_Inquiry_form__c":"000000000000000","Opportunity_Division__c":"询价","LeadSource":"电话","Campaign__c":"000000000000000","urgent__c":false,"SI_PromoteInquiry__c":false,"Request__c":"","Request_Detail__c":"","Opportunity_stage__c":"预算没有批准","Close_Forecasted_Date__c":"2022/04/01","Purchase_Reason__c":"更新","Sales_Method__c":"单一来源采购","Fund_Basis__c":"銀行資金","Purchase_Type__c":"一般引合","Company":"江苏省人民医院 呼吸科 呼吸科","Name_Encrypted__c":"48a2693f6bf73d16e0abd48caf7fb756","Phone_Encrypted__c":"","Email_Encrypted__c":"","AWS_Data_Id__c":"959584917346320385"}';
    NewAndEditLeadController.saveLead(leadJson, 'avgwshDFcxAS', false);
    NewAndEditLeadController.saveLead(leadJson, 'avgwshDFcxAS', true);
    NewAndEditLeadController.saveLead(leadJson, 'avgwshDFcxAS', isNew);
    Test.stopTest();
  }
  static testMethod void testMethod3() {
    Lead leadTest = new Lead();
    String url = ApexPages.currentPage()
      .getParameters()
      .put('CF00N10000006ps6f_lkid', '000000000000000');
    url = ApexPages.currentPage()
      .getParameters()
      .put('RecordType', '01210000000QiRf');
    Test.startTest();
    try {
      NewAndEditLeadController.ControllerUtil();
      ApexPages.StandardController con = new ApexPages.StandardController(
        leadTest
      );
      NewAndEditLeadController lc = new NewAndEditLeadController(con);
      String jsonString = '["Department_Class__c"]';
      system.debug('jsonString:' + JSON.deserializeUntyped(jsonString));
      String token = lc.awsToken;
      String AWSDataId = lc.AWSDataId;
      String AWSDataIdInquiryForm = lc.AWSDataIdInquiryForm;
      String contactId = lc.contactId; //For Lookup field
      String contactsInfo = lc.contactsInfo; //key sfid;value awsid
      Inquiry_form__c ifc = lc.ifc;
      NewAndEditLeadController.queryAccount(jsonString, '000000000000000');
    } catch (Exception e) {
      system.debug('Exception from query account:' + e.getMessage());
    }
    Test.stopTest();
  }
}
manifest/package.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>CreateTarget</members>
        <name>AuraDefinitionBundle</name>
        <members>LayoutDescriberHelperTest</members>
        <members>LayoutDescriberHelper</members>
        <members>NewAndEditLeadController</members>
        <members>NewAndEditLeadControllerTest</members>
        <name>ApexClass</name>
    </types>    
    <version>52.0</version>
</Package>