From a90c9ecfc5118547d0a92b2fee2779eca95e09a5 Mon Sep 17 00:00:00 2001
From: buli <137736985@qq.com>
Date: 星期四, 10 三月 2022 18:49:39 +0800
Subject: [PATCH] New Code For PIPL20220310

---
 force-app/main/default/pages/ViewTenderinformationDecryptInfo.page-meta.xml         |    7 
 force-app/main/default/classes/ControllerResponse.cls                               |   16 
 force-app/main/default/classes/TestClass.cls-meta.xml                               |    5 
 force-app/main/default/pages/ViewAddressDecryptInfo.page-meta.xml                   |    7 
 force-app/main/default/classes/NewAndEditASEActivityController.cls-meta.xml         |    5 
 force-app/main/default/pages/ViewInspectionReportDecryptInfo.page-meta.xml          |    7 
 force-app/main/default/pages/ViewReportDecryptInfo.page                             |   40 
 force-app/main/default/classes/NewAndEditASEActivityController.cls                  |   49 
 force-app/main/default/classes/NewAndEditAgencyContactController.cls-meta.xml       |    5 
 force-app/main/default/aura/NewAgencyContact/NewAgencyContactHelper.js              |   77 
 force-app/main/default/classes/MetaDataUtility.cls                                  |  177 
 force-app/main/default/classes/NewAndEditTenderinformationController.cls            |   45 
 force-app/main/default/pages/TenderInformationUploadPdf.page-meta.xml               |    7 
 force-app/main/default/triggers/FileAddressTrigger.trigger-meta.xml                 |    5 
 force-app/main/default/classes/NewAndEditQISController.cls-meta.xml                 |    5 
 force-app/main/default/pages/NewAndEditCase.page-meta.xml                           |    7 
 force-app/main/default/pages/ViewContactDecryptInfo.page-meta.xml                   |    7 
 force-app/main/default/pages/ViewOnCallDecrypt.page                                 |   27 
 force-app/main/default/pages/NewAndEditASEActivity.page-meta.xml                    |    7 
 force-app/main/default/pages/ViewContactDecryptInfo.page                            |   68 
 force-app/main/default/pages/ViewQISReportDecryptInfo.page                          |   65 
 force-app/main/default/pages/NewAndEditCampaignMember.page-meta.xml                 |    7 
 force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page-meta.xml            |    7 
 force-app/main/default/classes/NewAndEditEventController.cls                        |   44 
 force-app/main/default/classes/Option.cls-meta.xml                                  |    5 
 force-app/main/default/pages/SearchContactPage.page                                 |  185 
 force-app/main/default/classes/NewAndEditReportController.cls                       |  160 
 force-app/main/default/pages/ViewAgencyContactDecryptInfo.page-meta.xml             |    7 
 force-app/main/default/classes/FileUploadController.cls                             |   68 
 force-app/main/default/pages/ViewASEActivityDecryptInfo.page                        |   85 
 force-app/main/default/pages/ViewAgencyContactDecryptInfo.page                      |   56 
 force-app/main/default/classes/DeveloperUtility.cls-meta.xml                        |    5 
 force-app/main/default/classes/NewAndEditContactController.cls-meta.xml             |    5 
 force-app/main/default/pages/ViewInquiryFormDecryptInfo.page                        |   56 
 force-app/main/default/pages/NewAndEditAgencyContact.page-meta.xml                  |    7 
 force-app/main/default/classes/MetaDataUtility.cls-meta.xml                         |    5 
 force-app/main/default/pages/NewAndEditReport.page-meta.xml                         |    7 
 force-app/main/default/pages/UploadPdf.page-meta.xml                                |    7 
 force-app/main/default/pages/NewConsumApply.page                                    |  402 +
 force-app/main/default/classes/NewAndEditInquiryFormController.cls-meta.xml         |    5 
 force-app/main/default/classes/FieldInfo.cls                                        |   44 
 force-app/main/default/pages/SearchContactPage.page-meta.xml                        |    7 
 force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp                   |   60 
 force-app/main/default/classes/NewAndEditCampaignMemberController.cls               |   18 
 force-app/main/default/classes/NewAndEditInspectionReportController.cls-meta.xml    |    5 
 force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page          |   26 
 force-app/main/default/pages/ViewInquiryFormDecryptInfo.page-meta.xml               |    7 
 force-app/main/default/pages/NewListOfConsumables.page                              |    2 
 force-app/main/default/pages/SearchLeadPage.page                                    |  185 
 force-app/main/default/pages/ViewReportDecryptInfo.page-meta.xml                    |    7 
 force-app/main/default/pages/ViewAddressDecryptInfo.page                            |   32 
 force-app/main/default/classes/DeleteBatch.cls                                      |   20 
 force-app/main/default/classes/NewRepairController.cls-meta.xml                     |    5 
 force-app/main/default/pages/NewRepairPage.page-meta.xml                            |    7 
 force-app/main/default/classes/PIHelper.cls                                         |  216 
 force-app/main/default/classes/NFM702ControllerHandler.cls                          |    5 
 force-app/main/default/classes/FileUploadController.cls-meta.xml                    |    5 
 force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls-meta.xml  |    5 
 force-app/main/default/pages/B_Test.page                                            |  304 +
 force-app/main/default/pages/NewAndEditRepairSubOrder.page                          |  575 ++
 force-app/main/default/classes/NewAndEditCampaignMemberController.cls-meta.xml      |    5 
 force-app/main/default/pages/NewAndEditInspectionReport.page-meta.xml               |    7 
 force-app/main/default/classes/NFM702ControllerHandler.cls-meta.xml                 |    5 
 force-app/main/default/classes/FieldInfo.cls-meta.xml                               |    5 
 force-app/main/default/classes/SearchLeadController.cls                             |   53 
 force-app/main/default/pages/UploadPdf.page                                         |  190 
 force-app/main/default/triggers/FileAddressTrigger.trigger                          |   13 
 force-app/main/default/pages/ViewCaseDecryptInfo.page                               |   30 
 force-app/main/default/classes/DeleteBatch.cls-meta.xml                             |    5 
 force-app/main/default/pages/NewAndEditCase.page                                    |  442 +
 force-app/main/default/pages/NewRentalApply.page                                    |  387 +
 force-app/main/default/pages/ViewRepairEncrypt.page-meta.xml                        |    7 
 force-app/main/default/pages/ViewListOfConsumablesDecrypt.page                      |    2 
 force-app/main/default/classes/NewAndEditReportController.cls-meta.xml              |    5 
 force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page-meta.xml         |    7 
 force-app/main/default/classes/NewAndEditCaseController.cls-meta.xml                |    5 
 force-app/main/default/pages/TestVfPage.page                                        |    3 
 force-app/main/default/pages/NewAndEditInspectionReport.page                        |  436 +
 force-app/main/default/classes/NewAndEditQISController.cls                          |   12 
 force-app/main/default/pages/NewAndEditReport.page                                  |  590 ++
 force-app/main/default/classes/NewAndEditInspectionReportController.cls             |   25 
 force-app/main/default/pages/RentalApplyUploadPdf.page-meta.xml                     |    7 
 force-app/main/default/aura/NewAgencyContact/NewAgencyContactController.js          |  217 
 force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page                     |   56 
 force-app/main/default/classes/NewAgencyContactController.cls-meta.xml              |    5 
 force-app/main/default/classes/ViewParticipantsController.cls-meta.xml              |    5 
 force-app/main/default/classes/NewAndEditTenderinformationController.cls-meta.xml   |    5 
 force-app/main/default/pages/NewAndEditQIS.page-meta.xml                            |    7 
 force-app/main/default/classes/NewAndEditEventController.cls-meta.xml               |    5 
 force-app/main/default/classes/SoqlHelper.cls                                       |  136 
 force-app/main/default/classes/NewAndEditBaseController.cls-meta.xml                |    5 
 force-app/main/default/classes/ControllerResponse.cls-meta.xml                      |    5 
 force-app/main/default/pages/NewAndEditContact.page                                 |  485 ++
 force-app/main/default/pages/ViewLeadDecryptInfo.page-meta.xml                      |    7 
 force-app/main/default/classes/TestClass.cls                                        |   41 
 force-app/main/default/classes/NewAndEditRepairSubOrderController.cls-meta.xml      |    5 
 force-app/main/default/pages/TestClass.page                                         |    2 
 force-app/main/default/classes/NewAndEditAgencyContactController.cls                |   20 
 force-app/main/default/classes/NewAndEditContactController.cls                      |   52 
 force-app/main/default/classes/SearchContactController.cls-meta.xml                 |    5 
 force-app/main/default/classes/NewListOfConsumablesController.cls                   |    3 
 force-app/main/default/pages/ViewEventDecryptInfo.page                              |   93 
 force-app/main/default/pages/ViewInspectionReportDecryptInfo.page                   |   56 
 force-app/main/default/pages/ViewListOfConsumablesDecrypt.page-meta.xml             |    7 
 force-app/main/default/classes/RentalApplyController.cls-meta.xml                   |    5 
 force-app/main/default/classes/NewAndEditRepairSubOrderController.cls               |   40 
 force-app/main/default/pages/NewAndEditAgencyContact.page                           |  511 ++
 force-app/main/default/classes/B_Test.cls                                           |  161 
 force-app/main/default/classes/ViewParticipantsController.cls                       |    6 
 force-app/main/default/classes/Option.cls                                           |    5 
 force-app/main/default/classes/NewConsumApplyController.cls-meta.xml                |    5 
 force-app/main/default/classes/TestController.cls-meta.xml                          |    5 
 force-app/main/default/pages/ViewOnCallDecrypt.page-meta.xml                        |    7 
 force-app/main/default/pages/ViewRentalApplyDecrypt.page                            |   27 
 force-app/main/default/classes/OnCallController.cls-meta.xml                        |    5 
 force-app/main/default/classes/TestController.cls                                   |   15 
 force-app/main/default/pages/NewAndEditASEActivity.page                             |  526 ++
 force-app/main/default/pages/ViewASEActivityDecryptInfo.page-meta.xml               |    7 
 force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page                  |  300 +
 force-app/main/default/pages/ViewDecryptConsumApply.page-meta.xml                   |    7 
 force-app/main/default/pages/TestVfPage.page-meta.xml                               |    7 
 force-app/main/default/classes/RentalApplyController.cls                            |  153 
 force-app/main/default/pages/NewAndEditRepairSubOrder.page-meta.xml                 |    7 
 force-app/main/default/pages/NewOnCall.page-meta.xml                                |    7 
 force-app/main/default/pages/RentalApplyUploadPdf.page                              |  190 
 force-app/main/default/pages/ConsumApplyUploadPdf.page-meta.xml                     |    7 
 force-app/main/default/pages/NewAndEditContact.page-meta.xml                        |    7 
 force-app/main/default/classes/NewAndEditInquiryFormController.cls                  |   36 
 force-app/main/default/pages/NewConsumApply.page-meta.xml                           |    7 
 force-app/main/default/classes/NewConsumApplyController.cls                         |  139 
 force-app/main/default/classes/SObjectHelper.cls-meta.xml                           |    5 
 force-app/main/default/pages/ViewRepairEncrypt.page                                 |   47 
 force-app/main/default/pages/ViewLeadDecryptInfo.page                               |   32 
 force-app/main/default/pages/NewRepairPage.page                                     |    2 
 force-app/main/default/classes/SoqlHelper.cls-meta.xml                              |    5 
 force-app/main/default/classes/NewRepairController.cls                              |  148 
 force-app/main/default/pages/NewRepair.page                                         |  327 +
 force-app/main/default/pages/TestClass.page-meta.xml                                |    7 
 force-app/main/default/classes/NewAndEditCaseController.cls                         |  146 
 force-app/main/default/pages/NewAndEditTenderinformation.page-meta.xml              |    7 
 force-app/main/default/pages/NewListOfConsumables.page-meta.xml                     |    7 
 force-app/main/default/pages/ViewRentalApplyDecrypt.page-meta.xml                   |    7 
 force-app/main/default/classes/NewAndEditBaseController.cls                         |  260 +
 force-app/main/default/pages/NewAndEditInquiryForm.page-meta.xml                    |    7 
 force-app/main/default/pages/NewAndEditAddress.page-meta.xml                        |    7 
 force-app/main/default/classes/SObjectHelper.cls                                    |  445 +
 force-app/main/default/classes/PIHelper.cls-meta.xml                                |    5 
 force-app/main/default/pages/ViewCaseDecryptInfo.page-meta.xml                      |    7 
 force-app/main/default/pages/NewAndEditQIS.page                                     |  558 ++
 force-app/main/default/pages/TenderInformationUploadPdf.page                        |  190 
 force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page-meta.xml |    7 
 force-app/main/default/pages/ViewTenderinformationDecryptInfo.page                  |   58 
 force-app/main/default/classes/SearchLeadController.cls-meta.xml                    |    5 
 force-app/main/default/pages/NewOnCall.page                                         |  298 +
 force-app/main/default/classes/SearchContactController.cls                          |   61 
 force-app/main/default/classes/NewAgencyContactController.cls                       |  124 
 force-app/main/default/pages/NewRentalApply.page-meta.xml                           |    7 
 force-app/main/default/pages/NewRepair.page-meta.xml                                |    7 
 force-app/main/default/pages/ViewDecryptConsumApply.page                            |   27 
 force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp-meta.xml          |    5 
 force-app/main/default/pages/SearchLeadPage.page-meta.xml                           |    7 
 force-app/main/default/pages/ViewParticipantsDecryptInfo.page                       |   28 
 force-app/main/default/pages/ViewParticipantsDecryptInfo.page-meta.xml              |    7 
 force-app/main/default/classes/OnCallController.cls                                 |  129 
 force-app/main/default/classes/NewListOfConsumablesController.cls-meta.xml          |    5 
 force-app/main/default/pages/ViewQISReportDecryptInfo.page-meta.xml                 |    7 
 force-app/main/default/classes/B_Test.cls-meta.xml                                  |    5 
 force-app/main/default/classes/DeveloperUtility.cls                                 |   62 
 force-app/main/default/aura/NewAgencyContact/NewAgencyContact.css                   |   15 
 force-app/main/default/pages/B_Test.page-meta.xml                                   |    7 
 force-app/main/default/pages/ViewEventDecryptInfo.page-meta.xml                     |    7 
 force-app/main/default/pages/NewAndEditCampaignMember.page                          |  421 +
 force-app/main/default/pages/NewAndEditInquiryForm.page                             |  607 ++
 force-app/main/default/pages/NewAndEditAddress.page                                 |  427 +
 force-app/main/default/pages/NewAndEditTenderinformation.page                       |  434 +
 force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls           |  125 
 force-app/main/default/pages/ConsumApplyUploadPdf.page                              |  190 
 177 files changed, 14,252 insertions(+), 0 deletions(-)

diff --git a/force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp b/force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp
new file mode 100644
index 0000000..8be5cc8
--- /dev/null
+++ b/force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp
@@ -0,0 +1,60 @@
+<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId,lightning:actionOverride,lightning:isUrlAddressable" access="global" 
+                controller="NewAgencyContactController">
+    
+    <aura:attribute name = "recordId" type = "Id" default = ""/>
+    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
+    <aura:attribute name="layout" type="LayoutDescriberHelper.LayoutWrapper"/>
+    <aura:attribute name="record_data" type="Map"/>
+    <aura:attribute name="section_names" type="List"/>
+    <aura:attribute name="showSpinner" type="Boolean" default = "False"/>
+    <aura:attribute name="staticResource" type="Map"/>
+    <aura:attribute name="pi_fields_map" type="Map"/>
+    
+    
+    
+	<div class="{! v.container_class}">
+        <!-- header -->
+        <header class="slds-modal__header">
+            <h2 id="modal-heading-01" class="slds-modal__title slds-hyphenate">
+                Create Agency Contact
+            </h2>
+        </header>
+
+        <div class="slds-modal__content slds-p-around_medium">
+            <aura:if isTrue="{!v.showSpinner}">
+                <lightning:spinner alternativeText="Loading" size="medium" />
+            </aura:if>
+            
+            
+            <lightning:recordEditForm objectApiName="Agency_Contact__c">
+                
+                <lightning:accordion activeSectionName="{! v.section_names }" allowMultipleSectionsOpen="true" class="greyyyy" >
+                    <aura:iteration items="{!v.layout}" var="section">
+                        <aura:if isTrue="{! section.editHeading }">
+                            <lightning:accordionSection name="{! section.label }" label="{! section.label }">
+                                
+                                <aura:iteration items="{! section.layoutColumns}" var="col">
+                                    <aura:iteration items="{! col.layoutItems}" var="field">
+                                        <aura:if isTrue="{! field.behavior != 'Readonly' }">
+                                        	<lightning:inputField required="{! field.behavior == 'Required' }" fieldName="{! field.field}" value="{! field.value}" />
+                                            
+                                        </aura:if>
+                                    </aura:iteration>
+                                    
+                                </aura:iteration>
+                                
+                                
+                            </lightning:accordionSection>
+                        </aura:if>
+                    </aura:iteration>
+                </lightning:accordion>
+            </lightning:recordEditForm>
+			
+            <div  style="text-align:center;margin: 5px;">
+                <lightning:button class="slds-button slds-button_neutral" label="鍙栨秷" onclick="{! c.cancelClick }" />
+                <lightning:button class="slds-button slds-button_brand" variant="brand" label="淇濆瓨" onclick="{! c.saveClick }" />
+
+            </div>
+        </div>
+    </div>
+</aura:component>
\ No newline at end of file
diff --git a/force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp-meta.xml b/force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp-meta.xml
new file mode 100644
index 0000000..632b900
--- /dev/null
+++ b/force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<AuraDefinitionBundle xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <description>A Lightning Component Bundle</description>
+</AuraDefinitionBundle>
diff --git a/force-app/main/default/aura/NewAgencyContact/NewAgencyContact.css b/force-app/main/default/aura/NewAgencyContact/NewAgencyContact.css
new file mode 100644
index 0000000..919a7e5
--- /dev/null
+++ b/force-app/main/default/aura/NewAgencyContact/NewAgencyContact.css
@@ -0,0 +1,15 @@
+.THIS {
+}
+
+.THIS .greyyyy .slds-button_reset{
+ display: flex;
+    align-items: center;
+ background: var(--lwc-colorBackground,rgb(243, 242, 242));
+ cursor: pointer;
+    width: 100%;
+    height: 2rem;
+    text-align: left;
+    color: currentColor;
+    font-size: inherit;
+    padding: 0 var(--lwc-spacingXSmall,0.5rem);
+}
\ No newline at end of file
diff --git a/force-app/main/default/aura/NewAgencyContact/NewAgencyContactController.js b/force-app/main/default/aura/NewAgencyContact/NewAgencyContactController.js
new file mode 100644
index 0000000..8069347
--- /dev/null
+++ b/force-app/main/default/aura/NewAgencyContact/NewAgencyContactController.js
@@ -0,0 +1,217 @@
+({
+	doInit : function(component, event, helper) {
+        let rid = component.get('v.recordId');
+        let pid = null;
+        if(!rid){
+            pid = window.location.href.replace("https://","").split("/")[4];
+        }
+        
+        component.set("v.showSpinner", true);
+        helper.CallBackAction(component,'Init',{
+            rid : rid,
+            pid : pid,
+            //rid : component.get('v.recordId'),
+            record_type_id : component.get("v.pageReference").state.recordTypeId,
+        },function(data){
+            component.set("v.showSpinner", false);
+            
+            
+            if(data.getState() == "SUCCESS"){
+                var rv = data.getReturnValue();
+            	console.log(rv);
+                if(rv.IsSuccess){
+					let layout = JSON.parse(rv.Data.layout);
+                    let fields = rv.Data.fields;
+                    let staticResource = JSON.parse(rv.Data.staticResource)
+                    let section_names = [];
+                    section_names = layout.map(s=>s.label);
+                    component.set('v.section_names',section_names);
+
+                    let m = {};
+                    for(let f of staticResource.PIDetails){
+                        m[f.SF_Field_API_Name__c] = f;
+                    }
+                    component.set('v.pi_fields_map',m);
+
+                    
+
+                    if(rv.Data && rv.Data.data && rv.Data.data.AWS_Data_Id__c){
+                        helper.AwsGet(staticResource.queryUrl, {
+                            dataId : rv.Data.data.AWS_Data_Id__c
+                        }, function(data){
+                            console.log('data = ' + data);
+                            
+                            for(let f of staticResource.PIDetails){
+                                
+                                if(data.object && data.object.hasOwnProperty(f.AWS_Field_API__c)){
+                                    rv.Data.data[f.SF_Field_API_Name__c] = data.object[f.AWS_Field_API__c];
+                                    if(data.object.hasOwnProperty(f.AWS_Encrypted_Field_API__c) && data.object[f.AWS_Encrypted_Field_API__c]){
+                                        rv.Data.data[f.SF_Field_Encrypted_API__c] = data.object[f.AWS_Encrypted_Field_API__c];
+                                    }
+                                }
+                            }
+                            
+                            for(let s of layout){
+                                for(let c of s.layoutColumns){
+                                    for(let item of c.layoutItems){
+                                        if(rv.Data.data.hasOwnProperty(item.field)){
+                                            item.value = rv.Data.data[item.field];
+                                        }
+                                        
+                                        if(fields.hasOwnProperty(item.field)){
+                                            item.fi = fields[item.field];
+                                        }
+                                    }
+                                }
+                            }
+
+                    		component.set('v.record_data',rv.Data.data);
+                            component.set('v.layout',layout);
+                        }, staticResource.token);
+                    }else{
+                        
+                        for(let s of layout){
+                            for(let c of s.layoutColumns){
+                                for(let item of c.layoutItems){
+                                    if(rv.Data && fields.hasOwnProperty(item.field) && fields[item.field].References && fields[item.field].References.map(m=>m.value).indexOf(rv.Data.pidType) > -1){
+                                        item.value = pid;
+                                    }
+                                }
+                            }
+                        }
+                        component.set('v.layout',layout);
+                    }
+                    
+                    
+                    component.set('v.fields',fields);
+                    component.set('v.staticResource',staticResource);
+                }else{
+                    helper.ShowToast({
+                        "message" : rv.Message,
+                        "type" : "error"
+                    });
+                }
+                
+            }else{
+                
+                helper.ShowToast({
+                    "message" : "Init error",
+                    "type" : "error"
+                });
+                
+            }
+        });
+	},
+    saveClick : function(component, event, helper){
+        
+        let staticResource = component.get('v.staticResource');
+        let record_id = component.get('v.recordId');
+        let url = staticResource.newUrl;
+        let payloadPi = {};
+        if (record_id) {
+            url = staticResource.updateUrl
+            payloadPi['dataId'] = component.get('v.record_data').AWS_Data_Id__c;
+        }
+        let layout = component.get('v.layout');
+        
+        let pi_fields_map = component.get('v.pi_fields_map');
+        
+        for(let s of layout){
+            for(let c of s.layoutColumns){                
+                for(let item of c.layoutItems){
+                    if(pi_fields_map.hasOwnProperty(item.field)){
+                        
+                        payloadPi[pi_fields_map[item.field].AWS_Field_API__c] = item.value;
+                    }
+                }
+            }
+        }
+        
+        component.set("v.showSpinner", true);
+        helper.AwsPost(url, [payloadPi], function(result){
+            
+            let obj = result.object[0];
+            let data = {};
+            if(record_id){
+                data.Id = record_id;
+            }else{
+                data.AWS_Data_Id__c = obj.dataId;
+            }
+            for(let s of layout){
+                for(let c of s.layoutColumns){                
+                    for(let item of c.layoutItems){
+                        if(item.field && item.behavior != "Readonly"){
+                            if(pi_fields_map.hasOwnProperty(item.field)){
+                                data[item.field] = obj[pi_fields_map[item.field].AWS_Field_API__c];
+                                data[pi_fields_map[item.field].SF_Field_Encrypted_API__c] = obj[pi_fields_map[item.field].AWS_Encrypted_Field_API__c];
+                            }else{
+                                data[item.field] = item.value;
+                            }
+                        }
+                        
+                    }
+                }
+            }
+            
+            
+            $A.getCallback(function(){
+                helper.CallBackAction(component,'Save',{
+                    data : data,
+                    transId : result.txId
+                },function(data){
+                    component.set("v.showSpinner", false);
+                    if(data.getState() == "SUCCESS"){
+                        var rv = data.getReturnValue();
+                        console.log(rv);
+                        var sfId = rv.Data.recordId;
+                        
+                        helper.AwsPost(staticResource.transactionUrl,{
+                            txId: result.txId,
+                            sfRecordId:sfId,
+                            isSuccess: rv.IsSuccess ? 1 : 0
+                        },function(data){
+                            if(rv.IsSuccess){
+                                helper.ShowToast({
+                                    "message" : "鎴愬姛",
+                                    "type" : "success"
+                                });
+                                
+                                if (record_id){
+                                    
+                                    $A.get("e.force:closeQuickAction").fire();
+                                    $A.get('e.force:refreshView').fire();
+                                }else{
+                                    var sObjectEvent = $A.get("e.force:navigateToSObject");
+                                    sObjectEvent.setParams({
+                                        "recordId": sfId
+                                    })
+                                    sObjectEvent.fire();
+                                }
+                            }else{
+                                helper.ShowToast({
+                                    "message" : rv.Message,
+                                    "type" : "error"
+                                });
+                            }
+                        },staticResource.token);
+                        
+                        
+                    }else{
+                        
+                        helper.ShowToast({
+                            "message" : "Init error",
+                            "type" : "error"
+                        });
+                        
+                    }
+                });
+            })();
+            
+        }, staticResource.token);
+    },
+    cancelClick : function(component, event, helper){
+        $A.get("e.force:closeQuickAction").fire();
+    },
+    
+    scriptsLoaded : function(component, event, helper){}
+})
\ No newline at end of file
diff --git a/force-app/main/default/aura/NewAgencyContact/NewAgencyContactHelper.js b/force-app/main/default/aura/NewAgencyContact/NewAgencyContactHelper.js
new file mode 100644
index 0000000..e3d4714
--- /dev/null
+++ b/force-app/main/default/aura/NewAgencyContact/NewAgencyContactHelper.js
@@ -0,0 +1,77 @@
+({
+	CallBackAction  : function(component,action_name,para,callback) {
+		var action = component.get("c." + action_name.trimStart().replace("c.",""));
+        if(para){
+            action.setParams(para);
+        }
+        if(callback){
+            action.setCallback(this,function(data){
+                callback(data);
+            });
+        }
+        
+        $A.enqueueAction(action);
+	},
+    ShowToast : function(paras){
+        var toastEvent = $A.get("e.force:showToast");
+        toastEvent.setParams(paras);
+        toastEvent.fire();
+    },
+    AwsPost : function(postURL, data ,callback,token){
+        let payloadForNewPI = '';
+        if(typeof(data) == 'string'){
+            payloadForNewPI = data;
+        }else{
+            payloadForNewPI = JSON.stringify(data);
+        }
+        
+        fetch(postURL, {
+            method: 'POST',
+            body: payloadForNewPI,
+            headers: {
+                'Content-Type': 'application/json',
+                'pi-token': token
+            }
+        }).then((data) => {
+            console.log('data=' + JSON.stringify(data));
+            return data.json();
+        }).then((result) => {
+            //this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(result),this.successStatus);
+            if(callback) callback(result);
+        }).catch(error => {
+            console.log('error');
+            //this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(error),this.failStatus);
+            console.log(error);
+        });
+    },
+    AwsGet : function(url, data ,callback,token){
+        
+        if(typeof(data) == 'string'){
+            url += data;
+        }else{
+            let i = 0;
+            for(let p in data){
+                url += (i++) ? '&' : '?';
+                url += p + '=' + data[p];
+            }
+        }
+        
+        fetch(url, {
+            method: 'GET',
+            headers: {
+                'Content-Type': 'application/json',
+                'pi-token': token
+            }
+        }).then((data) => {
+            console.log('data=' + JSON.stringify(data));
+            return data.json();
+        }).then((result) => {
+            //this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(result),this.successStatus);
+            if(callback) callback(result);
+        }).catch(error => {
+            console.log('error');
+            //this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(error),this.failStatus);
+            console.log(error);
+        });
+    }
+})
\ No newline at end of file
diff --git a/force-app/main/default/classes/B_Test.cls b/force-app/main/default/classes/B_Test.cls
new file mode 100644
index 0000000..976c009
--- /dev/null
+++ b/force-app/main/default/classes/B_Test.cls
@@ -0,0 +1,161 @@
+public without sharing class B_Test {
+    public Contact newCon { get; set; }
+    public Contact searchCon { get; set; }
+    public List<LineInfo> lineInfoList { get; set; }
+    public String conId { get; set; }
+
+    public String openLine { get; set; }
+    private String accountId;
+    // SWAG-BB44G7  鎵�鍦ㄥ尰闄d start
+    private String HPId;
+    private Integer i = 0;
+    // SWAG-BB44G7  鎵�鍦ㄥ尰闄d end
+    private String nowValue;
+
+
+
+
+
+
+    public final string ApiPrefix{get;private set;} 
+    public String staticResource {get; set;}
+
+
+
+
+
+    public B_Test() {
+        openLine = Apexpages.currentPage().getParameters().get('line');
+        accountId = Apexpages.currentPage().getParameters().get('acc');
+        // SWAG-BB44G7  妫�绱㈡墍鍦ㄥ尰闄d start
+        
+        Account temAccount =
+            [select id, Parent.parentid from account where id = : accountId];
+        if (temAccount.Parent.parentid != null) {
+            HPId = temAccount.Parent.parentid;
+            i = 1;
+        }else{
+            HPId = accountId;
+            i = 2;
+        }
+        // SWAG-BB44G7  妫�绱㈡墍鍦ㄥ尰闄d end
+        nowValue = Apexpages.currentPage().getParameters().get('now');
+        
+        lineInfoList = new List<LineInfo>(); 
+
+        ApiPrefix = 'PIBackApi';
+        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Contact');
+        staticResource = JSON.serialize(piIntegration);
+        System.debug('B_Test');
+    }
+
+    public void init() {
+        searchCon = new Contact();
+        if (nowValue != null && nowValue != '') {
+            searchCon = [select Id, Name, Department__c, Type__c, Search_LastName__c, Search_FirstName__c, Phone, Supplement__c,
+                         FirstName, LastName
+                         from Contact where Id = :nowValue];
+            searchCon.Search_LastName__c = searchCon.LastName;
+            searchCon.Search_FirstName__c = searchCon.FirstName;
+        }
+
+        searchContact();
+
+        newCon = new Contact();
+        newCon.AccountId = accountId;
+
+        return;
+    }
+
+
+    public PageReference searchContact() {
+        String searchStr = 'select Id, Name, Department__c, Type__c, AccountName__c, Supplement__c, Phone,accountid ';
+        searchStr += '        from Contact ';
+        searchStr += '       where Isactive__c = \'鏈夋晥\' ';
+        // SWAG-BB44G7  妫�绱㈡墍鍦ㄥ尰闄㈢殑瀹㈡埛浜哄憳 start
+        if(i == 1 ){
+            searchStr += '         and Account.parent.parentid = :HPId ';
+        }
+        if(i == 2){
+            searchStr += '         and AccountId = :HPId ';
+        }
+        // searchStr += '         and Account.parent.parentid = :HPId ';
+        // SWAG-BB44G7  妫�绱㈡墍鍦ㄥ尰闄㈢殑瀹㈡埛浜哄憳 end
+        if (searchCon.Search_LastName__c != null && searchCon.Search_LastName__c != '') {
+            searchStr += '     and LastName like \'%' + searchCon.Search_LastName__c + '%\'';
+        }
+        if (searchCon.Search_FirstName__c != null && searchCon.Search_FirstName__c != '') {
+            searchStr += '     and FirstName like \'%' + searchCon.Search_FirstName__c + '%\'';
+        }
+        system.debug('=====searchStr:' + searchStr);
+
+        List<Contact> searchResult = Database.query(searchStr);
+
+        lineInfoList = new List<LineInfo>();
+        Integer line = 0;
+        for (Contact con : searchResult) {
+            line += 1;
+            LineInfo li = new LineInfo(line, con);
+            lineInfoList.add(li);
+        }
+
+        editClear();
+
+        return null;
+    }
+
+    public PageReference editContact() {
+        if (conId != null && conId != '') {
+            newCon = [select Id, Name, Department__c, Type__c, Search_LastName__c, Search_FirstName__c, Phone, Supplement__c,LastName_Encrypted__c,Phone_Encrypted__c,
+                      FirstName, LastName,AWS_Data_Id__c
+                      from Contact where Id = :conId];
+        }
+        System.debug(newCon);
+        System.debug('editContact');
+        return null;
+    }
+
+    public PageReference saveNew()  {
+        if (newCon.Search_LastName__c == null || newCon.Search_LastName__c == '') {
+            newCon.Search_LastName__c.addError('蹇呴』濉啓銆�');
+            return null;
+        }
+        newCon.LastName = newCon.Search_LastName__c;
+        newCon.FirstName = newCon.Search_FirstName__c;
+        upsert newCon;
+
+        searchCon.Search_LastName__c = newCon.LastName;
+        searchCon.Search_FirstName__c = newCon.FirstName;
+        searchContact();
+
+        return null;
+    }
+
+    public PageReference editClear()  {
+        newCon = new Contact();
+        newCon.AccountId = accountId;
+
+        return null;
+    }
+
+    class LineInfo {
+        public Integer lineNo { get; set; }
+        public Contact con { get; set; }
+
+        public LineInfo(Integer in_line) {
+            lineNo = in_line;
+            con = new Contact();
+        }
+
+        public LineInfo(Integer in_line, Contact in_con) {
+            lineNo = in_line;
+            con = in_con;
+        }
+    }
+
+    // @RemoteAction
+    // global static Response saveContact(String leadJson,String transId) {
+        
+    //     return NewAndEditBaseController.save(new Contact(),leadJson,transId,isNew);
+    // }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/B_Test.cls-meta.xml b/force-app/main/default/classes/B_Test.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/B_Test.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/ControllerResponse.cls b/force-app/main/default/classes/ControllerResponse.cls
new file mode 100644
index 0000000..3fec3a3
--- /dev/null
+++ b/force-app/main/default/classes/ControllerResponse.cls
@@ -0,0 +1,16 @@
+public class ControllerResponse {
+	
+    @AuraEnabled
+    public boolean IsSuccess{get;set;}
+    
+    @AuraEnabled
+    public string Message{get;set;}
+    
+    @AuraEnabled
+    public object Data{get;set;}
+    
+    public ControllerResponse(){
+        IsSuccess = false;
+        Message = '';
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/ControllerResponse.cls-meta.xml b/force-app/main/default/classes/ControllerResponse.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/ControllerResponse.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/DeleteBatch.cls b/force-app/main/default/classes/DeleteBatch.cls
new file mode 100644
index 0000000..01798aa
--- /dev/null
+++ b/force-app/main/default/classes/DeleteBatch.cls
@@ -0,0 +1,20 @@
+global class DeleteBatch implements Database.Batchable<sObject>{
+    global String queryString;
+    global DeleteBatch(String queryString){
+        this.queryString = queryString;
+    }
+    global Database.QueryLocator start(Database.BatchableContext bc) {
+       
+        return Database.getQueryLocator(this.queryString);
+    }
+    global void execute(Database.BatchableContext BC, List<sObject> scope) {
+        try{
+            delete scope;
+        }Catch(Exception e){
+            system.debug('ERROR:' + e.getMessage());
+        }
+    }
+    global void finish(Database.BatchableContext BC) {
+    }
+
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/DeleteBatch.cls-meta.xml b/force-app/main/default/classes/DeleteBatch.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/DeleteBatch.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/DeveloperUtility.cls b/force-app/main/default/classes/DeveloperUtility.cls
new file mode 100644
index 0000000..f8f0662
--- /dev/null
+++ b/force-app/main/default/classes/DeveloperUtility.cls
@@ -0,0 +1,62 @@
+public class DeveloperUtility {
+	
+    public static List<HTTPResponse> CreateFields(string sobject_name,string [] fields){
+        List<HTTPResponse> results = new List<HTTPResponse>();
+        for(string f : fields){
+            string old_label = f.removeEnd('__c').replace('_',' ');
+            string label = old_label + ' Encrypted';
+            string name =  label.replace(' ','_')+'__c';
+            string description = '';
+            system.debug('old_label='+old_label);
+            system.debug('label='+label);
+            system.debug('name='+name);
+            results.add(CreateField(sobject_name,label,name,description,'Text'));
+        }
+        return results;
+    }
+    
+    
+    public static HTTPResponse CreateField(string sobject_name, string label,string name,string description,string type){
+        HTTP h = new HTTP();
+        HTTPRequest req = new HTTPRequest();
+        req.setMethod('POST');
+        req.setHeader('Content-Type', 'text/xml');
+        req.setHeader('SOAPAction', 'create');
+        
+        
+        //string sobject_name = 'Contact';
+        //string label = 'Title';
+        //string name =  'Title'+'_Encrypted__c';
+        //string description = '';
+        
+        //string type = 'Text';
+        boolean typeSpecified = true;
+        
+        String b = '<?xml version="1.0" encoding="UTF-8"?>';
+        b += '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">';
+        b += '<soapenv:Header>';
+        b += '<ns1:SessionHeader soapenv:mustUnderstand="0" xmlns:ns1="http://soap.sforce.com/2006/04/metadata">';
+        b += '<ns1:sessionId>' + UserInfo.getSessionId() + '</ns1:sessionId>';
+        b += '</ns1:SessionHeader>';
+        b += '</soapenv:Header>';
+        b += '<soapenv:Body>';
+        b += '<create xmlns="http://soap.sforce.com/2006/04/metadata">';
+        b += '<metadata xsi:type="ns2:CustomField" xmlns:ns2="http://soap.sforce.com/2006/04/metadata">';
+        b += '<type>'+type+'</type>';
+        b += '<fullName>'+sobject_name+'.'+name+'</fullName>';
+        b += '<label>'+label+'</label>';
+        b += '<length>255</length>';
+        b += '<description>'+type+'</description>';
+        b += '</metadata>';
+        b += '</create>';
+        b += '</soapenv:Body>';
+        b += '</soapenv:Envelope>';
+        
+        req.setBody(b);
+        req.setCompressed(false);
+        req.setEndpoint('https://ocsm--pipl.my.salesforce.com/services/Soap/m/25.0');
+        HTTPResponse resp = h.send(req);
+        System.debug(resp.getBody());
+        return resp;
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/DeveloperUtility.cls-meta.xml b/force-app/main/default/classes/DeveloperUtility.cls-meta.xml
new file mode 100644
index 0000000..f928c8e
--- /dev/null
+++ b/force-app/main/default/classes/DeveloperUtility.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/FieldInfo.cls b/force-app/main/default/classes/FieldInfo.cls
new file mode 100644
index 0000000..0046cc0
--- /dev/null
+++ b/force-app/main/default/classes/FieldInfo.cls
@@ -0,0 +1,44 @@
+public class FieldInfo
+{
+    @AuraEnabled public string TypeEnumName{get;set;}
+    @AuraEnabled public string Label{get;set;}
+    @AuraEnabled public string Name{get;set;}
+    @AuraEnabled public object Value{get;set;}
+    //@AuraEnabled public schema.DisplayType DisplayType{get;set;}
+    @AuraEnabled public List<Option> Options{get;set;}
+	@AuraEnabled public boolean IsRequired{get;set;}
+    @AuraEnabled public List<Option> References{get;set;}
+    
+    public Option GetFirstItemByLabel(string label){
+        if(Options == null)return null;
+        for(Option lv : Options){
+            if(lv!=null&&lv.value == label)return lv;
+        }
+        return null;
+    }
+    
+    public Option GetFirstItemByValue(string val){
+        if(Options == null)return null;
+        for(Option lv : Options){
+            if(lv!=null&&lv.value == val)return lv;
+        }
+        return null;
+    }
+    
+   public static void CopyTo(FieldInfo source,FieldInfo target)
+   {
+       if(source == null || target == null )
+       {
+           return;
+       }
+       
+       target.TypeEnumName = source.TypeEnumName;
+       target.Label = source.Label;
+       target.Name = source.Name;
+       target.IsRequired = source.IsRequired;
+       target.Options = source.Options;
+       target.Value = source.Value;
+   }
+    
+    
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/FieldInfo.cls-meta.xml b/force-app/main/default/classes/FieldInfo.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/FieldInfo.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/FileUploadController.cls b/force-app/main/default/classes/FileUploadController.cls
new file mode 100644
index 0000000..c1fd78e
--- /dev/null
+++ b/force-app/main/default/classes/FileUploadController.cls
@@ -0,0 +1,68 @@
+global without sharing class FileUploadController {
+    public String staticResource {get; set;}
+    public static String sobjectTypeValue = 'Document';
+    public String PIPL_Input_PDF_Error_Msg{set;get;}
+    public List<FileAddress__c>  fileList{set;get;}
+    public Document documentData{set;get;}
+    public String parentId{set;get;}
+    public FileUploadController(ApexPages.StandardController controller) {
+        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Document'));
+        SObject obj = controller.getRecord();     
+        parentId = obj.Id;
+        system.debug('Parent Id:'+parentId); 
+        fileList=getFileds(parentId);
+    }
+
+    global class Response{
+        public String recordId{set;get;}
+        public String message{set;get;}
+        public String status{set;get;}
+    }
+
+    @RemoteAction
+    global static Response saveFile(String fileName,String key,String transId,String parentId){
+        FileAddress__c file = new FileAddress__c();
+        PIHelper.PIIntegration pI=PIHelper.getPIIntegrationInfo('Document');
+        file.DownloadLink__c =pI.undeleteUrl+key+'&fileName='+fileName;
+        file.DownloadLink2__c =pI.undeleteUrl+key+'&fileName='+fileName;
+        file.FileName__c =fileName;
+        file.ViewLink__c =pI.queryUrl+key;
+        file.ParentRecordId__c =parentId;
+        file.AWS_File_Key__c = key;
+        Response response =new Response();
+        Savepoint sp = Database.setSavepoint();
+        try {
+            insert file;
+            //4. 鎻掑叆鏃ュ織 
+            //update 20220218 鍔犲叆鏂扮殑鏃ュ織鏂瑰紡
+            PIHelper.saveTransLog(sobjectTypeValue,key,transId,file.Id,JSON.serialize(file),'success','');
+            response.recordId=file.Id;
+            response.status='success';
+            return response;
+        } catch (Exception e) {
+            System.debug('into catch'+e.getMessage());
+            PIHelper.saveTransLog(sobjectTypeValue,key,transId,file.Id,JSON.serialize(file),'fail',e.getMessage());
+            Database.rollback(sp);
+            response.message=e.getMessage();
+            response.status='fail';
+            return response;
+        }
+        
+       
+    }
+
+    public PageReference refreshFiles() {
+        system.debug('refresh files');
+        fileList=getFileds(parentId);
+        system.debug('fileList size:'+String.valueOf(fileList.size()));
+        system.debug(JSON.serialize(fileList));
+        return null;
+    }
+    
+    public static List<FileAddress__c> getFileds(String parentId){
+        if(String.isNotBlank(parentId)){
+            return [SELECT Id,ParentRecordId__c, FileName__c,DownloadLink__c,DownloadLink2__c,FileAddress__c.ViewLink__c FROM FileAddress__c where ParentRecordId__c=:parentId order by createddate desc];
+        }
+        return [SELECT Id, ParentRecordId__c,FileName__c,DownloadLink__c,DownloadLink2__c,FileAddress__c.ViewLink__c FROM FileAddress__c order by createddate desc limit 100];
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/FileUploadController.cls-meta.xml b/force-app/main/default/classes/FileUploadController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/FileUploadController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/MetaDataUtility.cls b/force-app/main/default/classes/MetaDataUtility.cls
new file mode 100644
index 0000000..e7d6eb2
--- /dev/null
+++ b/force-app/main/default/classes/MetaDataUtility.cls
@@ -0,0 +1,177 @@
+public without sharing class MetaDataUtility {
+
+    public static List<Metadata.LayoutSection> GetRecordTypePageLayout(string record_type_id,string objectType){
+        
+        Map<string,object> mso = null;
+        string layout_name = GetRecordTypePageLayoutName(record_type_id,objectType,UserInfo.getProfileId());
+        
+        List<Metadata.LayoutSection>  temp =  GetLayoutSections(objectType,layout_name);
+        List<Metadata.LayoutSection>  layoutSectionList = new List<Metadata.LayoutSection>();
+        for(Metadata.LayoutSection section : temp){
+            boolean a = false;
+            for( Metadata.LayoutColumn c: section.layoutColumns){
+                //system.debug(c);
+                if(c.layoutItems != null && c.layoutItems.size() > 0 ){
+                    a = true;
+                }
+                
+            }
+            if(a){
+				layoutSectionList.add(section);             
+            }
+        }
+        return layoutSectionList;
+    }
+    
+    /*[{
+            "attributes": {
+                "type": "Layout",
+                "url": "/services/data/v53.0/tooling/sobjects/Layout/00h10000009iAb5AAE"
+            },
+            "Id": "00h10000009iAb5AAE",
+            "Name": ".瀹㈡埛浜哄憳銉偆銈€偊銉�",
+            "TableEnumOrId": "01I10000000er3hEAA",
+            "LayoutType": "Standard"
+        }]
+     */ 
+    
+    public static string GetTableOrEnumId(string objectType){
+        
+        Map<string,object> mso = null;
+        string resp = null;
+        string table_or_enum_id = objectType;
+        if(objectType.endsWith('__c')){
+            resp = ToolingQuery('SELECT id,DeveloperName from CustomObject where DeveloperName =\''+objectType.replace('__c', '')+'\'');
+            if(resp == null){
+                system.debug('resp is not ok');
+                return null;
+            }else{
+                mso = (Map<string,object>)Json.deserializeUntyped(resp);
+                if(integer.valueOf(mso.get('size')) > 0){
+                    table_or_enum_id =  string.valueOf(((Map<string,object>)(((List<object>)mso.get('records'))[0])).get('Id')); 
+                }else{
+                    system.debug('no records');
+                	return null;
+                }
+            }
+        }
+        
+        return table_or_enum_id;
+    }
+    
+    public static List<object> GetAllPageLayout(string objectType){
+        string resp = null;
+        Map<string,object> mso = null;
+        
+        
+        string table_or_enum_id =  GetTableOrEnumId(objectType);
+        
+        if(string.isBlank(table_or_enum_id)){
+            return new List<object>();
+        }
+        
+        resp = ToolingQuery('SELECT id,name,TableEnumOrId,LayoutType  FROM Layout where TableEnumOrId = \''+table_or_enum_id+'\'');
+        if(resp == null){
+            system.debug('Layout where TableEnumOrId='+table_or_enum_id+' is null');
+            return null;
+        }else{
+            mso = (Map<string,object>)Json.deserializeUntyped(resp);
+            if(integer.valueOf(mso.get('size')) > 0){
+                return (List<object>)mso.get('records');
+            }else{
+                system.debug('no records');
+                return new List<object>();
+            }
+        }
+    }
+    
+    
+    public static string GetRecordTypePageLayoutName(string record_type_id,string objectType, string profile_id){
+		
+        if(!string.isBlank(objectType)){
+            List<sobject> lso = [SELECT Id, Name, DeveloperName, SobjectType, IsActive, Description, BusinessProcessId FROM RecordType where SobjectType = :objectType];
+            if(lso.size()==0){
+                return string.valueOf(((Map<string,object>)(GetAllPageLayout(objectType)[0])).get('Name'));
+            }
+        }
+        
+        // 01210000000QfWdAAK
+        string query = 'SELECT Layout.Name, Layout.TableEnumOrId, ProfileId, Profile.Name, RecordTypeId FROM ProfileLayout where id!=null ';
+        if(!string.isBlank(record_type_id)){
+            query += ' and RecordTypeId = \''+record_type_id+'\'';
+        }
+        
+        if(!string.isBlank(objectType)){
+            query += ' and TableEnumOrId = \''+ GetTableOrEnumId(objectType) +'\'';
+        }
+        
+        if(!string.isBlank(profile_id)){
+            query += ' and ProfileId = \''+profile_id+'\'';
+        }
+        query += ' order by LastModifiedDate desc ';
+        system.debug('query='+query);
+        string s = ToolingQuery(query);
+        if(string.isBlank(s)){
+            system.debug('s is blank');
+            return null;
+        }else{
+            Map<string,object> mso = (Map<string,object>)JSON.deserializeUntyped(s);
+        
+            if(integer.valueOf(mso.get('size')) > 0){
+                List<object> records = ((List<object>)mso.get('records'));
+            
+                mso = (Map<string,object>)(records[0]);
+                return string.valueOf(((Map<string,object>)(mso.get('Layout'))).get('Name'));
+            }else{
+                return null;
+            }
+        }
+        
+        
+        
+    }
+    
+    public static string ToolingQuery(string query){
+        
+        system.debug('query='+query);
+        String baseURL = 'callout:SF_Rest_API/services/data/v41.0/tooling/query?q='+ query.replace(' ', '+');
+        HttpResponse resp = null;
+        HttpRequest req = new HttpRequest();         
+        req.setMethod('GET');
+        
+        //req.setHeader('Authorization', 'Bearer ' + UserInfo.getsessionid()); 
+        //req.setEndpoint(baseURL); 
+        req.setEndpoint(baseURL); 
+        
+        Http client = new Http();    
+        resp = client.send(req);
+        
+        system.debug(resp.getStatus());
+        system.debug(resp.getStatusCode());
+        if(resp.getStatus() == 'OK'){
+            string s = resp.getBody();
+            system.debug(resp.getBody());
+        	return s;
+        }else{
+            system.debug('status is not ok,error:'+resp.getBody());
+            return null;
+        }
+        
+    }
+    
+    public static List<Metadata.LayoutSection> GetLayoutSections(string object_name, string layout_name){
+        List<String> componentNameList = new List<String>{object_name+'-'+layout_name};
+        //閫氳繃Metadata.Operations.retrieve鑾峰彇metadata
+        //Metadata.Layout -> Metadata.LayoutSection -> Metadata.LayoutColumn objects -> Metadata.LayoutItem objects
+        List<Metadata.Metadata> componentList = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, componentNameList);
+        if(componentList?.size() > 0){
+            Metadata.Layout layout = (Metadata.Layout) componentList.get(0);
+            List<Metadata.LayoutSection> layoutSectionList = layout.layoutSections;
+            return layoutSectionList;
+        }
+        else{
+            return null;
+        }
+        
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/MetaDataUtility.cls-meta.xml b/force-app/main/default/classes/MetaDataUtility.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/MetaDataUtility.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NFM702ControllerHandler.cls b/force-app/main/default/classes/NFM702ControllerHandler.cls
new file mode 100644
index 0000000..f366511
--- /dev/null
+++ b/force-app/main/default/classes/NFM702ControllerHandler.cls
@@ -0,0 +1,5 @@
+public with sharing class NFM702ControllerHandler {
+    public NFM702ControllerHandler() {
+        
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NFM702ControllerHandler.cls-meta.xml b/force-app/main/default/classes/NFM702ControllerHandler.cls-meta.xml
new file mode 100644
index 0000000..f3bac1f
--- /dev/null
+++ b/force-app/main/default/classes/NFM702ControllerHandler.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>41.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAgencyContactController.cls b/force-app/main/default/classes/NewAgencyContactController.cls
new file mode 100644
index 0000000..ac558ca
--- /dev/null
+++ b/force-app/main/default/classes/NewAgencyContactController.cls
@@ -0,0 +1,124 @@
+public class NewAgencyContactController {
+
+    static string sobjectType = 'Agency_Contact__c';
+    
+    @AuraEnabled
+    public static ControllerResponse Init(string rid,Id pid, string record_type_id){
+        system.debug('rid='+rid+',length='+(rid==null?'null':rid.length()+''));
+        system.debug('record_type_id='+record_type_id+',length='+(record_type_id==null?'null':record_type_id.length()+''));
+        
+        
+        ControllerResponse res = new ControllerResponse();
+        Map<string,object> data = new Map<string,object>();
+        res.Data = data;
+        
+        Agency_Contact__c ac = null;
+        List<Metadata.LayoutSection> layout = null;
+        if(string.isBlank(rid)){
+            
+            layout = MetaDataUtility.GetRecordTypePageLayout(record_type_id, sobjectType);
+            data.put('layout', Json.serialize(layout));
+            
+        }else{
+            ac = [select RecordTypeId from Agency_Contact__c where id = :rid];
+            if(ac == null){
+                res.Message = 'id涓嶅瓨鍦�';
+            	return res;
+            }
+            record_type_id = ac.RecordTypeId;
+            system.debug('record_type_id is fresh ='+ac.RecordTypeId);
+            
+            layout = MetaDataUtility.GetRecordTypePageLayout(record_type_id, sobjectType);
+            data.put('layout', Json.serialize(layout));
+            
+            List<String> fieldApiList = new List<String>(); 
+            /*
+            for (LayoutDescriberHelper.LayoutSection ls : layout.layoutSections) {
+                for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
+                    if (lf.fieldAPI != '') {
+                        System.debug('lf.fieldAPI='+lf.fieldAPI+' fieldType='+lf.fieldType);
+                        fieldApiList.add(lf.fieldAPI);
+                    }
+                }
+            }
+			*/
+            for( Metadata.LayoutSection s: layout){
+               system.debug(s);
+                for( Metadata.LayoutColumn c: s.layoutColumns){
+                   system.debug(c);
+                    if(c.layoutItems != null){
+                        for( Metadata.layoutItem item: c.layoutItems){
+                           system.debug(item);
+                            fieldApiList.add(item.field);
+                        }
+                    }
+                    
+                }
+            }
+            
+            system.debug(fieldApiList);
+            ac = database.query(SoqlHelper.DistinctQueryFields('select id, AWS_Data_Id__c , ' + string.join(fieldApiList, ',') + ' from ' + sobjectType + ' where id = :rid'));
+            
+            data.put('data', ac);
+        }
+        if(!string.isBlank(pid)){
+            data.put('pidType',pid.getSObjectType().getDescribe().getName());
+        }
+        data.put('fields', SObjectHelper.GetFieldInfos(sobjectType));
+        data.put('staticResource', Json.serialize(PIHelper.getPIIntegrationInfo(sobjectType)));
+        res.IsSuccess = true;
+        return res;
+    }
+    
+    @AuraEnabled
+    public static ControllerResponse Save(Map<string,object> data,string transId){
+        system.debug('data='+data);
+        system.debug(!data.containsKey('Id') );
+        system.debug( data.get('Id') == null);
+        //NewAndEditBaseController.Response response = NewAndEditBaseController.save(new Agency_Contact__c(),Json.serialize(data),transId, !data.containsKey('Id') || data.get('Id') == null );
+        //ControllerResponse r = new ControllerResponse();
+        
+        Sobject sobj = new Agency_Contact__c();
+        ControllerResponse r = SaveCore(sobj, data, transId);
+        if (r.IsSuccess) {
+            r.Data = new Map<string,object>{
+                'recordId'=> sobj.Id
+            };
+        }
+        return r;
+    }
+    
+
+    public static ControllerResponse SaveCore(Sobject sobj, Map<string,object> data,string transId ) {
+        string sobjectTypeValue = sobj.getSObjectType().getDescribe().getName();
+        System.debug('sobjectTypeValue:'+sobjectTypeValue+' Info:' + JSON.serialize(data));
+        
+        //1. Prepare the payload for  Lead
+        Map<String, Schema.SObjectField> fieldAPIToTypeMap = SobjectHelper.GetFieldMap(sobjectTypeValue);
+        ControllerResponse r = new ControllerResponse();
+        
+        //2. Save Record Process
+        String awsDataId = string.valueOf(data.get('AWS_Data_Id__c'));
+        Savepoint sp = Database.setSavepoint();
+        try{
+            for(string field : fieldAPIToTypeMap.keySet()){
+                if(data.containsKey(field)){
+                    sobj.put(field, data.get(field));
+                }
+            }
+            upsert sobj;
+            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,sobj.Id,transId, Json.serialize(data) ,'success','');
+            //System.debug('respzhj = ' + resp);
+            r.IsSuccess = true;
+            return r;
+
+        } catch(Exception e) {
+            System.debug('into catch'+e.getMessage());
+            Database.rollback(sp);
+            r.IsSuccess = false;
+            r.message = e.getMessage()+e.getStackTraceString();
+            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,sobj.Id,transId, Json.serialize(data) ,'failed',r.message);
+            return r;
+        }
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAgencyContactController.cls-meta.xml b/force-app/main/default/classes/NewAgencyContactController.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/NewAgencyContactController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditASEActivityController.cls b/force-app/main/default/classes/NewAndEditASEActivityController.cls
new file mode 100644
index 0000000..2196438
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditASEActivityController.cls
@@ -0,0 +1,49 @@
+/*
+ * Author: Yanan Chen
+ * Created Date: 02/14/2022
+ * Purpose: Utility class for describe layouts
+ * Test Class: NewAndEditASEActivityController
+ * History: 
+ *      02/14/2022 - Yanan Chen - Initial Code.
+ * 
+ * */
+global class NewAndEditASEActivityController extends NewAndEditBaseController 
+{
+    // public String contactsInfo {set;get;}//key sfid;value awsid
+    public String PIPL_Input_Account_Error_Msg{set;get;}
+    public String contactId{set;get;}//For Lookup field
+    public String contactAWS{set;get;}
+    public String staticResourceContact {get; set;}
+    public NewAndEditASEActivityController(ApexPages.StandardController controller) {
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('ASEActivity__c').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);
+        LookUpOverrideFields.add('ReporterASE__c');
+        Init(controller.getRecord());
+
+        //娣诲姞椤�
+        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
+        SObject obj = controller.getRecord();
+        if(obj.Id == null){
+            //鍒濆鍖栧姞杞藉��
+            obj.put('OwnerId',UserInfo.getUserId());
+        }
+        //鑾峰彇contact 鍔犲瘑ID
+        // contactsInfo = LookUpOverrideFieldsMapJson;
+        //contact淇℃伅锛堟悳绱㈡煡璇uery url鐢級
+        ASEActivity__c aseActivity = [Select Id, ReporterASE__c From ASEActivity__c Where Id = : obj.Id];
+        if(aseActivity.ReporterASE__c != null){
+            Contact contact = [Select Id, AWS_Data_Id__c From Contact Where Id = : aseActivity.ReporterASE__c];
+            System.debug('contact : ' + contact );
+            contactAWS = contact.AWS_Data_Id__c;
+            System.debug('contactAWS : ' + contactAWS );
+        }
+        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
+    }
+
+    
+    @RemoteAction
+    global static Response saveASEActivity(String leadJson,String transId,Boolean isNew) {
+        return save(new ASEActivity__c(),leadJson,transId,isNew);
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditASEActivityController.cls-meta.xml b/force-app/main/default/classes/NewAndEditASEActivityController.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditASEActivityController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditAgencyContactController.cls b/force-app/main/default/classes/NewAndEditAgencyContactController.cls
new file mode 100644
index 0000000..341550c
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditAgencyContactController.cls
@@ -0,0 +1,20 @@
+global without sharing class NewAndEditAgencyContactController extends NewAndEditBaseController 
+{
+	public string staticResourceContact{get;private set;}
+    global NewAndEditAgencyContactController(ApexPages.StandardController controller) {
+        
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Agency_Contact__c').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);
+        LookUpOverrideFields.add('Contact__c');
+        Init(controller.getRecord());
+        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Contact');
+        staticResourceContact = JSON.serialize(piIntegration);
+    }
+
+    
+    @RemoteAction
+    global static Response saveContact(String leadJson,String transId,Boolean isNew) {
+        return save(new Agency_Contact__c(),leadJson,transId,isNew);
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditAgencyContactController.cls-meta.xml b/force-app/main/default/classes/NewAndEditAgencyContactController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditAgencyContactController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditBaseController.cls b/force-app/main/default/classes/NewAndEditBaseController.cls
new file mode 100644
index 0000000..49c45e5
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditBaseController.cls
@@ -0,0 +1,260 @@
+global abstract class NewAndEditBaseController {
+
+    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
+    public String awsToken{set;get;}
+    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
+    public String sobjectTypeValue {private set; get;}
+    public Boolean isNewMode{set;get;}
+    public String rtTypeId {get; set;}
+    public String AWSDataId{set;get;}
+
+    // 褰撳墠瀵硅薄鎵�鏈夌殑鍔犲瘑瀛楁闆嗗悎
+    public List<String> encryptedAPIList{private set;get;}
+
+    // 褰撳墠椤甸潰涓殑鍔犲瘑瀛楁闆嗗悎
+    public List<String> layoutEncryptedAPIList{private set;get;}
+    //fieldLabel fieldAPI
+    public String requiredFieldAPIListStr {get;private set;}
+    public String fieldApiListStr {get;private set;}
+
+
+    public String fieldAPIToLabelMapStr {get;private set;}
+    public String staticResource {get; set;}
+    public string SobjectName{get{return sobjectTypeValue;}}
+    public string SobjectLabel{get;private set;}
+
+    public Map<string,string> AWSToSobjectMap{
+        get{
+            Map<string,string> temp = new Map<string,string>();
+            temp.putAll(AWSToSobjectNonEncryptedMap);
+            temp.putAll(AWSToSobjectEncryptedMap);
+            return temp;
+        }
+    }
+    public string AWSToSobjectMapJson{get{return JSON.serialize(AWSToSobjectMap);}}
+
+    public Map<string,string> AWSToSobjectNonEncryptedMap{get;private set;}
+    public string AWSToSobjectNonEncryptedMapJson{get{return JSON.serialize(AWSToSobjectNonEncryptedMap);}}
+    public string AWSToSobjectNonEncryptedMapKeySet{get{return JSON.serialize(new List<string>(AWSToSobjectNonEncryptedMap.keySet()));}}
+
+    public Map<string,string> AWSToSobjectEncryptedMap{get;private set;}
+    public string AWSToSobjectEncryptedMapJson{get{return JSON.serialize(AWSToSobjectMap);}}
+
+    public final string ApiPrefix{get;private set;} 
+
+    public String sobjectPrefix{get;private set;}
+    public String SaveAndNewButtonUrl{get;private set;}
+    public List<String> VLookUpFields{get;private set;}
+    public String VLookUpFieldsJson{get{return Json.serialize(VLookUpFields);}}
+    public List<String> LookUpOverrideFields{get;private set;}
+    public string LookUpOverrideFieldsMapJson{get;private set;}
+    
+
+    public NewAndEditBaseController(){
+        ApiPrefix = 'PIBackApi';
+        AWSToSobjectNonEncryptedMap = new Map<string,string>();
+        AWSToSobjectEncryptedMap = new Map<string,string>();
+        VLookUpFields = new List<String>();
+        layoutEncryptedAPIList = new List<String>();
+        LookUpOverrideFields = new List<String>();
+    }
+
+    protected virtual void Init(SObject obj){
+        sobjectTypeValue = obj.getSObjectType().getDescribe().getName();
+        SobjectLabel = obj.getSObjectType().getDescribe().getLabel();
+        system.debug('obj='+sobjectTypeValue);
+        
+        isNewMode = true;
+        List<Sobject> lso = Database.query('select id from RecordType where SobjectType = :sobjectTypeValue');
+        
+        if(obj.Id != null){
+            isNewMode = false;
+            string sql = 'select Id';
+            if (lso.size()>0) {
+                sql += ',RecordTypeId';
+            }
+            sql += GenerateReferenceSql()+',AWS_Data_Id__c from '+sobjectTypeValue+' where id =\''+obj.Id+'\' ';
+            System.debug('sql='+sql);
+            Sobject leadData = Database.query(sql);
+            if (lso.size()>0){
+                rtTypeId = (String)leadData.get('RecordTypeId');
+            }
+            
+            AWSDataId = (String)leadData.get('AWS_Data_Id__c');
+
+            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
+            for (string f : LookUpOverrideFields) {
+                object o = leadData.get(f);
+                System.debug('leadData.get('+f+')='+o);
+                if (!String.isBlank(String.valueOf(o))) {
+                    sfIdToAWSIdMap.put(String.valueOf(o).subString(0,15), String.valueOf(leadData.getSobject(GetReferenceField(f)).get('AWS_Data_Id__c')));
+                }
+            }
+           
+            LookUpOverrideFieldsMapJson = JSON.serialize(sfIdToAWSIdMap);
+
+
+        }else{
+            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
+        }
+        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo(sobjectTypeValue);
+        layoutEncryptedAPIList = piIntegration.PIFields;
+        encryptedAPIList = piIntegration.PIFields;
+        staticResource = JSON.serialize(piIntegration);
+        sobjectPrefix = piIntegration.sobjectPrefix;
+        SaveAndNewButtonUrl = string.format('/{0}/e', new string[]{sobjectPrefix});
+        if (lso.size() > 1) {
+            SaveAndNewButtonUrl = String.format('/setup/ui/recordtypeselect.jsp?ent={0}&retURL=/{1}/o&save_new_url=/{1}/e?retURL=%2F{1}%2Fo', new String[]{sobjectTypeValue,sobjectPrefix});
+        }
+
+        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
+            
+            AWSToSobjectNonEncryptedMap.put(PIDetail.AWS_Field_API__c, PIDetail.SF_Field_API_Name__c);
+            AWSToSobjectEncryptedMap.put(PIDetail.AWS_Encrypted_Field_API__c, PIDetail.SF_Field_Encrypted_API__c);
+        }
+        System.debug(new List<string>(AWSToSobjectNonEncryptedMap.keySet()));
+        system.debug('AWSToSobjectNonEncryptedMapJson=');
+        system.debug(AWSToSobjectNonEncryptedMapJson);
+        try{
+            LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, sobjectTypeValue,'classic');
+            layoutSections = LayoutWrapperValue.layoutSections;
+            List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
+            Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
+            List<String> fieldApiList = new List<String>(); 
+            for (LayoutDescriberHelper.LayoutSection ls : layoutSections) {
+                for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
+                    if (lf.fieldAPI != '') {
+                        System.debug('lf.fieldAPI='+lf.fieldAPI+' fieldType='+lf.fieldType);
+                        fieldApiList.add(lf.fieldAPI);
+                        if (lf.fieldType == 'reference') {
+                            VLookUpFields.add(lf.fieldAPI);
+                        }
+
+                        //鍦╲iew瑙e瘑section涓彧闇�鏄剧ず褰撳墠layout涓殑鍔犲瘑瀛楁
+                        // if (encryptedAPIList.contains(lf.fieldAPI)) {
+                        //     layoutEncryptedAPIList.add(lf.fieldAPI);
+                        // }
+                    }
+                }
+            }
+            fieldApiListStr = JSON.serialize(fieldApiList);
+            fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
+            requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
+            //awsToken = AWSServiceTool.getAWSToken();
+        }catch(Exception e){
+            system.debug('Exception from get layout service:'+e.getmessage());
+        }
+    }
+
+    public static string GetReferenceField(string f){
+        if (f.endsWith('__c')) {
+            return f.substring(0,f.length()-1)+'r';
+        }
+        else if(f.endsWith('Id') || f.endsWith('id') || f.endsWith('ID')) {
+            return f.substring(0, f.length()-2);
+        }
+        else{
+            return f;
+        }
+    }
+
+    public string GenerateReferenceSql(){
+        string res ='';
+        for (string f : LookUpOverrideFields) {
+            res += ','+f+','+GetReferenceField(f)+'.AWS_Data_Id__c';
+        }
+        return res;
+    }
+
+    global class Response{
+        public String recordId{set;get;}
+        public String message{set;get;}
+        public String status{set;get;}
+    }
+
+    @RemoteAction
+    global static Response save(Sobject sobj, String leadJson,String transId,Boolean isNew) {
+        string sobjectTypeValue = sobj.getSObjectType().getDescribe().getName();
+        System.debug('sobjectTypeValue:'+sobjectTypeValue+' Info:' + JSON.serialize(leadJson));
+        System.debug('json length='+leadJson.length());
+        //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);
+        Sobject leadInfo = sobj;
+        for (String fieldAPI: fieldValueMap.keySet()) {
+            system.debug('field API='+fieldAPI);
+            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))?0:Decimal.valueOf(fieldValue)); 
+            } else if(String.valueof(fielddataType)=='BOOLEAN'){
+                leadInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
+            }else {
+                leadInfo.put(fieldAPI,fieldValue);
+            }                  
+        }
+
+        system.debug('for (String fieldAPI: fieldValueMap.keySet()) end');
+
+        
+        //2. Save Record Process
+        String status = 'success';    
+        Response resp = new Response();
+        String awsDataId = '';
+        Savepoint sp = Database.setSavepoint();
+        try{
+            System.debug('abcde');
+            if(isNew){
+                System.debug('leadInfozhj = ' + leadInfo);
+                insert leadInfo;
+            }else{
+                System.debug('into update');
+                awsDataId = (String)leadInfo.get('AWS_Data_Id__c');
+                if (string.isBlank(awsDataId)) {
+                    throw new DMLException('鏇存柊鏃禔WS_Data_Id__c涓嶈兘涓虹┖');
+                }
+                System.debug('awsDataId = ' + awsDataId);
+                Sobject[] leads = Database.query('select id from '+sobjectTypeValue+' where AWS_Data_Id__c =:awsDataId');
+                System.debug('leads[0].id = ' + leads[0].id);
+                leadInfo.put('Id',leads[0].id);//For testing;
+                update leadInfo;
+            }
+            // //saveTransLog(transId, leadInfo.AWS_Data_Id__c, status, '');
+            // Transaction_Log__c traLog = new Transaction_Log__c();
+            // // AWS_Data_Id__c=AWSDataId,TransId__c=transId,JsonContent__c=leadJson,Status__c=status
+            // traLog.AWS_Data_Id__c = AWSDataId;
+            // traLog.TransId__c = transId;
+            // traLog.JsonContent__c = leadJson;
+            // traLog.Status__c = status;
+            // insert traLog;
+            resp.recordId = leadInfo.Id;
+            // resp.message = 'success saveLead';
+            resp.status = status;
+            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,leadInfo.Id,transId, leadJson ,status,'');
+            // (String module,String awsDataId,String sfId, String transId,String content,String status,String respMsg)
+            System.debug('respzhj = ' + resp);
+            return resp;
+
+        } catch(Exception e) {
+            System.debug('into catch'+e.getMessage());
+            Database.rollback(sp);
+            resp.status = 'Exception';
+            resp.message = e.getMessage()+e.getStackTraceString();
+            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,leadInfo.Id,transId, leadJson ,status,resp.message);
+            // PIHelper.saveTransLog(sobjectTypeValue,(String)leadInfo.get('AWS_Data_Id__c'),transId, leadJson,status,e.getStackTraceString());
+            return resp;
+        }
+    }
+    
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditBaseController.cls-meta.xml b/force-app/main/default/classes/NewAndEditBaseController.cls-meta.xml
new file mode 100644
index 0000000..f928c8e
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditBaseController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditCampaignMemberController.cls b/force-app/main/default/classes/NewAndEditCampaignMemberController.cls
new file mode 100644
index 0000000..02f349b
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditCampaignMemberController.cls
@@ -0,0 +1,18 @@
+global class NewAndEditCampaignMemberController extends NewAndEditBaseController 
+{
+	public String staticResourceContact {get; set;}
+    public NewAndEditCampaignMemberController(ApexPages.StandardController controller) {
+        
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('CampaignMember').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        //controller.addFields(fieldList);
+        //Init(controller.getRecord());
+        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
+    }
+
+    
+    @RemoteAction
+    global static Response saveCampaignMember(String leadJson,String transId,Boolean isNew) {
+        return save(new CampaignMember(),leadJson,transId,isNew);
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditCampaignMemberController.cls-meta.xml b/force-app/main/default/classes/NewAndEditCampaignMemberController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditCampaignMemberController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditCaseController.cls b/force-app/main/default/classes/NewAndEditCaseController.cls
new file mode 100644
index 0000000..b27867a
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditCaseController.cls
@@ -0,0 +1,146 @@
+/*
+ * Author: Mingjie Yin
+ * Created Date: 02/07/2022
+ * Purpose: Utility class for describe layouts
+ * Test Class: NewAndEditCaseController
+ * History: 
+ *      02/07/2022 - Mingjie Yin - Initial Code.
+ * 
+ * */
+global without sharing class NewAndEditCaseController {
+    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 = 'Case';
+    public Boolean isNewMode{set;get;}
+    public String rtTypeId {get; set;}
+    public String AWSDataId{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 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 NewAndEditCaseController(ApexPages.StandardController controller) {
+        isNewMode = true;
+        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;
+        //鑾峰彇鎵�鏈夊瓧娈�
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Case').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);
+        SObject obj = controller.getRecord();        
+        if(obj.Id != null){
+            //鏇存柊
+            isNewMode = false;
+            Case caseData = [select Id,RecordTypeId,AWS_Data_Id__c,ContactId,Contact.AWS_Data_Id__c from Case where id =: obj.Id];
+            rtTypeId = caseData.RecordTypeId;
+            AWSDataId = caseData.AWS_Data_Id__c;
+            System.debug('AWSDataId=' + AWSDataId);
+            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
+            if(caseData.ContactId != null){
+                sfIdToAWSIdMap.put(String.valueof(caseData.ContactId).subString(0,15),caseData.Contact.AWS_Data_Id__c);
+            }
+            // sfIdToAWSIdMap.put(String.valueof(caseData.ContactId).subString(0,15),caseData.Contact.AWS_Data_Id__c);
+            
+            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
+        }else{
+            //鏂板缓
+            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
+            obj.put('OwnerId',UserInfo.getUserId());
+        }
+        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Case','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('Case');
+        staticResource = JSON.serialize(piIntegration);
+        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
+        encryptedAPIList = piIntegration.PIFields;
+        sobjectPrefix = piIntegration.sobjectPrefix;
+    }
+    global class Response{
+        public String recordId{set;get;}
+        public String message{set;get;}
+        public String status{set;get;}
+    }
+    @RemoteAction
+    global static Response saveCase(String caseJson,String transId,Boolean isNew) {
+        System.debug('Case Info:' + JSON.serialize(caseJson));
+        //1. Prepare the payload for  Case
+        Schema.SObjectType caseSchema = schemaMap.get(sobjectTypeValue);
+        Map<String, Schema.SObjectField> fieldAPIToTypeMap = caseSchema.getDescribe().fields.getMap();
+        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(caseJson);
+        Case caseInfo = new Case();
+        //鑷畾涔夋牸寮忚浆鎹�
+        for (String fieldAPI: fieldValueMap.keySet()) {
+            system.debug('field API'+fieldAPI);
+            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();  
+            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI)); 
+            if(String.isBlank(fieldValue)){
+                continue;
+            }
+            if(String.valueOf(fielddataType)=='DATE'){
+                caseInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
+            }else if(String.valueOf(fielddataType)=='DATETIME'){
+                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
+                if(String.isNotBlank(dt)&&dt.contains('T')){
+                    dt = dt.replace('T',' ');
+                    caseInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
+                }             
+            }else if(String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
+                caseInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
+            } else if(String.valueof(fielddataType)=='BOOLEAN'){
+                caseInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
+            }else {
+                caseInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
+            }                  
+        }
+        
+        //2. Save Record Process
+        String status = 'success';    
+        Response resp = new Response();
+        Savepoint sp = Database.setSavepoint();
+        String rid = '';
+        try{
+            System.debug('abcde');
+            if(isNew){
+                System.debug('caseInfozhj = ' + caseInfo);
+                insert caseInfo;
+            }else{
+                System.debug('into update');
+                String awsDataId = (String)caseInfo.get('AWS_Data_Id__c');
+                System.debug('awsDataId = ' + awsDataId);
+                Case[] cases = [select id from Case where AWS_Data_Id__c =:awsDataId];
+                System.debug('Cases[0].id = ' + cases[0].id);
+                caseInfo.put('Id',cases[0].id);//For testing;
+                update caseInfo;
+            }
+            rid=caseInfo.Id;
+            PIHelper.saveTransLog(sobjectTypeValue,(String)caseInfo.get('AWS_Data_Id__c'),rid,transId,caseJson ,status,'');
+            resp.recordId = caseInfo.Id;
+            resp.message = '';
+            resp.status = status;
+            System.debug('resp from sfdx back-end' + resp);
+            return resp;
+        } catch(Exception e) {
+            System.debug('into catch'+e.getMessage());
+            Database.rollback(sp);
+            status = 'fail';
+            PIHelper.saveTransLog(sobjectTypeValue,(String)caseInfo.get('AWS_Data_Id__c'),rid,transId,caseJson,status,e.getMessage());
+            resp.message = e.getMessage();            
+            resp.status = status;
+            return resp;
+        }
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditCaseController.cls-meta.xml b/force-app/main/default/classes/NewAndEditCaseController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditCaseController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditContactController.cls b/force-app/main/default/classes/NewAndEditContactController.cls
new file mode 100644
index 0000000..59c3e6e
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditContactController.cls
@@ -0,0 +1,52 @@
+global class NewAndEditContactController extends NewAndEditBaseController 
+{
+    public String unifiedIContactID{set;get;}
+	
+    public NewAndEditContactController(ApexPages.StandardController controller) {
+        
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Contact').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);
+        Init(controller.getRecord());
+        String contactId = controller.getRecord().Id;
+        if(contactId != null){
+            Contact c = [select UnifiedI_Contact_ID__c from Contact where Id =:contactId ];
+            system.debug('Contact c = '+c);
+            unifiedIContactID = c.UnifiedI_Contact_ID__c;
+        }
+
+        // AWSToSobjectNonEncryptedMap.put('lastName', 'LastName');
+        // AWSToSobjectNonEncryptedMap.put('phone', 'Phone');
+        // AWSToSobjectNonEncryptedMap.put('email', 'Email');
+        // AWSToSobjectNonEncryptedMap.put('medicalStaffFullName', 'MedicalStaff_Full_name__c');
+        // AWSToSobjectNonEncryptedMap.put('mobilePhone', 'MobilePhone');
+        // AWSToSobjectNonEncryptedMap.put('title', 'Title');
+        // AWSToSobjectNonEncryptedMap.put('olyAssistantType', 'OLY_Assistant_Type__c');
+        // AWSToSobjectNonEncryptedMap.put('jobCategoryPicklist', 'Job_Category_picklist__c');
+        // AWSToSobjectNonEncryptedMap.put('type', 'Type__c');
+        // AWSToSobjectNonEncryptedMap.put('contactAddress', 'Contact_address__c');
+        // AWSToSobjectNonEncryptedMap.put('contactType', 'ContactType__c');
+        // AWSToSobjectNonEncryptedMap.put('doctorDivision1', 'Doctor_Division1__c');
+        // AWSToSobjectNonEncryptedMap.put('uniqueNumber', 'UniqueNumber__c');
+
+        // AWSToSobjectEncryptedMap.put('lastNameEncrypt', 'LastName_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('phoneEncrypt', 'Phone_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('emailEncrypt', 'Email_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('medicalStaffFullNameEncrypt', 'MedicalStaff_Full_name_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('mobilePhoneEncrypt', 'MobilePhone_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('titleEncrypt', 'Title_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('olyAssistantTypeEncrypt', 'OLY_Assistant_Type_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('jobCategoryPicklistEncrypt', 'Job_Category_picklist_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('typeEncrypt', 'Type_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('contactAddressEncrypt', 'Contact_address_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('contactTypeEncrypt', 'ContactType_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('doctorDivision1Encrypt', 'Doctor_Division1_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('uniqueNumberEncrypt', 'UniqueNumber_Encrypted__c');
+    }
+
+    
+    @RemoteAction
+    global static Response saveContact(String leadJson,String transId,Boolean isNew) {
+        return save(new Contact(),leadJson,transId,isNew);
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditContactController.cls-meta.xml b/force-app/main/default/classes/NewAndEditContactController.cls-meta.xml
new file mode 100644
index 0000000..f928c8e
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditContactController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditEventController.cls b/force-app/main/default/classes/NewAndEditEventController.cls
new file mode 100644
index 0000000..7d8c2b2
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditEventController.cls
@@ -0,0 +1,44 @@
+/*
+ * Author: Yanan Chen
+ * Created Date: 02/15/2022
+ * Purpose: Utility class for describe layouts
+ * Test Class: NewAndEditEventController
+ * History: 
+ *      02/15/2022 - Yanan Chen - Initial Code.
+ * 
+ * */
+global class NewAndEditEventController extends NewAndEditBaseController {
+    public String contactAWSIds{set;get;}
+    public String staticResources {get; set;}
+    public NewAndEditEventController (ApexPages.StandardController controller) {
+        
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Event').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);
+        Init(controller.getRecord());
+        //1. get 璁块棶瀵硅薄ID
+        //query event by controller.getRecord().Id;
+        Event event = [SELECT  Id, Visitor1_ID__c, Visitor2_ID__c,  Visitor3_ID__c, Visitor4_ID__c, Visitor5_ID__c FROM Event WHERE Id =:controller.getRecord().Id];
+        System.debug('event: ' + event);
+        Set<String> contactIds = new Set<String>();
+        List<String> conAWSIds = new List<String>();
+        contactIds.add(event.Visitor1_ID__c);
+        contactIds.add(event.Visitor2_ID__c);
+        contactIds.add(event.Visitor3_ID__c);
+        contactIds.add(event.Visitor4_ID__c);
+        contactIds.add(event.Visitor5_ID__c);
+        List<Contact> conListForReport = new List<Contact>([select id,AWS_Data_Id__c from Contact where id in:contactIds and AWS_Data_Id__c!='']);
+        for(Contact con:conListForReport){
+            conAWSIds.add(con.AWS_Data_Id__c);
+        }
+        contactAWSIds = JSON.serialize(conAWSIds);
+        system.debug('Contact AWSIDs:'+contactAWSIds);
+        staticResources = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
+    }
+
+    
+    // @RemoteAction
+    // global static Response saveEvent(String leadJson,String transId,Boolean isNew) {
+    //     return save(new Event(),leadJson,transId,isNew);
+    // }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditEventController.cls-meta.xml b/force-app/main/default/classes/NewAndEditEventController.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditEventController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditInquiryFormController.cls b/force-app/main/default/classes/NewAndEditInquiryFormController.cls
new file mode 100644
index 0000000..b3d2e0c
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditInquiryFormController.cls
@@ -0,0 +1,36 @@
+global class NewAndEditInquiryFormController extends NewAndEditBaseController 
+{
+    // public String contactsInfo {set;get;}//key sfid;value awsid
+    // public String leadsInfo {set;get;}//key sfid;value awsid
+    public String PIPL_Input_Account_Error_Msg{set;get;}
+    public String contactId{set;get;}//For Lookup field
+    public String leadId{set;get;}//For Lead Lookup
+    public String staticResourceContact {get; set;}
+    public String staticResourceLead {get; set;}
+    public NewAndEditInquiryFormController(ApexPages.StandardController controller) {
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Inquiry_form__c').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);
+        // contact lookup
+        LookUpOverrideFields.add('Contact_Name__c');
+        LookUpOverrideFields.add('Lead_link__c');
+        Init(controller.getRecord());
+        //娣诲姞椤�
+        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
+        SObject obj = controller.getRecord();
+        if(obj.Id == null){
+            //鍒濆鍖栧姞杞藉��
+            obj.put('OwnerId',UserInfo.getUserId());
+        }
+        //contact淇℃伅锛堟悳绱㈡煡璇uery url鐢級
+        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
+        //Lead淇℃伅锛堟悳绱㈡煡璇uery url鐢級
+        staticResourceLead = JSON.serialize(PIHelper.getPIIntegrationInfo('Lead'));
+    }
+
+    
+    @RemoteAction
+    global static Response saveInquiryForm(String leadJson,String transId,Boolean isNew) {
+        return save(new Inquiry_form__c(),leadJson,transId,isNew);
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditInquiryFormController.cls-meta.xml b/force-app/main/default/classes/NewAndEditInquiryFormController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditInquiryFormController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditInspectionReportController.cls b/force-app/main/default/classes/NewAndEditInspectionReportController.cls
new file mode 100644
index 0000000..6ca96d4
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditInspectionReportController.cls
@@ -0,0 +1,25 @@
+global class NewAndEditInspectionReportController extends NewAndEditBaseController 
+{
+    public NewAndEditInspectionReportController(ApexPages.StandardController controller) {
+        
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Inspection_Report__c').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);
+        Init(controller.getRecord());
+
+        //AWSToSobjectNonEncryptedMap.put('responsiblePersonHP', 'Responsible_Person__c');
+        //AWSToSobjectNonEncryptedMap.put('technicianHP', 'Technician_HP__c');
+        //AWSToSobjectNonEncryptedMap.put('callerPhone', 'phone__c');
+
+        //AWSToSobjectEncryptedMap.put('responsiblePersonHPEncrypt', 'Responsible_Person_Encrypted__c');
+        //AWSToSobjectEncryptedMap.put('technicianHPEncrypt', 'Technician_HP_Encrypted__c');
+        //AWSToSobjectEncryptedMap.put('callerPhoneEncrypt', 'phone_Encrypted__c');
+        //system.debug('layoutEncryptedAPIList');
+    }
+
+    
+    @RemoteAction
+    global static Response saveInspectionReport(String leadJson,String transId,Boolean isNew) {
+        return save(new Inspection_Report__c(),leadJson,transId,isNew);
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditInspectionReportController.cls-meta.xml b/force-app/main/default/classes/NewAndEditInspectionReportController.cls-meta.xml
new file mode 100644
index 0000000..f928c8e
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditInspectionReportController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditQISController.cls b/force-app/main/default/classes/NewAndEditQISController.cls
new file mode 100644
index 0000000..83f7535
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditQISController.cls
@@ -0,0 +1,12 @@
+global with sharing class NewAndEditQISController extends NewAndEditBaseController{
+    public NewAndEditQISController(ApexPages.StandardController controller) {
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('QIS_Report__c').getDescribe().fields.getMap().keyset());  
+        controller.addFields(fieldList);
+        Init(controller.getRecord());
+    }
+
+    @RemoteAction
+    global static Response saveQISReport(String leadJson,String transId,Boolean isNew) {
+        return save(new QIS_Report__c(),leadJson,transId,isNew);
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditQISController.cls-meta.xml b/force-app/main/default/classes/NewAndEditQISController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditQISController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditRepairSubOrderController.cls b/force-app/main/default/classes/NewAndEditRepairSubOrderController.cls
new file mode 100644
index 0000000..0c99dfb
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditRepairSubOrderController.cls
@@ -0,0 +1,40 @@
+/*
+ * Author: Yanan Chen
+ * Created Date: 02/14/2022
+ * Purpose: Utility class for describe layouts
+ * Test Class: NewAndEditRepairSubOrderController
+ * History: 
+ *      02/14/2022 - Yanan Chen - Initial Code.
+ * 
+ * */
+global class NewAndEditRepairSubOrderController extends NewAndEditBaseController 
+{
+    public String contactsInfo {set;get;}//key sfid;value awsid
+    public String PIPL_Input_Account_Error_Msg{set;get;}
+    public String contactId{set;get;}//For Lookup field
+    public String staticResourceContact {get; set;}
+    public NewAndEditRepairSubOrderController(ApexPages.StandardController controller) {
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('RepairSubOrder__c').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);
+        LookUpOverrideFields.add('Receiver__c');
+        LookUpOverrideFields.add('Applicanter__c');
+        //contactId = LookUpOverrideFieldsMapJson;
+        Init(controller.getRecord());
+
+        //娣诲姞椤�
+        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
+        SObject obj = controller.getRecord();
+        if(obj.Id == null){
+            //鍒濆鍖栧姞杞藉��
+            obj.put('OwnerId',UserInfo.getUserId());
+        }
+        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
+    }
+
+    
+    @RemoteAction
+    global static Response saveRepairSubOrder(String leadJson,String transId,Boolean isNew) {
+        return save(new RepairSubOrder__c(),leadJson,transId,isNew);
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditRepairSubOrderController.cls-meta.xml b/force-app/main/default/classes/NewAndEditRepairSubOrderController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditRepairSubOrderController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditReportController.cls b/force-app/main/default/classes/NewAndEditReportController.cls
new file mode 100644
index 0000000..53ca9f1
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditReportController.cls
@@ -0,0 +1,160 @@
+global without sharing class NewAndEditReportController {
+    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
+    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
+    public static String sobjectTypeValue = 'Report__c';
+    public Boolean isNewMode{set;get;}
+    public String rtTypeId {get; set;}
+    public String AWSDataId{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 requiredFieldAPIListStr {get; set;}
+    public String fieldAPIToLabelMapStr {get; set;}
+    public String requiredErrorMsg{set;get;}
+    public String contactsInfo {set;get;}
+    public String PIPL_Input_Account_Error_Msg{set;get;}
+    public String SaveAndNewButtonUrl{get;private set;}
+    public String sobjectPrefix{get;private set;}
+    public String sobjecttypeForFrontEnd{set;get;}
+    public String sobjectId{set;get;}
+    public NewAndEditReportController(ApexPages.StandardController controller) {
+        sobjectId = [SELECT CustomObjectId,CustomObjectName  FROM CustomObjectUserLicenseMetrics   where CustomObjectName ='Report' limit 1].CustomObjectId;
+        isNewMode = true;
+        requiredErrorMsg = Label.Input_Required_Field_Msg;
+        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
+        sobjecttypeForFrontEnd = sobjectTypeValue;
+        //鑾峰彇鎵�鏈夊瓧娈�
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Report__c').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);
+        SObject obj = controller.getRecord();        
+        if(obj.Id != null){
+            //鏇存柊
+            isNewMode = false;
+            Report__c ReportData = [select Id,RecordTypeId,AWS_Data_Id__c,Practitioner1__c,Practitioner1__r.AWS_Data_Id__c,
+            Practitioner2__c,Practitioner2__r.AWS_Data_Id__c,Practitioner3__c,Practitioner3__r.AWS_Data_Id__c,
+            Practitioner4__c,Practitioner4__r.AWS_Data_Id__c,Practitioner5__c,Practitioner5__r.AWS_Data_Id__c,
+            Person_In_Charge__c,Person_In_Charge__r.AWS_Data_Id__c
+            from Report__c where id =: obj.Id];
+            system.debug('ReportData = ' + ReportData);
+
+            rtTypeId = ReportData.RecordTypeId;
+            AWSDataId = ReportData.AWS_Data_Id__c;
+            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
+            if(ReportData.Practitioner1__r.Id != null && ReportData.Practitioner1__r.AWS_Data_Id__c!=null){
+                sfIdToAWSIdMap.put(String.valueof(ReportData.Practitioner1__r.Id).subString(0,15),ReportData.Practitioner1__r.AWS_Data_Id__c);
+            }
+            if(ReportData.Practitioner2__r.Id != null && ReportData.Practitioner2__r.AWS_Data_Id__c!=null){
+                sfIdToAWSIdMap.put(String.valueof(ReportData.Practitioner2__r.Id).subString(0,15),ReportData.Practitioner2__r.AWS_Data_Id__c);
+            }
+            if(ReportData.Practitioner3__r.Id != null && ReportData.Practitioner3__r.AWS_Data_Id__c!=null){
+                sfIdToAWSIdMap.put(String.valueof(ReportData.Practitioner3__r.Id).subString(0,15),ReportData.Practitioner3__r.AWS_Data_Id__c);
+            }
+            if(ReportData.Practitioner4__r.Id != null && ReportData.Practitioner4__r.AWS_Data_Id__c!=null){
+                sfIdToAWSIdMap.put(String.valueof(ReportData.Practitioner4__r.Id).subString(0,15),ReportData.Practitioner4__r.AWS_Data_Id__c);
+            }
+            if(ReportData.Practitioner5__r.Id != null && ReportData.Practitioner5__r.AWS_Data_Id__c!=null){
+                sfIdToAWSIdMap.put(String.valueof(ReportData.Practitioner5__r.Id).subString(0,15),ReportData.Practitioner5__r.AWS_Data_Id__c);
+            }
+            if(ReportData.Person_In_Charge__r.Id != null && ReportData.Person_In_Charge__r.AWS_Data_Id__c!=null){
+                sfIdToAWSIdMap.put(String.valueof(ReportData.Person_In_Charge__r.Id).subString(0,15),ReportData.Person_In_Charge__r.AWS_Data_Id__c);
+            }
+            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
+        }else{
+            //鏂板缓
+            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
+            obj.put('OwnerId',UserInfo.getUserId());
+        }
+        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Report__c','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('Report__c');
+        staticResource = JSON.serialize(piIntegration);
+        encryptedAPIList = piIntegration.PIFields;
+        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
+        sobjectPrefix = piIntegration.sobjectPrefix;
+    }
+
+    global class Response{
+        public String recordId{set;get;}
+        public String message{set;get;}
+        public String status{set;get;}
+    }
+
+    @RemoteAction
+    global static Response saveReport(String reportJson,String transId,Boolean isNew) {
+        System.debug('report Info:' + JSON.serialize(reportJson));
+        //System.debug('rtTypeId: ' + rtTypeId);
+        //1. Prepare the payload for  report
+        Schema.SObjectType reportSchema = schemaMap.get(sobjectTypeValue);
+        Map<String, Schema.SObjectField> fieldAPIToTypeMap = reportSchema.getDescribe().fields.getMap();
+        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(reportJson);
+        Report__c reportInfo = new Report__c();
+
+        System.debug('鑷畾涔夋牸寮忚浆鎹㈠紑濮�');
+        //鑷畾涔夋牸寮忚浆鎹�
+        for (String fieldAPI: fieldValueMap.keySet()) {
+            System.debug('field API'+fieldAPI);
+            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();  
+            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI)); 
+            if(String.isBlank(fieldValue)){
+                continue;
+            }
+            if(String.valueOf(fielddataType)=='DATE'){
+                reportInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
+            }else if(String.valueOf(fielddataType)=='DATETIME'){
+                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
+                if(String.isNotBlank(dt)&&dt.contains('T')){
+                    dt = dt.replace('T',' ');
+                    reportInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
+                }             
+            }else if(String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
+                reportInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
+            } else if(String.valueof(fielddataType)=='BOOLEAN'){
+                reportInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
+            }else {
+                reportInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
+            }                  
+        }
+        System.debug('鑷畾涔夋牸寮忚浆鎹㈢粨鏉�');
+
+        //2. Save Record Process
+        String status = 'success';    
+        Response resp = new Response();
+        Savepoint sp = Database.setSavepoint();
+        String rid = '';
+        try{
+            if(isNew){
+                System.debug('reportInfo = ' + reportInfo);
+                insert reportInfo;
+            }else{
+                System.debug('into update');
+                String awsDataId = (String)reportInfo.get('AWS_Data_Id__c');
+                System.debug('awsDataId = ' + awsDataId);
+                report__c[] reports = [select id from report__c where AWS_Data_Id__c =:awsDataId];
+                System.debug('reports[0].id = ' + reports[0].id);
+                reportInfo.put('Id',reports[0].id);//For testing;
+                update reportInfo;
+            }
+            rid=reportInfo.Id;
+            PIHelper.saveTransLog(sobjectTypeValue,(String)reportInfo.get('AWS_Data_Id__c'),rid,transId,reportJson ,status,'');
+            resp.recordId = reportInfo.Id;
+            // resp.message = 'success savereport';
+            resp.status = status;
+            return resp;
+
+        } catch(Exception e) {
+            System.debug('into catch'+e.getMessage());
+            Database.rollback(sp);
+            status = 'fail';
+            PIHelper.saveTransLog(sobjectTypeValue,(String)reportInfo.get('AWS_Data_Id__c'),rid,transId,reportJson,status,e.getMessage());
+            resp.message = e.getMessage();            
+            resp.status = status;
+            return resp;
+        }
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditReportController.cls-meta.xml b/force-app/main/default/classes/NewAndEditReportController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditReportController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewAndEditTenderinformationController.cls b/force-app/main/default/classes/NewAndEditTenderinformationController.cls
new file mode 100644
index 0000000..83a9d42
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditTenderinformationController.cls
@@ -0,0 +1,45 @@
+global class NewAndEditTenderinformationController extends NewAndEditBaseController 
+{
+	
+    public NewAndEditTenderinformationController(ApexPages.StandardController controller) {
+        
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Tender_information__c').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);
+        Init(controller.getRecord());
+
+        // AWSToSobjectNonEncryptedMap.put('lastName', 'LastName');
+        // AWSToSobjectNonEncryptedMap.put('phone', 'Phone');
+        // AWSToSobjectNonEncryptedMap.put('email', 'Email');
+        // AWSToSobjectNonEncryptedMap.put('medicalStaffFullName', 'MedicalStaff_Full_name__c');
+        // AWSToSobjectNonEncryptedMap.put('mobilePhone', 'MobilePhone');
+        // AWSToSobjectNonEncryptedMap.put('title', 'Title');
+        // AWSToSobjectNonEncryptedMap.put('olyAssistantType', 'OLY_Assistant_Type__c');
+        // AWSToSobjectNonEncryptedMap.put('jobCategoryPicklist', 'Job_Category_picklist__c');
+        // AWSToSobjectNonEncryptedMap.put('type', 'Type__c');
+        // AWSToSobjectNonEncryptedMap.put('contactAddress', 'Contact_address__c');
+        // AWSToSobjectNonEncryptedMap.put('contactType', 'ContactType__c');
+        // AWSToSobjectNonEncryptedMap.put('doctorDivision1', 'Doctor_Division1__c');
+        // AWSToSobjectNonEncryptedMap.put('uniqueNumber', 'UniqueNumber__c');
+
+        // AWSToSobjectEncryptedMap.put('lastNameEncrypt', 'LastName_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('phoneEncrypt', 'Phone_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('emailEncrypt', 'Email_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('medicalStaffFullNameEncrypt', 'MedicalStaff_Full_name_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('mobilePhoneEncrypt', 'MobilePhone_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('titleEncrypt', 'Title_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('olyAssistantTypeEncrypt', 'OLY_Assistant_Type_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('jobCategoryPicklistEncrypt', 'Job_Category_picklist_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('typeEncrypt', 'Type_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('contactAddressEncrypt', 'Contact_address_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('contactTypeEncrypt', 'ContactType_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('doctorDivision1Encrypt', 'Doctor_Division1_Encrypted__c');
+        // AWSToSobjectEncryptedMap.put('uniqueNumberEncrypt', 'UniqueNumber_Encrypted__c');
+    }
+
+    
+    @RemoteAction
+    global static Response saveTenderinformation(String leadJson,String transId,Boolean isNew) {
+        return save(new Tender_information__c(),leadJson,transId,isNew);
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewAndEditTenderinformationController.cls-meta.xml b/force-app/main/default/classes/NewAndEditTenderinformationController.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/NewAndEditTenderinformationController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewConsumApplyController.cls b/force-app/main/default/classes/NewConsumApplyController.cls
new file mode 100644
index 0000000..c8efb33
--- /dev/null
+++ b/force-app/main/default/classes/NewConsumApplyController.cls
@@ -0,0 +1,139 @@
+/**
+ * @description       : 
+ * @author            : ChangeMeIn@UserSettingsUnder.SFDoc
+ * @group             : 
+ * @last modified on  : 03-10-2022
+ * @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
+**/
+global without sharing class NewConsumApplyController {
+    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 = 'Consum_Apply__c';
+    public Boolean isNewMode{set;get;}
+    public String rtTypeId {get; set;}
+    public String AWSDataId{set;get;}
+    public List<String> encryptedAPIList{set;get;}   
+    public String staticResource {get; set;}
+    public String staticResourceContact {get; set;}
+    public String requiredFieldAPIListStr {get; set;}
+    public String fieldAPIToLabelMapStr {get; set;}
+    public String Input_Required_Field_Msg{set;get;}
+    public String requiredErrorMsg{set;get;}
+    public String contactsInfo {set;get;}
+    public String contactId{set;get;}
+    public String PIPL_Input_Account_Error_Msg{set;get;}
+    public NewConsumApplyController(ApexPages.StandardController controller) {
+        isNewMode = true;
+        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
+        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
+        //鑾峰彇鎵�鏈夊瓧娈�
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Consum_Apply__c').getDescribe().fields.getMap().keyset());  
+        controller.addFields(fieldList);
+        SObject obj = controller.getRecord();        
+        if(obj.Id != null){
+            //鏇存柊
+            isNewMode = false;
+            Consum_Apply__c consumApplyData = [select Id,RecordTypeId,AWS_Data_Id__c,Loaner_medical_Staff__c,Loaner_medical_Staff__r.AWS_Data_Id__c from Consum_Apply__c where id =: obj.Id];
+            rtTypeId = consumApplyData.RecordTypeId;
+            AWSDataId = consumApplyData.AWS_Data_Id__c;
+            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
+            // if(consumApplyData.Loaner_medical_Staff__c != null && consumApplyData.Loaner_medical_Staff__c != '') {
+            if(consumApplyData.Loaner_medical_Staff__r.Id != null){
+                sfIdToAWSIdMap.put(String.valueof(consumApplyData.Loaner_medical_Staff__r.Id).subString(0,15),consumApplyData.Loaner_medical_Staff__r.AWS_Data_Id__c);
+            }
+            // sfIdToAWSIdMap.put(String.valueof(consumApplyData.Contact_Name__r.Id).subString(0,15),consumApplyData.Loaner_medical_Staff__r.AWS_Data_Id__c);
+            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
+        }else{
+            //鏂板缓
+            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
+            obj.put('OwnerId',UserInfo.getUserId());
+        }
+        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Consum_Apply__c','classic');
+        layoutSections = LayoutWrapperValue.layoutSections;
+        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
+        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
+        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
+        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
+        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Consum_Apply__c'));
+        encryptedAPIList = PIHelper.getPIIntegrationInfo('Consum_Apply__c').PIFields;
+        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
+    }
+
+    global class Response{
+        public String recordId{set;get;}
+        public String message{set;get;}
+        public String status{set;get;}
+    }
+
+    @RemoteAction
+    global static Response saveConsumApply(String consumApplyJson,String transId,Boolean isNew) {
+        System.debug('Consum_Apply__c Info:' + JSON.serialize(consumApplyJson));
+        //1. Prepare the payload for  Consum_Apply__c
+        Schema.SObjectType consumApplySchema = schemaMap.get(sobjectTypeValue);
+        Map<String, Schema.SObjectField> fieldAPIToTypeMap = consumApplySchema.getDescribe().fields.getMap();
+        system.debug(fieldAPIToTypeMap);
+        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(consumApplyJson);
+        Consum_Apply__c consumApplyInfo = new Consum_Apply__c();
+        //鑷畾涔夋牸寮忚浆鎹�
+        for (String fieldAPI: fieldValueMap.keySet()) {
+            system.debug('field API='+fieldAPI);
+            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'){
+                consumApplyInfo.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',' ');
+                    consumApplyInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
+                }else{
+                    consumApplyInfo.put(fieldAPI, null);
+                }                    
+            }else if(String.valueof(fielddataType)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
+                consumApplyInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?0:Decimal.valueOf(fieldValue)); 
+            } else if(String.valueof(fielddataType)=='BOOLEAN'){
+                consumApplyInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
+            }else {
+                consumApplyInfo.put(fieldAPI,fieldValue);
+            }                 
+        }
+        
+        //2. Save Record Process
+        String status = 'success';    
+        Response resp = new Response();
+        Savepoint sp = Database.setSavepoint();
+        String rid = '';
+        try{
+            System.debug('abcde');
+            if(isNew){
+                System.debug('consumApplyInfozhj = ' + consumApplyInfo);
+                insert consumApplyInfo;
+                System.debug('consumApplyInfo.Id' + consumApplyInfo.Id);
+            }else{
+                System.debug('into update');
+                String awsDataId = (String)consumApplyInfo.get('AWS_Data_Id__c');
+                System.debug('awsDataId = ' + awsDataId);
+                Consum_Apply__c[] ConsumApplys = [select id from Consum_Apply__c where AWS_Data_Id__c =:awsDataId];
+                System.debug('ConsumApplys[0].id = ' + ConsumApplys[0].id);
+                consumApplyInfo.put('Id',ConsumApplys[0].id);//For testing;
+                update consumApplyInfo;
+            }
+            rid=consumApplyInfo.Id;
+            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)consumApplyInfo.get('AWS_Data_Id__c'),consumApplyJson ,status,'');
+            resp.recordId = consumApplyInfo.Id;
+            resp.message = '';
+            resp.status = status;
+            System.debug('resp from sfdx back-end' + resp);
+            return resp;
+        } catch(Exception e) {
+            System.debug('into catch'+e.getMessage());
+            Database.rollback(sp);
+            status = 'fail';
+            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)consumApplyInfo.get('AWS_Data_Id__c'),consumApplyJson,status,e.getMessage());
+            resp.message = e.getMessage();            
+            resp.status = status;
+            return resp;
+        }
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewConsumApplyController.cls-meta.xml b/force-app/main/default/classes/NewConsumApplyController.cls-meta.xml
new file mode 100644
index 0000000..f928c8e
--- /dev/null
+++ b/force-app/main/default/classes/NewConsumApplyController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls b/force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls
new file mode 100644
index 0000000..99d2209
--- /dev/null
+++ b/force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls
@@ -0,0 +1,125 @@
+global without sharing class NewConsumApplyEquipSetDetailController {
+    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 = 'Consum_Apply_Equipment_Set_Detail__c';
+    public Boolean isNewMode{set;get;}
+    public String rtTypeId {get; set;}
+    public String AWSDataId{set;get;}
+    public List<String> encryptedAPIList{set;get;}   
+    public String staticResource {get; set;}
+    public String requiredFieldAPIListStr {get; set;}
+    public String fieldAPIToLabelMapStr {get; set;}
+    public String Input_Required_Field_Msg{set;get;}
+    public String requiredErrorMsg{set;get;}
+    public String sobjecttypeForFrontEnd{set;get;}
+    public String sobjectPrefix{set;get;}
+    public NewConsumApplyEquipSetDetailController(ApexPages.StandardController controller) {
+        isNewMode = true;
+        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
+        sobjecttypeForFrontEnd = sobjectTypeValue;
+        //鑾峰彇鎵�鏈夊瓧娈�
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Consum_Apply_Equipment_Set_Detail__c').getDescribe().fields.getMap().keyset());  
+        controller.addFields(fieldList);
+        SObject obj = controller.getRecord();        
+        if(obj.Id != null){
+            //鏇存柊
+            isNewMode = false;
+            Consum_Apply_Equipment_Set_Detail__c consumApplyData = [select Id,AWS_Data_Id__c from Consum_Apply_Equipment_Set_Detail__c where id =: obj.Id];
+            AWSDataId = consumApplyData.AWS_Data_Id__c;
+        }else{
+            //鏂板缓
+            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
+        }
+        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Consum_Apply_Equipment_Set_Detail__c','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('Consum_Apply_Equipment_Set_Detail__c');
+        staticResource = JSON.serialize(piIntegration);
+        encryptedAPIList = piIntegration.PIFields;
+        sobjectPrefix = piIntegration.sobjectPrefix;
+    }
+
+    global class Response{
+        public String recordId{set;get;}
+        public String message{set;get;}
+        public String status{set;get;}
+    }
+
+    @RemoteAction
+    global static Response saveConsumApply(String consumApplyJson,String transId,Boolean isNew) {
+        System.debug('Consum_Apply_Equipment_Set_Detail__c Info:' + JSON.serialize(consumApplyJson));
+        //1. Prepare the payload for  Consum_Apply_Equipment_Set_Detail__c
+        Schema.SObjectType consumApplySchema = schemaMap.get(sobjectTypeValue);
+        Map<String, Schema.SObjectField> fieldAPIToTypeMap = consumApplySchema.getDescribe().fields.getMap();
+        system.debug(fieldAPIToTypeMap);
+        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(consumApplyJson);
+        Consum_Apply_Equipment_Set_Detail__c consumApplyInfo = new Consum_Apply_Equipment_Set_Detail__c();
+        //鑷畾涔夋牸寮忚浆鎹�
+        for (String fieldAPI: fieldValueMap.keySet()) {
+            system.debug('field API'+fieldAPI);
+            String fieldValue = String.valueOf(fieldAPIToTypeMap.get(fieldAPI));
+            if(String.isBlank(fieldValue)){
+                continue;
+            }
+            Schema.DescribeFieldResult fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe();  
+            Schema.DisplayType fieldDatas = fielddataType.getType();
+            if(String.valueOf(fielddatas)=='DATE'){
+                consumApplyInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
+            }else if(String.valueOf(fielddatas)=='DATETIME'){
+                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
+                if(String.isNotBlank(dt)&&dt.contains('T')){
+                    dt = dt.replace('T',' ');
+                    consumApplyInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
+                }             
+            }else if(String.valueOf(fielddatas)=='Number'||String.valueOf(fielddatas)=='DOUBLE'){
+                // ||String.valueOf(fielddatas)=='Decimal'
+                consumApplyInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
+            } else if(String.valueof(fielddatas)=='BOOLEAN'){
+                consumApplyInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
+            }else {
+                consumApplyInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
+            }                  
+        }
+        
+        //2. Save Record Process
+        String status = 'success';    
+        Response resp = new Response();
+        Savepoint sp = Database.setSavepoint();
+        String rid = '';
+        try{
+            System.debug('abcde');
+            if(isNew){
+                System.debug('consumApplyInfozhj = ' + consumApplyInfo);
+                insert consumApplyInfo;
+                System.debug('consumApplyInfo.Id' + consumApplyInfo.Id);
+            }else{
+                System.debug('into update');
+                String awsDataId = (String)consumApplyInfo.get('AWS_Data_Id__c');
+                System.debug('awsDataId = ' + awsDataId);
+                Consum_Apply_Equipment_Set_Detail__c[] ConsumApplys = [select id from Consum_Apply_Equipment_Set_Detail__c where AWS_Data_Id__c =:awsDataId];
+                System.debug('ConsumApplys[0].id = ' + ConsumApplys[0].id);
+                consumApplyInfo.put('Id',ConsumApplys[0].id);//For testing;
+                update consumApplyInfo;
+            }
+            rid=consumApplyInfo.Id;
+            PIHelper.saveTransLog(sobjectTypeValue,(String)consumApplyInfo.get('AWS_Data_Id__c'),rid,transId,consumApplyJson,status,'');
+            resp.recordId = consumApplyInfo.Id;
+            resp.message = 'success saveConsumApply';
+            resp.status = status;
+            System.debug('respzhj = ' + resp);
+            return resp;
+        } catch(Exception e) {
+            System.debug('into catch'+e.getMessage());
+            Database.rollback(sp);
+            status = 'fail';
+            PIHelper.saveTransLog(sobjectTypeValue,(String)consumApplyInfo.get('AWS_Data_Id__c'),rid,transId,consumApplyJson,status,e.getMessage());
+            resp.message = e.getMessage();            
+            resp.status = status;
+            return resp;
+        }
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls-meta.xml b/force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewListOfConsumablesController.cls b/force-app/main/default/classes/NewListOfConsumablesController.cls
new file mode 100644
index 0000000..c287515
--- /dev/null
+++ b/force-app/main/default/classes/NewListOfConsumablesController.cls
@@ -0,0 +1,3 @@
+public class NewListOfConsumablesController {
+
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewListOfConsumablesController.cls-meta.xml b/force-app/main/default/classes/NewListOfConsumablesController.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/NewListOfConsumablesController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/NewRepairController.cls b/force-app/main/default/classes/NewRepairController.cls
new file mode 100644
index 0000000..e0391de
--- /dev/null
+++ b/force-app/main/default/classes/NewRepairController.cls
@@ -0,0 +1,148 @@
+/*
+ *@Description: 
+ *@Author: Dennis Rodman 
+ *@Date: 2022-03-10 10:26:47
+*/
+global without sharing class NewRepairController {
+    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 = 'Repair__c';
+    public Boolean isNewMode{set;get;}
+    public String rtTypeId {get; set;}
+    public String AWSDataId{set;get;}
+    public String DecryptAWSDataId{set;get;}
+    public String ContactAWSDataId{set;get;}
+    public List<String> encryptedAPIList{set;get;}
+    public String staticResource {get; set;}
+    public String staticResourceContact {get; set;}
+    public String staticResourceAddress {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 sobjectId{set;get;}
+    public NewRepairController(ApexPages.StandardController controller) {
+        sobjectId = [SELECT CustomObjectId,CustomObjectName  FROM CustomObjectUserLicenseMetrics   where CustomObjectName ='Repair' limit 1].CustomObjectId;
+        isNewMode = true;
+        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;
+        //鑾峰彇鎵�鏈夊瓧娈�
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Repair__c').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);        
+        SObject obj = controller.getRecord();        
+        if(obj.Id != null){
+            //鏇存柊
+            isNewMode = false;
+            Repair__c repairData = [select Id,RecordTypeId,AWS_Data_Id__c,Address_AWS_Data_Id__c,Contact_AWS_Data_Id__c,Address_Contacts_Encrypt__c,Address_Contacts_Name_Encrypt__c,Address_Telephone_Encrypt__c,Address_ZipCode_Encrypt__c,Detailed_Address_Encrypt__c from Repair__c where id =: obj.Id];
+            rtTypeId = repairData.RecordTypeId;
+            AWSDataId = repairData.AWS_Data_Id__c;
+            DecryptAWSDataId = String.valueOf(repairData.Address_AWS_Data_Id__c);
+            ContactAWSDataId = String.valueOf(repairData.Contact_AWS_Data_Id__c);
+        }else{
+            //鏂板缓
+            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
+            if(String.isBlank(rtTypeId)||String.isEmpty(rtTypeId)){
+                List<RecordType> rtList = new List<RecordType>([select Id,DeveloperName from RecordType  where SobjectType ='Repair__c' and DeveloperName ='Repair']);
+                rtTypeId = rtList[0].Id;
+            }
+        }
+        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Repair__c','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('Repair__c');
+        PIHelper.PIIntegration piIntegrationAddress = PIHelper.getPIIntegrationInfo('Address__c');
+        PIHelper.PIIntegration piIntegrationContact = PIHelper.getPIIntegrationInfo('Contact');
+        staticResource = JSON.serialize(piIntegration);
+        staticResourceAddress = JSON.serialize(piIntegrationAddress);
+        staticResourceContact = JSON.serialize(piIntegrationContact);
+        encryptedAPIList = piIntegration.PIFields;
+        sobjectPrefix = piIntegration.sobjectPrefix;
+    }
+
+    global class Response{
+        public String recordId{set;get;}
+        public String message{set;get;}
+        public String status{set;get;}
+    }
+
+    @RemoteAction
+    global static Response saveRepair(String repairJson,String transId,Boolean isNew) {
+        System.debug('Repair__c Info:' + JSON.serialize(repairJson));
+        //1. Prepare the payload for  Repair__c
+        Schema.SObjectType repairSchema = schemaMap.get(sobjectTypeValue);
+        Map<String, Schema.SObjectField> fieldAPIToTypeMap = repairSchema.getDescribe().fields.getMap();
+        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(repairJson);
+        Repair__c repairInfo = new Repair__c();
+        //鑷畾涔夋牸寮忚浆鎹�
+        for (String fieldAPI: fieldValueMap.keySet()) {
+            system.debug('field API'+fieldAPI);
+            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();  
+            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI)); 
+            if(String.isBlank(fieldValue)){
+                continue;
+            }
+            if(String.valueOf(fielddataType)=='DATE'){
+                repairInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
+            }else if(String.valueOf(fielddataType)=='DATETIME'){
+                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
+                if(String.isNotBlank(dt)&&dt.contains('T')){
+                    dt = dt.replace('T',' ');
+                    repairInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
+                }             
+            }else if(String.valueOf(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='CURRENCY'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
+                repairInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
+            } else if(String.valueof(fielddataType)=='BOOLEAN'){
+                repairInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
+            }else {
+                repairInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
+            }                  
+        }
+        
+        //2. Save Record Process
+        String status = 'success';    
+        Response resp = new Response();
+        Savepoint sp = Database.setSavepoint();
+        String rid = '';
+        try{
+            System.debug('abcde');
+            if(isNew){
+                System.debug('repairInfozhj = ' + repairInfo);
+                insert repairInfo;
+            }else{
+                System.debug('into update');
+                String awsDataId = (String)repairInfo.get('AWS_Data_Id__c');
+                System.debug('awsDataId = ' + awsDataId);
+                Repair__c[] repairs = [select id from Repair__c where AWS_Data_Id__c =:awsDataId];
+                System.debug('repairs[0].id = ' + repairs[0].id);
+                repairInfo.put('Id',repairs[0].id);//For testing;
+                update repairInfo;
+            }
+            rid=repairInfo.Id;
+            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)repairInfo.get('AWS_Data_Id__c'),repairJson ,status,'');
+            resp.recordId = repairInfo.Id;
+            resp.message = '';
+            resp.status = status;
+            System.debug('resp from sfdx back-end' + resp);
+            return resp;
+
+        } catch(Exception e) {
+            System.debug('into catch'+e.getMessage());
+            Database.rollback(sp);
+            status = 'fail';
+            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)repairInfo.get('AWS_Data_Id__c'),repairJson,status,e.getMessage());
+            resp.message = e.getMessage();            
+            resp.status = status;
+            return resp;
+        }
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/NewRepairController.cls-meta.xml b/force-app/main/default/classes/NewRepairController.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/NewRepairController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/OnCallController.cls b/force-app/main/default/classes/OnCallController.cls
new file mode 100644
index 0000000..f6beda8
--- /dev/null
+++ b/force-app/main/default/classes/OnCallController.cls
@@ -0,0 +1,129 @@
+global without sharing class OnCallController {
+    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 = 'On_Call__c';
+    public Boolean isNewMode{set;get;}
+    public String rtTypeId {get; set;}
+    public String AWSDataId{set;get;}
+    public List<String> encryptedAPIList{set;get;}
+    public String staticResource {get; set;}
+    public String staticResourceContact {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 sobjectId{set;get;}
+    public OnCallController(ApexPages.StandardController controller) {
+        // sobjectId = [SELECT CustomObjectId,CustomObjectName  FROM CustomObjectUserLicenseMetrics   where CustomObjectName ='OnCall' limit 1].CustomObjectId;
+        isNewMode = true;
+        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;
+        //鑾峰彇鎵�鏈夊瓧娈�
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('On_Call__c').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);        
+        SObject obj = controller.getRecord();        
+        if(obj.Id != null){
+            //鏇存柊
+            isNewMode = false;
+            On_Call__c onCallData = [select Id,AWS_Data_Id__c from On_Call__c where id =: obj.Id];
+            AWSDataId = onCallData.AWS_Data_Id__c;
+        }else{
+            //鏂板缓
+            rtTypeId = null;
+        }
+        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'On_Call__c','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('On_Call__c');
+        staticResource = JSON.serialize(piIntegration);
+        encryptedAPIList = piIntegration.PIFields;
+        sobjectPrefix = piIntegration.sobjectPrefix;
+    }
+
+    global class Response{
+        public String recordId{set;get;}
+        public String message{set;get;}
+        public String status{set;get;}
+    }
+
+    @RemoteAction
+    global static Response saveOnCall(String onCallJson,String transId,Boolean isNew) {
+        System.debug('On_Call__c Info:' + JSON.serialize(onCallJson));
+        //1. Prepare the payload for  On_Call__c
+        Schema.SObjectType onCallSchema = schemaMap.get(sobjectTypeValue);
+        Map<String, Schema.SObjectField> fieldAPIToTypeMap = onCallSchema.getDescribe().fields.getMap();
+        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(onCallJson);
+        On_Call__c onCallInfo = new On_Call__c();
+        //鑷畾涔夋牸寮忚浆鎹�
+        for (String fieldAPI: fieldValueMap.keySet()) {
+            system.debug('field API'+fieldAPI);
+            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();  
+            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI)); 
+            if(String.isBlank(fieldValue)){
+                continue;
+            }
+            if(String.valueOf(fielddataType)=='DATE'){
+                onCallInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
+            }else if(String.valueOf(fielddataType)=='DATETIME'){
+                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
+                if(String.isNotBlank(dt)&&dt.contains('T')){
+                    dt = dt.replace('T',' ');
+                    onCallInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
+                }             
+            }else if(String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
+                onCallInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
+            } else if(String.valueof(fielddataType)=='BOOLEAN'){
+                onCallInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
+            }else {
+                onCallInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
+            }                  
+        }
+        
+        //2. Save Record Process
+        String status = 'success';    
+        Response resp = new Response();
+        Savepoint sp = Database.setSavepoint();
+        String rid = '';
+        try{
+            System.debug('abcde');
+            if(isNew){
+                System.debug('onCallInfozhj = ' + onCallInfo);
+                insert onCallInfo;
+            }else{
+                System.debug('into update');
+                String awsDataId = (String)onCallInfo.get('AWS_Data_Id__c');
+                System.debug('awsDataId = ' + awsDataId);
+                On_Call__c[] onCalls = [select id from On_Call__c where AWS_Data_Id__c =:awsDataId];
+                System.debug('onCalls[0].id = ' + onCalls[0].id);
+                onCallInfo.put('Id',onCalls[0].id);//For testing;
+                update onCallInfo;
+            }
+            rid=onCallInfo.Id;
+            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)onCallInfo.get('AWS_Data_Id__c'),onCallJson ,status,'');
+            resp.recordId = onCallInfo.Id;
+            resp.message = '';
+            resp.status = status;
+            System.debug('resp from sfdx back-end' + resp);
+            return resp;
+
+        } catch(Exception e) {
+            System.debug('into catch'+e.getMessage());
+            Database.rollback(sp);
+            status = 'fail';
+            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)onCallInfo.get('AWS_Data_Id__c'),onCallJson,status,e.getMessage());
+            resp.message = e.getMessage();            
+            resp.status = status;
+            return resp;
+        }
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/OnCallController.cls-meta.xml b/force-app/main/default/classes/OnCallController.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/OnCallController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/Option.cls b/force-app/main/default/classes/Option.cls
new file mode 100644
index 0000000..12e1c7e
--- /dev/null
+++ b/force-app/main/default/classes/Option.cls
@@ -0,0 +1,5 @@
+public class Option {
+    @AuraEnabled public string label{get;set;}
+    @AuraEnabled public string value{get;set;}
+    @AuraEnabled public boolean Selected{get;set;}
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/Option.cls-meta.xml b/force-app/main/default/classes/Option.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/Option.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/PIHelper.cls b/force-app/main/default/classes/PIHelper.cls
new file mode 100644
index 0000000..48cc2cd
--- /dev/null
+++ b/force-app/main/default/classes/PIHelper.cls
@@ -0,0 +1,216 @@
+/*
+ * Author: Bubba Li
+ * Created Date: 01/26/2022
+ * Purpose: Utility class for PI 
+ * Test Class: PIHelper
+ * History: 
+ *      01/26/2022 - Bubba Li - Initial Code.
+ * 
+ * */
+global without sharing class PIHelper {
+    public static String getObjectKeyPrefix(String objName){
+        try{
+            schema.sObjectType sObjType = Schema.getGlobalDescribe().get(objName);
+            return (sObjType.getDescribe().getKeyPrefix());
+        }catch(Exception e){
+            system.debug('Exception from get key prefix:'+e.getMessage());
+            return '';
+        }    
+    }
+    // confirm file transaction
+    @future(callout =true)
+    public static void confirmFileTrans(String module,Integer isSuccess, String   sfRecordId ,String transId ,String token,String transUrl){
+        Boolean result =false;
+        Transaction_Log__c traLog = new Transaction_Log__c();
+        traLog.Module__c = 'ConfirmFileTransaction '+module;
+        traLog.Interface_URL__c = transUrl;
+        traLog.TransId__c = transId;
+        traLog.SFRecordId__c=sfRecordId;
+        try {
+            Http http = new Http();
+            HttpRequest request = new HttpRequest();
+            request.setEndpoint(transUrl);
+            request.setMethod('POST');
+            TransRequestBody requestBody =new TransRequestBody();
+            requestBody.isSuccess=isSuccess;
+            requestBody.sfRecordId=sfRecordId;
+            requestBody.txId =transId;
+            request.setBody(JSON.serialize(requestBody));
+            system.debug('request---'+request.tostring());
+            HttpResponse response = http.send(request);
+            system.debug('token--'+token);
+            system.debug('confirm result--'+response.getBody());
+            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
+            result = (Boolean)results.get('success');
+            System.debug('result = ' + result);
+            traLog.Status__c = 'success';
+            traLog.Response__c=response.getBody();
+        } catch (Exception e) {  
+            traLog.Status__c = 'fail';
+            traLog.Response__c = e.getMessage();    
+        }
+        insert traLog;
+    }
+     // confirm tx transaction
+
+     public static void confirmTrans(String module,Integer isSuccess, String   sfRecordId ,String transId ,String token,String transUrl,List<idList> idList){
+         Boolean result =false;
+         Transaction_Log__c traLog = new Transaction_Log__c();
+         traLog.Module__c = 'Confirm Transaction '+module;
+         traLog.Interface_URL__c = transUrl;
+         traLog.TransId__c = transId;
+         if (!String.isEmpty(sfRecordId)) {
+            traLog.SFRecordId__c=sfRecordId;
+         }else {
+            traLog.SFRecordId__c=JSON.serialize(idList);
+         }
+         
+         try {
+             Http http = new Http();
+             HttpRequest request = new HttpRequest();
+             request.setEndpoint(transUrl);
+             request.setMethod('POST');
+             TransactionRequestBody requestBody =new TransactionRequestBody();
+             requestBody.isSuccess=isSuccess;
+             requestBody.sfRecordId=sfRecordId;
+             requestBody.idList=idList;
+             requestBody.txId =transId;
+             request.setBody(JSON.serialize(requestBody));
+             system.debug('request---'+request.tostring());
+             HttpResponse response = http.send(request);
+             system.debug('confirm result--'+response.getBody());
+             Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
+             result = (Boolean)results.get('success');
+             System.debug('result = ' + result);
+             traLog.Status__c = 'success';
+             traLog.Response__c=response.getBody();
+         } catch (Exception e) {  
+             traLog.Status__c = 'fail';
+             traLog.Response__c = e.getMessage();    
+         }
+         insert traLog;
+     }
+    // Use this log method
+    public static void saveTransLog(String module,String awsDataId,String sfId, String transId,String content,String status,String respMsg){
+        Transaction_Log__c traLog = new Transaction_Log__c();
+        traLog.AWS_Data_Id__c = awsDataId;
+        traLog.SFRecordId__c = sfId;
+        traLog.Module__c = 'Upsert SF ' + module;
+        traLog.TransId__c = transId;
+        traLog.Request__c = content;
+        traLog.Status__c = status;
+        traLog.Response__c = respMsg;
+        traLog.Interface_URL__c = traLog.Module__c;
+        insert traLog;
+    }
+    public static PIIntegration getPIIntegrationInfo(String sobjectType){
+        PIIntegration piIntegration = new PIIntegration();
+        //鏌ヨurl
+        PI_Policy_Configuration__c config = [select Full_New_URL__c,Full_Search_URL__c,Full_Update_URL__c,Full_Undelete_URL__c,Full_Read_URL__c,Full_Delete_URL__c,Full_View_Unified_Contact_URL__c,TransactionURL__c from PI_Policy_Configuration__c where Sobject_Type__c =: sobjectType];
+        System.debug('config = ' + config);
+
+        //鑾峰彇appid鍜宎ppsecret
+        AWS_Integration_Info__mdt awsConfiguration = [SELECT App_Id__c,Token_URL__c,App_Secret__c,Host_URL__c FROM AWS_Integration_Info__mdt  WHERE DeveloperName = 'AWS_Default_Configuration'];
+        if (awsConfiguration == null) {
+            System.debug('AWS_Integration_Info__mdt娌¢厤缃�');
+            return null;
+        }
+        String awsAppId = awsConfiguration.App_Id__c;
+        String awsAppSecret = awsConfiguration.App_Secret__c;
+
+        System.debug('awsAppId = ' + awsAppId);
+        System.debug('awsAppSecret = ' + awsAppSecret);
+        System.debug('Host_URL__c = ' + awsConfiguration.Host_URL__c);
+        System.debug('Token URL = ' + awsConfiguration.Token_URL__c);
+
+        //鑾峰彇token
+        String token = '';
+        try{
+            Http http = new Http();
+            HttpRequest request = new HttpRequest();
+            String url = awsConfiguration.Token_URL__c;
+            request.setEndpoint(url);
+            request.setMethod('GET');
+            HttpResponse response = http.send(request);
+            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
+            token = (String)results.get('object');
+            System.debug('token = ' + token);
+        }catch(Exception e){
+            Transaction_Log__c traLog = new Transaction_Log__c();
+            traLog.Module__c = 'Get Token';
+            traLog.Status__c = 'fail';
+            traLog.Response__c = e.getMessage();
+            traLog.Interface_URL__c = awsConfiguration.Token_URL__c;
+            insert traLog;
+        }
+    
+        //Insert Get Token Log
+
+        //鑾峰彇鏁忔劅瀛楁
+        piIntegration.PIDetails = [select id,PI_Policy_Configuration__r.Full_New_URL__c, Enable_Encrypt__c, SF_Field_API_Name__c,SF_Field_Encrypted_API__c, AWS_Field_API__c,AWS_Encrypted_Field_API__c,Field_Type__c from PI_Field_Policy_Detail__c  where PI_Policy_Configuration_Name__c =:sobjectType and Enable_Encrypt__c=true];
+        List<String> vLookUpFields = new List<String>();
+        List<String> PIFields = new List<String>();
+        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
+            if(PIDetail.Field_Type__c == 'Reference'){
+                vLookUpFields.add(PIDetail.SF_Field_API_Name__c);
+            }
+            PIFields.add(PIDetail.SF_Field_API_Name__c);
+        }
+
+        System.debug('vLookUpFields = ' + vLookUpFields.toString());
+        System.debug('PIFields = ' + PIFields.toString());
+
+        //濉厖鏁版嵁
+        piIntegration.newUrl = config.Full_New_URL__c;
+        piIntegration.updateUrl = config.Full_Update_URL__c;
+        piIntegration.queryUrl = config.Full_Read_URL__c;
+        piIntegration.deleteUrl = config.Full_Delete_URL__c;
+        piIntegration.undeleteUrl = config.Full_Undelete_URL__c;
+        piIntegration.viewUnifiedContactUrl = config.Full_View_Unified_Contact_URL__c;
+        piIntegration.transactionURL = config.TransactionURL__c;
+        piIntegration.hostUrl = awsConfiguration.Host_URL__c;
+        piIntegration.searchUrl = config.Full_Search_URL__c;
+        piIntegration.token = token;
+        piIntegration.awsAppId = awsAppId;
+        piIntegration.awsAppSecret = awsAppSecret;
+        piIntegration.vLookUpFields = vLookUpFields;
+        piIntegration.PIFields = PIFields;
+        piIntegration.sobjectPrefix = getObjectKeyPrefix(sobjectType);
+        System.debug('piIntegration' + piIntegration);
+        return piIntegration;
+    }
+    global class PIIntegration{
+        public String sobjectPrefix{set;get;}
+        public String searchUrl{set;get;}
+        public String newUrl{set;get;}
+        public String updateUrl{set;get;}
+        public String queryUrl{set;get;}
+        public String deleteUrl{set;get;}
+        public String undeleteUrl{set;get;}
+        public String viewUnifiedContactUrl{set;get;}
+        public String hostUrl{set;get;}
+        public String token{set;get;}
+        public String awsAppId{set;get;}
+        public String awsAppSecret{set;get;}
+        public String transactionUrl{set;get;}
+        public List<String> vLookUpFields{set;get;}
+        public List<String> PIFields{set;get;}
+        public List<PI_Field_Policy_Detail__c > PIDetails{set;get;}
+    }
+    global class TransRequestBody{
+        public Integer isSuccess{set;get;}
+        public String sfRecordId{set;get;}
+        public String txId{set;get;}
+        
+    }
+    global class TransactionRequestBody{
+        public Integer isSuccess{set;get;}
+        public String sfRecordId{set;get;}
+        public String txId{set;get;}
+        public List<idList> idList{set;get;} 
+    }
+    global class idList{
+        public String awsId{set;get;}
+        public String sfRecordId{set;get;}
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/PIHelper.cls-meta.xml b/force-app/main/default/classes/PIHelper.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/PIHelper.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/RentalApplyController.cls b/force-app/main/default/classes/RentalApplyController.cls
new file mode 100644
index 0000000..8fa1e82
--- /dev/null
+++ b/force-app/main/default/classes/RentalApplyController.cls
@@ -0,0 +1,153 @@
+global without sharing class RentalApplyController {
+    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 = 'Rental_Apply__c';
+    public Boolean isNewMode{set;get;}
+    public String rtTypeId {get; set;}
+    public String AWSDataId{set;get;}
+    public List<String> encryptedAPIList{set;get;}   
+    public String staticResource {get; set;}
+    public String staticResourceContact {get; set;}
+    public String requiredFieldAPIListStr {get; set;}
+    public String fieldAPIToLabelMapStr {get; set;}
+    public String Input_Required_Field_Msg{set;get;}
+    public String requiredErrorMsg{set;get;}
+    public String contactsInfo {set;get;}
+    public String contactId{set;get;}
+    public String PIPL_Input_Account_Error_Msg{set;get;}
+    public RentalApplyController(ApexPages.StandardController controller) {
+        isNewMode = true;
+        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
+        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
+        //鑾峰彇鎵�鏈夊瓧娈�
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Rental_Apply__c').getDescribe().fields.getMap().keyset());  
+        controller.addFields(fieldList);
+        SObject obj = controller.getRecord();        
+        if(obj.Id != null){
+            //鏇存柊
+            isNewMode = false;
+            Rental_Apply__c rentalApplyData = [select Id,RecordTypeId,AWS_Data_Id__c,Loaner_medical_Staff__c,Loaner_medical_Staff__r.AWS_Data_Id__c from Rental_Apply__c where id =: obj.Id];
+            rtTypeId = rentalApplyData.RecordTypeId;
+            AWSDataId = rentalApplyData.AWS_Data_Id__c;
+            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
+            sfIdToAWSIdMap.put(String.valueof(rentalApplyData.Loaner_medical_Staff__r.Id).subString(0,15),rentalApplyData.Loaner_medical_Staff__r.AWS_Data_Id__c);
+            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
+        }else{
+            //鏂板缓
+            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
+        }
+        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Rental_Apply__c','classic');
+        layoutSections = LayoutWrapperValue.layoutSections;
+        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
+        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
+        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
+        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
+        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Rental_Apply__c'));
+        encryptedAPIList = PIHelper.getPIIntegrationInfo('Rental_Apply__c').PIFields;
+        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
+    }
+
+    global class Response{
+        public String recordId{set;get;}
+        public String message{set;get;}
+        public String status{set;get;}
+    }
+
+    @RemoteAction
+    global static Response saveRentalApply(String rentalApplyJson,String transId,Boolean isNew) {
+        System.debug('Rental_Apply__c Info:' + JSON.serialize(rentalApplyJson));
+        //1. Prepare the payload for  Rental_Apply__c
+        Schema.SObjectType rentalApplySchema = schemaMap.get(sobjectTypeValue);
+        Map<String, Schema.SObjectField> fieldAPIToTypeMap = rentalApplySchema.getDescribe().fields.getMap();
+        system.debug(fieldAPIToTypeMap);
+        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(rentalApplyJson);
+        Rental_Apply__c rentalApplyInfo = new Rental_Apply__c();
+        //鑷畾涔夋牸寮忚浆鎹�
+        for (String fieldAPI: fieldValueMap.keySet()) {
+            system.debug('field API='+fieldAPI);
+            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'){
+                rentalApplyInfo.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',' ');
+                    rentalApplyInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
+                }else{
+                    rentalApplyInfo.put(fieldAPI, null);
+                }                    
+            }else if(String.valueof(fielddataType)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
+                rentalApplyInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?0:Decimal.valueOf(fieldValue)); 
+            } else if(String.valueof(fielddataType)=='BOOLEAN'){
+                rentalApplyInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
+            }else {
+                rentalApplyInfo.put(fieldAPI,fieldValue);
+            }
+            // system.debug('field API'+fieldAPI);
+            // String fieldValue = String.valueOf(fieldAPIToTypeMap.get(fieldAPI));
+            // if(String.isBlank(fieldValue) || String.isEmpty(fieldValue)){
+            //     continue;
+            // }
+            // Schema.DescribeFieldResult fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe();  
+            // Schema.DisplayType fieldDatas = fielddataType.getType();
+            // system.debug('fieldValue='+fieldValue);
+            // if(String.valueOf(fielddatas)=='DATE'){
+            //     rentalApplyInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
+            // }else if(String.valueOf(fielddatas)=='DATETIME'){
+            //     String dt = String.valueOf(fieldValueMap.get(fieldAPI));
+            //     if(String.isNotBlank(dt)&&dt.contains('T')){
+            //         dt = dt.replace('T',' ');
+            //         rentalApplyInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
+            //     }             
+            // }else if(String.valueOf(fielddatas)=='Number'||String.valueOf(fielddatas)=='DOUBLE'){
+            //     system.debug('decimal error:'+ String.valueOf(fieldValueMap.get(fieldAPI)));
+            //     rentalApplyInfo.put(fieldAPI, decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
+            // } else if(String.valueof(fielddatas)=='BOOLEAN'){
+            //     rentalApplyInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
+            // }else {
+            //     rentalApplyInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
+            // }                  
+        }
+        
+        //2. Save Record Process
+        String status = 'success';    
+        Response resp = new Response();
+        Savepoint sp = Database.setSavepoint();
+        String rid = '';
+        try{
+            System.debug('abcde');
+            if(isNew){
+                System.debug('rentalApplyInfozhj = ' + rentalApplyInfo);
+                insert rentalApplyInfo;
+                System.debug('rentalApplyInfo.Id' + rentalApplyInfo.Id);
+            }else{
+                System.debug('into update');
+                String awsDataId = (String)rentalApplyInfo.get('AWS_Data_Id__c');
+                System.debug('awsDataId = ' + awsDataId);
+                Rental_Apply__c[] RentalApplys = [select id from Rental_Apply__c where AWS_Data_Id__c =:awsDataId];
+                System.debug('RentalApplys[0].id = ' + RentalApplys[0].id);
+                rentalApplyInfo.put('Id',RentalApplys[0].id);//For testing;
+                update rentalApplyInfo;
+            }
+            rid=rentalApplyInfo.Id;
+            // PIHelper.saveTransLog(sobjectTypeValue,transId, (String)rentalApplyInfo.get('AWS_Data_Id__c'),rentalApplyJson ,status,'');
+            PIHelper.saveTransLog(sobjectTypeValue,(String)rentalApplyInfo.get('AWS_Data_Id__c'),rid,transId,rentalApplyJson,status,'');
+            resp.recordId = rid;
+            resp.message = 'success saveRentalApply';
+            resp.status = status;
+            System.debug('respzhj = ' + resp);
+            return resp;
+        } catch(Exception e) {
+            System.debug('into catch'+e.getMessage());
+            Database.rollback(sp);
+            status = 'fail';
+            // PIHelper.saveTransLog(sobjectTypeValue,transId, (String)rentalApplyInfo.get('AWS_Data_Id__c'),rentalApplyJson,status,e.getMessage());
+            PIHelper.saveTransLog(sobjectTypeValue,(String)rentalApplyInfo.get('AWS_Data_Id__c'),rid,transId,rentalApplyJson,status,e.getMessage());
+            resp.message = e.getMessage();            
+            resp.status = status;
+            return resp;
+        }
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/RentalApplyController.cls-meta.xml b/force-app/main/default/classes/RentalApplyController.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/RentalApplyController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/SObjectHelper.cls b/force-app/main/default/classes/SObjectHelper.cls
new file mode 100644
index 0000000..fd949b6
--- /dev/null
+++ b/force-app/main/default/classes/SObjectHelper.cls
@@ -0,0 +1,445 @@
+public without sharing class SObjectHelper {
+    
+    /**
+     * Copy every field values from from_sobj to to_sobj, if the field is in to_sobj and the value is not null
+     */
+    public static void MergeValue(Sobject to_sobj,Sobject from_sobj)
+    {
+        CopyTo(to_sobj,from_sobj,true);
+    }
+
+    /**
+     * Copy every field values from from_sobj to to_sobj
+     */
+    public static void OverwriteValue(Sobject to_sobj,Sobject from_sobj)
+    {
+        CopyTo(to_sobj,from_sobj,false);
+    }
+
+    static void CopyTo(Sobject to_sobj,Sobject from_sobj, Boolean skip_from_null)
+    {
+        Map<String, Schema.SObjectField> to_sobj_map = GetFields(to_sobj.getSObjectType().getDescribe().getName());
+        Map<String, Schema.SObjectField> from_sobj_map = GetFields(from_sobj.getSObjectType().getDescribe().getName());
+        for (string field : from_sobj_map.keySet()) {
+
+            object obj = from_sobj.get(field);
+            object obj1 = to_sobj.get(field);
+
+            if (obj != obj1 && to_sobj_map.containsKey(field) && to_sobj_map.get(field).getDescribe().isUpdateable()) {
+                
+                if (obj != null || !skip_from_null) {
+                    System.debug('obj='+obj);
+                    System.debug('obj1='+obj1);
+                    to_sobj.put(field, obj);
+                }
+            }
+        }
+    }
+
+
+
+
+    private static Map<string,Map<String, Schema.SObjectField>> sobject_field_map = new Map<string,Map<String, Schema.SObjectField>>();
+
+    public static Map<String, Schema.SObjectField> GetFieldMap(string obj_name)
+    {
+        Map<String, Schema.SObjectField> fm = null;
+        if(string.isBlank(obj_name))return fm;
+
+        if(sobject_field_map.containsKey(obj_name))
+        {
+            fm = sobject_field_map.get(obj_name);
+        }
+        else
+        {
+            fm = GetFields(obj_name);
+            if (fm != null) {
+                sobject_field_map.put(obj_name, fm);
+            }
+        }
+        return fm;
+    }
+/*
+    private static Map<string,Set<string>> sobject_common_fields = new Map<string,Set<string>>();
+
+    // get sobject fields that not be assigned in FieldPermission, they were stardard fields
+    public static Set<string> GetCommonFields(string obj_name)
+    {
+        Set<string> fields = null;
+        if(string.isBlank(obj_name))return fields;
+
+        if(sobject_common_fields.containsKey(obj_name))
+        {
+            fields = sobject_common_fields.get(obj_name);
+        }
+        else
+        {
+            Map<String, Schema.SObjectField> all_fields = GetFieldMap(obj_name);
+            Id profile_id = UserUtility.GetSysAdminProfileId();
+            List<FieldPermissions> lfp = [SELECT Id, ParentId, SobjectType, Field, PermissionsEdit, PermissionsRead, SystemModstamp FROM FieldPermissions
+            where parentId in (select id from permissionset where PermissionSet.Profile.Id = :profile_id) and sobjecttype = :obj_name ];
+            Set<string> admin_s = new Set<string>();
+            
+            for(FieldPermissions fp : lfp)
+            {
+                if(fp.PermissionsRead)
+                {
+                    admin_s.add(fp.Field.replace(fp.SobjectType+'.',''));
+                }
+            }
+            
+            // if a field not in admin's permission, the field is a common(standard) field
+            for (string f : all_fields.keySet()) {
+                if (!admin_s.contains(f) && !f.endsWith('__c')) {
+                    if (fields == null) {
+                        fields = new Set<string>();
+                    }
+                    fields.add(f);
+                }
+            }
+
+            if (fields != null) {
+                sobject_common_fields.put(obj_name, fields);
+            }
+        }
+        return fields;
+    }
+
+    public static Set<string> GetCurrentProfileAccessableFields(string obj_name)
+    {
+        return GetProfileAccessableFields(UserInfo.getProfileId(), obj_name);
+    }
+
+    private static Map<Id,Map<string,List<FieldPermissions>>> profile_field_permission_buffer = new Map<Id,Map<string,List<FieldPermissions>>>();
+
+    public static Set<string> GetProfileAccessableFields(Id profile_id, string obj_name)
+    {
+        List<FieldPermissions> lfp = null;
+        if(!profile_field_permission_buffer.containsKey(profile_id) || !profile_field_permission_buffer.get(profile_id).containsKey(obj_name)){
+            lfp = [SELECT Id, ParentId, SobjectType, Field, PermissionsEdit, PermissionsRead, SystemModstamp FROM FieldPermissions
+                                        where parentId in (select id from permissionset where PermissionSet.Profile.Id = :profile_id) and sobjecttype = :obj_name ];
+            system.debug(string.format('profile {0} object {1} updated ', new object[]{profile_id,obj_name,lfp.size()}));
+
+            Map<string,List<FieldPermissions>> temp = null;
+            if(profile_field_permission_buffer.containsKey(profile_id))
+            {
+                temp = profile_field_permission_buffer.get(profile_id);
+            }
+            else{
+                temp = new Map<string,List<FieldPermissions>>();
+                profile_field_permission_buffer.put(profile_id,temp);
+            }
+            
+            temp.put(obj_name,lfp);
+        }
+        else{
+            lfp = profile_field_permission_buffer.get(profile_id).get(obj_name);
+        }
+        Set<string> ls = new Set<string>();
+        for(FieldPermissions fp : lfp)
+        {
+            if(fp.PermissionsRead)
+            {
+                ls.add(fp.Field.replace(fp.SobjectType+'.',''));
+            }
+        }
+
+        Set<string> css = GetCommonFields(obj_name);
+        if (css != null) {
+            ls.addAll(css);
+        }
+
+        return ls;
+    }*/
+
+    public static Map<string,FieldInfo> GetFieldInfos(string obj_name)
+    {
+        Map<string,Schema.SObjectField> fields_map = SObjecthelper.GetFieldMap(obj_name);
+        if(fields_map == null)
+        {
+            return null;
+        }
+        Map<string,FieldInfo> res = new Map<string,FieldInfo>();
+        Map<string,FieldInfo> result = new Map<string,FieldInfo>();
+        FieldInfo temp = null;
+        for(string s : fields_map.keySet())
+        {
+
+            Schema.DescribeFieldResult dfr = fields_map.get(s).getDescribe();
+            temp = new FieldInfo();
+            temp.Name = dfr.getName();
+            temp.Label = dfr.getLabel();
+            
+            // resolve 'Business Phone' bug
+            if(obj_name.toLowerCase() == 'contact' && temp.Name =='Phone' && temp.Label =='Business Phone'){
+                temp.Label = 'Phone';
+            }
+            
+            Schema.DisplayType dt = dfr.getType();
+            temp.TypeEnumName = dt.name();
+            
+            
+            //temp.DisplayType = dt;
+            if((dt == schema.DisplayType.MULTIPICKLIST) || (dt == schema.DisplayType.PICKLIST) )
+            {
+                temp.Options = new List<Option>();
+                List<Schema.PicklistEntry> pick_list_values = dfr.getPickListValues();
+                for (Schema.PicklistEntry a : pick_list_values) {
+                    if (!a.isActive()) {
+                        continue;
+                    }
+
+                    Option lv = new Option();
+                    lv.label = a.getLabel();
+                    lv.value = a.getValue();
+                    temp.Options.add(lv);  
+                }
+            }
+            
+            if(dt == schema.DisplayType.REFERENCE )
+            {
+                temp.References = new List<Option>();
+                for(Schema.SObjectType reference : dfr.getReferenceTo()) {
+                    System.debug('Lookup reference object name: ' + reference.getDescribe().getName());
+                    System.debug('Lookup reference object label: ' + reference.getDescribe().getLabel());
+                    Option lv = new Option();
+                    lv.label = reference.getDescribe().getLabel();
+                    lv.value = reference.getDescribe().getName();
+                    temp.References.add(lv);  
+                }
+                List<Schema.PicklistEntry> pick_list_values = dfr.getPickListValues();
+                for (Schema.PicklistEntry a : pick_list_values) {
+                    if (!a.isActive()) {
+                        continue;
+                    }
+
+                    
+                }
+            }
+            
+            res.put(s,temp);
+        }
+        
+        return res;
+    }
+    
+    public static Map<String, Schema.SObjectField> GetFields(Sobject sobj ){
+        return GetFields(sobj.getSObjectType().getDescribe().getName());
+    }
+    
+    public static Map<String, Schema.SObjectField> GetFields(string obj_name )
+    {
+        Map<String, Schema.SObjectType> mss = Schema.getGlobalDescribe();
+        if(mss.containsKey(obj_name)){
+            return Transform(mss.get(obj_name).getDescribe().fields.getMap());
+        }
+        else{
+            return null;
+        }
+    }
+    
+    public static Map<String, Schema.FieldSet> GetFieldSets(string obj_name )
+    {
+        Map<String, Schema.SObjectType> mss = Schema.getGlobalDescribe();
+        if(!mss.containsKey(obj_name))return null;
+        Map<String, Schema.FieldSet> mssfs = mss.get(obj_name).getDescribe().fieldSets.getMap();
+        return mssfs;
+    }
+    
+    public static Map<String, Schema.FieldSetMember> GetFieldSet(string obj_name,string field_set_name )
+    {
+        Map<String, Schema.FieldSet> mssfs = GetFieldSets(obj_name);
+        if(!mssfs.containsKey(field_set_name))return null;
+        Map<String, Schema.FieldSetMember> result = new Map<String, Schema.FieldSetMember>();
+        for(Schema.FieldSetMember member : mssfs.get(field_set_name).getFields()){
+            Schema.SObjectField ssf = member.getSObjectField();
+            result.put(ssf.getDescribe().getName(),member);
+        }
+        return result;
+    }
+    
+    static Map<String, Schema.SObjectField> Transform(Map<String, Schema.SObjectField> mssof){
+        if(mssof == null)return null;
+        Map<String, Schema.SObjectField> result = new Map<String, Schema.SObjectField>();
+        for(string key : mssof.keySet()){
+            result.put(mssof.get(key).getDescribe().getName(),mssof.get(key));
+        }
+        return result;
+    }
+    /*
+    static Map<String, Schema.FieldSet> Transform(Map<String, Schema.FieldSet> mssfs){
+        if(mssfs == null)return null;
+        Map<String, Schema.FieldSet> result = new Map<String, Schema.FieldSet>();
+        for(string key : mssfs.keySet()){
+            result.put(mssfs.get(key).getName(),mssfs.get(key));
+        }
+        return result;
+    }*/
+    
+    public static Map<string,string> GetPicklistLabelValueMap(string objectName, string fieldName){
+        
+        List<Schema.PicklistEntry> temp = GetPicklistEntryList(objectName,fieldName);
+        if(temp == null)return null;
+        
+        Map<string,string> res = new Map<string,string>();
+        
+        for(Schema.PicklistEntry pe : temp){
+            res.put(pe.getLabel(),pe.getValue());
+        }
+        return res;
+    }
+    
+    public static Map<string,string> GetPicklistValueLabelMap(string objectName, string fieldName){
+        
+        List<Schema.PicklistEntry> temp = GetPicklistEntryList(objectName,fieldName);
+        if(temp == null)return null;
+        
+        Map<string,string> res = new Map<string,string>();
+        
+        for(Schema.PicklistEntry pe : temp){
+            res.put(pe.getValue(),pe.getLabel());
+        }
+        return res;
+    }
+    
+    public static List<Schema.PicklistEntry> GetPicklistEntryList(string objectName, string fieldName){
+        
+        Map<String,String> picklistMap = new Map<String,String>();
+        Schema.SObjectType targetSobjectType = Schema.getGlobalDescribe().get(objectName);
+        Schema.DescribeSObjectResult objectDescribe = targetSobjectType.getDescribe(); 
+        Map<String, Schema.SObjectField> fieldMap = objectDescribe.fields.getMap();
+        if(!fieldMap.containsKey(fieldName))return null;
+        List<Schema.PicklistEntry> picklistEntries = fieldMap.get(fieldName).getDescribe().getPickListValues(); 
+        return picklistEntries;
+    }
+        
+	
+    
+    
+    
+    
+    public static string GetFieldDescription(string object_name, string field_name){
+
+        if(string.isBlank(object_name) || String.isBlank(field_name))return null;
+
+        // List<FieldDefinition> fd = [Select Label, QualifiedApiName, Description from FieldDefinition Where EntityDefinition.QualifiedApiName=:object_name and QualifiedApiName=:field_name];
+        List<FieldDefinition> fds = GetFieldDefinitions(object_name);
+        for(FieldDefinition fd : fds)
+        {
+            if(fd.QualifiedApiName == field_name){
+                return fd.Description;
+            }
+        }
+        return null;
+    }
+    
+    public static List<FieldDefinition> GetFieldDefinitions(string object_name){
+        return [Select Label, QualifiedApiName, Description from FieldDefinition Where EntityDefinition.QualifiedApiName=:object_name];
+    }
+    
+    /*
+    public static Schema.FieldSet GetFieldSet(string obj_name,string fieldset_name )
+    {
+        Map<String, Schema.FieldSet> msf = GetFieldSets(obj_name);
+        if(msf.containsKey(fieldset_name))return msf.get(fieldset_name);
+        return null;
+    }
+    
+    public static Schema.FieldSet GetFieldSetByName(string obj_name,string fieldset_name )
+    {
+        Map<String, Schema.FieldSet> msf = GetFieldSets(obj_name);
+        for(string key : msf.keyset())
+        {
+            if(msf.get(key).getName() == fieldset_name )
+            {
+                return msf.get(key);
+            }
+        }
+        return null;
+    }*/
+    
+
+    /**
+     * get sobject field value, support forign field if it was queried
+     * e.g. GetSObjectField(lead_obj,'Owner.Name')
+     */
+    public static object GetSObjectField(object o,string f_str){
+        return GetSObjectField((sobject)o,f_str);
+    }
+    
+    /**
+     * get sobject field value, support forign field if it was queried
+     * e.g. GetSObjectField(lead_obj,'Owner.Name')
+     */
+    public static object GetSObjectField(sobject o,string f_str){
+        List<string> fields = f_str.split('\\.');
+        //system.debug('fields = ' + fields);
+        sobject temp = o;
+        Object result = null;
+        for(integer i =0; i < fields.size();i++){
+            
+            if(temp == null) return null;
+
+            if(i==fields.size()-1){
+                result = temp.get(fields[i]);
+            }
+            else{
+                temp = temp.getSObject(fields[i]);
+            }
+            
+            /*
+            if(result instanceof SObject){
+                temp = (SObject)result;
+                continue;
+            }
+            break;*/
+        }
+        
+        return result;
+    }
+    
+    /*
+    public static Schema.FieldSet GetFieldSetByLabel(string obj_name,string fieldset_lable )
+    {
+        Map<String, Schema.FieldSet> msf = GetFieldSets(obj_name);
+        for(string key : msf.keyset())
+        {
+            if(msf.get(key).getLabel() == fieldset_lable )
+            {
+                return msf.get(key);
+            }
+        }
+        return null;
+    }*/
+
+    public static List<string> GetMultiPickListOptions(string val){
+        return GetOptions(val);
+    }
+	
+    public static List<string> GetOptions(string val){
+        if(val == null)return new List<string>();
+            return ValidMultiPickListValue(val).split(';');
+    }
+    
+    public static string AppendValueToMultiPickList(string old_val,string val){
+        return ValidMultiPickListValue(old_val+';'+val);
+    }
+    
+    public static string ValidMultiPickListValue( string val ){
+        if(string.isBlank(val))return val;
+        return ValidMultiPickListValue(val.split(';'));
+    }
+    
+    public static string ValidMultiPickListValue( List<string> vals ){
+        if(vals == null ) vals = new List<string>();
+        Set<string> ss = new Set<string>(vals);
+        List<string> ls = new List<string>();
+        for(string s : ss){
+            if(string.isBlank(s)){
+                continue;
+            }
+            ls.add(s);
+        }
+        return string.join(ls, ';');
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/SObjectHelper.cls-meta.xml b/force-app/main/default/classes/SObjectHelper.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/SObjectHelper.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/SearchContactController.cls b/force-app/main/default/classes/SearchContactController.cls
new file mode 100644
index 0000000..aa95550
--- /dev/null
+++ b/force-app/main/default/classes/SearchContactController.cls
@@ -0,0 +1,61 @@
+/*
+ * Author: Bubba Li
+ * Created Date: 02/08/2022
+ * Purpose: SearchContactController
+ * Test Class: SearchContactController
+ * History: 
+ *      02/08/2022 - Bubba Li - Initial Code.
+ * 
+ * */
+public without sharing class SearchContactController {
+    public String searchKeyWord{set;get;}
+    public String staticResource {get; set;}
+    public String contactAWSIds {set;get;}
+    public String contactsInfo {set;get;}
+    public String PIPL_Search_Contact_Label{set;get;}
+    public SearchContactController() {
+        String accountId = ApexPages.currentPage().getParameters().get('accountId');
+        PIPL_Search_Contact_Label = Label.PIPL_Search_Contact_Label;
+        //1. Query Contact by accountId
+        List<Contact> conList = new List<Contact>();
+        system.debug('Account Id from Front-end:'+accountId);
+        if(String.isNotBlank(accountId) && String.isNotEmpty(accountId)){
+            conList = new List<Contact>([select Id,AWS_Data_Id__c from Contact where AccountId=:accountId and AWS_Data_Id__c!='']);
+        }        
+        //2. Prepare the Contact Info
+        Map<String,Contact> awsIdToContactMap = new Map<String,Contact>();
+        List<String> conAWSIds = new List<String>();
+        for(Contact con:conList){
+            conAWSIds.add(con.AWS_Data_Id__c);
+            awsIdToContactMap.put(con.AWS_Data_Id__c,con);
+        }
+        contactsInfo = JSON.serialize(awsIdToContactMap);
+        contactAWSIds = JSON.serialize(conAWSIds);
+        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));        
+    }
+
+    @RemoteAction
+    public static Response searchContacts(String awsContactIds) {
+        Response resp = new Response();
+        resp.status = 'fail';
+        if(String.isBlank(awsContactIds)||String.isEmpty(awsContactIds)){
+            return resp;
+        }
+        List<String> awsDataIds = (List<String>) JSON.deserialize(awsContactIds, List<String>.class);
+        Map<String,Contact> awsIdToContactMapTemp = new Map<String,Contact>();
+        List<Contact> conListTemp = new List<Contact>([select Id,AWS_Data_Id__c from Contact where AWS_Data_Id__c in:awsDataIds]);
+        for(Contact con:conListTemp){
+            awsIdToContactMapTemp.put(con.AWS_Data_Id__c,con);
+        }
+        if(awsIdToContactMapTemp.keySet().size()>0){
+            resp.status = 'success';
+            resp.message = JSON.serialize(awsIdToContactMapTemp);
+        }
+        return resp;
+    }
+
+    public class Response{
+        public String message{set;get;}
+        public String status{set;get;}
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/SearchContactController.cls-meta.xml b/force-app/main/default/classes/SearchContactController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/SearchContactController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/SearchLeadController.cls b/force-app/main/default/classes/SearchLeadController.cls
new file mode 100644
index 0000000..c752de2
--- /dev/null
+++ b/force-app/main/default/classes/SearchLeadController.cls
@@ -0,0 +1,53 @@
+public without sharing class SearchLeadController {
+    public String searchKeyWord{set;get;}
+    public String staticResource {get; set;}
+    public String leadAWSIds {set;get;}
+    public String leadsInfo {set;get;}
+    public String PIPL_Search_Contact_Label{set;get;}
+    public SearchLeadController() {
+        // String accountId = ApexPages.currentPage().getParameters().get('accountId');
+        PIPL_Search_Contact_Label = Label.PIPL_Search_Contact_Label;
+        //1. Query Contact by accountId
+        List<Lead> leadList = new List<Lead>();
+        // system.debug('Account Id from Front-end:'+accountId);
+        // if(String.isNotBlank(accountId) && String.isNotEmpty(accountId)){
+        //     leadList = new List<Lead>([select Id,AWS_Data_Id__c from Lead where AccountId=:accountId and AWS_Data_Id__c!='']);
+        // }    
+        leadList = new List<Lead>([select Id,AWS_Data_Id__c from Lead where AWS_Data_Id__c!='']);    
+        //2. Prepare the Contact Info
+        Map<String,Lead> awsIdToLeadMap = new Map<String,Lead>();
+        List<String> leAWSIds = new List<String>();
+        for(Lead le:leadList){
+            leAWSIds.add(le.AWS_Data_Id__c);
+            awsIdToLeadMap.put(le.AWS_Data_Id__c,le);
+        }
+        leadsInfo = JSON.serialize(awsIdToLeadMap);
+        leadAWSIds = JSON.serialize(leAWSIds);
+        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Lead'));        
+    }
+
+    @RemoteAction
+    public static Response searchLeads(String awsLeadIds) {
+        Response resp = new Response();
+        resp.status = 'fail';
+        if(String.isBlank(awsLeadIds)||String.isEmpty(awsLeadIds)){
+            return resp;
+        }
+        List<String> awsDataIds = (List<String>) JSON.deserialize(awsLeadIds, List<String>.class);
+        Map<String,Lead> awsIdToLeadMapTemp = new Map<String,Lead>();
+        List<Lead> leadListTemp = new List<Lead>([select Id,AWS_Data_Id__c from Lead where AWS_Data_Id__c in:awsDataIds]);
+        for(Lead le:leadListTemp){
+            awsIdToLeadMapTemp.put(le.AWS_Data_Id__c,le);
+        }
+        if(awsIdToLeadMapTemp.keySet().size()>0){
+            resp.status = 'success';
+            resp.message = JSON.serialize(awsIdToLeadMapTemp);
+        }
+        return resp;
+    }
+
+    public class Response{
+        public String message{set;get;}
+        public String status{set;get;}
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/SearchLeadController.cls-meta.xml b/force-app/main/default/classes/SearchLeadController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/SearchLeadController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/SoqlHelper.cls b/force-app/main/default/classes/SoqlHelper.cls
new file mode 100644
index 0000000..1aaee51
--- /dev/null
+++ b/force-app/main/default/classes/SoqlHelper.cls
@@ -0,0 +1,136 @@
+public  class SoqlHelper {
+
+    public static string DistinctQueryFields(string sql)
+    {
+        string query_fields = sql;
+        if (query_fields == null) {
+            return null;
+        }
+        query_fields = query_fields.trim();
+        Integer sel_i = query_fields.indexOfIgnoreCase('select ');
+        string sel = 'select ';
+        
+        if ( sel_i < 0) {
+            sel = '';
+        }
+
+        string whe = '';
+        Integer whe_i = query_fields.indexOfIgnoreCase(' from ');
+        if ( whe_i >= 0) {
+            whe = query_fields.substring(whe_i);
+        }
+        string query = query_fields.substring(sel_i < 0 ? 0 : sel.length(), whe_i < 0 ? query_fields.length() : whe_i);
+        Set<string> ss = new Set<string>();
+        for(string f : query.split(',')){
+            string s = f.trim().toLowerCase();
+            //System.debug('s='+s);
+            ss.add(s);
+        }
+
+        return sel + QueryFields(ss) + whe;
+
+    }
+    
+    public static string WId(string wid){
+        return '\'' + wid + '\'';
+    }
+   
+    public static string QueryFields(Set<string> lo){
+        return QueryFields(new List<string>(lo));
+    }
+    
+    public static string QueryFields(List<object> lo){
+        return string.join(lo, ',');
+    }
+
+    public static string ToInCondition(List<AggregateResult> lar ,string key)
+    {
+        if(lar==null || lar.size() == 0)
+        {
+            return null;
+        }
+        
+        string ss = ' ( ';
+        boolean b = true;
+        for(AggregateResult ar : lar)
+        {
+            if(ar.get(key)==null)continue;
+            if( b )
+            {
+                b = false;
+                ss += '\''+ar.get(key)+'\'';
+            }
+            else
+            {
+                ss += ',\''+ar.get(key)+'\'';
+            }
+            
+        }
+        ss+=') ';
+        return ss;
+    }
+    
+    public static string ToInCondition(Set<string> so){
+        return ToInCondition(new List<string>(so));
+    }
+    
+    public static string ToInCondition(List<object> lo)
+    {
+        Set<object> so = new Set<object>(lo);
+        lo = new List<object>(so);
+        return '(\''+ string.join(lo, '\',\'')+'\')';
+    }
+    
+    public static void InsertList(List<Sobject> so_list)
+    {
+        if(so_list == null || so_list.size() == 0)return;
+        insert so_list;
+    }
+    
+    public static void UpdateList(List<Sobject> so_list)
+    {
+        if(so_list == null || so_list.size() == 0)return;
+        update so_list;
+    }
+    
+    public static Map<string,Database.UpsertResult> UpsertList(List<Sobject> so_list, Schema.SObjectField field)
+    {
+        Map<string,Database.UpsertResult> mid = new Map<string,Database.UpsertResult>();
+        if(so_list == null || so_list.size() == 0)return mid;
+        List<Database.UpsertResult> urList2 = Database.upsert( so_list, field, false);
+        
+        Set<String> accBasicRecordIdSet = new Set<String>();
+        integer index = 0;
+        string errorString = '';
+        string field_str = field.getDescribe().getName();
+        for(Database.UpsertResult ur : urList2){
+            if(!ur.IsSuccess()){
+                object fv = so_list[index].get(field_str);
+                
+                mid.put(fv+'',ur);
+                errorString = '';
+                for(Database.Error errs: ur.getErrors()){
+                    errorString += errs.getMessage() + ';';
+                }
+                //LogHelper.CreateRunTimeLog('runtime error', errorString, false, fv+'');
+            }
+            index++;
+        }
+        return mid;
+    }
+    
+    public static void DeleteList(List<Sobject> so_list)
+    {
+        if(so_list == null || so_list.size() == 0)return;
+        delete so_list;
+    }
+
+
+    @future
+    public static void DeleteListAsync(List<Id> id_list)
+    {
+        if(id_list == null || id_list.size() == 0)return;
+        Database.delete(id_list);
+    }
+    
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/SoqlHelper.cls-meta.xml b/force-app/main/default/classes/SoqlHelper.cls-meta.xml
new file mode 100644
index 0000000..40d6793
--- /dev/null
+++ b/force-app/main/default/classes/SoqlHelper.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/TestClass.cls b/force-app/main/default/classes/TestClass.cls
new file mode 100644
index 0000000..b0a0bb3
--- /dev/null
+++ b/force-app/main/default/classes/TestClass.cls
@@ -0,0 +1,41 @@
+public without sharing class TestClass 
+{
+    public static List<Metadata.LayoutSection> GetLayoutSections(string object_name, string layout_name){
+        List<String> componentNameList = new List<String>{object_name+'-'+layout_name};
+        //閫氳繃Metadata.Operations.retrieve鑾峰彇metadata
+        //Metadata.Layout -> Metadata.LayoutSection -> Metadata.LayoutColumn objects -> Metadata.LayoutItem objects
+        List<Metadata.Metadata> componentList = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, componentNameList);
+        if(componentList?.size() > 0){
+            Metadata.Layout layout = (Metadata.Layout) componentList.get(0);
+            List<Metadata.LayoutSection> layoutSectionList = layout.layoutSections;
+            return layoutSectionList;
+        }
+        else{
+            return null;
+        }
+        
+    }
+
+    public static void Foo(){
+        string query = 'SELECT Layout.Name, Layout.TableEnumOrId, ProfileId, Profile.Name, RecordTypeId FROM ProfileLayout where recordtypeid=\'01210000000QfWdAAK\'';
+
+        String baseURL = URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v41.0/tooling/query?q='+ query.replace(' ', '+');
+        HttpResponse resp = null;
+        HttpRequest req = new HttpRequest();         
+        req.setMethod('GET');        
+        req.setHeader('Authorization', 'Bearer ' + UserInfo.getsessionid()); 
+        req.setEndpoint(baseURL); 
+        Http client = new Http();    
+        resp = client.send(req);
+        Map<string,object> mso = (Map<string,object>)JSON.deserializeUntyped(resp.getBody());
+        for(string key : mso.keySet()){
+            system.debug('key='+key);
+            system.debug(mso.get(key));
+        }
+        mso = (Map<string,object>)(((List<object>)mso.get('records'))[0]);
+        for(string key : mso.keySet()){
+            system.debug('key='+key);
+            system.debug(mso.get(key));
+        }
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/TestClass.cls-meta.xml b/force-app/main/default/classes/TestClass.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/TestClass.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/TestController.cls b/force-app/main/default/classes/TestController.cls
new file mode 100644
index 0000000..4279e5e
--- /dev/null
+++ b/force-app/main/default/classes/TestController.cls
@@ -0,0 +1,15 @@
+public without sharing class TestController extends NewAndEditBaseController 
+{
+    public TestController(ApexPages.StandardController controller) {
+        
+        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Inquiry_form__c').getDescribe().fields.getMap().keyset());  
+        // Add fields to controller. This is to avoid the SOQL error in visualforce page
+        controller.addFields(fieldList);
+        LookUpOverrideFields.add('Contact_Name__c');
+        //娣诲姞椤�
+        Init(controller.getRecord());
+        system.debug(LookUpOverrideFieldsMapJson);
+    }
+
+
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/TestController.cls-meta.xml b/force-app/main/default/classes/TestController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/TestController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/classes/ViewParticipantsController.cls b/force-app/main/default/classes/ViewParticipantsController.cls
new file mode 100644
index 0000000..f88d12b
--- /dev/null
+++ b/force-app/main/default/classes/ViewParticipantsController.cls
@@ -0,0 +1,6 @@
+global class ViewParticipantsController {
+    public String staticResourceContact {get; set;}
+    public ViewParticipantsController(ApexPages.StandardController controller) {
+        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
+    }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/ViewParticipantsController.cls-meta.xml b/force-app/main/default/classes/ViewParticipantsController.cls-meta.xml
new file mode 100644
index 0000000..dd61d1f
--- /dev/null
+++ b/force-app/main/default/classes/ViewParticipantsController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexClass>
diff --git a/force-app/main/default/pages/B_Test.page b/force-app/main/default/pages/B_Test.page
new file mode 100644
index 0000000..e036be2
--- /dev/null
+++ b/force-app/main/default/pages/B_Test.page
@@ -0,0 +1,304 @@
+<apex:page id="Page" controller="B_Test" sidebar="false" showHeader="false" action="{!init}">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script type="text/javascript">
+    var staticResources = JSON.parse('{!staticResource}');
+    	var awsResult = [{
+聽聽聽聽聽聽聽聽聽聽聽聽"dataId":聽"942720697313001472",
+聽聽聽聽聽聽聽聽聽聽聽聽"isDelete":聽0,
+聽聽聽聽聽聽聽聽聽聽聽聽"lastName":聽"寮犱笁12312321",
+聽聽聽聽聽聽聽聽聽聽聽聽"phone":聽"2988a8e6bcc90e83f54f81bc841aa822",
+聽聽聽聽聽聽聽聽聽聽聽聽"email":聽"d0152175c99a1c050f46d0d23996ff987b738add75e73c476b65611ba4a2b1b5",
+聽聽聽聽聽聽聽聽聽聽聽聽"medicalStaffFullName":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"mobilePhone":聽"2988a8e6bcc90e83f54f81bc841aa822",
+聽聽聽聽聽聽聽聽聽聽聽聽"title":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"olyAssistantType":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"jobCategoryPicklist":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"type":聽"3b13e2b5c5fd4003a931a38dcaf1c545",
+聽聽聽聽聽聽聽聽聽聽聽聽"contactAddress":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"contactType":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"doctorDivision1":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"uniqueNumber":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"lastNameEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"phoneEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"emailEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"medicalStaffFullNameEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"mobilePhoneEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"titleEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"olyAssistantTypeEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"jobCategoryPicklistEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"typeEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"contactAddressEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"contactTypeEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"doctorDivision1Encrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"uniqueNumberEncrypt":聽null
+聽聽聽聽聽聽聽聽},{
+聽聽聽聽聽聽聽聽聽聽聽聽"dataId":聽"942720697313001472",
+聽聽聽聽聽聽聽聽聽聽聽聽"isDelete":聽0,
+聽聽聽聽聽聽聽聽聽聽聽聽"lastName":聽"鏉庡洓12312321",
+聽聽聽聽聽聽聽聽聽聽聽聽"phone":聽"2988a8e6bcc90e83f54f81bc841aa822",
+聽聽聽聽聽聽聽聽聽聽聽聽"email":聽"d0152175c99a1c050f46d0d23996ff987b738add75e73c476b65611ba4a2b1b5",
+聽聽聽聽聽聽聽聽聽聽聽聽"medicalStaffFullName":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"mobilePhone":聽"2988a8e6bcc90e83f54f81bc841aa822",
+聽聽聽聽聽聽聽聽聽聽聽聽"title":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"olyAssistantType":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"jobCategoryPicklist":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"type":聽"3b13e2b5c5fd4003a931a38dcaf1c545",
+聽聽聽聽聽聽聽聽聽聽聽聽"contactAddress":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"contactType":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"doctorDivision1":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"uniqueNumber":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"lastNameEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"phoneEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"emailEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"medicalStaffFullNameEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"mobilePhoneEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"titleEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"olyAssistantTypeEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"jobCategoryPicklistEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"typeEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"contactAddressEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"contactTypeEncrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"doctorDivision1Encrypt":聽null,
+聽聽聽聽聽聽聽聽聽聽聽聽"uniqueNumberEncrypt":聽null
+聽聽聽聽聽聽聽聽}];
+
+
+        var now_edit_id = '';
+        function sobjectToAws(){
+            return {
+                "LastName":"寮犱笁",
+                "Phone":"13800138000"
+            }
+        }
+
+        function searchContactJs() {
+            blockme();
+            searchContact();
+        }
+
+        function editContactJs(conid) {
+            blockme();
+            now_edit_id=conid;
+            editContact(conid);
+        }
+
+        function editSaveJs() {
+            blockme();
+            ProcessPI({},GetEditObj());
+        }
+
+        function editClearJs() {
+            blockme();
+            editClear();
+        }
+
+        function setContact(line) {
+            var openLine = '{!openLine}';
+            var cm = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':contact';
+            var cmid = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':contactId';
+
+
+            var conid = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':conId')).value();
+            var conname = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':conName')).value();
+
+            j$(escapeVfId(cmid),window.opener.document).val(conid);
+            j$(escapeVfId(cm),window.opener.document).val(conname);
+
+            // SWAG-BB44G7  璁剧疆鎵�鍦ㄧ瀹ゅ悕瀛楀拰id鐨勪綅缃拰鍐呭 start
+            var department = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':department';
+            var departmentid = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':departmentid';
+            var departmentHidden = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':departmentHidden';
+            var departmentHiddenId = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':departmentHiddenId';
+            var accid = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':accountid')).value();
+            var accName = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':accountName')).value();
+            
+            j$(escapeVfId(department),window.opener.document).val(accName);
+            j$(escapeVfId(departmentid),window.opener.document).val(accid);
+            j$(escapeVfId(departmentHidden),window.opener.document).val(accName);
+            j$(escapeVfId(departmentHiddenId),window.opener.document).val(accid);
+
+
+            // SWAG-BB44G7  璁剧疆鎵�鍦ㄧ瀹ゅ悕瀛楀拰id鐨勪綅缃拰鍐呭 end 
+
+            window.close();
+        }
+    
+    	jQuery(function(){
+            alert("Init杩斿洖涔嬪悗锛岀户缁煡璇WS");
+        	
+        })
+
+
+        
+/*
+        function insertOrUpdateBack(payloadJson, r, isNewMode){
+                
+            payloadJson.LastName = r.object[0].lastName;
+            payloadJson.Phone = r.object[0].phone;
+            payloadJson.LastName_Encrypted__c = r.object[0].lastNameEncrypted;
+            payloadJson.Phone_Encrypted__c = r.object[0].phoneEncrypted;
+            payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+            return payloadJson;
+        }*/
+
+        var aws_result = {};
+        function GetAWSResultObj(){
+            if(aws_result && aws_result.object && aws_result.object.length > 0){
+                return aws_result.object[0];
+            }
+            return null;
+        }
+        function ProcessPI(sobjJson, payloadForNewPI) {
+            //blockme();
+            let url = staticResources.newUrl
+            if (now_edit_id) {
+            	url = staticResources.updateUrl
+            }
+            AWSService.post(staticResources.updateUrl, payloadForNewPI, function(result){
+                aws_result = result;
+                SetEditObj();
+                saveNew();
+            }, staticResources.token);
+        }
+
+        function Trans(){
+            let status = aws_result.status == '0';
+
+            AWSService.sfdcBack({status:status}, aws_result, aws_result.txId, staticResources.token, staticResources.transactionURL,function(){
+                unblockUI();
+            })
+        }
+
+
+    </script>
+
+    <apex:form id="allForm">
+       
+
+        <apex:actionFunction name="searchContact" action="{!searchContact}" rerender="allForm" onComplete="unblockUI();">
+        </apex:actionFunction>
+        <apex:actionFunction name="editContact" action="{!editContact}" rerender="allForm" onComplete="unblockUI();assignUnencrypted()">
+            <apex:param name="firstParam" assignTo="{!conId}" value="" />
+        </apex:actionFunction>
+        <apex:actionFunction name="saveNew" action="{!saveNew}" rerender="allForm" onComplete="Trans();">
+        </apex:actionFunction>
+        <apex:actionFunction name="editClear" action="{!editClear}" rerender="allForm" onComplete="unblockUI();">
+        </apex:actionFunction>
+
+        <apex:outputPanel id="allPanel">
+            <apex:pageBlock id="searchBlock" title="妫�绱㈡潯浠�">
+                <table class="linetable" border="0" style="border-collapse: collapse;width:600px;table-layout:fixed;">
+                    <colgroup>
+                        <col width="50px" />
+                        <col width="150px" />
+                        <col width="50px" />
+                        <col width="150px" />
+                        <col width="200px" />
+                    </colgroup>
+                    <tr>
+                        <td>{!$ObjectType.Contact.fields.LastName.Label}</td>
+                        <td><apex:inputField value="{!searchCon.Search_LastName__c}" style="width: 90%"/></td>
+                        <td>{!$ObjectType.Contact.fields.FirstName.Label}</td>
+                        <td><apex:inputField value="{!searchCon.Search_FirstName__c}" style="width: 90%"/></td>
+                        <td><input type="button" value="妫�绱�" onclick="searchContactJs(); return null;" /></td>
+                    </tr>
+                </table>
+            </apex:pageBlock>
+
+            <apex:pageBlock id="listBlock" title="妫�绱㈢粨鏋�">
+            <div style="height: 200px; overflow-y: auto; overflow-x: hidden;">
+                <table class="edittable" border="0" style="border-collapse: collapse;width:580px;table-layout:fixed;">
+                    <colgroup>
+                        <col width="50px" />
+                        <col width="100px" />
+                        <col width="380px" />
+                        <col width="50px" />
+                    </colgroup>
+                    <tr>
+                        <th>No.</th>
+                        <th>{!$ObjectType.Contact.fields.Name.Label}</th>
+                        <th>{!$ObjectType.Contact.fields.AccountName__c.Label}</th>
+                        <th>鎿嶄綔</th>
+                    </tr>
+                    <apex:repeat id="lineinfo" value="{!lineInfoList}" var="lineinfo">
+                    <tr>
+                        <td>{!lineinfo.lineNo}
+                            <apex:inputHidden id="conId" value="{!lineinfo.con.id}"/>
+                            <apex:inputHidden id="conName" value="{!lineinfo.con.name}"/>
+                            <apex:inputHidden id="accountName" value="{!lineinfo.con.AccountName__c}"/>
+                            <apex:inputHidden id="accountid" value="{!lineinfo.con.accountid}"/>
+                        </td>
+                        <td><a href="#" onclick="setContact('{!lineinfo.lineNo}');">{!lineinfo.con.Name}</a></td>
+                        <td>{!lineinfo.con.AccountName__c}</td>
+                        <td><input style="width:90%;" type="button" value="缂栬緫" onclick="editContactJs('{!lineinfo.con.Id}'); return null;" /></td>
+                    </tr>
+                    </apex:repeat>
+                </table>
+            </div>
+            </apex:pageBlock>
+            <script>
+                function assignUnencrypted(){
+                    let obj = sobjectToAws();
+                    document.getElementById("Page:allForm:editBlock:Search_LastName__c").value = obj.LastName;
+                    document.getElementById("Page:allForm:editBlock:Phone").value = obj.Phone;
+                }
+
+                function GetEditObj(){
+                    return JSON.stringify([{
+                        lastName : document.getElementById("Page:allForm:editBlock:Search_LastName__c").value,
+                        phone : document.getElementById("Page:allForm:editBlock:Phone").value,
+                        dataId:document.getElementById("Page:allForm:editBlock:AWS_Data_Id__c").value,
+                    }]);
+                }
+
+                function SetEditObj(){
+                    let obj = GetAWSResultObj();
+                    if(obj){
+                        document.getElementById("Page:allForm:editBlock:Search_LastName__c").value = obj.lastName;
+                        document.getElementById("Page:allForm:editBlock:LastName_Encrypted__c").value = obj.lastNameEncrypt;
+                        document.getElementById("Page:allForm:editBlock:Phone").value = obj.phone;
+                        document.getElementById("Page:allForm:editBlock:Phone_Encrypted__c").value = obj.phoneEncrypt;
+                    }
+                    
+                }
+            </script>
+            <apex:pageBlock id="editBlock" title="鑱旂郴浜虹紪杈�">
+                <apex:pageBlockButtons location="top">
+                    <apex:commandButton onclick="editClearJs();" value="娓呯┖" rerender="dummy"/>
+                    <apex:commandButton onclick="editSaveJs();" value="淇濆瓨" rerender="dummy"/>
+                </apex:pageBlockButtons>
+                
+                <apex:inputHidden id="LastName_Encrypted__c" value="{!newCon.LastName_Encrypted__c}"/>
+                <apex:inputHidden id="Phone_Encrypted__c" value="{!newCon.Phone_Encrypted__c}"/>
+                <apex:inputHidden id="AWS_Data_Id__c" value="{!newCon.AWS_Data_Id__c}"/>
+                <table class="edittable" border="0" style="border-collapse: collapse; width:600px; table-layout:fixed;">
+                    <colgroup>
+                        <col width="50px" />
+                        <col width="150px" />
+                        <col width="50px" />
+                        <col width="150px" />
+                        <col width="50px" />
+                        <col width="150px" />
+                    </colgroup>
+                    <tr>
+                        <td>{!$ObjectType.Contact.fields.LastName.Label}</td>
+                        <td><span><div class="requiredInput"><div class="requiredBlock"></div>
+                            <apex:inputField id="Search_LastName__c" value="{!newCon.Search_LastName__c}" style="width: 90%"/>
+                        </div></span></td>
+                        
+                        <td>{!$ObjectType.Contact.fields.Phone.Label}</td>
+                        <td><apex:inputField id="Phone" value="{!newCon.Phone}" style="width: 90%"/></td>
+                    </tr>
+                    <tr>
+                        <td>{!$ObjectType.Contact.fields.Supplement__c.Label}</td>
+                        <td colspan="5"><apex:inputField id="Supplement__c" value="{!newCon.Supplement__c}" style="width: 95%; resize: none; height: 50px"/></td>
+                    </tr>
+                </table>
+            </apex:pageBlock>
+
+        </apex:outputPanel>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/B_Test.page-meta.xml b/force-app/main/default/pages/B_Test.page-meta.xml
new file mode 100644
index 0000000..6dd5fce
--- /dev/null
+++ b/force-app/main/default/pages/B_Test.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>B_Test</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ConsumApplyUploadPdf.page b/force-app/main/default/pages/ConsumApplyUploadPdf.page
new file mode 100644
index 0000000..d628e99
--- /dev/null
+++ b/force-app/main/default/pages/ConsumApplyUploadPdf.page
@@ -0,0 +1,190 @@
+<!-- 璇ラ〉闈㈢敤浜嶭ead瀵硅薄涓婁紶PDF锛屾湭鏉ュ鏋滆娣诲姞鍏朵粬瀵硅薄鐨勪笂浼燩DF鍔熻兘锛屽鍒惰椤甸潰锛屽皢**standardController**淇敼涓哄叾浠栧璞PI鍚嶇О鍗冲彲 -->
+<apex:page standardController="Consum_Apply__c" extensions="FileUploadController" id="page" lightningStyleSheets="true">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script>
+        var staticResources = JSON.parse('{!staticResource}');
+        var parentId = '{!parentId}';
+        var uploadUrl = staticResources.newUrl;
+        var key;
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:theForm:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'message errorM3';
+        }
+
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:theForm:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+        function getFileContent(event) {
+            var fileObject = document.getElementById("page:theForm:block:uploadSection:file");
+            var reader = new FileReader();
+            var data = reader.readAsDataURL(fileObject.files[0]);
+            debugger
+            console.log(event);
+        }
+        function getBase64(file) {
+            return new Promise((resolve, reject) => {
+                const reader = new FileReader();
+                reader.readAsDataURL(file);
+                reader.onload = () => resolve(reader.result);
+                reader.onerror = error => reject(error);
+            });
+        }
+        function disableButtonStatus() {
+            let btnNode = document.getElementById('uploadFileId');
+            btnNode.classList.add("btnDisabled");
+        }
+
+        function enableButtonStatus() {
+            let btnNode = document.getElementById('uploadFileId');
+            btnNode.classList.remove("btnDisabled");
+        }
+
+        function uploadFile() {
+            disableButtonStatus();
+            var fileObject = document.getElementById("file").files[0];
+            getBase64(fileObject).then(
+                data => {
+                    console.log(data);
+                    uploadFileToAWS(data, (fileObject.size).toString(), fileObject.name);
+                    
+                }
+            );
+        }
+        function confirmTrans(transId, isSuccess) {
+            
+            fetch(staticResources.updateUrl, {
+                method: 'POST',
+                body: JSON.stringify({ 'txId': transId, "isSuccess": isSuccess }),
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then(data => {
+                console.log("confirmTrans-" + JSON.stringify(data));
+                document.getElementById("file").files[0].name = '';
+                enableButtonStatus();
+                refreshFiles();            
+                return data.status;
+            })
+            
+        }
+        function calculateFileSize(fileObject) {
+            if (fileObject.size > 20971520) {
+                alertErrorMessage('鏂囦欢杩囧ぇ锛岃閫夋嫨灏忎簬20mb鐨勬枃浠�');
+            }
+        }
+        function uploadFileToAWS(data, size, fileName) {
+            console.log("body=" + JSON.stringify({ 'file': data, "size": size, 'fileName': fileName }));
+            
+            fetch(uploadUrl, {
+                method: 'POST',
+                body: JSON.stringify({ 'file': data, "size": size, 'fileName': fileName }),
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then(result => {
+
+                console.log("result" + JSON.stringify(result));
+                
+                if (result.success == true) {
+                    key = result.object;
+
+                    Visualforce.remoting.Manager.invokeAction(
+                        '{!$RemoteAction.FileUploadController.saveFile}',
+                        fileName, key, result.txId, parentId,
+                        function (resultvalue, event) {
+
+
+                            
+                            //2. show file list
+                            if (resultvalue.status == 'fail') {
+                                alertErrorMessage(resultvalue.message);
+                                //1. Confirm trans
+                                confirmTrans(result.txId, 0);                              
+                            } else {
+                                alertErrorMessage('涓婁紶鎴愬姛');
+                                confirmTrans(result.txId, 1);
+                            }
+                            
+                            // window.location.reload();
+                        },
+                        { escape: true }
+                    );
+                   
+                    console.log('key' + key);
+                } else {
+                    alertErrorMessage('涓婁紶澶辫触璇风◢鍚庡啀璇曪紒');
+                }
+            }).catch((error) => {
+                console.error('Error:', error);
+            })
+            debugger
+        }
+        function downPdf(fileUrl) {
+            window.open(fileUrl,'_blank');
+        }
+
+    </script>
+    <style>
+        .pdf .num {
+            width: 30%;
+        }
+
+        .pdf.name {
+            width: 30%
+        }
+
+        .pdf.downLink {
+            width: 40%
+        }
+    </style>
+    <apex:form id="theForm">
+        <apex:actionFunction name="refreshFiles" action="{!refreshFiles}" reRender="pdf,uploadSection"/>      
+        <br/>
+        <br/>
+        <apex:pageBlock id="block">
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            <apex:pageBlockSection id="uploadSection">
+                <!-- <apex:inputFile id="file" value="{!documentData.body}" filename="{!documentData.name}" /> -->
+                <input type="file" id="file" name="filename"/>
+                <input class="btn" id='uploadFileId' type="Button" value="纭涓婁紶" onclick="uploadFile()" />
+            </apex:pageBlockSection>
+        </apex:pageBlock>
+        <apex:pageBlock title="PDF鍒楄〃" id="pdf">
+            <!-- <apex:pageBlockSection > -->
+            <!-- show uploated file list -->
+            <apex:pageBlockTable value="{!fileList}" var="file" align="center" columns="3" columnsWidth="30%,30%,40%">
+                <apex:column id="name" headerValue="鏂囦欢鍚嶇О">
+                    <apex:outputLink value="/{!file.Id}" target="_blank">{!file.FileName__c}</apex:outputLink>
+                </apex:column>
+                <!-- <apex:column id="num" headerValue="鐖惰褰曢摼鎺�">
+                    <apex:outputLink value="/{!file.ParentRecordId__c}" target="_blank">{!file.ParentRecordId__c}</apex:outputLink>
+                </apex:column> -->
+                <apex:column id="previewLink" headerValue="棰勮閾炬帴">
+                    <apex:outputLink value="{!file.ViewLink__c}" target="{!file.ViewLink__c}">棰勮閾炬帴
+                    </apex:outputLink>
+                </apex:column>
+                <apex:column id="downLink" headerValue="涓嬭浇閾炬帴">
+                    <!-- <apex:outputLink value= "{!file.DownloadLink__c}" target="{!file.DownloadLink__c}">涓嬭浇閾炬帴
+                    </apex:outputLink> -->
+                    <input class="btn" id='downloadFileButton' type="Button" value="涓嬭浇" onclick="downPdf('{!file.DownloadLink__c}')" />
+                </apex:column>
+            </apex:pageBlockTable>
+            <!-- </apex:pageBlockSection> -->
+        </apex:pageBlock>
+    </apex:form>
+
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ConsumApplyUploadPdf.page-meta.xml b/force-app/main/default/pages/ConsumApplyUploadPdf.page-meta.xml
new file mode 100644
index 0000000..68da06b
--- /dev/null
+++ b/force-app/main/default/pages/ConsumApplyUploadPdf.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ConsumApplyUploadPdf</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditASEActivity.page b/force-app/main/default/pages/NewAndEditASEActivity.page
new file mode 100644
index 0000000..e93ab70
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditASEActivity.page
@@ -0,0 +1,526 @@
+<apex:page standardController="ASEActivity__c" extensions="NewAndEditASEActivityController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <style>
+        .disabledbutton {
+            pointer-events: none;
+            opacity: 0.4;
+        }
+    </style>
+    <script>
+        
+        var config = {};
+        config = {
+            SobjectName : "{!SobjectName}",
+            ApiPrefix:"{!ApiPrefix}",
+            SaveAndNew:false,
+            AWSToSobjectMap:{!AWSToSobjectMapJson},
+            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
+            SobjectToAWSModel:function (sobjJson) {
+                let leadPayloadList = [];
+                let leadPIData = {};
+
+                for(let f in config.AWSToSobjectMap){
+                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
+                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
+                    }
+                    else{
+                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
+                    }
+                } 
+
+
+                leadPIData.sfRecordId = '';
+                console.log('Sobject PI Data:' + leadPIData);
+                leadPayloadList.push(leadPIData);
+                console.log(JSON.stringify(leadPayloadList));
+                return JSON.stringify(leadPayloadList);
+            },
+            insertOrUpdateBack:function(payloadJson, r, isNewMode){
+                
+                for(let f in config.AWSToSobjectMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+
+                for(let f in config.AWSToSobjectEncryptedMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+                
+                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                if (isNewMode) {
+                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                } else {
+                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                }
+                return payloadJson;
+            },
+            queryBack:function (data) {
+                console.log('data = ' + data);
+                if(data.object){
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
+                        if(data.object.hasOwnProperty(f) && ele){
+                            
+                            // 澶氶�夌壒娈婂鐞�
+                            if(ele.type == 'select-multiple'){
+                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
+                            if(ele && data.object[f]){
+                                let arr = data.object[f].split(';');
+
+                                // 缁欓殣钘忕殑select璧嬪��
+                                for(let op of ele.options){
+                                    op.selected = arr.indexOf(op.value)>-1;
+                                }
+                                
+                                // 鍒╃敤鎸夐挳缁欐樉绀虹殑select璧嬪��
+                                let ra = document.getElementById(ele.id + '_right_arrow');
+                                if(ra){
+                                    ra.click();
+                                }
+                                
+                            }
+                            }else{
+                                ele.value = data.object[f];
+                            }
+                            
+                        }
+                        else{
+                            console.log(f + 'is not in data.object');
+                        }
+                    }
+                }
+                else{
+                    console.log('data.object = ' + data.object);
+                }
+                
+
+                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                // document.querySelector("[data-id='Phone']").value = data.object.phone;
+                // document.querySelector("[data-id='Email']").value = data.object.email;
+            },
+            updateMethod:"NewAndEditASEActivityController.saveASEActivity",
+            insertMethod:"NewAndEditASEActivityController.saveASEActivity"
+        }
+    
+        AWSService.sfSessionId = '{!GETSESSIONID()}';
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        var staticResources = JSON.parse('{!staticResource}');
+        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
+        console.log('{!staticResource}');
+        var VLookUpFields = {! VLookUpFieldsJson};
+        function ProcessPI(sobjJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+                NewPIToAWS(sobjJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(sobjJson, payloadForNewPI)
+            }
+        }
+
+        var GetEleByClass = function(class_name){
+            let eles = document.getElementsByClassName(class_name);
+            if(eles.length > 0) return eles[0];
+            return null;
+        }
+
+        var GetEleApiName = function(ele){
+            for(let c of ele.classList){
+                if(c.indexOf(config.ApiPrefix+'_')>-1){
+                    return c.replace(config.ApiPrefix+'_','');
+                }
+            }
+            return '';
+        }
+
+        function IsFormElement(tag_name){
+            return ['input','select','textarea'].indexOf(tag_name)>-1;
+        }
+
+        function getPIPayload(sobjJson) {
+            return config.SobjectToAWSModel(sobjJson);
+        }
+
+        function validateFieldValueFormate() {
+            let error_msg = '';
+            // let textEmail = "[data-id='Email']";
+            let textPhone = "[data-id='CustomerTel__c']";
+            // //Email
+            // let email = document.querySelector(textEmail);
+            // if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
+            //     error_msg += ';閭欢鏍煎紡閿欒';
+            // }
+            let phone = document.querySelector(textPhone);
+
+            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
+                error_msg += ';鐢佃瘽鍙风爜閿欒';
+            }
+
+            for(let e of document.getElementsByTagName('select')){
+                for(let op of e.options){
+                    if(op.value == "*****" && op.selected){
+                        error_msg += ';涓嬫媺妗嗕笉鑳戒富鍔ㄩ�夋嫨瀵嗘枃閫夐」';
+                    }
+                }
+            }
+
+            if(error_msg.length>0 && error_msg[0]== ';'){
+                error_msg = error_msg.substring(1);
+            }
+
+            return error_msg;
+        }
+
+        function getSobjectInformation() {
+
+            let nodelist = document.getElementsByClassName(config.ApiPrefix);
+            let result = {}
+            for (let index = 0; index < nodelist.length; index++) {
+                let ele = nodelist[index];
+                let field_api_name = GetEleApiName(ele);
+                let tag_name = ele.tagName.toLowerCase();
+                if(!IsFormElement(tag_name)){
+                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
+                    continue;
+                }
+
+                if (VLookUpFields.indexOf(field_api_name)>=0) {
+                    console.log(ele.id.indexOf('lkwgt'));
+                    if (ele.id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = ele.id + '_lkid';
+                        let vlook_ele = document.getElementById(vlookUpNodeId);
+                        let v = '';
+                        if(vlook_ele){
+                            v = vlook_ele.value;
+                        }else{
+                            v = ele.value;
+                        }
+
+                        if(v && v != "000000000000000"){
+                            result[field_api_name] = v;
+                        }
+                        
+                    }
+                } else if (ele.type == 'checkbox') {
+                    result[field_api_name] = ele.checked;
+                } else if (ele.type == 'select-multiple') {
+                    //field_api_name
+                    let multiple = field_api_name;
+                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[field_api_name] = targets;
+                } else {
+                    result[field_api_name] = ele.value;
+                }
+            }
+            return result;
+        }
+        function QuerySobjectFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+        function queryBack(data) {
+            console.log('data = ' + data);
+            config.queryBack(data);
+            unblockUI();
+        };
+
+
+        function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + r);
+            console.log('payloadJson=' + payloadJson);
+            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
+        }
+
+        function redirectCallBack(sfId,errorMsg) {
+            unblockUI();
+            if(errorMsg){
+                alertErrorMessage(errorMsg);
+            }
+            else{
+                if(config.SaveAndNew){
+                    window.open('{! SaveAndNewButtonUrl }','_self');
+                }else{
+                    window.open('/' + sfId, '_self');
+                }
+            }
+            
+        }
+
+        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.updateMethod;
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
+            
+        }
+
+        function NewPIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.insertMethod;
+            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
+            
+        }
+        
+
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for(i = 0;i<requiredFieldAPIList.length;i++){
+                if(formData[requiredFieldAPIList[i]]){
+                    continue;
+                }else{
+                    if(blankRequiredFields == ''){
+                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }else{
+                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+                    
+                }
+            }
+            return blankRequiredFields;
+        }
+        function saveSobjectProcess(save_and_new) {
+            if(save_and_new){
+                config.SaveAndNew = true;
+            }
+            
+            hiddenErrorMsgNode();
+            //1. Get Sobject Information from Form
+            let sobjJson = getSobjectInformation();
+            //2. Validate the Sobject field value formate, for example the email formate or phone formate
+
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage(validationResultMessage);
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
+                return
+            }
+            // //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(sobjJson);
+
+            // //4. Get Authentication Information for AWS
+            // loadAWSAuthentication();
+
+            // //5. ASEActivity to AWS 
+            ProcessPI(sobjJson, payloadForNewPI);
+            // awsToken = TestToken;
+            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
+        }
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+        
+        var newSearchContactWindow = null;  
+        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+        function htmlToElement(html) {
+            var template = document.createElement('template');
+            html = html.trim(); // Never return a text node of whitespace as the result
+            template.innerHTML = html;
+            return template.content.firstChild;
+        }
+        
+        function searchContact(contactNodeId){
+            // errorMsg 闅愯棌
+            if(document.getElementsByClassName("errorMsg").length > 0){
+                document.getElementsByClassName("errorMsg")[0].style.display="none";
+            }
+
+            let accountValue = "";
+            let suffixUrl = "";
+            if (document.querySelector("[data-id='Department__c']")) {
+                let accountNodeId = document.querySelector("[data-id='Department__c']").id + '_lkid';
+                accountValue = document.getElementById(accountNodeId).value;   
+            } 
+            console.log('accountValue = ' + accountValue);
+            if(accountValue !='000000000000000'){
+                suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
+            }else{
+                suffixUrl = "?contactId="+contactNodeId;
+            }
+            let baseUrl = "/apex/SearchContactPage";
+            let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
+            newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
+            if (window.focus) {
+                newSearchContactWindow.focus();
+            }
+            return false;
+        }
+        
+        function closePopupWindow() {
+            if (null != newSearchContactWindow) {
+                newSearchContactWindow.close();
+            }
+            let contactInfoStr = document.getElementById('page:form:contactId').value;
+            console.log('closePopup:'+contactInfoStr);
+            let contactInfo = JSON.parse(contactInfoStr);
+            let contactNodeId = document.querySelector("[data-id='ReporterASE__c']").id + '_lkid';
+            document.getElementById(contactNodeId).value = contactInfo.ContactId;
+            document.querySelector("[data-id='ReporterASE__c']").value = contactInfo.Name;
+        }
+        
+        
+        function replaceSearchContactLookup() {
+            let lookUpNode = htmlToElement(contactHtmlString);
+            console.log(lookUpNode);
+            if (!{!isNewMode}) {
+                //1. Query Contact from AWS by AWSDataId
+                queryContactName()
+            }           
+            let parentNode = document.querySelector("[data-id='ReporterASE__c']").parentNode;
+            document.querySelector("[data-id='ReporterASE__c']").removeAttribute("onchange");
+            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='ReporterASE__c']").parentNode.children[2]);
+        }
+
+        function queryContactName() {
+            let sfId = document.getElementById(document.querySelector("[data-id='ReporterASE__c']").id + '_lkid').value;
+            let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
+            let dataId = contactsInfo[sfId];
+            let queryContactBack = function(data){
+                //To Do later
+                console.log('ContactData = ' + data.object);
+                
+                document.querySelector("[data-id='ReporterASE__c']").value = data.object.lastName;
+            }
+            AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
+            // let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+            // fetch(url, {
+            //     method: 'GET',
+            //     headers: {
+            //         'Content-Type': 'application/json',
+            //         'pi-token': staticResources.token
+            //     }
+            // }).then((data) => {
+            //     return data.json();
+            // }).then((result) => {
+            //     document.querySelector("[data-id='ReporterASE__c']").value = result.object.lastName;
+            // })
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
+                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <apex:inputHidden value="{!contactId}" id="contactId"/>
+        <apex:pageblock id="block">
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!ASEActivity__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                sfdcPage.appendToOnloadQueue(function () {
+                    //1. Set Last Name label
+                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for Sobject Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();
+                        QuerySobjectFromAWS();
+                    }  
+                    //Replace Vlookup Field
+                    replaceSearchContactLookup();
+                    document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
+                    document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");   
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditASEActivity.page-meta.xml b/force-app/main/default/pages/NewAndEditASEActivity.page-meta.xml
new file mode 100644
index 0000000..89cb45e
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditASEActivity.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditASEActivity</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditAddress.page b/force-app/main/default/pages/NewAndEditAddress.page
new file mode 100644
index 0000000..d8e3c51
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditAddress.page
@@ -0,0 +1,427 @@
+<apex:page standardController="Address__c" extensions="NewAndEditAddressController" id="page">
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <style>
+        .disabledbutton {
+            pointer-events: none;
+            opacity: 0.4;
+        }
+    </style>
+    <script>
+        AWSService.sfSessionId = '{!GETSESSIONID()}';
+        var staticResources = JSON.parse('{!staticResource}');
+        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        var redirectMode = 'Save';//1. Save 2. SaveAndNew
+        var requiredAPIToChangedLabelMap = new Map();
+        requiredAPIToChangedLabelMap.set('LastName', '{!PIPL_Name_Label}');
+        console.log('{!contactsInfo}');
+        var VLookUpFields = new Set(['Contacts__c', 'Province__c', 'City__c', 'Customer__c']);
+        function ProcessPI(addressJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+                NewPIToAWS(addressJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(addressJson, payloadForNewPI)
+            }
+        }   
+
+        function enableButton(obj){
+            obj.classList.remove("btnDisabled");
+        }
+
+        function disableButton(obj){
+            obj.classList.add("btnDisabled");
+        }
+
+        function disableButtonStatus(){
+            let btnList = document.getElementsByClassName('btn');
+            for(let i=0;i<btnList.length;i++){              
+                disableButton(btnList[i]);
+            }
+        }
+
+        function enableButtonStatus(){
+            let btnList = document.getElementsByClassName('btn');
+            for(let i=0;i<btnList.length;i++){
+                enableButton(btnList[i]);   
+            }
+        }
+
+        function getPIPayload(addressJson) {
+            let addressPayloadList = [];
+            let Telephone = addressJson.Telephone__c;
+            let ZipCode = addressJson.ZipCode__c;
+            let DetailedAddress = addressJson.Detailed_Address__c;
+            let addressPIData = new Object();
+            addressPIData.telephone = Telephone;
+            addressPIData.zipCode = ZipCode;
+            addressPIData.detailedAddress = DetailedAddress;
+            addressPIData.sfRecordId = '';
+            console.log('Address PI Data:' + addressPIData);
+            addressPayloadList.push(addressPIData);
+            console.log(JSON.stringify(addressPayloadList));
+            return JSON.stringify(addressPayloadList);
+        }
+
+        function validateFieldValueFormate() {
+            let error_msg = '';
+            // let textEmail = "[data-id='Email']";
+            let textPhone = "[data-id='Telephone__c']";
+            //Email
+            // let email = document.querySelector(textEmail);
+            // if(email && !/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/.test(email.value)){
+            //     error_msg += ';閭欢鏍煎紡閿欒';
+            // }
+            let phone = document.querySelector(textPhone);
+
+            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
+                error_msg += ';鐢佃瘽鍙风爜閿欒';
+            }
+
+            for(let e of document.getElementsByTagName('select')){
+                for(let op of e.options){
+                    if(op.value == "*****" && op.selected){
+                        error_msg += ';涓嬫媺妗嗕笉鑳戒富鍔ㄩ�夋嫨瀵嗘枃閫夐」';
+                    }
+                }
+            }
+
+            if(error_msg.length>0 && error_msg[0]== ';'){
+                error_msg = error_msg.substring(1);
+            }
+
+            return error_msg;
+        }
+        
+        function getAddressInformation() {
+
+            let nodelist = document.querySelectorAll("[data-id]");
+            let result = {}
+            result.RecordTypeId = '{!rtTypeId}';
+            for (let index = 0; index < nodelist.length; index++) {
+                if (VLookUpFields.has(nodelist[index].getAttribute("data-id"))) {
+                    console.log(nodelist[index].id.indexOf('lkwgt'));
+                    if (nodelist[index].id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = nodelist[index].id + '_lkid';
+                        let vlookUpNodeValue = document.getElementById(vlookUpNodeId).value;
+                        result[nodelist[index].getAttribute("data-id")] = vlookUpNodeValue;
+                    }
+                } else if (nodelist[index].type == 'checkbox') {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].checked;
+                } else if (nodelist[index].type == 'select-multiple') {
+                    //nodelist[index].getAttribute("data-id")
+                    let multiple = nodelist[index].getAttribute("data-id");
+                    let targets = document.querySelector("[data-id=" + multiple + "]").parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[nodelist[index].getAttribute("data-id")] = targets;
+                } else {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].value;
+                }
+                let x = index + 1;
+                if (x <= nodelist.length - 1 && (nodelist[x].getAttribute("data-id") == nodelist[index].getAttribute("data-id"))) {
+                    index++;
+                }
+            }
+            return result;
+        }
+        function QueryAddressFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+        var queryBack = function queryBack(data) {
+            console.log('data = ' + data);
+            document.querySelector("[data-id='Telephone__c']").value = data.object.telephone;
+            document.querySelector("[data-id='ZipCode__c']").value = data.object.zipCode;
+            document.querySelector("[data-id='Detailed_Address__c']").value = data.object.detailedAddress;
+            unblockUI();
+        };
+
+        var insertOrUpdateBack = function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + r);
+            console.log('payloadJson=' + payloadJson);
+            payloadJson.Telephone__c = r.object[0].telephone;
+            payloadJson.ZipCode__c = r.object[0].zipCode;
+            payloadJson.Detailed_Address__c = r.object[0].detailedAddress;
+            payloadJson.Telephone_Encrypted__c = r.object[0].telephoneEncrypt;
+            payloadJson.ZipCode_Encrypted__c = r.object[0].zipCodeEncrypt;
+            payloadJson.Detailed_Address_Encrypted__c = r.object[0].detailedAddressEncrypt;
+            //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+            payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            if (isNewMode) {
+                payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+            } else {
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            }
+            return payloadJson;
+        }
+
+        var redirectCallBack = function redirectCallBack(sfId,errorMessage) {
+            if(sfId){
+                if(redirectMode == 'Save'){
+                    window.open('/' + sfId, '_self');
+                }else if(redirectMode == 'SaveAndNew'){
+                    window.open('/' + sfId + '/e?retURL=%2F' + sfId + '=%2Fo', '_self');
+                }
+            }else{
+                // alert(errorMessage);
+                alertErrorMessage(errorMessage);
+            }
+        }
+
+
+        function UpdatePIToAWS(addressJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewAndEditAddressController.saveAddress}';
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, addressJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
+        }
+
+        function NewPIToAWS(addressJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewAndEditAddressController.saveAddress}';
+            AWSService.insert(staticResources.newUrl, addressJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
+        }
+
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for(i = 0;i<requiredFieldAPIList.length;i++){
+                if(formData[requiredFieldAPIList[i]]){
+                    continue;
+                }else{
+                    let fieldAPIValue = requiredFieldAPIList[i]
+                    let fieldLabelValue = fieldAPIToLabelMap[fieldAPIValue];
+                    if (requiredAPIToChangedLabelMap.has(fieldAPIValue)) {
+                        fieldLabelValue = requiredAPIToChangedLabelMap.get(fieldAPIValue);
+                    }
+                    if(blankRequiredFields == ''){
+                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }else{
+                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+                    
+                }
+            }
+            return blankRequiredFields;
+        }
+        function saveAddressProcess(saveMode) {
+
+            disableButtonStatus();
+            redirectMode = saveMode;
+            console.log('redirectMode'+redirectMode);
+            hiddenErrorMsgNode();
+            //1. Get Address Information from Form
+            let addressJson = getAddressInformation();
+            //2. Validate the Address field value formate, for example the email formate or phone formate
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage(validationResultMessage);
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(addressJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('{!Input_Required_Field_Msg}'+checkRequiredFieldMsgResult);
+                return
+            }
+            //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(addressJson);
+
+            //4. Address to AWS 
+            ProcessPI(addressJson, payloadForNewPI);
+        }
+
+        function alertErrorMessage(errorMsg) {
+            enableButtonStatus();
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsg = '閿欒锛氭棤鏁堟暟鎹��'+'\n' + errorMsg;
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+            unblockUI();
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+        var newSearchContactWindow = null;  
+        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+        function htmlToElement(html) {
+            var template = document.createElement('template');
+            html = html.trim(); // Never return a text node of whitespace as the result
+            template.innerHTML = html;
+            return template.content.firstChild;
+        }
+        function searchContact(contactNodeId) {
+            //1. Check account value
+            let accountNodeId = document.querySelector("[data-id='Customer__c']").id + '_lkid';
+            let accountValue = document.getElementById(accountNodeId).value;
+            console.log(accountValue);
+            if (accountValue != '000000000000000') {
+                let baseUrl = "/apex/SearchContactPage";
+                let suffixUrl = "?contactId=" + contactNodeId + "&accountId=" + accountValue;
+                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
+                newSearchContactWindow = window.open(baseUrl + suffixUrl, 'Popup', newSearchContactParam);
+                if (window.focus) {
+                    newSearchContactWindow.focus();
+                }
+                return false;
+            } else {
+                //alertErrorMessage('{!PIPL_Input_Account_Error_Msg}');
+                alertErrorMessage('璇峰厛閫夋嫨瀹㈡埛');
+            }
+        }
+        function closePopupWindow() {            
+            if (null != newSearchContactWindow) {
+                newSearchContactWindow.close();
+            }
+            let contactInfoStr = document.getElementById('page:form:contactId').value;
+            console.log('closePopup:'+contactInfoStr);
+            let contactInfo = JSON.parse(contactInfoStr);
+            let contactNodeId = document.querySelector("[data-id='Contacts__c']").id + '_lkid';
+            document.getElementById(contactNodeId).value = contactInfo.ContactId;
+            document.querySelector("[data-id='Contacts__c']").value = contactInfo.Name;
+        }     
+        function replaceSearchContactLookup() {
+            let lookUpNode = htmlToElement(contactHtmlString);
+            console.log(lookUpNode);
+            if (!{!isNewMode}) {
+                //1. Query Contact from AWS by AWSDataId
+                queryContactName()
+                // document.querySelector("[data-id='Contacts__c']").value = '鐜嬪';
+            }           
+            let parentNode = document.querySelector("[data-id='Contacts__c']").parentNode;
+            document.querySelector("[data-id='Contacts__c']").removeAttribute("onchange");
+            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Contacts__c']").parentNode.children[2]);
+        }
+
+        function queryContactName() {
+            let sfId = document.getElementById(document.querySelector("[data-id='Contacts__c']").id + '_lkid').value;
+            let contactsInfo = JSON.parse('{!contactsInfo}');
+            let dataId = contactsInfo[sfId];
+            let queryContactBack = function(data){
+                //To Do later
+                console.log('ContactData = ' + data.object);
+                
+                document.querySelector("[data-id='Contacts__c']").value = data.object.lastName;
+            }
+            AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
+            // let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+            // fetch(url, {
+            //     method: 'GET',
+            //     headers: {
+            //         'Content-Type': 'application/json',
+            //         'pi-token': staticResources.token
+            //     }
+            // }).then((data) => {
+            //     return data.json();
+            // }).then((result) => {
+            //     document.querySelector("[data-id='Contacts__c']").value = result.object.lastName;
+            // })
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="鏀惰揣鍦板潃" class="pageTitleIcon" title="鏀惰揣鍦板潃" />
+                <h1 class="pageType">鏀惰揣鍦板潃缂栬緫
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> 鏂板缓鏀惰揣鍦板潃</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target=address_edit.htm&amp;section=Address&amp;language=zh_CN&amp;release=234.18.14&amp;instance=CS58&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <apex:inputHidden value="{!contactId}" id="contactId"/>
+        <apex:pageblock id="block"> 
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">鏀惰揣鍦板潃缂栬緫</h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveAddressProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveAddressProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>          
+            <br/>
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" showHeader="{!layoutSection.useHeader}" collapsible="{!layoutSection.allowCollapse}"
+                    columns="{!layoutSection.columns}">
+                    
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField html-data-id="{!layoutField.fieldAPI}" value="{!Address__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                sfdcPage.appendToOnloadQueue(function () {
+                    //1. Set Last Name label
+                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for Address Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();//for loading search by Li Jun 20220218
+                        QueryAddressFromAWS();
+                    }
+                    //Replace Vlookup Field
+                    replaceSearchContactLookup();
+                    //3. Set Readonly Attribute
+                // document.querySelector("[data-id='OwnerId']").classList.add("disabledbutton");
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveAddressProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveAddressProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditAddress.page-meta.xml b/force-app/main/default/pages/NewAndEditAddress.page-meta.xml
new file mode 100644
index 0000000..c737fbf
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditAddress.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditAddress</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditAgencyContact.page b/force-app/main/default/pages/NewAndEditAgencyContact.page
new file mode 100644
index 0000000..639f9dc
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditAgencyContact.page
@@ -0,0 +1,511 @@
+<apex:page standardController="Agency_Contact__c" extensions="NewAndEditAgencyContactController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script>
+        
+        var config = {};
+        config = {
+            SobjectName : "{!SobjectName}",
+            ApiPrefix:"{!ApiPrefix}",
+            SaveAndNew:false,
+            AWSToSobjectMap:{!AWSToSobjectMapJson},
+            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
+            SobjectToAWSModel:function (sobjJson) {
+                let leadPayloadList = [];
+                let leadPIData = {};
+
+                for(let f in config.AWSToSobjectMap){
+                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
+                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
+                    }
+                    else{
+                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
+                    }
+                } 
+
+
+                leadPIData.sfRecordId = '';
+                console.log('Sobject PI Data:' + leadPIData);
+                leadPayloadList.push(leadPIData);
+                console.log(JSON.stringify(leadPayloadList));
+                return JSON.stringify(leadPayloadList);
+            },
+            insertOrUpdateBack:function(payloadJson, r, isNewMode){
+                
+                for(let f in config.AWSToSobjectMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+
+                for(let f in config.AWSToSobjectEncryptedMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+                
+                if('{!rtTypeId}'){
+                    payloadJson.RecordTypeId = '{!rtTypeId}';
+                }
+                
+                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                if (isNewMode) {
+                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                } else {
+                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                }
+                return payloadJson;
+            },
+            queryBack:function (data) {
+                console.log('data = ' + data);
+                if(data.object){
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
+                        if(data.object.hasOwnProperty(f) && ele){
+                            
+                            // 澶氶�夌壒娈婂鐞�
+                            if(ele.type == 'select-multiple'){
+                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
+                               if(ele && data.object[f]){
+                                   let arr = data.object[f].split(';');
+
+                                   // 缁欓殣钘忕殑select璧嬪��
+                                   for(let op of ele.options){
+                                       op.selected = arr.indexOf(op.value)>-1;
+                                   }
+                                   
+                                   // 鍒╃敤鎸夐挳缁欐樉绀虹殑select璧嬪��
+                                   let ra = document.getElementById(ele.id + '_right_arrow');
+                                   if(ra){
+                                       ra.click();
+                                   }
+                                   
+                               }
+                            }else{
+                                ele.value = data.object[f];
+                            }
+                            
+                        }
+                        else{
+                            console.log(f + 'is not in data.object');
+                        }
+                    }
+                }
+                else{
+                    console.log('data.object = ' + data.object);
+                }
+                
+
+                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                // document.querySelector("[data-id='Phone']").value = data.object.phone;
+                // document.querySelector("[data-id='Email']").value = data.object.email;
+            },
+            updateMethod:"NewAndEditAgencyContactController.saveContact",
+            insertMethod:"NewAndEditAgencyContactController.saveContact"
+        }
+    
+        var staticResources = JSON.parse('{!staticResource}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        console.log('{!staticResource}');
+        var VLookUpFields = {! VLookUpFieldsJson};
+        function ProcessPI(sobjJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+            	NewPIToAWS(sobjJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(sobjJson, payloadForNewPI)
+            }
+        }
+
+        var GetEleByClass = function(class_name){
+            let eles = document.getElementsByClassName(class_name);
+            if(eles.length > 0) return eles[0];
+            return null;
+        }
+
+        var GetEleApiName = function(ele){
+            for(let c of ele.classList){
+                if(c.indexOf(config.ApiPrefix+'_')>-1){
+                    return c.replace(config.ApiPrefix+'_','');
+                }
+            }
+            return '';
+        }
+
+        function IsFormElement(tag_name){
+            return ['input','select','textarea'].indexOf(tag_name)>-1;
+        }
+
+        function getPIPayload(sobjJson) {
+            return config.SobjectToAWSModel(sobjJson);
+        }
+
+        function validateFieldValueFormate() {
+            let error_msg = '';
+            let textEmail = "[data-id='Email']";
+            let textPhone = "[data-id='Phone']";
+            //Email
+            let email = document.querySelector(textEmail);
+            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
+                error_msg += ';閭欢鏍煎紡閿欒';
+            }
+            let phone = document.querySelector(textPhone);
+
+            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
+                error_msg += ';鐢佃瘽鍙风爜閿欒';
+            }
+
+            for(let e of document.getElementsByTagName('select')){
+                for(let op of e.options){
+                    if(op.value == "*****" && op.selected){
+                        error_msg += ';涓嬫媺妗嗕笉鑳戒富鍔ㄩ�夋嫨瀵嗘枃閫夐」';
+                    }
+                }
+            }
+
+            if(error_msg.length>0 && error_msg[0]== ';'){
+                error_msg = error_msg.substring(1);
+            }
+
+            return error_msg;
+        }
+
+        function getSobjectInformation() {
+
+            let nodelist = document.getElementsByClassName(config.ApiPrefix);
+            let result = {}
+            for (let index = 0; index < nodelist.length; index++) {
+                let ele = nodelist[index];
+                let field_api_name = GetEleApiName(ele);
+                let tag_name = ele.tagName.toLowerCase();
+                if(!IsFormElement(tag_name)){
+                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
+                    continue;
+                }
+
+                if (VLookUpFields.indexOf(field_api_name)>=0) {
+                    console.log(ele.id.indexOf('lkwgt'));
+                    if (ele.id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = ele.id + '_lkid';
+                        let vlook_ele = document.getElementById(vlookUpNodeId);
+                        let v = '';
+                        if(vlook_ele){
+                            v = vlook_ele.value;
+                        }else{
+                            v = ele.value;
+                        }
+
+                        if(v && v != "000000000000000"){
+                            result[field_api_name] = v;
+                        }
+                        
+                    }
+                } else if (ele.type == 'checkbox') {
+                    result[field_api_name] = ele.checked;
+                } else if (ele.type == 'select-multiple') {
+                    //field_api_name
+                    let multiple = field_api_name;
+                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[field_api_name] = targets;
+                } else {
+                    result[field_api_name] = ele.value;
+                }
+            }
+            return result;
+        }
+        function QuerySobjectFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+        function queryBack(data) {
+            console.log('data = ' + data);
+            config.queryBack(data);
+            unblockUI();
+        };
+
+
+        function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + r);
+            console.log('payloadJson=' + payloadJson);
+            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
+        }
+
+        function redirectCallBack(sfId,errorMsg) {
+            unblockUI();
+            if(errorMsg){
+                alertErrorMessage(errorMsg);
+            }
+            else{
+                if(config.SaveAndNew){
+                    window.open('{! SaveAndNewButtonUrl }','_self');
+                }else{
+                    window.open('/' + sfId, '_self');
+                }
+            }
+            
+        }
+
+        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.updateMethod;
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
+            
+        }
+
+        function NewPIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.insertMethod;
+            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
+            
+        }
+        
+
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for(i = 0;i<requiredFieldAPIList.length;i++){
+                if(formData[requiredFieldAPIList[i]]){
+                    continue;
+                }else{
+                    if(blankRequiredFields == ''){
+                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }else{
+                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+                    
+                }
+            }
+            return blankRequiredFields;
+        }
+        function saveSobjectProcess(save_and_new) {
+            if(save_and_new){
+                config.SaveAndNew = true;
+            }
+            
+            hiddenErrorMsgNode();
+            //1. Get Sobject Information from Form
+            let sobjJson = getSobjectInformation();
+            //2. Validate the Sobject field value formate, for example the email formate or phone formate
+
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage(validationResultMessage);
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
+                return
+            }
+            // //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(sobjJson);
+
+            // //4. Get Authentication Information for AWS
+            // loadAWSAuthentication();
+
+            // //5. lead to AWS 
+            ProcessPI(sobjJson, payloadForNewPI);
+            // awsToken = TestToken;
+            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
+        }
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+
+        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
+        var newSearchContactWindow = null;  
+        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page_form_contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+        function htmlToElement(html) {
+            var template = document.createElement('template');
+            html = html.trim(); // Never return a text node of whitespace as the result
+            template.innerHTML = html;
+            return template.content.firstChild;
+        }
+        //鑷畾涔塴ookup鏌ヨ
+        function searchContact(contactNodeId){
+            let accountValue = "";
+            // if (document.querySelector("[data-id='Account__c']")) {
+            //     let accountNodeId = document.querySelector("[data-id='Account__c']").id + '_lkid';
+            //     accountValue = document.getElementById(accountNodeId).value;   
+            // } 
+            console.log(accountValue);
+            if(true || accountValue !='000000000000000'){
+                let baseUrl = "/apex/SearchContactPage";
+                let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
+                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
+                newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
+                if (window.focus) {
+                    newSearchContactWindow.focus();
+                }
+                return false;
+            }else{
+                alertErrorMessage('{!$Label.PIPL_Input_Account_Error_Msg}');
+            }
+        }
+        //绐楀彛鍏抽棴鏃跺彂鐢�
+        function closePopupWindow() {
+            if (null != newSearchContactWindow) {
+                newSearchContactWindow.close();
+            }
+            let contactInfoStr = document.getElementById('page_form_contactId').value;
+            console.log('closePopup:'+contactInfoStr);
+            let contactInfo = JSON.parse(contactInfoStr);
+            let contactNodeId = document.querySelector("[data-id='Contact__c']").id + '_lkid';
+            document.getElementById(contactNodeId).value = contactInfo.ContactId;
+            document.querySelector("[data-id='Contact__c']").value = contactInfo.Name;
+        }
+
+        //鏇挎崲vlookup
+        function replaceSearchContactLookup() {
+            let lookUpNode = htmlToElement(contactHtmlString);
+            console.log(lookUpNode);
+            if (!{!isNewMode}) {
+                //1. Query Contact from AWS by AWSDataId
+                // document.querySelector("[data-id='ContactId']").value = '鐜嬪';
+                queryContactName()
+            }           
+            let parentNode = document.querySelector("[data-id='Contact__c']").parentNode;
+            document.querySelector("[data-id='Contact__c']").removeAttribute("onchange");
+            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Contact__c']").parentNode.children[2]);
+        }
+
+        function queryContactName() {
+            let sfId = document.getElementById(document.querySelector("[data-id='Contact__c']").id + '_lkid').value;
+            let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
+            let dataId = contactsInfo[sfId];
+            let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+            fetch(url, {
+                method: 'GET',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then((result) => {
+                document.querySelector("[data-id='Contact__c']").value = result.object.lastName;
+            })
+        }
+
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
+                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <input type="hidden"  id="page_form_contactId"/>
+        <apex:pageblock id="block">
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Agency_Contact__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                sfdcPage.appendToOnloadQueue(function () {
+                    //1. Set Last Name label
+                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for Sobject Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();
+                        QuerySobjectFromAWS();
+                    }
+
+                    //Replace Vlookup Field
+                    replaceSearchContactLookup();
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditAgencyContact.page-meta.xml b/force-app/main/default/pages/NewAndEditAgencyContact.page-meta.xml
new file mode 100644
index 0000000..ec2bd99
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditAgencyContact.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditAgencyContact</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditCampaignMember.page b/force-app/main/default/pages/NewAndEditCampaignMember.page
new file mode 100644
index 0000000..8f0d120
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditCampaignMember.page
@@ -0,0 +1,421 @@
+<apex:page standardController="CampaignMember__c" extensions="NewAndEditCampaignMemberController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script>
+        
+        var config = {};
+        config = {
+            SobjectName : "{!SobjectName}",
+            ApiPrefix:"{!ApiPrefix}",
+            SaveAndNew:false,
+            AWSToSobjectMap:{!AWSToSobjectMapJson},
+            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
+            SobjectToAWSModel:function (sobjJson) {
+                let leadPayloadList = [];
+                let leadPIData = {};
+
+                for(let f in config.AWSToSobjectMap){
+                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
+                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
+                    }
+                    else{
+                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
+                    }
+                } 
+
+
+                leadPIData.sfRecordId = '';
+                console.log('Sobject PI Data:' + leadPIData);
+                leadPayloadList.push(leadPIData);
+                console.log(JSON.stringify(leadPayloadList));
+                return JSON.stringify(leadPayloadList);
+            },
+            insertOrUpdateBack:function(payloadJson, r, isNewMode){
+                
+                for(let f in config.AWSToSobjectMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+
+                for(let f in config.AWSToSobjectEncryptedMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+                
+                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                if (isNewMode) {
+                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                } else {
+                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                }
+                return payloadJson;
+            },
+            queryBack:function (data) {
+                console.log('data = ' + data);
+                if(data.object){
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
+                        if(data.object.hasOwnProperty(f) && ele){
+                            
+                            // 澶氶�夌壒娈婂鐞�
+                            if(ele.type == 'select-multiple'){
+                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
+                               if(ele && data.object[f]){
+                                   let arr = data.object[f].split(';');
+
+                                   // 缁欓殣钘忕殑select璧嬪��
+                                   for(let op of ele.options){
+                                       op.selected = arr.indexOf(op.value)>-1;
+                                   }
+                                   
+                                   // 鍒╃敤鎸夐挳缁欐樉绀虹殑select璧嬪��
+                                   let ra = document.getElementById(ele.id + '_right_arrow');
+                                   if(ra){
+                                       ra.click();
+                                   }
+                                   
+                               }
+                            }else{
+                                ele.value = data.object[f];
+                            }
+                            
+                        }
+                        else{
+                            console.log(f + 'is not in data.object');
+                        }
+                    }
+                }
+                else{
+                    console.log('data.object = ' + data.object);
+                }
+            },
+            updateMethod:"NewAndEditCampaignMemberController.saveCampaignMember",
+            insertMethod:"NewAndEditCampaignMemberController.saveCampaignMember"
+        }
+    
+        var staticResources = JSON.parse('{!staticResource}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        console.log('{!staticResource}');
+        var VLookUpFields = {! VLookUpFieldsJson};
+        function ProcessPI(sobjJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+            	NewPIToAWS(sobjJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(sobjJson, payloadForNewPI)
+            }
+        }
+
+        var GetEleByClass = function(class_name){
+            let eles = document.getElementsByClassName(class_name);
+            if(eles.length > 0) return eles[0];
+            return null;
+        }
+
+        var GetEleApiName = function(ele){
+            for(let c of ele.classList){
+                if(c.indexOf(config.ApiPrefix+'_')>-1){
+                    return c.replace(config.ApiPrefix+'_','');
+                }
+            }
+            return '';
+        }
+
+        function IsFormElement(tag_name){
+            return ['input','select','textarea'].indexOf(tag_name)>-1;
+        }
+
+        function getPIPayload(sobjJson) {
+            return config.SobjectToAWSModel(sobjJson);
+        }
+
+        function validateFieldValueFormate() {
+            let error_msg = '';
+            let textEmail = "[data-id='Email']";
+            let textPhone = "[data-id='Phone']";
+            //Email
+            let email = document.querySelector(textEmail);
+            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
+                error_msg += ';閭欢鏍煎紡閿欒';
+            }
+            let phone = document.querySelector(textPhone);
+
+            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
+                error_msg += ';鐢佃瘽鍙风爜閿欒';
+            }
+
+            for(let e of document.getElementsByTagName('select')){
+                for(let op of e.options){
+                    if(op.value == "*****" && op.selected){
+                        error_msg += ';涓嬫媺妗嗕笉鑳戒富鍔ㄩ�夋嫨瀵嗘枃閫夐」';
+                    }
+                }
+            }
+
+            if(error_msg.length>0 && error_msg[0]== ';'){
+                error_msg = error_msg.substring(1);
+            }
+
+            return error_msg;
+        }
+
+        function getSobjectInformation() {
+
+            let nodelist = document.getElementsByClassName(config.ApiPrefix);
+            let result = {}
+            for (let index = 0; index < nodelist.length; index++) {
+                let ele = nodelist[index];
+                let field_api_name = GetEleApiName(ele);
+                let tag_name = ele.tagName.toLowerCase();
+                if(!IsFormElement(tag_name)){
+                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
+                    continue;
+                }
+
+                if (VLookUpFields.indexOf(field_api_name)>=0) {
+                    console.log(ele.id.indexOf('lkwgt'));
+                    if (ele.id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = ele.id + '_lkid';
+                        let vlook_ele = document.getElementById(vlookUpNodeId);
+                        let v = '';
+                        if(vlook_ele){
+                            v = vlook_ele.value;
+                        }else{
+                            v = ele.value;
+                        }
+
+                        if(v && v != "000000000000000"){
+                            result[field_api_name] = v;
+                        }
+                        
+                    }
+                } else if (ele.type == 'checkbox') {
+                    result[field_api_name] = ele.checked;
+                } else if (ele.type == 'select-multiple') {
+                    //field_api_name
+                    let multiple = field_api_name;
+                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[field_api_name] = targets;
+                } else {
+                    result[field_api_name] = ele.value;
+                }
+            }
+            return result;
+        }
+        function QuerySobjectFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+        function queryBack(data) {
+            console.log('data = ' + data);
+            config.queryBack(data);
+        };
+
+
+        function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + r);
+            console.log('payloadJson=' + payloadJson);
+            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
+        }
+
+        function redirectCallBack(sfId,errorMsg) {
+            unblockUI();
+            if(errorMsg){
+                alertErrorMessage(errorMsg);
+            }
+            else{
+                if(config.SaveAndNew){
+                    window.open('{! SaveAndNewButtonUrl }','_self');
+                }else{
+                    window.open('/' + sfId, '_self');
+                }
+            }
+            
+        }
+
+        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.updateMethod;
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
+            
+        }
+
+        function NewPIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.insertMethod;
+            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
+            
+        }
+        
+
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for(i = 0;i<requiredFieldAPIList.length;i++){
+                if(formData[requiredFieldAPIList[i]]){
+                    continue;
+                }else{
+                    if(blankRequiredFields == ''){
+                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }else{
+                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+                    
+                }
+            }
+            return blankRequiredFields;
+        }
+        function saveSobjectProcess(save_and_new) {
+            if(save_and_new){
+                config.SaveAndNew = true;
+            }
+            
+            hiddenErrorMsgNode();
+            //1. Get Sobject Information from Form
+            let sobjJson = getSobjectInformation();
+            //2. Validate the Sobject field value formate, for example the email formate or phone formate
+
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage(validationResultMessage);
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
+                return
+            }
+            // //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(sobjJson);
+
+            // //4. Get Authentication Information for AWS
+            // loadAWSAuthentication();
+
+            // //5. lead to AWS 
+            ProcessPI(sobjJson, payloadForNewPI);
+            // awsToken = TestToken;
+            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
+        }
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
+                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        
+        <apex:pageblock id="block">
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!CampaignMember__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                sfdcPage.appendToOnloadQueue(function () {
+                    //1. Set Last Name label
+                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for Sobject Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        QuerySobjectFromAWS();
+                    }   
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditCampaignMember.page-meta.xml b/force-app/main/default/pages/NewAndEditCampaignMember.page-meta.xml
new file mode 100644
index 0000000..c9cad86
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditCampaignMember.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditCampaignMember</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditCase.page b/force-app/main/default/pages/NewAndEditCase.page
new file mode 100644
index 0000000..092954e
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditCase.page
@@ -0,0 +1,442 @@
+<apex:page standardController="Case" extensions="NewAndEditCaseController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <style>
+        .disabledbutton {
+            pointer-events: none;
+            opacity: 0.4;
+        }
+    </style>
+    <script>
+        AWSService.sfSessionId = '{!GETSESSIONID()}';
+        var staticResources = JSON.parse('{!staticResource}');
+        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        var redirectMode = "Save";
+        var requiredAPIToChangedLabelMap = new Map();
+        requiredAPIToChangedLabelMap.set('LastName', '{!PIPL_Name_Label}');
+        console.log('{!contactsInfo}');
+        var VLookUpFields = new Set(['Account__c', 'ContactId', 'Asset__c', 'prod__c', 'Competitor_info__c', 'AccountId', 'Field1_staff__c']);
+        //鍒ゆ柇insert or update
+        function ProcessPI(caseJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+                NewPIToAWS(caseJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(caseJson, payloadForNewPI)
+            }
+        }
+        //闃叉鎸夐挳閲嶅鐐瑰嚮
+        function enableButton(obj){
+            obj.classList.remove("btnDisabled");
+        }
+
+        function disableButton(obj){
+            obj.classList.add("btnDisabled");
+        }
+
+        function disableButtonStatus(){
+            let btnList = document.getElementsByClassName('btn');
+            for(let i=0;i<btnList.length;i++){              
+                disableButton(btnList[i]);
+            }
+        }
+
+        function enableButtonStatus(){
+            let btnList = document.getElementsByClassName('btn');
+            for(let i=0;i<btnList.length;i++){
+                enableButton(btnList[i]);   
+            }
+        }
+
+        //鑾峰彇鍔犲瘑瀛楁
+        function getPIPayload(caseJson) {
+            let casePayloadList = [];
+            let CicTelephone = caseJson.cic_telephone__c;
+            let CaseCustomer = caseJson.CASE_CUSTOMER__c;
+            let CustomerManual = caseJson.Customer_manual__c;
+            let casePIData = new Object();
+            casePIData.cicTelephone = CicTelephone;
+            casePIData.caseCustomer = CaseCustomer;
+            casePIData.customerManual = CustomerManual;
+            casePIData.sfRecordId = '';
+            console.log('Case PI Data:' + casePIData);
+            casePayloadList.push(casePIData);
+            console.log(JSON.stringify(casePayloadList));
+            return JSON.stringify(casePayloadList);
+        }
+        //鍒ゆ柇鏁版嵁鏍煎紡
+        function validateFieldValueFormate() {
+            //let textEmail = "[data-id='Email']";
+            let textPhone = "[data-id='cic_telephone__c']";
+            if (!document.querySelector("[data-id='Account__c']")) {
+                return true;
+            }
+            //Email
+            //let email = document.querySelector(textEmail).value;
+            let phone = document.querySelector(textPhone).value;
+            if (phone == "") {
+                return true;
+            }
+            //let regEmail = /^[\w-]{3,12}@[\da-zA-Z]{2,6}\.[a-zA-Z]+$/;
+            let regPhone = /^1[3|5|8|7][0-9]\d{4,8}$/;
+
+            //let emailFormate = regEmail.test(email);
+            let phoneFormate = regPhone.test(phone);
+
+            //console.log(emailFormate);
+            console.log(phoneFormate);
+            //if (emailFormate == true && phoneFormate == true) {
+            if (phoneFormate == true) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+        //鑾峰彇琛ㄥ崟鏁版嵁
+        function getCaseInformation() {
+
+            let nodelist = document.querySelectorAll("[data-id]");
+            let result = {}
+            result.RecordTypeId = '{!rtTypeId}'
+            for (let index = 0; index < nodelist.length; index++) {
+                if (VLookUpFields.has(nodelist[index].getAttribute("data-id"))) {
+                    console.log(nodelist[index].id.indexOf('lkwgt'));
+                    if (nodelist[index].id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = nodelist[index].id + '_lkid';
+                        let vlookUpNodeValue = document.getElementById(vlookUpNodeId).value;
+                        result[nodelist[index].getAttribute("data-id")] = vlookUpNodeValue;
+                    }
+                } else if (nodelist[index].type == 'checkbox') {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].checked;
+                } else if (nodelist[index].type == 'select-multiple') {
+                    //nodelist[index].getAttribute("data-id")
+                    let multiple = nodelist[index].getAttribute("data-id");
+                    let targets = document.querySelector("[data-id=" + multiple + "]").parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[nodelist[index].getAttribute("data-id")] = targets;
+                } else {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].value;
+                }
+                let x = index + 1;
+                if (x <= nodelist.length-1 && (nodelist[x].getAttribute("data-id") == nodelist[index].getAttribute("data-id"))) {
+                    index++;
+                }
+            }
+            //閽堝id鐨勬墜鍔ㄦ坊鍔�
+            if (document.getElementById("page:form:block:j_id31:0:j_id32:j_id33:1:j_id34_lkid") && (!result.hasOwnProperty("Field1_staff__c") || !result["Field1_staff__c"])){
+                if(document.getElementById("page:form:block:j_id31:0:j_id32:j_id33:1:j_id34_lkid").value != '000000000000000'){
+                	result["Field1_staff__c"] = document.getElementById("page:form:block:j_id31:0:j_id32:j_id33:1:j_id34_lkid").value;
+                }
+            }
+            
+            return result;
+        }
+        //鏌ヨ
+        function QueryCaseFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+        //闇�瑕佽В瀵嗗瓧娈�
+        var queryBack = function queryBack(data) {
+            console.log('data = ' + data);
+            document.querySelector("[data-id='cic_telephone__c']").value = data.object.cicTelephone;
+            document.querySelector("[data-id='CASE_CUSTOMER__c']").value = data.object.caseCustomer;
+            document.querySelector("[data-id='Customer_manual__c']").value = data.object.customerManual;
+        };
+
+        var insertOrUpdateBack = function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + r);
+            console.log('payloadJson=' + payloadJson);
+            payloadJson.cic_telephone__c = r.object[0].cicTelephone;
+            payloadJson.CASE_CUSTOMER__c = r.object[0].caseCustomer;
+            payloadJson.Customer_manual__c = r.object[0].customerManual;
+            payloadJson.cic_telephone_Encrypted__c = r.object[0].cicTelephoneEncrypt;
+            payloadJson.CASE_CUSTOMER_Encrypted__c = r.object[0].caseCustomerEncrypt;
+            payloadJson.Customer_manual_Encrypted__c = r.object[0].customerManualEncrypt;
+            //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+            payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            if (isNewMode) {
+                payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+            } else {
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            }
+            return payloadJson;
+        }
+        //鍥炶皟鍑芥暟锛岀偣鍑诲悗浜嬩欢
+        var redirectCallBack = function redirectCallBack(sfId,errorMessage) {
+            if(sfId){
+                if(redirectMode == 'Save'){
+                    window.open('/' + sfId, '_self');
+                }else if(redirectMode == 'SaveAndNew'){
+                    window.open('/setup/ui/recordtypeselect.jsp?ent='+'{!sobjecttypeForFrontEnd}'+'&retURL=/'+'{!sobjectPrefix}'+'/o&save_new_url=/'+'{!sobjectPrefix}'+'/e?retURL=%2F'+'{!sobjectPrefix}'+'%2Fo','_self');
+                }else if(redirectMode == 'SaveAndClose'){
+                    window.open('/' + sfId + '/s?retURL=%2F' + sfId + '&co=1', '_self');
+                }
+            }else{
+                alertErrorMessage(errorMessage);
+            }
+        }
+        //update to AWS
+        function UpdatePIToAWS(caseJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewAndEditCaseController.saveCase}';
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, caseJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack, redirectCallBack);
+        }
+        //insert to AWS
+        function NewPIToAWS(caseJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewAndEditCaseController.saveCase}';
+            AWSService.insert(staticResources.newUrl, caseJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack, redirectCallBack);
+        }
+        //蹇呭~瀛楁
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for (i = 0; i < requiredFieldAPIList.length; i++) {
+                if (formData[requiredFieldAPIList[i]]) {
+                    continue;
+                } else {
+                    let fieldAPIValue = requiredFieldAPIList[i]
+                    let fieldLabelValue = fieldAPIToLabelMap[fieldAPIValue];
+                    if (requiredAPIToChangedLabelMap.has(fieldAPIValue)) {
+                        fieldLabelValue = requiredAPIToChangedLabelMap.get(fieldAPIValue);
+                    }
+                    if (blankRequiredFields == '') {
+                        blankRequiredFields = blankRequiredFields + fieldLabelValue;
+                    } else {
+                        blankRequiredFields = blankRequiredFields + ',' + fieldLabelValue;
+                    }
+
+                }
+            }
+            return blankRequiredFields;
+        }
+        //鎸夐挳鐐瑰嚮浜嬩欢
+        function saveCaseProcess(saveMode) {
+            disableButtonStatus();
+            redirectMode = saveMode;
+            console.log('redirectMode'+redirectMode);
+            hiddenErrorMsgNode();
+            //1. Get Case Information from Form
+            let caseJson = getCaseInformation();
+            //2. Validate the Case field value formate, for example the email formate or phone formate
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (!validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                //alertErrorMessage('閭鏍煎紡杈撳叆鏈夎锛岃閲嶆柊杈撳叆锛�');
+                alertErrorMessage('鎵嬫満鏍煎紡杈撳叆鏈夎锛岃閲嶆柊杈撳叆锛�');
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(caseJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('{!Input_Required_Field_Msg}'+checkRequiredFieldMsgResult);
+                return
+            }
+            //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(caseJson);
+
+            //4. Case to AWS 
+            ProcessPI(caseJson, payloadForNewPI);
+        }
+        //error 鎶ラ敊
+        function alertErrorMessage(errorMsg) {
+            enableButtonStatus();
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsg = '閿欒锛氭棤鏁堟暟鎹��'+'\n' + errorMsg;
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+            unblockUI();
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+        var newSearchContactWindow = null;  
+        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+        function htmlToElement(html) {
+            var template = document.createElement('template');
+            html = html.trim(); // Never return a text node of whitespace as the result
+            template.innerHTML = html;
+            return template.content.firstChild;
+        }
+        //鑷畾涔塴ookup鏌ヨ
+        function searchContact(contactNodeId){
+            let accountValue = "";
+            if (document.querySelector("[data-id='Account__c']")) {
+                let accountNodeId = document.querySelector("[data-id='Account__c']").id + '_lkid';
+                accountValue = document.getElementById(accountNodeId).value;   
+            } 
+            console.log(accountValue);
+            if(accountValue !='000000000000000'){
+                let baseUrl = "/apex/SearchContactPage";
+                let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
+                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
+                newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
+                if (window.focus) {
+                    newSearchContactWindow.focus();
+                }
+                return false;
+            }else{
+                alertErrorMessage('{!PIPL_Input_Account_Error_Msg}');
+            }
+        }
+        //绐楀彛鍏抽棴鏃跺彂鐢�
+        function closePopupWindow() {
+            if (null != newSearchContactWindow) {
+                newSearchContactWindow.close();
+            }
+            let contactInfoStr = document.getElementById('page:form:contactId').value;
+            console.log('closePopup:'+contactInfoStr);
+            let contactInfo = JSON.parse(contactInfoStr);
+            let contactNodeId = document.querySelector("[data-id='ContactId']").id + '_lkid';
+            document.getElementById(contactNodeId).value = contactInfo.ContactId;
+            document.querySelector("[data-id='ContactId']").value = contactInfo.Name;
+        }
+        //鏇挎崲vlookup
+        function replaceSearchContactLookup() {
+            let lookUpNode = htmlToElement(contactHtmlString);
+            console.log(lookUpNode);
+            if (!{!isNewMode}) {
+                //1. Query Contact from AWS by AWSDataId
+                // document.querySelector("[data-id='ContactId']").value = '鐜嬪';
+                queryContactName()
+            }           
+            let parentNode = document.querySelector("[data-id='ContactId']").parentNode;
+            document.querySelector("[data-id='ContactId']").removeAttribute("onchange");
+            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='ContactId']").parentNode.children[2]);
+        }
+
+        function queryContactName() {
+            let sfId = document.getElementById(document.querySelector("[data-id='ContactId']").id + '_lkid').value;
+            let contactsInfo = JSON.parse('{!contactsInfo}');
+            let dataId = contactsInfo[sfId];
+            // let queryContactBack = function(data){
+            //     //To Do later
+            //     console.log('ContactData = ' + data.object);
+                
+            //     document.querySelector("[data-id='ContactId']").value = data.object.lastName;
+            // }
+            // AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
+            let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+            fetch(url, {
+                method: 'GET',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then((result) => {
+                document.querySelector("[data-id='ContactId']").value = result.object.lastName;
+            })
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="CIC" class="pageTitleIcon" title="CIC" />
+                <h1 class="pageType">CIC缂栬緫
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> 鏂板缓CIC</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target=cases_edit.htm&amp;section=Cases&amp;language=zh_CN&amp;release=234.18.14&amp;instance=CS58&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <apex:inputHidden value="{!contactId}" id="contactId"/>
+        <apex:pageblock id="block"> 
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">CIC缂栬緫</h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveCaseProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞跺叧闂�" onclick="saveCaseProcess('SaveAndClose')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveCaseProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>          
+            <br/>
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" showHeader="{!layoutSection.useHeader}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField html-data-id="{!layoutField.fieldAPI}" value="{!Case[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                sfdcPage.appendToOnloadQueue(function () {
+                    //1. Set Last Name label
+                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for Case Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();
+                        QueryCaseFromAWS();
+                        unblockUI();
+                    }
+                    //Replace Vlookup Field
+                    replaceSearchContactLookup();
+                    //3. Set Readonly Attribute
+                    document.querySelector("[data-id='OwnerId']").classList.add("disabledbutton");
+                    document.querySelector("[data-id='RecordTypeId']").classList.add("disabledbutton");
+                    //闇�瑕侀殣钘�
+                    // document.querySelector("[data-id='SuppliedEmail']").classList.add("displayblock");
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButton" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveCaseProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞跺叧闂�" onclick="saveCaseProcess('SaveAndClose')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveCaseProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditCase.page-meta.xml b/force-app/main/default/pages/NewAndEditCase.page-meta.xml
new file mode 100644
index 0000000..16f39cf
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditCase.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditCase</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditContact.page b/force-app/main/default/pages/NewAndEditContact.page
new file mode 100644
index 0000000..0a78a75
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditContact.page
@@ -0,0 +1,485 @@
+<apex:page standardController="Contact" extensions="NewAndEditContactController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script>
+        
+        var config = {};
+        config = {
+            SobjectName : "{!SobjectName}",
+            ApiPrefix:"{!ApiPrefix}",
+            SaveAndNew:false,
+            AWSToSobjectMap:{!AWSToSobjectMapJson},
+            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+            AWSToSobjectNonEncryptedMapKeySet:{!AWSToSobjectNonEncryptedMapKeySet},
+            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
+            SobjectToAWSModel:function (sobjJson) {
+                let leadPayloadList = [];
+                let leadPIData = {};
+
+                for(let f in config.AWSToSobjectMap){
+                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
+                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
+                    }
+                    else{
+                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
+                    }
+                } 
+
+                leadPIData.medicalStaffFullName = leadPIData.lastName;// 瀹屾垚field update workflow
+                leadPIData.sfRecordId = '';
+                console.log('Sobject PI Data:' + leadPIData);
+                leadPayloadList.push(leadPIData);
+                console.log(JSON.stringify(leadPayloadList));
+                return JSON.stringify(leadPayloadList);
+            },
+            insertOrUpdateBack:function(payloadJson, r, isNewMode){
+                
+                for(let f in config.AWSToSobjectMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+
+                for(let f in config.AWSToSobjectEncryptedMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+                
+                if('{!rtTypeId}'){
+                    payloadJson.RecordTypeId = '{!rtTypeId}';
+                }
+                
+                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                if (isNewMode) {
+                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                } else {
+                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                }
+                return payloadJson;
+            },
+            queryBack:function (data) {
+                console.log('data = ' + data);
+                if(data.object){
+                    for(let f of config.AWSToSobjectNonEncryptedMapKeySet){
+                        let ele = document.getElementById(api_id_map[config.AWSToSobjectNonEncryptedMap[f]])
+                        if(data.object.hasOwnProperty(f) && ele){
+                            
+                            // 澶氶�夌壒娈婂鐞�
+                            if(ele.type == 'select-multiple'){
+                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
+                               if(ele ){
+                                   //_unselected
+                                   let v = '';
+                                   if(data.object[f]){
+                                       v = data.object[f];
+                                   }
+                                   
+                                   let arr = v.split(';');
+
+                                   // 娓呯┖宸叉湁閫夐」
+                                   /*
+                                   let sl = document.getElementById(ele.id + '_selected');
+                                   if(sl){
+                                       for(let op of sl.options){
+                                           op.selected = true;
+                                       }
+                                       let la = document.getElementById(ele.id + '_left_arrow');
+                                       if(la){
+                                           la.click();
+                                       }
+                                   }
+                                   
+                                   // 璧嬪�兼柊閫夐」
+                                   let us = document.getElementById(ele.id + '_unselected');
+                                   if(us){
+                                       for(let op of us.options){
+                                           op.selected = arr.indexOf(op.value)>-1;
+                                       }
+                                       let ra = document.getElementById(ele.id + '_right_arrow');
+                                       if(ra){
+                                           ra.click();
+                                       }
+                                   }*/
+                                   for(let op of ele.options){
+                                       op.selected = arr.indexOf(op.value)>-1;
+                                   }
+                                   let ra = document.getElementById(ele.id + '_right_arrow');
+                                   if(ra){
+                                       ra.click();
+                                   }
+                                   
+                               }
+                            }else{
+                                ele.value = data.object[f];
+                            }
+
+                            if(ele.type.indexOf("select")>-1 && ele.value){
+                                jQuery(ele).change()
+                            }
+                            
+                        }
+                        else{
+                            console.log(f + 'is not in data.object');
+                        }
+                    }
+                }
+                else{
+                    console.log('data.object = ' + data.object);
+                }
+                
+
+                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                // document.querySelector("[data-id='Phone']").value = data.object.phone;
+                // document.querySelector("[data-id='Email']").value = data.object.email;
+            },
+            updateMethod:"NewAndEditContactController.saveContact",
+            insertMethod:"NewAndEditContactController.saveContact"
+        }
+    
+        AWSService.sfSessionId = '{!GETSESSIONID()}';
+        var staticResources = JSON.parse('{!staticResource}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        console.log('{!staticResource}');
+        var VLookUpFields = {! VLookUpFieldsJson};
+        function ProcessPI(sobjJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+            	NewPIToAWS(sobjJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(sobjJson, payloadForNewPI)
+            }
+        }
+
+        var GetEleByClass = function(class_name){
+            let eles = document.getElementsByClassName(class_name);
+            if(eles.length > 0) return eles[0];
+            return null;
+        }
+
+        var GetEleApiName = function(ele){
+            for(let c of ele.classList){
+                if(c.indexOf(config.ApiPrefix+'_')>-1){
+                    return c.replace(config.ApiPrefix+'_','');
+                }
+            }
+            return '';
+        }
+
+        function IsFormTag(tag_name){
+            return ['input','select','textarea'].indexOf(tag_name.toLowerCase())>-1;
+        }
+    	
+    	function IsFormElement(e){
+            return IsFormTag(e.tagName);
+        }
+
+        function getPIPayload(sobjJson) {
+            return config.SobjectToAWSModel(sobjJson);
+        }
+
+        function validateFieldValueFormate() {
+            let error_msg = '';
+            let textEmail = "[data-id='Email']";
+            let textPhone = "[data-id='Phone']";
+            //Email
+            let email = document.querySelector(textEmail);
+            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
+                error_msg += ';閭欢鏍煎紡閿欒';
+            }
+            let phone = document.querySelector(textPhone);
+
+            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
+                error_msg += ';鐢佃瘽鍙风爜閿欒';
+            }
+
+            for(let e of document.getElementsByTagName('select')){
+                for(let op of e.options){
+                    if(op.value == "*****" && op.selected){
+                        error_msg += ';涓嬫媺妗嗕笉鑳戒富鍔ㄩ�夋嫨瀵嗘枃閫夐」';
+                    }
+                }
+            }
+
+            if(error_msg.length>0 && error_msg[0]== ';'){
+                error_msg = error_msg.substring(1);
+            }
+
+            return error_msg;
+        }
+
+        function getSobjectInformation() {
+            //api_id_map
+//let nodelist = document.getElementsByClassName(config.ApiPrefix);
+            let result = {}
+            for (let index in api_id_map) {
+                let ele = document.getElementById(api_id_map[index]);
+                let field_api_name = index;
+                let tag_name = ele.tagName.toLowerCase();
+                if(!IsFormTag(tag_name)){
+                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
+                    continue;
+                }
+
+                if (VLookUpFields.indexOf(field_api_name)>=0) {
+                    console.log(ele.id.indexOf('lkwgt'));
+                    if (ele.id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = ele.id + '_lkid';
+                        let vlook_ele = document.getElementById(vlookUpNodeId);
+                        let v = '';
+                        if(vlook_ele){
+                            v = vlook_ele.value;
+                        }else{
+                            v = ele.value;
+                        }
+
+                        if(v && v != "000000000000000"){
+                            result[field_api_name] = v;
+                        }
+                        
+                    }
+                } else if (ele.type == 'checkbox') {
+                    result[field_api_name] = ele.checked;
+                } else if (ele.type == 'select-multiple') {
+                    //field_api_name
+                    let multiple = field_api_name;
+                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[field_api_name] = targets;
+                } else {
+                    result[field_api_name] = ele.value;
+                }
+                
+                // let e1 = document.getElementById(api_id_map[field_api_name]);
+                // if(!result[field_api_name] && e1 && e1.value){
+                // 	result[field_api_name] = e1.value;
+                // }
+            }
+            return result;
+        }
+        function QuerySobjectFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+        function queryBack(data) {
+            console.log('data = ' + data);
+            config.queryBack(data);
+            unblockUI();
+        };
+
+
+        function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + r);
+            console.log('payloadJson=' + payloadJson);
+            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
+        }
+
+        function redirectCallBack(sfId,errorMsg) {
+            unblockUI();
+            if(errorMsg){
+                alertErrorMessage(errorMsg);
+            }
+            else{
+                if(config.SaveAndNew){
+                    window.open('{! SaveAndNewButtonUrl }','_self');
+                }else{
+                    window.open('/' + sfId, '_self');
+                }
+            }
+            
+        }
+
+        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.updateMethod;
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
+            
+        }
+
+        function NewPIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.insertMethod;
+            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
+            
+        }
+        
+
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for(i = 0;i<requiredFieldAPIList.length;i++){
+                if(formData[requiredFieldAPIList[i]]){
+                    continue;
+                }else{
+                    if(blankRequiredFields == ''){
+                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }else{
+                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+                    
+                }
+            }
+            return blankRequiredFields;
+        }
+        function saveSobjectProcess(save_and_new) {
+            if(save_and_new){
+                config.SaveAndNew = true;
+            }
+            
+            hiddenErrorMsgNode();
+            //1. Get Sobject Information from Form
+            let sobjJson = getSobjectInformation();
+            //2. Validate the Sobject field value formate, for example the email formate or phone formate
+
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage(validationResultMessage);
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
+                return
+            }
+            // //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(sobjJson);
+
+            // //4. Get Authentication Information for AWS
+            // loadAWSAuthentication();
+
+            // //5. lead to AWS 
+            ProcessPI(sobjJson, payloadForNewPI);
+            // awsToken = TestToken;
+            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
+        }
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
+                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        
+        <apex:pageblock id="block">
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+                    
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Contact[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                                         required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+                    
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+            var init_nodes = document.getElementsByClassName("PIBackApi");
+            var api_id_map={};
+            for(let e of init_nodes){
+            	if(IsFormElement(e)){
+                    if(e.getAttribute("multiple") != 'multiple' || e.style.display == 'none' && e.id.indexOf('selected') < 0){
+                        api_id_map[GetEleApiName(e)] = e.id;
+                    }
+                	 
+                }
+            }
+            console.log(api_id_map);
+            sfdcPage.appendToOnloadQueue(function () {
+                //1. Set Last Name label
+                //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                //2. Query AWS Data by dataId 
+                console.log('Mode for Sobject Page:' + {!isNewMode});
+                if (!{!isNewMode}) {
+                    blockme();
+                    QuerySobjectFromAWS();
+                }
+            });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditContact.page-meta.xml b/force-app/main/default/pages/NewAndEditContact.page-meta.xml
new file mode 100644
index 0000000..1f3f827
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditContact.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditContact</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditInquiryForm.page b/force-app/main/default/pages/NewAndEditInquiryForm.page
new file mode 100644
index 0000000..ddf818a
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditInquiryForm.page
@@ -0,0 +1,607 @@
+<apex:page standardController="Inquiry_form__c" extensions="NewAndEditInquiryFormController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <style>
+        .disabledbutton {
+            pointer-events: none;
+            opacity: 0.4;
+        }
+    </style>
+    <script>
+        AWSService.sfSessionId = '{!GETSESSIONID()}';
+        //閰嶇疆鏂规硶
+        var config = {};
+        config = {
+            SobjectName : "{!SobjectName}",
+            ApiPrefix:"{!ApiPrefix}",
+            SaveAndNew:false,
+            AWSToSobjectMap:{!AWSToSobjectMapJson},
+            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
+            SobjectToAWSModel:function (sobjJson) {
+                let leadPayloadList = [];
+                let leadPIData = {};
+
+                for(let f in config.AWSToSobjectMap){
+                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
+                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
+                    }
+                    else{
+                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
+                    }
+                } 
+
+
+                leadPIData.sfRecordId = '';
+                console.log('Sobject PI Data:' + leadPIData);
+                leadPayloadList.push(leadPIData);
+                console.log(JSON.stringify(leadPayloadList));
+                return JSON.stringify(leadPayloadList);
+            },
+            insertOrUpdateBack:function(payloadJson, r, isNewMode){
+                
+                for(let f in config.AWSToSobjectMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+
+                for(let f in config.AWSToSobjectEncryptedMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+                
+                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                if (isNewMode) {
+                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                } else {
+                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                }
+                return payloadJson;
+            },
+            queryBack:function (data) {
+                console.log('data = ' + data);
+                if(data.object){
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
+                        if(data.object.hasOwnProperty(f) && ele){
+                            
+                            // 澶氶�夌壒娈婂鐞�
+                            if(ele.type == 'select-multiple'){
+                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
+                               if(ele && data.object[f]){
+                                   let arr = data.object[f].split(';');
+
+                                   // 缁欓殣钘忕殑select璧嬪��
+                                   for(let op of ele.options){
+                                       op.selected = arr.indexOf(op.value)>-1;
+                                   }
+                                   
+                                   // 鍒╃敤鎸夐挳缁欐樉绀虹殑select璧嬪��
+                                   let ra = document.getElementById(ele.id + '_right_arrow');
+                                   if(ra){
+                                       ra.click();
+                                   }
+                                   
+                               }
+                            }else{
+                                ele.value = data.object[f];
+                            }
+                            
+                        }
+                        else{
+                            console.log(f + 'is not in data.object');
+                        }
+                    }
+                }
+                else{
+                    console.log('data.object = ' + data.object);
+                }
+                
+
+                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                // document.querySelector("[data-id='Phone']").value = data.object.phone;
+                // document.querySelector("[data-id='Email']").value = data.object.email;
+            },
+            updateMethod:"NewAndEditInquiryFormController.saveInquiryForm",
+            insertMethod:"NewAndEditInquiryFormController.saveInquiryForm"
+        }
+    
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        var staticResources = JSON.parse('{!staticResource}');
+        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
+        var staticResourcesLead = JSON.parse('{!staticResourceLead}');
+        console.log('{!staticResource}');
+        var VLookUpFields = {! VLookUpFieldsJson};
+        function ProcessPI(sobjJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+            	NewPIToAWS(sobjJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(sobjJson, payloadForNewPI)
+            }
+        }
+
+        var GetEleByClass = function(class_name){
+            let eles = document.getElementsByClassName(class_name);
+            if(eles.length > 0) return eles[0];
+            return null;
+        }
+
+        var GetEleApiName = function(ele){
+            for(let c of ele.classList){
+                if(c.indexOf(config.ApiPrefix+'_')>-1){
+                    return c.replace(config.ApiPrefix+'_','');
+                }
+            }
+            return '';
+        }
+
+        function IsFormElement(tag_name){
+            return ['input','select','textarea'].indexOf(tag_name)>-1;
+        }
+
+        function getPIPayload(sobjJson) {
+            return config.SobjectToAWSModel(sobjJson);
+        }
+
+        function validateFieldValueFormate() {
+            let error_msg = '';
+            let textEmail = "[data-id='Email__c']";
+            let textPhone = "[data-id='Phone__c']";
+            if (document.querySelector("[data-id='Email__c']").value != "" && document.querySelector("[data-id='Email__c']").value != null) {
+                //Email
+                let email = document.querySelector(textEmail);
+                if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
+                    error_msg += ';閭欢鏍煎紡閿欒';
+                }
+            }
+
+            if (document.querySelector("[data-id='Phone__c']").value != "" && document.querySelector("[data-id='Phone__c']").value != null) {
+                let phone = document.querySelector(textPhone);
+                if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
+                    error_msg += ';鐢佃瘽鍙风爜閿欒';
+                }
+            }
+            
+            for(let e of document.getElementsByTagName('select')){
+                for(let op of e.options){
+                    if(op.value == "*****" && op.selected){
+                        error_msg += ';涓嬫媺妗嗕笉鑳戒富鍔ㄩ�夋嫨瀵嗘枃閫夐」';
+                    }
+                }
+            }
+
+            if(error_msg.length>0 && error_msg[0]== ';'){
+                error_msg = error_msg.substring(1);
+            }
+
+            return error_msg;
+        }
+
+        function getSobjectInformation() {
+
+            let nodelist = document.getElementsByClassName(config.ApiPrefix);
+            let result = {}
+            for (let index = 0; index < nodelist.length; index++) {
+                let ele = nodelist[index];
+                let field_api_name = GetEleApiName(ele);
+                let tag_name = ele.tagName.toLowerCase();
+                if(!IsFormElement(tag_name)){
+                    console.log('tag_name='+tag_name+',field_api_name '+field_api_name+' is not a form element');
+                    continue;
+                }
+
+                if (VLookUpFields.indexOf(field_api_name)>=0) {
+                    console.log(ele.id.indexOf('lkwgt'));
+                    if (ele.id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = ele.id + '_lkid';
+                        let vlook_ele = document.getElementById(vlookUpNodeId);
+                        let v = '';
+                        if(vlook_ele){
+                            v = vlook_ele.value;
+                        }else{
+                            v = ele.value;
+                        }
+
+                        if(v && v != "000000000000000"){
+                            result[field_api_name] = v;
+                        }
+                        
+                    }
+                } else if (ele.type == 'checkbox') {
+                    result[field_api_name] = ele.checked;
+                } else if (ele.type == 'select-multiple') {
+                    //field_api_name
+                    let multiple = field_api_name;
+                    let targets = "";
+                    //InquiryForm鐗规畩澶勭悊
+                    if(multiple == "Product1__c" || multiple == "Request1__c"){
+                        targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[2].rows[1].cells[2].innerText;
+                    }else{
+                        targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    }
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[field_api_name] = targets;
+                } else {
+                    result[field_api_name] = ele.value;
+                }
+            }
+            return result;
+        }
+        //鏌ヨ 瑙e瘑
+        function QuerySobjectFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+        //鏌ヨ 杩斿洖
+        function queryBack(data) {
+            console.log('data = ' + data);
+            config.queryBack(data);
+        };
+        //鏂板缓/鏇存敼 杩斿洖
+        function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + r);
+            console.log('payloadJson=' + payloadJson);
+            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
+        }
+
+        function redirectCallBack(sfId,errorMsg) {
+            unblockUI();
+            if(errorMsg){
+                alertErrorMessage(errorMsg);
+            }
+            else{
+                if(config.SaveAndNew){
+                    window.open('{! SaveAndNewButtonUrl }','_self');
+                }else{
+                    window.open('/' + sfId, '_self');
+                }
+            }
+            
+        }
+        //鏇存柊 to AWS
+        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.updateMethod;
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
+            
+        }
+        //鏂板缓 to AWS
+        function NewPIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.insertMethod;
+            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
+            
+        }
+        
+        //蹇呭~瀛楁
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for(i = 0;i<requiredFieldAPIList.length;i++){
+                if(formData[requiredFieldAPIList[i]]){
+                    continue;
+                }else{
+                    if(blankRequiredFields == ''){
+                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }else{
+                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+                    
+                }
+            }
+            return blankRequiredFields;
+        }
+        //鎸夐挳鐐瑰嚮鏂规硶
+        function saveSobjectProcess(save_and_new) {
+            if(save_and_new){
+                config.SaveAndNew = true;
+            }
+            
+            hiddenErrorMsgNode();
+            //1. Get Sobject Information from Form
+            let sobjJson = getSobjectInformation();
+            //2. Validate the Sobject field value formate, for example the email formate or phone formate
+
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage(validationResultMessage);
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
+                return
+            }
+            // //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(sobjJson);
+
+            // //4. Get Authentication Information for AWS
+            // loadAWSAuthentication();
+
+            // //5. Inquiry to AWS 
+            ProcessPI(sobjJson, payloadForNewPI);
+            // awsToken = TestToken;
+            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
+        }
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+        
+        var newSearchContactWindow = null;  
+        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+        function htmlToElement(html) {
+            var template = document.createElement('template');
+            html = html.trim(); // Never return a text node of whitespace as the result
+            template.innerHTML = html;
+            return template.content.firstChild;
+        }
+        //鑷畾涔塴ookup鏌ヨ
+        function searchContact(contactNodeId){
+            // errorMsg 闅愯棌
+            if(document.getElementsByClassName("errorMsg").length > 0){
+                document.getElementsByClassName("errorMsg")[0].style.display="none";
+            }
+
+            let accountValue = "";
+            let suffixUrl = "";
+            if (document.querySelector("[data-id='Hospital_Name__c']")) {
+                let accountNodeId = document.querySelector("[data-id='Hospital_Name__c']").id + '_lkid';
+                accountValue = document.getElementById(accountNodeId).value;   
+            } 
+            console.log(accountValue);
+            if(accountValue !='000000000000000'){
+                suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
+            }else{
+                suffixUrl = "?contactId="+contactNodeId;
+            }
+            let baseUrl = "/apex/SearchContactPage";
+            let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
+            newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
+            if (window.focus) {
+                newSearchContactWindow.focus();
+            }
+            return false;
+        }
+        //绐楀彛鍏抽棴鏃跺彂鐢�
+        function closePopupWindow() {
+            if (null != newSearchContactWindow) {
+                newSearchContactWindow.close();
+            }
+            let contactInfoStr = document.getElementById('page:form:contactId').value;
+            console.log('closePopup:'+contactInfoStr);
+            let contactInfo = JSON.parse(contactInfoStr);
+            let contactNodeId = document.querySelector("[data-id='Contact_Name__c']").id + '_lkid';
+            document.getElementById(contactNodeId).value = contactInfo.ContactId;
+            document.querySelector("[data-id='Contact_Name__c']").value = contactInfo.Name;
+        }
+        
+        //鏇挎崲vlookup
+        function replaceSearchContactLookup() {
+            let lookUpNode = htmlToElement(contactHtmlString);
+            console.log(lookUpNode);
+            if (!{!isNewMode}) {
+                //1. Query Contact from AWS by AWSDataId
+                queryContactName()
+            }           
+            let parentNode = document.querySelector("[data-id='Contact_Name__c']").parentNode;
+            document.querySelector("[data-id='Contact_Name__c']").removeAttribute("onchange");
+            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Contact_Name__c']").parentNode.children[2]);
+        }
+
+        function queryContactName() {
+            let sfId = document.getElementById(document.querySelector("[data-id='Contact_Name__c']").id + '_lkid').value;
+            let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
+            let dataId = contactsInfo[sfId];
+            // let queryContactBack = function(data){
+            //     //To Do later
+            //     console.log('ContactData = ' + data.object);
+                
+            //     document.querySelector("[data-id='Contact_Name__c']").value = data.object.lastName;
+            // }
+            // AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
+            let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+            fetch(url, {
+                method: 'GET',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then((result) => {
+                document.querySelector("[data-id='Contact_Name__c']").value = result.object.lastName;
+            })
+        }
+        
+        //For Lead Search
+        var leadHtmlString = '<img src="/img/s.gif" onclick="searchLead(\'page:form:leadId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';        
+        var newSearchLeadWindow = null;  
+        //绐楀彛鍏抽棴鏃跺彂鐢�
+        function closeLeadPopupWindow() {
+            if (null != newSearchLeadWindow) {
+                newSearchLeadWindow.close();
+            }
+            let leadInfoStr = document.getElementById('page:form:leadId').value;
+            console.log('closePopup:'+leadInfoStr);
+            let leadInfo = JSON.parse(leadInfoStr);
+            let leadNodeId = document.querySelector("[data-id='Lead_link__c']").id + '_lkid';
+            document.getElementById(leadNodeId).value = leadInfo.LeadId;
+            document.querySelector("[data-id='Lead_link__c']").value = leadInfo.Name;
+        }
+        function searchLead(leadNodeId){
+            // let accountValue = "";
+            // let suffixUrl = "";
+            let suffixUrl = "?leadId="+leadNodeId;
+            let baseUrl = "/apex/SearchLeadPage";
+            let newSearchLeadParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
+            newSearchLeadWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchLeadParam);
+            if (window.focus) {
+                newSearchLeadWindow.focus();
+            }
+            return false;
+        }
+        //鏇挎崲鏌ユ壘Lead
+        function replaceSearchLeadLookup() {
+            let lookUpNode = htmlToElement(leadHtmlString);
+            console.log(lookUpNode);
+            if (!{!isNewMode}) {
+                //1. Query Lead from AWS by AWSDataId
+                queryLeadName()
+            }           
+            let parentNode = document.querySelector("[data-id='Lead_link__c']").parentNode;
+            document.querySelector("[data-id='Lead_link__c']").removeAttribute("onchange");
+            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Lead_link__c']").parentNode.children[2]);
+        }
+        function queryLeadName() {
+            let sfId = document.getElementById(document.querySelector("[data-id='Lead_link__c']").id + '_lkid').value;
+            let leadsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
+            let dataId = leadsInfo[sfId];
+            // let queryLeadBack = function(data){
+            //     //To Do later
+            //     console.log('ContactData = ' + data.object);
+                
+            //     document.querySelector("[data-id='Lead_link__c']").value = data.object.lastName;
+            // }
+            // AWSService.query(staticResourcesLead.queryUrl, dataId, queryLeadBack, staticResources.token);
+            let url = staticResourcesLead.queryUrl + '?dataId=' + dataId;
+            fetch(url, {
+                method: 'GET',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then((result) => {
+                document.querySelector("[data-id='Lead_link__c']").value = result.object.lastName;
+            })
+        }
+        
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
+                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <apex:inputHidden value="{!contactId}" id="contactId"/>
+        <apex:inputHidden value="{!leadId}" id="leadId"/>
+        <apex:pageblock id="block">
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Inquiry_form__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                sfdcPage.appendToOnloadQueue(function () {
+                    //1. Set Last Name label
+                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for Sobject Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();
+                        QuerySobjectFromAWS();
+                        unblockUI();
+                    }   
+                    //Replace Contact Vlookup Field
+                    replaceSearchContactLookup();
+                    //Replace Lead Vlookup Field
+                    replaceSearchLeadLookup(); 
+                    document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
+                    document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditInquiryForm.page-meta.xml b/force-app/main/default/pages/NewAndEditInquiryForm.page-meta.xml
new file mode 100644
index 0000000..9dde4a7
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditInquiryForm.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditInquiryForm</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditInspectionReport.page b/force-app/main/default/pages/NewAndEditInspectionReport.page
new file mode 100644
index 0000000..5038294
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditInspectionReport.page
@@ -0,0 +1,436 @@
+<apex:page standardController="Inspection_Report__c" extensions="NewAndEditInspectionReportController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script>
+        
+        var config = {};
+        config = {
+            SobjectName : "{!SobjectName}",
+            ApiPrefix:"{!ApiPrefix}",
+            SaveAndNew:false,
+            AWSToSobjectMap:{!AWSToSobjectMapJson},
+            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
+            SobjectToAWSModel:function (sobjJson) {
+                let leadPayloadList = [];
+                let leadPIData = {};
+
+                for(let f in config.AWSToSobjectMap){
+                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
+                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
+                    }
+                    else{
+                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
+                    }
+                } 
+
+
+                leadPIData.sfRecordId = '';
+                console.log('Sobject PI Data:' + leadPIData);
+                leadPayloadList.push(leadPIData);
+                console.log(JSON.stringify(leadPayloadList));
+                return JSON.stringify(leadPayloadList);
+            },
+            insertOrUpdateBack:function(payloadJson, r, isNewMode){
+                
+                for(let f in config.AWSToSobjectMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+
+                for(let f in config.AWSToSobjectEncryptedMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+                
+                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                if (isNewMode) {
+                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                } else {
+                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                }
+                return payloadJson;
+            },
+            queryBack:function (data) {
+                console.log('data = ' + data);
+                if(data.object){
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
+                        if(data.object.hasOwnProperty(f) && ele){
+                            
+                            // 澶氶�夌壒娈婂鐞�
+                            if(ele.type == 'select-multiple'){
+                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
+                               if(ele && data.object[f]){
+                                   let arr = data.object[f].split(';');
+
+                                   // 缁欓殣钘忕殑select璧嬪��
+                                   for(let op of ele.options){
+                                       op.selected = arr.indexOf(op.value)>-1;
+                                   }
+                                   
+                                   // 鍒╃敤鎸夐挳缁欐樉绀虹殑select璧嬪��
+                                   let ra = document.getElementById(ele.id + '_right_arrow');
+                                   if(ra){
+                                       ra.click();
+                                   }
+                                   
+                               }
+                            }else{
+                                ele.value = data.object[f];
+                            }
+                            
+                        }
+                        else{
+                            console.log(f + 'is not in data.object');
+                        }
+                    }
+                }
+                else{
+                    console.log('data.object = ' + data.object);
+                }
+                
+
+                //document.querySelector("[data-id='Responsible_Person__c']").value = data.object.responsiblePersonHP;
+                //document.querySelector("[data-id='phone__c']").value = data.object.callerPhone;
+                //document.querySelector("[data-id='Email']").value = data.object.email;
+            },
+            updateMethod:"NewAndEditInspectionReportController.saveInspectionReport",
+            insertMethod:"NewAndEditInspectionReportController.saveInspectionReport"
+        }
+    	AWSService.sfSessionId = '{!GETSESSIONID()}';
+        var staticResources = JSON.parse('{!staticResource}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        console.log('{!staticResource}');
+        var VLookUpFields = {! VLookUpFieldsJson};
+        function ProcessPI(sobjJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+            	NewPIToAWS(sobjJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(sobjJson, payloadForNewPI)
+            }
+        }
+
+        var GetEleByClass = function(class_name){
+            let eles = document.getElementsByClassName(class_name);
+            if(eles.length > 0) return eles[0];
+            return null;
+        }
+
+        var GetEleApiName = function(ele){
+            for(let c of ele.classList){
+                if(c.indexOf(config.ApiPrefix+'_')>-1){
+                    return c.replace(config.ApiPrefix+'_','');
+                }
+            }
+            return '';
+        }
+
+        function IsFormElement(tag_name){
+            return ['input','select','textarea'].indexOf(tag_name)>-1;
+        }
+
+        function getPIPayload(sobjJson) {
+            return config.SobjectToAWSModel(sobjJson);
+        }
+
+        function validateFieldValueFormate() {
+            let error_msg = '';
+            let textEmail = "[data-id='Email']";
+            let textPhone = "[data-id='Phone']";
+            //Email
+            let email = document.querySelector(textEmail);
+            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
+                error_msg += ';閭欢鏍煎紡閿欒';
+            }
+            let phone = document.querySelector(textPhone);
+
+            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
+                error_msg += ';鐢佃瘽鍙风爜閿欒';
+            }
+
+            for(let e of document.getElementsByTagName('select')){
+                for(let op of e.options){
+                    if(op.value == "*****" && op.selected){
+                        error_msg += ';涓嬫媺妗嗕笉鑳戒富鍔ㄩ�夋嫨瀵嗘枃閫夐」';
+                    }
+                }
+            }
+
+            if(error_msg.length>0 && error_msg[0]== ';'){
+                error_msg = error_msg.substring(1);
+            }
+
+            return error_msg;
+        }
+
+        function getSobjectInformation() {
+
+            let nodelist = document.getElementsByClassName(config.ApiPrefix);
+            let result = {}
+            for (let index = 0; index < nodelist.length; index++) {
+                let ele = nodelist[index];
+                console.log('ele:'+ele)
+                let field_api_name = GetEleApiName(ele);
+                console.log('field_api_name:'+field_api_name)
+                let tag_name = ele.tagName.toLowerCase();
+                if(!IsFormElement(tag_name)){
+                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
+                    continue;
+                }
+
+                if (VLookUpFields.indexOf(field_api_name)>=0) {
+                    console.log(ele.id.indexOf('lkwgt'));
+                    if (ele.id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = ele.id + '_lkid';
+                        let vlook_ele = document.getElementById(vlookUpNodeId);
+                        let v = '';
+                        if(vlook_ele){
+                            v = vlook_ele.value;
+                        }else{
+                            v = ele.value;
+                        }
+
+                        if(v && v != "000000000000000"){
+                            result[field_api_name] = v;
+                        }
+                        
+                    }
+                } else if (ele.type == 'checkbox') {
+                    result[field_api_name] = ele.checked;
+                } else if (ele.type == 'select-multiple') {
+                    //field_api_name
+                    let multiple = field_api_name;
+                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[field_api_name] = targets;
+                } else {
+                    result[field_api_name] = ele.value;
+                }
+                
+            }
+            //let reporter = GetEleApiName(nodelist[5])
+            //console.log('reporter:'+reporter);
+            result['Reporter__c'] = document.getElementById('page:form:block:j_id50:0:j_id51:j_id52:4:j_id53_lkid').value;
+            return result;
+        }
+        function QuerySobjectFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+        function queryBack(data) {
+            console.log('data = ' + data);
+            config.queryBack(data);
+            unblockUI();
+        };
+
+
+        function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + r);
+            console.log('payloadJson=' + payloadJson);
+            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
+        }
+
+        function redirectCallBack(sfId,errorMsg) {
+            unblockUI();
+            if(errorMsg){
+                alertErrorMessage(errorMsg);
+            }
+            else{
+                if(config.SaveAndNew){
+                    window.open('{! SaveAndNewButtonUrl }','_self');
+                }else{
+                    window.open('/' + sfId, '_self');
+                }
+            }
+            
+        }
+
+        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.updateMethod;
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
+            
+        }
+
+        function NewPIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.insertMethod;
+            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
+            
+        }
+        
+
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for(i = 0;i<requiredFieldAPIList.length;i++){
+                if(formData[requiredFieldAPIList[i]]){
+                    continue;
+                }else{
+                    if(blankRequiredFields == ''){
+                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }else{
+                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+                    
+                }
+            }
+            return blankRequiredFields;
+        }
+        function saveSobjectProcess(save_and_new) {
+            if(save_and_new){
+                config.SaveAndNew = true;
+            }
+            
+            hiddenErrorMsgNode();
+            //1. Get Sobject Information from Form
+            let sobjJson = getSobjectInformation();
+            //2. Validate the Sobject field value formate, for example the email formate or phone formate
+
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage(validationResultMessage);
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
+            console.log('sobjJson:'+sobjJson);
+            console.log('check:'+checkRequiredFieldMsgResult);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
+                return
+            }
+            // //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(sobjJson);
+
+            // //4. Get Authentication Information for AWS
+            // loadAWSAuthentication();
+
+            // //5. lead to AWS 
+            ProcessPI(sobjJson, payloadForNewPI);
+            // awsToken = TestToken;
+            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
+        }
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
+                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        
+        <apex:pageblock id="block">
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Inspection_Report__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                sfdcPage.appendToOnloadQueue(function () {
+                    //1. Set Last Name label
+                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for Sobject Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();
+                        QuerySobjectFromAWS();
+                    }   
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditInspectionReport.page-meta.xml b/force-app/main/default/pages/NewAndEditInspectionReport.page-meta.xml
new file mode 100644
index 0000000..42cf234
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditInspectionReport.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditInspectionReport</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditQIS.page b/force-app/main/default/pages/NewAndEditQIS.page
new file mode 100644
index 0000000..63b4410
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditQIS.page
@@ -0,0 +1,558 @@
+<apex:page standardController="QIS_Report__c" extensions="NewAndEditQISController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script>
+        
+        var config = {};
+        config = {
+            SobjectName : "{!SobjectName}",
+            ApiPrefix:"{!ApiPrefix}",
+            SaveAndNew:false,
+            AWSToSobjectMap:{!AWSToSobjectMapJson},
+            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+            AWSToSobjectNonEncryptedMapKeySet:{!AWSToSobjectNonEncryptedMapKeySet},
+            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
+            SobjectToAWSModel:function (sobjJson) {
+                let leadPayloadList = [];
+                let leadPIData = {};
+
+                for(let f in config.AWSToSobjectMap){
+                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
+                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
+                    }
+                    else{
+                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
+                    }
+                } 
+
+                leadPIData.medicalStaffFullName = leadPIData.lastName;// 瀹屾垚field update workflow
+                leadPIData.sfRecordId = '';
+                console.log('Sobject PI Data:' + leadPIData);
+                leadPayloadList.push(leadPIData);
+                console.log(JSON.stringify(leadPayloadList));
+                return JSON.stringify(leadPayloadList);
+            },
+            insertOrUpdateBack:function(payloadJson, r, isNewMode){
+                
+                for(let f in config.AWSToSobjectMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+
+                for(let f in config.AWSToSobjectEncryptedMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+                
+                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                if (isNewMode) {
+                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                } else {
+                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                }
+                return payloadJson;
+            },
+            queryBack:function (data) {
+                console.log('data = ' + data);
+                if(data.object){
+                    for(let f of config.AWSToSobjectNonEncryptedMapKeySet){
+                        let ele = document.getElementById(api_id_map[config.AWSToSobjectNonEncryptedMap[f]])
+                        if(data.object.hasOwnProperty(f) && ele){
+                            
+                            // 澶氶�夌壒娈婂鐞�
+                            if(ele.type == 'select-multiple'){
+                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
+                               if(ele && data.object[f]){
+                                   let arr = data.object[f].split(';');
+
+                                   // 缁欓殣钘忕殑select璧嬪��
+                                   for(let op of ele.options){
+                                       op.selected = arr.indexOf(op.value)>-1;
+                                   }
+                                   
+                                   // 鍒╃敤鎸夐挳缁欐樉绀虹殑select璧嬪��
+                                   let ra = document.getElementById(ele.id + '_right_arrow');
+                                   if(ra){
+                                       ra.click();
+                                   }
+                                   
+                               }
+                            }else{
+                                ele.value = data.object[f];
+                            }
+
+                            if(ele.type.indexOf("select")>-1 && ele.value){
+                                jQuery(ele).change()
+                            }
+                            
+                        }
+                        else{
+                            console.log(f + 'is not in data.object');
+                        }
+                    }
+                }
+                else{
+                    console.log('data.object = ' + data.object);
+                }
+                
+
+                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                // document.querySelector("[data-id='Phone']").value = data.object.phone;
+                // document.querySelector("[data-id='Email']").value = data.object.email;
+            },
+            updateMethod:"NewAndEditQISController.saveQISReport",
+            insertMethod:"NewAndEditQISController.saveQISReport"
+        }
+    
+        AWSService.sfSessionId = '{!GETSESSIONID()}';
+        var staticResources = JSON.parse('{!staticResource}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        console.log('{!staticResource}');
+        var VLookUpFields = {! VLookUpFieldsJson};
+        function ProcessPI(sobjJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+            	NewPIToAWS(sobjJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(sobjJson, payloadForNewPI)
+            }
+        }
+
+        var GetEleByClass = function(class_name){
+            let eles = document.getElementsByClassName(class_name);
+            if(eles.length > 0) return eles[0];
+            return null;
+        }
+
+        var GetEleApiName = function(ele){
+            for(let c of ele.classList){
+                if(c.indexOf(config.ApiPrefix+'_')>-1){
+                    return c.replace(config.ApiPrefix+'_','');
+                }
+            }
+            return '';
+        }
+
+        function IsFormTag(tag_name){
+            return ['input','select','textarea'].indexOf(tag_name.toLowerCase())>-1;
+        }
+    	
+    	function IsFormElement(e){
+            return IsFormTag(e.tagName);
+        }
+
+        function getPIPayload(sobjJson) {
+            return config.SobjectToAWSModel(sobjJson);
+        }
+
+        function validateFieldValueFormate() {
+            let error_msg = '';
+            //let textEmail = "[data-id='Email']";
+            let textPhone = "[data-id='Caller_phone__c']";
+            //Email
+            // let email = document.querySelector(textEmail);
+            // if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
+            //     error_msg += ';閭欢鏍煎紡閿欒';
+            // }
+            let phone = document.querySelector(textPhone);
+
+            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
+                error_msg += ';鐢佃瘽鍙风爜閿欒';
+            }
+
+            for(let e of document.getElementsByTagName('select')){
+                for(let op of e.options){
+                    if(op.value == "*****" && op.selected){
+                        error_msg += ';涓嬫媺妗嗕笉鑳戒富鍔ㄩ�夋嫨瀵嗘枃閫夐」';
+                    }
+                }
+            }
+
+            if(error_msg.length>0 && error_msg[0]== ';'){
+                error_msg = error_msg.substring(1);
+            }
+
+            return error_msg;
+        }
+
+        function getSobjectInformation() {
+            //api_id_map
+//let nodelist = document.getElementsByClassName(config.ApiPrefix);
+            let result = {}
+            for (let index in api_id_map) {
+                let ele = document.getElementById(api_id_map[index]);
+                let field_api_name = index;
+                let tag_name = ele.tagName.toLowerCase();
+                if(!IsFormTag(tag_name)){
+                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
+                    continue;
+                }
+
+                if (VLookUpFields.indexOf(field_api_name)>=0) {
+                    console.log(ele.id.indexOf('lkwgt'));
+                    if (ele.id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = ele.id + '_lkid';
+                        let vlook_ele = document.getElementById(vlookUpNodeId);
+                        let v = '';
+                        if(vlook_ele){
+                            v = vlook_ele.value;
+                        }else{
+                            v = ele.value;
+                        }
+
+                        if(v && v != "000000000000000"){
+                            result[field_api_name] = v;
+                        }
+                        
+                    }
+                } else if (ele.type == 'checkbox') {
+                    result[field_api_name] = ele.checked;
+                } else if (ele.type == 'select-multiple') {
+                    //field_api_name
+                    let multiple = field_api_name;
+                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[field_api_name] = targets;
+                } else {
+                    result[field_api_name] = ele.value;
+                }
+                
+                // let e1 = document.getElementById(api_id_map[field_api_name]);
+                // if(!result[field_api_name] && e1 && e1.value){
+                // 	result[field_api_name] = e1.value;
+                // }
+            }
+            //璧嬪�煎瘜鏂囨湰鍖哄煙
+            //闂鍐呭鎻忚堪锛堝浘鐗囷級-FSE-OCSM-OSH
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:4:j_id51:j_id52:15:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.problem_detail_photo__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:4:j_id51:j_id52:15:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //闂鍐呭鎻忚堪锛堝浘鐗囷級-OSH鍥炵瓟瀹屾瘯-鐜板満缁撴-final
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:5:j_id51:j_id52:15:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.problem_detail_photo__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:5:j_id51:j_id52:15:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖1 - OCSM-鐜板満缁撴-final
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:14:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_1__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:14:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖2-OCSM-鐜板満缁撴-final
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:14:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_2__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:14:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖3 -OCSM-鐜板満缁撴-final
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:14:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_3__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:14:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖4 -OCSM-鐜板満缁撴-final
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:14:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_4__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:14:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH1 - OCSM
+             if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:19:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_1__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:19:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH2-OCSM
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:19:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_2__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:19:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH3 -OCSM
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:19:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_3__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:19:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH4 -OCSM
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:19:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_4__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:19:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH1 - OSH鍥炵瓟瀹屾瘯
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:18:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_1__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:18:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH2-OSH鍥炵瓟瀹屾瘯
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:18:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_2__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:18:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH3 -OSH鍥炵瓟瀹屾瘯
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:18:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_3__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:18:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH4 -OSH鍥炵瓟瀹屾瘯
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:18:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_4__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:18:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖1 - OSH
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:13:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_1__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:13:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖2-OSH
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:13:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_2__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:13:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖3 -OSH
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:13:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_3__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:13:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖4 -OSH
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:13:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_4__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:13:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH1 - OSH
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:16:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_1__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:16:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH2-OSH
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:16:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_2__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:16:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH3 -OSH
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:16:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_3__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:16:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH4 -OSH
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:16:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_4__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:16:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH1 -鐜板満缁撴-final
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:17:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_1__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:17:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH2-鐜板満缁撴-final
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:17:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_2__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:17:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH3 -鐜板満缁撴-final
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:17:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_3__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:17:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖OSH4 -鐜板満缁撴-final
+            if(document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:17:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
+                result.Photo_OSH_4__c = document.querySelector("[title = 'RTF 绶ㄨ集鍣�, page:form:block:j_id50:17:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            return result;
+        }
+        function QuerySobjectFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+        function queryBack(data) {
+            console.log('data = ' + data);
+            config.queryBack(data);
+            unblockUI();
+        };
+
+
+        function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + r);
+            console.log('payloadJson=' + payloadJson);
+            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
+        }
+
+        function redirectCallBack(sfId,errorMsg) {
+            unblockUI();
+            if(errorMsg){
+                alertErrorMessage(errorMsg);
+            }
+            else{
+                if(config.SaveAndNew){
+                    window.open('{! SaveAndNewButtonUrl }','_self');
+                    
+                }else{
+                    window.open('/' + sfId, '_self');
+                }
+            }
+            
+        }
+
+        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.updateMethod;
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
+            
+        }
+
+        function NewPIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.insertMethod;
+            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
+            
+        }
+        
+
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for(i = 0;i<requiredFieldAPIList.length;i++){
+                if(formData[requiredFieldAPIList[i]]){
+                    continue;
+                }else{
+                    if(blankRequiredFields == ''){
+                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }else{
+                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+                    
+                }
+            }
+            return blankRequiredFields;
+        }
+        function saveSobjectProcess(save_and_new) {
+            
+            if(save_and_new){
+                config.SaveAndNew = true;
+            }
+            
+            hiddenErrorMsgNode();
+            //1. Get Sobject Information from Form
+            let sobjJson = getSobjectInformation();
+            //2. Validate the Sobject field value formate, for example the email formate or phone formate
+
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage(validationResultMessage);
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
+                return
+            }
+            // //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(sobjJson);
+
+            // //4. Get Authentication Information for AWS
+            // loadAWSAuthentication();
+
+            // //5. lead to AWS 
+            ProcessPI(sobjJson, payloadForNewPI);
+            // awsToken = TestToken;
+            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
+        }
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
+                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        
+        <apex:pageblock id="block">
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+                    
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!QIS_Report__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                                         required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+                    
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+            var init_nodes = document.getElementsByClassName("PIBackApi");
+            var api_id_map={};
+            for(let e of init_nodes){
+            	if(IsFormElement(e)){
+                	 api_id_map[GetEleApiName(e)] = e.id;
+                }
+            }
+            console.log(api_id_map);
+            sfdcPage.appendToOnloadQueue(function () {
+                //1. Set Last Name label
+                //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                //2. Query AWS Data by dataId 
+                console.log('Mode for Sobject Page:' + {!isNewMode});
+                if (!{!isNewMode}) {
+                    blockme();
+                    QuerySobjectFromAWS();
+                }
+            });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditQIS.page-meta.xml b/force-app/main/default/pages/NewAndEditQIS.page-meta.xml
new file mode 100644
index 0000000..3ff5f53
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditQIS.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditQIS</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditRepairSubOrder.page b/force-app/main/default/pages/NewAndEditRepairSubOrder.page
new file mode 100644
index 0000000..2a393ec
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditRepairSubOrder.page
@@ -0,0 +1,575 @@
+<apex:page standardController="RepairSubOrder__c" extensions="NewAndEditRepairSubOrderController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <style>
+        .disabledbutton {
+            pointer-events: none;
+            opacity: 0.4;
+        }
+    </style>
+    <script>
+        
+        var config = {};
+        config = {
+            SobjectName : "{!SobjectName}",
+            ApiPrefix:"{!ApiPrefix}",
+            SaveAndNew:false,
+            AWSToSobjectMap:{!AWSToSobjectMapJson},
+            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
+            SobjectToAWSModel:function (sobjJson) {
+                let leadPayloadList = [];
+                let leadPIData = {};
+
+                for(let f in config.AWSToSobjectMap){
+                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
+                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
+                    }
+                    else{
+                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
+                    }
+                } 
+
+
+                leadPIData.sfRecordId = '';
+                console.log('Sobject PI Data:' + leadPIData);
+                leadPayloadList.push(leadPIData);
+                console.log(JSON.stringify(leadPayloadList));
+                return JSON.stringify(leadPayloadList);
+            },
+            insertOrUpdateBack:function(payloadJson, r, isNewMode){
+                
+                for(let f in config.AWSToSobjectMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+
+                for(let f in config.AWSToSobjectEncryptedMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+                
+                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                if (isNewMode) {
+                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                } else {
+                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                }
+                return payloadJson;
+            },
+            queryBack:function (data) {
+                console.log('data = ' + data);
+                if(data.object){
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
+                        if(data.object.hasOwnProperty(f) && ele){
+                            
+                            // 澶氶�夌壒娈婂鐞�
+                            if(ele.type == 'select-multiple'){
+                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
+                               if(ele && data.object[f]){
+                                   let arr = data.object[f].split(';');
+
+                                   // 缁欓殣钘忕殑select璧嬪��
+                                   for(let op of ele.options){
+                                       op.selected = arr.indexOf(op.value)>-1;
+                                   }
+                                   
+                                   // 鍒╃敤鎸夐挳缁欐樉绀虹殑select璧嬪��
+                                   let ra = document.getElementById(ele.id + '_right_arrow');
+                                   if(ra){
+                                       ra.click();
+                                   }
+                                   
+                               }
+                            }else{
+                                ele.value = data.object[f];
+                            }
+                            
+                        }
+                        else{
+                            console.log(f + 'is not in data.object');
+                        }
+                    }
+                }
+                else{
+                    console.log('data.object = ' + data.object);
+                }
+                
+
+                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                // document.querySelector("[data-id='Phone']").value = data.object.phone;
+                // document.querySelector("[data-id='Email']").value = data.object.email;
+            },
+            updateMethod:"NewAndEditRepairSubOrderController.saveRepairSubOrder",
+            insertMethod:"NewAndEditRepairSubOrderController.saveRepairSubOrder"
+        }
+    
+        AWSService.sfSessionId = '{!GETSESSIONID()}';
+        var staticResources = JSON.parse('{!staticResource}');
+        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        console.log('{!staticResource}');
+        var VLookUpFields = {! VLookUpFieldsJson};
+        function ProcessPI(sobjJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+                NewPIToAWS(sobjJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(sobjJson, payloadForNewPI)
+            }
+        }
+
+        var GetEleByClass = function(class_name){
+            let eles = document.getElementsByClassName(class_name);
+            if(eles.length > 0) return eles[0];
+            return null;
+        }
+
+        var GetEleApiName = function(ele){
+            for(let c of ele.classList){
+                if(c.indexOf(config.ApiPrefix+'_')>-1){
+                    return c.replace(config.ApiPrefix+'_','');
+                }
+            }
+            return '';
+        }
+
+        function IsFormTag(tag_name){
+            return ['input','select','textarea'].indexOf(tag_name.toLowerCase())>-1;
+        }
+
+        function IsFormElement(tag_name){
+            return ['input','select','textarea'].indexOf(tag_name)>-1;
+        }
+
+        function getPIPayload(sobjJson) {
+            return config.SobjectToAWSModel(sobjJson);
+        }
+
+        function validateFieldValueFormate() {
+            let error_msg = '';
+            // let textEmail = "[data-id='Email']";
+            let textPhone = "[data-id='RepairApplicantTel__c']";
+            //Email
+            // let email = document.querySelector(textEmail);
+            // if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
+            //     error_msg += ';閭欢鏍煎紡閿欒';
+            // }
+            let phone = document.querySelector(textPhone);
+
+            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
+                error_msg += ';鐢佃瘽鍙风爜閿欒';
+            }
+
+            for(let e of document.getElementsByTagName('select')){
+                for(let op of e.options){
+                    if(op.value == "*****" && op.selected){
+                        error_msg += ';涓嬫媺妗嗕笉鑳戒富鍔ㄩ�夋嫨瀵嗘枃閫夐」';
+                    }
+                }
+            }
+
+            if(error_msg.length>0 && error_msg[0]== ';'){
+                error_msg = error_msg.substring(1);
+            }
+
+            return error_msg;
+        }
+
+        function getSobjectInformation() {
+
+            let nodelist = document.getElementsByClassName(config.ApiPrefix);
+            let result = {}
+            for (let index = 0; index < nodelist.length; index++) {
+                let ele = nodelist[index];
+                let field_api_name = GetEleApiName(ele);
+                let tag_name = ele.tagName.toLowerCase();
+                if(!IsFormElement(tag_name)){
+                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
+                    continue;
+                }
+
+                if (VLookUpFields.indexOf(field_api_name)>=0) {
+                    console.log(ele.id.indexOf('lkwgt'));
+                    if (ele.id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = ele.id + '_lkid';
+                        let vlook_ele = document.getElementById(vlookUpNodeId);
+                        let v = '';
+                        if(vlook_ele){
+                            v = vlook_ele.value;
+                        }else{
+                            v = ele.value;
+                        }
+
+                        if(v && v != "000000000000000"){
+                            result[field_api_name] = v;
+                        }
+                        
+                    }
+                } else if (ele.type == 'checkbox') {
+                    result[field_api_name] = ele.checked;
+                } else if (ele.type == 'select-multiple') {
+                    //field_api_name
+                    let multiple = field_api_name;
+                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[field_api_name] = targets;
+                } else {
+                    result[field_api_name] = ele.value;
+                }
+            }
+            return result;
+        }
+        function QuerySobjectFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+        function queryBack(data) {
+            console.log('data = ' + data);
+            config.queryBack(data);
+            unblockUI();
+        };
+
+
+        function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + r);
+            console.log('payloadJson=' + payloadJson);
+            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
+        }
+
+        function redirectCallBack(sfId,errorMsg) {
+            unblockUI();
+            if(errorMsg){
+                alertErrorMessage(errorMsg);
+            }
+            else{
+                if(config.SaveAndNew){
+                    window.open('{! SaveAndNewButtonUrl }','_self');
+                }else{
+                    window.open('/' + sfId, '_self');
+                }
+            }
+            
+        }
+
+        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.updateMethod;
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
+            
+        }
+
+        function NewPIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.insertMethod;
+            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
+            
+        }
+        
+
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for(i = 0;i<requiredFieldAPIList.length;i++){
+                if(formData[requiredFieldAPIList[i]]){
+                    continue;
+                }else{
+                    if(blankRequiredFields == ''){
+                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }else{
+                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+                    
+                }
+            }
+            return blankRequiredFields;
+        }
+        function saveSobjectProcess(save_and_new) {
+            if(save_and_new){
+                config.SaveAndNew = true;
+            }
+            
+            hiddenErrorMsgNode();
+            //1. Get Sobject Information from Form
+            let sobjJson = getSobjectInformation();
+            //2. Validate the Sobject field value formate, for example the email formate or phone formate
+
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage(validationResultMessage);
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
+                return
+            }
+            // //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(sobjJson);
+
+            // //4. Get Authentication Information for AWS
+            // loadAWSAuthentication();
+
+            // //5. RepairSubOrder to AWS 
+            ProcessPI(sobjJson, payloadForNewPI);
+            // awsToken = TestToken;
+            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
+        }
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+
+        //鏇挎崲vlookup
+        var newSearchContactWindow = null;  
+        var closeField = '';
+
+        function replaceSearchContactLookup() {
+            if (!{!isNewMode}) {
+                //1. Query Contact from AWS by AWSDataId
+                queryContactName()
+            }           
+            if(document.querySelector("[data-id='Receiver__c']") != null){
+                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'Receiver__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+                let lookUpNode = htmlToElement(contactHtmlString);
+                console.log(lookUpNode);
+                let parentNode = document.querySelector("[data-id='Receiver__c']").parentNode;
+                document.querySelector("[data-id='Receiver__c']").removeAttribute("onchange");
+                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Receiver__c']").parentNode.children[2]);
+            }
+            if(document.querySelector("[data-id='Applicanter__c']") != null){
+                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'Applicanter__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+                let lookUpNode = htmlToElement(contactHtmlString);
+                console.log(lookUpNode);
+                let parentNode = document.querySelector("[data-id='Applicanter__c']").parentNode;
+                document.querySelector("[data-id='Applicanter__c']").removeAttribute("onchange");
+                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Applicanter__c']").parentNode.children[2]);
+            }
+        }
+
+        function htmlToElement(html) {
+            var template = document.createElement('template');
+            html = html.trim(); // Never return a text node of whitespace as the result
+            template.innerHTML = html;
+            return template.content.firstChild;
+        }
+
+        function queryContactName() {
+            let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
+            if(document.querySelector("[data-id='Receiver__c']") != null){
+                let sfId = document.getElementById(document.querySelector("[data-id='Receiver__c']").id + '_lkid').value;
+                let dataId = contactsInfo[sfId];
+                queryContactNameFetch(dataId, 'Receiver__c');
+                
+            }
+            if(document.querySelector("[data-id='Applicanter__c']") != null){
+                let sfId = document.getElementById(document.querySelector("[data-id='Applicanter__c']").id + '_lkid').value;
+                let dataId = contactsInfo[sfId];
+                queryContactNameFetch(dataId, 'Applicanter__c');
+                
+            }
+        }
+        function queryContactNameFetch(dataId, filedId){
+            let queryContactBack = function(data){
+                //To Do later
+                console.log('ContactData = ' + data.object);
+                
+                document.querySelector("[data-id="+filedId+"]").value = data.object.lastName;
+            }
+            AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
+        //     fetch(url, {
+        //         method: 'GET',
+        //         headers: {
+        //             'Content-Type': 'application/json',
+        //             'pi-token': staticResources.token
+        //         }
+        //     }).then((data) => {
+        //         return data.json();
+        //     }).then((result) => {
+        //         if(result.object){
+        //             document.querySelector("[data-id="+filedId+"]").value = result.object.lastName;
+        //         }
+        //     })
+        }
+
+        
+        //鑷畾涔塴ookup鏌ヨ
+        function searchContact(contactNodeId,field){
+            closeField = field;
+            let accountValue = "";
+            if (document.querySelector("[data-id='Department__c']")) {
+                let accountNodeId = document.querySelector("[data-id='Department__c']").id + '_lkid';
+                accountValue = document.getElementById(accountNodeId).value;   
+            } 
+            console.log('accountValue = ' + accountValue);
+            if(accountValue !='000000000000000'){
+                suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
+            }else{
+                suffixUrl = "?contactId="+contactNodeId;
+            }
+            let baseUrl = "/apex/SearchContactPage";
+            let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
+            newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
+            if (window.focus) {
+                newSearchContactWindow.focus();
+            }
+            return false;
+            // if(true || accountValue !='000000000000000'){
+            //     let baseUrl = "/apex/SearchContactPage";
+            //     let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
+            //     let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
+            //     newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
+            //     if (window.focus) {
+            //         newSearchContactWindow.focus();
+            //     }
+            //     return false;
+            // }else{
+            //     alertErrorMessage('璇峰厛閫夋嫨绉戝!');
+            // }
+        }
+
+        function closePopupWindow() {
+            if (null != newSearchContactWindow) {
+                newSearchContactWindow.close();
+            }
+            let contactInfoStr = document.getElementById('page:form:contactId').value;
+            console.log('closePopup:'+contactInfoStr);
+            let contactInfo = JSON.parse(contactInfoStr);
+            let contactNodeId = document.querySelector("[data-id="+closeField+"]").id + '_lkid';
+            document.getElementById(contactNodeId).value = contactInfo.ContactId;
+            document.querySelector("[data-id="+closeField+"]").value = contactInfo.Name;     
+            
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
+                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <apex:inputHidden value="{!contactId}" id="contactId"/>
+        <apex:pageblock id="block">
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!RepairSubOrder__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                var init_nodes = document.getElementsByClassName("PIBackApi");
+                var api_id_map={};
+                for(let e of init_nodes){
+                    if(IsFormElement(e)){
+                         api_id_map[GetEleApiName(e)] = e.id;
+                    }
+                }
+                console.log(api_id_map);
+    
+                sfdcPage.appendToOnloadQueue(function () {
+                    //1. Set Last Name label
+                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for Sobject Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();
+                        QuerySobjectFromAWS();
+                    }   
+                    //Replace Vlookup Field
+                    replaceSearchContactLookup();
+                    //3. Set Readonly Attribute
+                    document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
+                    document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditRepairSubOrder.page-meta.xml b/force-app/main/default/pages/NewAndEditRepairSubOrder.page-meta.xml
new file mode 100644
index 0000000..59ac902
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditRepairSubOrder.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditRepairSubOrder</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditReport.page b/force-app/main/default/pages/NewAndEditReport.page
new file mode 100644
index 0000000..7b10a4b
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditReport.page
@@ -0,0 +1,590 @@
+<apex:page standardController="Report__c" extensions="NewAndEditReportController" id="page">
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+
+    <style>
+        .disabledbutton {
+            pointer-events: none;
+            opacity: 0.4;
+        }
+    </style>
+
+    <script>
+        AWSService.sfSessionId = '{!GETSESSIONID()}';
+        var staticResources = JSON.parse('{!staticResource}');
+        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
+        var redirectMode = 'Save';//1. Save 2. SaveAndNew
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        var VLookUpFields = new Set(['Hospital_Reference__c', 'Department_Class_Ref__c', 'Daily_Report__c', 'OwnerId','Hospital_Department__c',
+        'Competition_Company_Name__c','Report_OPDPlan__c','Loaner_request_no1__c','Practitioner1__c','Practitioner2__c','Practitioner3__c','Practitioner4__c',
+        'Practitioner5__c','Opportunity1__c',
+        'Opportunity2__c','Product01__c','Product1__c','Product2__c','Product3__c','Product4__c','Product5__c','Order_No__c','Person_In_Charge__c']);
+        var closeField = '';
+        // var myCkeditor = null;
+        // try {
+        //     myCkeditor = CKEDITOR;
+        // } catch (error) {
+        //     console.log('娌℃湁CKEDITOR')
+        // }
+
+
+        //閿欒鎻愮ず
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:j_id5:msgContent");
+            errorMsg = '閿欒锛氭棤鏁堟暟鎹��'+'\n' + errorMsg;
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+            unblockUI();
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:j_id5:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+
+        //1銆傝幏鍙栨墍鏈夊瓧娈靛��
+        function getReportInformation() {
+            let nodelist = document.querySelectorAll("[data-id]");
+            let result = {}
+            result.RecordTypeId = '{!rtTypeId}';
+            for (let index = 0; index < nodelist.length; index++) {
+                if (VLookUpFields.has(nodelist[index].getAttribute("data-id"))) {
+                    console.log(nodelist[index].id.indexOf('lkwgt'));
+                    if (nodelist[index].id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = nodelist[index].id + '_lkid';
+                        let vlookUpNodeValue = document.getElementById(vlookUpNodeId).value;
+                        result[nodelist[index].getAttribute("data-id")] = vlookUpNodeValue;
+                    }
+                } else if (nodelist[index].type == 'checkbox') {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].checked;
+                } else if (nodelist[index].type == 'select-multiple') {
+                    //nodelist[index].getAttribute("data-id")
+                    let multiple = nodelist[index].getAttribute("data-id");
+                    let targets = document.querySelector("[data-id=" + multiple + "]").nextSibling.children[0].children[1].children[2].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[nodelist[index].getAttribute("data-id")] = targets;
+                } else {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].value;
+                }
+                let x = index + 1;
+                if (x <= nodelist.length - 1 && (nodelist[x].getAttribute("data-id") == nodelist[index].getAttribute("data-id"))) {
+                    index++;
+                }
+            }
+            //鎵嬫湳鍒嗙被1
+            result.Technical_Category1__c = document.getElementById('page:form:j_id30:j_id60:4:j_id61:j_id62:2:j_id63')!=null?document.getElementById('page:form:j_id30:j_id60:4:j_id61:j_id62:2:j_id63').value:'';
+            //鎵嬫湳鍒嗙被2
+            result.Technical_Category2__c = document.getElementById('page:form:j_id30:j_id60:4:j_id61:j_id62:4:j_id63')!=null?document.getElementById('page:form:j_id30:j_id60:4:j_id61:j_id62:4:j_id63').value:'';
+            //鐩殑2
+            if(document.getElementById('page:form:j_id30:j_id60:3:j_id61:j_id62:1:j_id63')){
+                result.Purpose2__c = document.getElementById('page:form:j_id30:j_id60:3:j_id61:j_id62:1:j_id63').value;
+            }
+            if(document.getElementById('page:form:j_id30:j_id60:2:j_id61:j_id62:1:j_id63')){
+                result.Purpose2__c = document.getElementById('page:form:j_id30:j_id60:2:j_id61:j_id62:1:j_id63').value;
+            }
+            //瀵屾枃鏈璧嬪��
+            //鐢ㄦ埛绛惧瓧鐨勭収鐗�
+            if(document.querySelector("[aria-describedby = 'cke_34']")){
+                result.Customer_sigh_photo__c = document.querySelector("[aria-describedby = 'cke_34']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖1 Photo1__c
+            if(document.querySelector("[aria-describedby = 'cke_42']")){
+                result.Photo1__c = document.querySelector("[aria-describedby = 'cke_42']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖2 Photo2__c
+            if(document.querySelector("[aria-describedby = 'cke_75']")){
+                result.Photo2__c = document.querySelector("[aria-describedby = 'cke_75']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //鐓х墖3 Photo3__c
+            if(document.querySelector("[aria-describedby = 'cke_108']")){
+                result.Photo3__c = document.querySelector("[aria-describedby = 'cke_108']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //瀵瑰簲缁撴灉 VOC_follow_up_result__c cke_38
+            if(document.querySelector("[aria-describedby = 'cke_38']")){
+                result.VOC_follow_up_result__c = document.querySelector("[aria-describedby = 'cke_38']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            //瀵瑰簲缁撴灉绗竴娆� 	VOC_follow_up_result1__c cke_71
+            if(document.querySelector("[aria-describedby = 'cke_71']")){
+                result.VOC_follow_up_result1__c = document.querySelector("[aria-describedby = 'cke_71']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }
+            return result;
+        }
+
+        //2.楠岃瘉瑙勫垯
+        function validateFieldValueFormate() {
+            //VOC_Informer_Contact__c,Caller_phone_c__c
+            let error_msg = '';
+            let textEmail = "[data-id='	Follow_staff_email__c']";
+            let textPhone1 = "[data-id='VOC_Informer_Contact__c']";
+            let textPhone2 = "[data-id='Caller_phone_c__c']";
+            //Email
+            let email = document.querySelector(textEmail);
+            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
+                error_msg += ';瀵瑰簲鑰�(閭)鏍煎紡閿欒';
+            }
+
+            let phone1 = document.querySelector(textPhone1);
+            if(phone1 && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone1.value)){
+                error_msg += ';淇℃伅鎻愪緵浜鸿仈绯绘柟寮忥紙鐢佃瘽锛夊彿鐮侀敊璇�';
+            }
+            
+            let phone2 = document.querySelector(textPhone2);
+            if(phone2 && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone2.value)){
+                error_msg += ';鑱旂郴鐢佃瘽鍙风爜閿欒';
+            }
+
+            for(let e of document.getElementsByTagName('select')){
+                for(let op of e.options){
+                    if(op.value == "*****" && op.selected){
+                        error_msg += ';涓嬫媺妗嗕笉鑳戒富鍔ㄩ�夋嫨瀵嗘枃閫夐」';
+                    }
+                }
+            }
+
+            if(error_msg.length>0 && error_msg[0]== ';'){
+                error_msg = error_msg.substring(1);
+            }
+
+            return error_msg;
+        }
+
+        //3.楠岃瘉蹇呭~瀛楁
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for(i = 0;i<requiredFieldAPIList.length;i++){
+                if(formData[requiredFieldAPIList[i]]){
+                    continue;
+                }else{
+                    if(blankRequiredFields == ''){
+                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }else{
+                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+                    
+                }
+            }
+            return blankRequiredFields;
+        }
+
+        //4.鑾峰彇瑕佸姞瀵嗙殑瀛楁
+        function getPIPayload(reportJson) {
+            let reportPayloadList = [];
+            let reportPIData = new Object();
+            reportPIData.vocInformerName = document.querySelector("[data-id='VOC_Informer_Name__c']")!=null?document.querySelector("[data-id='VOC_Informer_Name__c']").value:'';
+            reportPIData.callerPhone = document.querySelector("[data-id='Caller_phone_c__c']")!=null?document.querySelector("[data-id='Caller_phone_c__c']").value:'';
+            reportPIData.vocInformerContact = document.querySelector("[data-id='VOC_Informer_Contact__c']")!=null?document.querySelector("[data-id='VOC_Informer_Contact__c']").value:'';
+            reportPIData.personInChargeText = document.querySelector("[data-id='Person_In_Charge_Text__c']")!=null?document.querySelector("[data-id='Person_In_Charge_Text__c']").value:'';
+            reportPIData.professorSighText = document.querySelector("[data-id='Professor_sigh_text__c']")!=null?document.querySelector("[data-id='Professor_sigh_text__c']").value:'';
+            reportPIData.staffInfoManual = document.querySelector("[data-id='Staff_Info_Manual_c__c']")!=null?document.querySelector("[data-id='Staff_Info_Manual_c__c']").value:'';
+            reportPIData.responsiblePersonHP = document.querySelector("[data-id='Responsible_Person_HP_c__c']")!=null?document.querySelector("[data-id='Responsible_Person_HP_c__c']").value:'';
+            reportPIData.practitioner1Part = document.querySelector("[data-id='Practitioner1_Part__c']")!=null?document.querySelector("[data-id='Practitioner1_Part__c']").value:'';
+            reportPIData.practitioner2Part = document.querySelector("[data-id='Practitioner2_Part__c']")!=null?document.querySelector("[data-id='Practitioner2_Part__c']").value:'';
+            reportPIData.practitioner3Part = document.querySelector("[data-id='Practitioner3_Part__c']")!=null?document.querySelector("[data-id='Practitioner3_Part__c']").value:'';
+            reportPIData.practitioner4Part = document.querySelector("[data-id='Practitioner4_Part__c']")!=null?document.querySelector("[data-id='Practitioner4_Part__c']").value:'';
+            reportPIData.practitioner5Part = document.querySelector("[data-id='Practitioner5_Part__c']")!=null?document.querySelector("[data-id='Practitioner5_Part__c']").value:'';
+            reportPIData.age = document.querySelector("[data-id='age__c']")!=null?document.querySelector("[data-id='age__c']").value:'';
+            reportPIData.medicalHistory = document.querySelector("[data-id='Medical_History__c']")!=null?document.querySelector("[data-id='Medical_History__c']").value:'';
+            reportPIData.sex = document.querySelector("[data-id='sex__c']")!=null?document.querySelector("[data-id='sex__c']").value:'';
+            reportPayloadList.push(reportPIData);
+            return JSON.stringify(reportPayloadList);
+        }
+
+        
+
+        //5.鏂板缓鎴栫紪杈�
+        function ProcessPI(reportJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+                NewPIToAWS(reportJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(reportJson, payloadForNewPI)
+            }
+        }
+
+        //鏂板缓
+        function NewPIToAWS(reportJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewAndEditReportController.saveReport}';
+            AWSService.insert(staticResources.newUrl, reportJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack, redirectCallBack);
+        }
+
+        //缂栬緫
+        function UpdatePIToAWS(reportJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewAndEditReportController.saveReport}';
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, reportJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
+        }
+
+        //鏌ヨ
+        function QueryLeadFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+
+        var queryBack = function queryBack(data) {
+            console.log('awsDataId = '+'{!AWSDataId}')
+            console.log('data = ' + JSON.stringify(data));
+            var i = 0;
+            //璧嬪��
+            document.querySelector("[data-id='VOC_Informer_Name__c']")!=null?document.querySelector("[data-id='VOC_Informer_Name__c']").value=data.object.vocInformerName.replace(/"/g,""):i++;
+            document.querySelector("[data-id='Caller_phone_c__c']")!=null?document.querySelector("[data-id='Caller_phone_c__c']").value=data.object.callerPhone.replace(/"/g,""):i++;
+            document.querySelector("[data-id='VOC_Informer_Contact__c']")!=null?document.querySelector("[data-id='VOC_Informer_Contact__c']").value=data.object.vocInformerContact.replace(/"/g,""):i++;
+            document.querySelector("[data-id='Person_In_Charge_Text__c']")!=null?document.querySelector("[data-id='Person_In_Charge_Text__c']").value=data.object.personInChargeText.replace(/"/g,""):i++;
+            document.querySelector("[data-id='Professor_sigh_text__c']")!=null?document.querySelector("[data-id='Professor_sigh_text__c']").value=data.object.professorSighText.replace(/"/g,""):i++;
+            document.querySelector("[data-id='Staff_Info_Manual_c__c']")!=null?document.querySelector("[data-id='Staff_Info_Manual_c__c']").value=data.object.staffInfoManual.replace(/"/g,""):i++;
+            document.querySelector("[data-id='Responsible_Person_HP_c__c']")!=null?document.querySelector("[data-id='Responsible_Person_HP_c__c']").value=data.object.responsiblePersonHP.replace(/"/g,""):i++;
+            document.querySelector("[data-id='Practitioner1_Part__c']")!=null?document.querySelector("[data-id='Practitioner1_Part__c']").value=data.object.practitioner1Part.replace(/"/g,""):i++;
+            document.querySelector("[data-id='Practitioner2_Part__c']")!=null?document.querySelector("[data-id='Practitioner2_Part__c']").value=data.object.practitioner2Part.replace(/"/g,""):i++;
+            document.querySelector("[data-id='Practitioner3_Part__c']")!=null?document.querySelector("[data-id='Practitioner3_Part__c']").value=data.object.practitioner3Part.replace(/"/g,""):i++;
+            document.querySelector("[data-id='Practitioner4_Part__c']")!=null?document.querySelector("[data-id='Practitioner4_Part__c']").value=data.object.practitioner4Part.replace(/"/g,""):i++;
+            document.querySelector("[data-id='Practitioner5_Part__c']")!=null?document.querySelector("[data-id='Practitioner5_Part__c']").value=data.object.practitioner5Part.replace(/"/g,""):i++;
+            document.querySelector("[data-id='age__c']")!=null?document.querySelector("[data-id='age__c']").value=data.object.age.replace(/"/g,""):i++;
+            document.querySelector("[data-id='Medical_History__c']")!=null?document.querySelector("[data-id='Medical_History__c']").value=data.object.medicalHistory.replace(/"/g,""):i++;
+            document.querySelector("[data-id='sex__c']")!=null?document.querySelector("[data-id='sex__c']").value=data.object.sex.replace(/"/g,""):i++;
+        };
+
+        //鏇挎崲vlookup
+        function replaceSearchContactLookup() {
+            if (!{!isNewMode}) {
+                queryContactName();
+            }           
+            if(document.querySelector("[data-id='Practitioner1__c']") != null){
+                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'Practitioner1__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+                let lookUpNode = htmlToElement(contactHtmlString);
+                let parentNode = document.querySelector("[data-id='Practitioner1__c']").parentNode;
+                document.querySelector("[data-id='Practitioner1__c']").removeAttribute("onchange");
+                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Practitioner1__c']").parentNode.children[2]);
+            }
+            if(document.querySelector("[data-id='Practitioner2__c']") != null){
+                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'Practitioner2__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+                let lookUpNode = htmlToElement(contactHtmlString);
+                let parentNode = document.querySelector("[data-id='Practitioner2__c']").parentNode;
+                document.querySelector("[data-id='Practitioner2__c']").removeAttribute("onchange");
+                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Practitioner2__c']").parentNode.children[2]);
+            }
+            if(document.querySelector("[data-id='Practitioner3__c']") != null){
+                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'Practitioner3__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+                let lookUpNode = htmlToElement(contactHtmlString);
+                let parentNode = document.querySelector("[data-id='Practitioner3__c']").parentNode;
+                document.querySelector("[data-id='Practitioner3__c']").removeAttribute("onchange");
+                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Practitioner3__c']").parentNode.children[2]);
+            }
+            if(document.querySelector("[data-id='Practitioner4__c']") != null){
+                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'Practitioner4__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+                let lookUpNode = htmlToElement(contactHtmlString);
+                let parentNode = document.querySelector("[data-id='Practitioner4__c']").parentNode;
+                document.querySelector("[data-id='Practitioner4__c']").removeAttribute("onchange");
+                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Practitioner4__c']").parentNode.children[2]);
+            }
+            if(document.querySelector("[data-id='Practitioner5__c']") != null){
+                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'Practitioner5__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+                let lookUpNode = htmlToElement(contactHtmlString);
+                let parentNode = document.querySelector("[data-id='Practitioner5__c']").parentNode;
+                document.querySelector("[data-id='Practitioner5__c']").removeAttribute("onchange");
+                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Practitioner5__c']").parentNode.children[2]);
+            }
+            if(document.querySelector("[data-id='Person_In_Charge__c']") != null){
+                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'Person_In_Charge__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+                let lookUpNode = htmlToElement(contactHtmlString);
+                let parentNode = document.querySelector("[data-id='Person_In_Charge__c']").parentNode;
+                document.querySelector("[data-id='Person_In_Charge__c']").removeAttribute("onchange");
+                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Person_In_Charge__c']").parentNode.children[2]);
+            }
+        }
+        var newSearchContactWindow = null;  
+        
+        function htmlToElement(html) {
+            var template = document.createElement('template');
+            html = html.trim(); // Never return a text node of whitespace as the result
+            template.innerHTML = html;
+            return template.content.firstChild;
+        }
+        function queryContactName() {
+            let contactsInfo = JSON.parse('{!contactsInfo}');
+            if(document.querySelector("[data-id='Practitioner1__c']") != null){
+                let sfId = document.getElementById(document.querySelector("[data-id='Practitioner1__c']").id + '_lkid').value;
+                let dataId = contactsInfo[sfId];
+                let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+                queryContactNameFetch(url,'Practitioner1__c');
+            }
+            if(document.querySelector("[data-id='Practitioner2__c']") != null){
+                let sfId = document.getElementById(document.querySelector("[data-id='Practitioner2__c']").id + '_lkid').value;
+                let dataId = contactsInfo[sfId];
+                let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+                queryContactNameFetch(url,'Practitioner2__c');
+            }
+            if(document.querySelector("[data-id='Practitioner3__c']") != null){
+                let sfId = document.getElementById(document.querySelector("[data-id='Practitioner3__c']").id + '_lkid').value;
+                let dataId = contactsInfo[sfId];
+                let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+                queryContactNameFetch(url,'Practitioner3__c');
+            }
+            if(document.querySelector("[data-id='Practitioner4__c']") != null){
+                let sfId = document.getElementById(document.querySelector("[data-id='Practitioner4__c']").id + '_lkid').value;
+                let dataId = contactsInfo[sfId];
+                let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+                queryContactNameFetch(url,'Practitioner4__c');
+            }
+            if(document.querySelector("[data-id='Practitioner5__c']") != null){
+                let sfId = document.getElementById(document.querySelector("[data-id='Practitioner5__c']").id + '_lkid').value;
+                let dataId = contactsInfo[sfId];
+                let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+                queryContactNameFetch(url,'Practitioner5__c');
+            }
+            if(document.querySelector("[data-id='Person_In_Charge__c']") != null){
+                let sfId = document.getElementById(document.querySelector("[data-id='Person_In_Charge__c']").id + '_lkid').value;
+                let dataId = contactsInfo[sfId];
+                let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+                queryContactNameFetch(url,'Person_In_Charge__c');
+            }
+        }
+
+        function queryContactNameFetch(url,filedId){
+            fetch(url, {
+                method: 'GET',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then((result) => {
+                if(result.object){
+                    document.querySelector("[data-id="+filedId+"]").value = result.object.lastName;
+                }
+            })
+        }
+
+        //鑷畾涔塴ookup鏌ヨ
+        function searchContact(contactNodeId,field){
+            closeField = field;
+            let accountValue = "";
+            if (document.querySelector("[data-id='Hospital_Department__c']")) {
+                let accountNodeId = document.querySelector("[data-id='Hospital_Department__c']").id + '_lkid';
+                accountValue = document.getElementById(accountNodeId).value;   
+            } 
+            console.log(accountValue);
+            if(accountValue !='000000000000000'){
+                let baseUrl = "/apex/SearchContactPage";
+                let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
+                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
+                newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
+                if (window.focus) {
+                    newSearchContactWindow.focus();
+                }
+                return false;
+            }else{
+                alertErrorMessage('{!PIPL_Input_Account_Error_Msg}');
+            }
+        }
+        //绐楀彛鍏抽棴鏃跺彂鐢�
+        function closePopupWindow() {
+            if (null != newSearchContactWindow) {
+                newSearchContactWindow.close();
+            }
+            let contactInfoStr = document.getElementById('page:form:contactId').value;
+            console.log('closePopup:'+contactInfoStr);
+            let contactInfo = JSON.parse(contactInfoStr);
+            let contactNodeId = document.querySelector("[data-id="+closeField+"]").id + '_lkid';
+            document.getElementById(contactNodeId).value = contactInfo.ContactId;
+            document.querySelector("[data-id="+closeField+"]").value = contactInfo.Name;
+        }
+
+        function htmlToElement(html) {
+            var template = document.createElement('template');
+            html = html.trim(); // Never return a text node of whitespace as the result
+            template.innerHTML = html;
+            return template.content.firstChild;
+        }
+
+        //鏂板缓缂栬緫鍥炶皟鍑芥暟
+        var insertOrUpdateBack = function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            console.log('Result from AWS' + result);
+            console.log('payloadJson=' + payloadJson);
+            payloadJson.VOC_Informer_Name__c = result.object[0].vocInformerName;
+            payloadJson.Caller_phone_c__c = result.object[0].callerPhone;
+            payloadJson.VOC_Informer_Contact__c = result.object[0].vocInformerContact;
+            payloadJson.Person_In_Charge_Text__c = result.object[0].personInChargeText;
+            payloadJson.Staff_Info_Manual_c__c = result.object[0].staffInfoManual;
+            payloadJson.Responsible_Person_HP_c__c = result.object[0].responsiblePersonHP;
+            payloadJson.Professor_sigh_text__c = result.object[0].professorSighText;
+            payloadJson.Practitioner1_Part__c = result.object[0].practitioner1Part;
+            payloadJson.Practitioner2_Part__c = result.object[0].practitioner2Part;
+            payloadJson.Practitioner3_Part__c = result.object[0].practitioner3Part;
+            payloadJson.Practitioner4_Part__c = result.object[0].practitioner4Part;
+            payloadJson.Practitioner5_Part__c = result.object[0].practitioner5Part;
+            payloadJson.age__c = result.object[0].age;
+            payloadJson.Medical_History__c = result.object[0].medicalHistory;
+            payloadJson.sex__c = result.object[0].sex;
+
+            payloadJson.VOC_Informer_Name_Encrypted__c = result.object[0].vocInformerNameEncrypt;
+            payloadJson.Caller_phone_c_Encrypted__c = result.object[0].callerPhoneEncrypt;
+            payloadJson.VOC_Informer_Contact_Encrypted__c = result.object[0].vocInformerContactEncrypt;
+            payloadJson.Person_In_Charge_Text_Encrypted__c = result.object[0].personInChargeTextEncrypt;
+            payloadJson.Professor_sigh_text_Encrypted__c = result.object[0].professorSighTextEncrypt;
+            payloadJson.Staff_Info_Manual_c_Encrypted__c = result.object[0].staffInfoManualEncrypt;
+            payloadJson.Responsible_Person_HP_c_Encrypted__c = result.object[0].responsiblePersonHPEncrypt;
+            payloadJson.Practitioner1_Part_Encrypted__c = result.object[0].practitioner1PartEncrypt;
+            payloadJson.Practitioner2_Part_Encrypted__c = result.object[0].practitioner2PartEncrypt;
+            payloadJson.Practitioner3_Part_Encrypted__c = result.object[0].practitioner3PartEncrypt;
+            payloadJson.Practitioner4_Part_Encrypted__c = result.object[0].practitioner4PartEncrypt;
+            payloadJson.Practitioner5_Part_Encrypted__c = result.object[0].practitioner5PartEncrypt;
+            payloadJson.age_Encrypted__c = result.object[0].ageEncrypt;
+            payloadJson.Medical_History_Encrypted__c = result.object[0].medicalHistoryEncrypt;
+            payloadJson.sex_Encrypted__c = result.object[0].sexEncrypt;
+            if (isNewMode) {
+                payloadJson.AWS_Data_Id__c = result.object[0].dataId;
+            } else {
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            }
+            return payloadJson;
+        }
+
+        //璺宠浆椤甸潰
+        var redirectCallBack = function redirectCallBack(sfId,errorMessage) {
+            if(sfId){
+                if(redirectMode == 'Save'){
+                    window.open('/' + sfId, '_self');
+                }else if(redirectMode == 'SaveAndNew'){
+                    window.open('/setup/ui/recordtypeselect.jsp?ent=' + '{!sobjectId}' + '&retURL=/' + '{!sobjectPrefix}' + '/o&save_new_url=/' + '{!sobjectPrefix}' + '/e?retURL=%2F' + '{!sobjectPrefix}' + '%2Fo', '_self');
+                }
+            }else{
+                alertErrorMessage(errorMessage);
+            }
+        }
+
+        //鐐瑰嚮淇濆瓨鎸夐挳
+        function saveReportProcess(saveMode) {
+            redirectMode = saveMode;
+            console.log('redirectMode' + redirectMode);
+            hiddenErrorMsgNode();
+            //1. Get report Information from Form
+            let reportJson = getReportInformation();
+            //2. Validate the report field value formate, for example the email formate or phone formate
+            let validationResultMessage = validateFieldValueFormate();
+            if (validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage(validationResultMessage);
+                return
+            }
+            // 3. Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(reportJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('{!requiredErrorMsg}'+checkRequiredFieldMsgResult);
+                return
+            }
+            //4. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(reportJson);
+            console.log('鍔犲瘑瀛楁锛�'+payloadForNewPI);
+
+            //5. report to AWS 
+            ProcessPI(reportJson, payloadForNewPI);
+        }
+    </script>
+
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="鎶ュ憡涔�" class="pageTitleIcon" title="鎶ュ憡涔�" />
+                <h1 class="pageType">鎶ュ憡涔�
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> 鏂板缓鎶ュ憡涔�</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target=leads_edit.htm&amp;section=Leads&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <apex:inputHidden value="{!contactId}" id="contactId" />
+        <!-- Error Msg-->
+        <!-- <apex:outputPanel id="errorMsg">
+            <apex:pageMessages id="msgContent" escape="false" />
+        </apex:outputPanel> -->
+        <apex:pageblock >
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">鎶ュ憡涔︾紪杈�</h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveReportProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveReportProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>          
+            <br/>
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" showHeader="{!layoutSection.useHeader}" collapsible="{!layoutSection.allowCollapse}"
+                    columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField html-data-id="{!layoutField.fieldAPI}" styleClass="{!layoutField.fieldAPI}" value="{!Report__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                sfdcPage.appendToOnloadQueue(function () {
+                    //1. Set Last Name label
+                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for Lead Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        QueryLeadFromAWS();
+                    }
+                    //Replace Vlookup Field
+                    replaceSearchContactLookup();
+                    //3. Set Readonly Attribute
+                    document.querySelector("[data-id='OwnerId']").classList.add("disabledbutton");
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveReportProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveReportProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditReport.page-meta.xml b/force-app/main/default/pages/NewAndEditReport.page-meta.xml
new file mode 100644
index 0000000..436e109
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditReport.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditReport</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewAndEditTenderinformation.page b/force-app/main/default/pages/NewAndEditTenderinformation.page
new file mode 100644
index 0000000..8cfa411
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditTenderinformation.page
@@ -0,0 +1,434 @@
+<apex:page standardController="Tender_information__c" extensions="NewAndEditTenderinformationController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script>
+        
+        var config = {};
+        config = {
+            SobjectName : "{!SobjectName}",
+            ApiPrefix:"{!ApiPrefix}",
+            SaveAndNew:false,
+            AWSToSobjectMap:{!AWSToSobjectMapJson},
+            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
+            SobjectToAWSModel:function (sobjJson) {
+                let leadPayloadList = [];
+                let leadPIData = {};
+
+                for(let f in config.AWSToSobjectMap){
+                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
+                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
+                    }
+                    else{
+                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
+                    }
+                } 
+
+
+                leadPIData.sfRecordId = '';
+                console.log('Sobject PI Data:' + leadPIData);
+                leadPayloadList.push(leadPIData);
+                console.log(JSON.stringify(leadPayloadList));
+                return JSON.stringify(leadPayloadList);
+            },
+            insertOrUpdateBack:function(payloadJson, r, isNewMode){
+                
+                for(let f in config.AWSToSobjectMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+
+                for(let f in config.AWSToSobjectEncryptedMap){
+                    if(r.object[0].hasOwnProperty(f)){
+                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
+                    }
+                    else{
+                        console.log(f + 'is not in r.object[0]');
+                    }
+                }
+                
+                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                if (isNewMode) {
+                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+                } else {
+                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+                }
+                return payloadJson;
+            },
+            queryBack:function (data) {
+                console.log('data = ' + data);
+                if(data.object){
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
+                        if(data.object.hasOwnProperty(f) && ele){
+                            
+                            // 澶氶�夌壒娈婂鐞�
+                            if(ele.type == 'select-multiple'){
+                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
+                               if(ele && data.object[f]){
+                                   let arr = data.object[f].split(';');
+
+                                   // 缁欓殣钘忕殑select璧嬪��
+                                   for(let op of ele.options){
+                                       op.selected = arr.indexOf(op.value)>-1;
+                                   }
+                                   
+                                   // 鍒╃敤鎸夐挳缁欐樉绀虹殑select璧嬪��
+                                   let ra = document.getElementById(ele.id + '_right_arrow');
+                                   if(ra){
+                                       ra.click();
+                                   }
+                                   
+                               }
+                            }else{
+                                ele.value = data.object[f];
+                            }
+                            
+                        }
+                        else{
+                            console.log(f + 'is not in data.object');
+                        }
+                    }
+                }
+                else{
+                    console.log('data.object = ' + data.object);
+                }
+                
+
+                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                // document.querySelector("[data-id='Phone']").value = data.object.phone;
+                // document.querySelector("[data-id='Email']").value = data.object.email;
+            },
+            updateMethod:"NewAndEditTenderinformationController.saveTenderinformation",
+            insertMethod:"NewAndEditTenderinformationController.saveTenderinformation"
+        }
+    	AWSService.sfSessionId = '{!GETSESSIONID()}';
+        var staticResources = JSON.parse('{!staticResource}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        console.log('{!staticResource}');
+        var VLookUpFields = {! VLookUpFieldsJson};
+        function ProcessPI(sobjJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode}) {
+            	NewPIToAWS(sobjJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(sobjJson, payloadForNewPI)
+            }
+        }
+
+        var GetEleByClass = function(class_name){
+            let eles = document.getElementsByClassName(class_name);
+            if(eles.length > 0) return eles[0];
+            return null;
+        }
+
+        var GetEleApiName = function(ele){
+            for(let c of ele.classList){
+                if(c.indexOf(config.ApiPrefix+'_')>-1){
+                    return c.replace(config.ApiPrefix+'_','');
+                }
+            }
+            return '';
+        }
+
+        function IsFormElement(tag_name){
+            return ['input','select','textarea'].indexOf(tag_name)>-1;
+        }
+
+        function getPIPayload(sobjJson) {
+            return config.SobjectToAWSModel(sobjJson);
+        }
+
+        function validateFieldValueFormate() {
+            let error_msg = '';
+            let textEmail = "[data-id='Email']";
+            let textPhone = "[data-id='Phone']";
+            //Email
+            let email = document.querySelector(textEmail);
+            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
+                error_msg += ';閭欢鏍煎紡閿欒';
+            }
+            let phone = document.querySelector(textPhone);
+
+            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
+                error_msg += ';鐢佃瘽鍙风爜閿欒';
+            }
+
+            for(let e of document.getElementsByTagName('select')){
+                for(let op of e.options){
+                    if(op.value == "*****" && op.selected){
+                        error_msg += ';涓嬫媺妗嗕笉鑳戒富鍔ㄩ�夋嫨瀵嗘枃閫夐」';
+                    }
+                }
+            }
+
+            if(error_msg.length>0 && error_msg[0]== ';'){
+                error_msg = error_msg.substring(1);
+            }
+
+            return error_msg;
+        }
+
+        function getSobjectInformation() {
+
+            let nodelist = document.getElementsByClassName(config.ApiPrefix);
+            let result = {}
+            for (let index = 0; index < nodelist.length; index++) {
+                let ele = nodelist[index];
+                let field_api_name = GetEleApiName(ele);
+                let tag_name = ele.tagName.toLowerCase();
+                if(!IsFormElement(tag_name)){
+                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
+                    continue;
+                }
+
+                if (VLookUpFields.indexOf(field_api_name)>=0) {
+                    console.log(ele.id.indexOf('lkwgt'));
+                    if (ele.id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = ele.id + '_lkid';
+                        let vlook_ele = document.getElementById(vlookUpNodeId);
+                        let v = '';
+                        if(vlook_ele){
+                            v = vlook_ele.value;
+                        }else{
+                            v = ele.value;
+                        }
+
+                        if(v && v != "000000000000000"){
+                            result[field_api_name] = v;
+                        }
+                        
+                    }
+                } else if (ele.type == 'checkbox') {
+                    result[field_api_name] = ele.checked;
+                } else if (ele.type == 'select-multiple') {
+                    //field_api_name
+                    let multiple = field_api_name;
+                    //let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    let targets = [];
+                    for(let i = 0; i < ele.selectedOptions.length; i++) {
+                        //let ele = nodelist[i];
+                        //targets = targets.replace(ele.selectedOptions[i].value,";");
+                        targets.push(ele.selectedOptions[i].value);
+                    }
+                    //targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[field_api_name] = targets.join(";");
+                } else {
+                    result[field_api_name] = ele.value;
+                }
+            }
+            return result;
+        }
+        function QuerySobjectFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+        function queryBack(data) {
+            console.log('data = ' + data);
+            config.queryBack(data);
+            unblockUI();
+        };
+
+
+        function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + r);
+            console.log('payloadJson=' + payloadJson);
+            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
+        }
+
+        function redirectCallBack(sfId,errorMsg) {
+            unblockUI();
+            if(errorMsg){
+                alertErrorMessage(errorMsg);
+            }
+            else{
+                if(config.SaveAndNew){
+                    window.open('{! SaveAndNewButtonUrl }','_self');
+                }else{
+                    window.open('/' + sfId, '_self');
+                }
+            }
+            
+        }
+
+        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.updateMethod;
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
+            
+        }
+
+        function NewPIToAWS(sobjJson, payloadForNewPI) {
+            let controllerSaveMethod = config.insertMethod;
+            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
+            
+        }
+        
+
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for(i = 0;i<requiredFieldAPIList.length;i++){
+                if(formData[requiredFieldAPIList[i]]){
+                    continue;
+                }else{
+                    if(blankRequiredFields == ''){
+                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }else{
+                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+                    
+                }
+            }
+            return blankRequiredFields;
+        }
+        function saveSobjectProcess(save_and_new) {
+            if(save_and_new){
+                config.SaveAndNew = true;
+            }
+            
+            hiddenErrorMsgNode();
+            //1. Get Sobject Information from Form
+            let sobjJson = getSobjectInformation();
+            //2. Validate the Sobject field value formate, for example the email formate or phone formate
+
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage(validationResultMessage);
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
+                return
+            }
+            // //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(sobjJson);
+
+            // //4. Get Authentication Information for AWS
+            // loadAWSAuthentication();
+
+            // //5. lead to AWS 
+            ProcessPI(sobjJson, payloadForNewPI);
+            // awsToken = TestToken;
+            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
+        }
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+        }
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
+                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        
+        <apex:pageblock id="block">
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Error Msg-->
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Tender_information__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                sfdcPage.appendToOnloadQueue(function () {
+                    //1. Set Last Name label
+                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '濮撳悕';
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for Sobject Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        bolckme();
+                        QuerySobjectFromAWS();
+                    }   
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
+                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
+                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewAndEditTenderinformation.page-meta.xml b/force-app/main/default/pages/NewAndEditTenderinformation.page-meta.xml
new file mode 100644
index 0000000..1995d9f
--- /dev/null
+++ b/force-app/main/default/pages/NewAndEditTenderinformation.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewAndEditTenderinformation</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewConsumApply.page b/force-app/main/default/pages/NewConsumApply.page
new file mode 100644
index 0000000..46a0c55
--- /dev/null
+++ b/force-app/main/default/pages/NewConsumApply.page
@@ -0,0 +1,402 @@
+<apex:page standardController="Consum_Apply__c" extensions="NewConsumApplyController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <style>
+        .disabledbutton {
+            pointer-events: none;
+            opacity: 0.4;
+        }
+    </style>
+    <script>
+        //Initial Required Information
+        var staticResources = JSON.parse('{!staticResource}');
+        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        var VLookUpFields = new Set(['Loaner_medical_Staff__c', 'Hospital__c', 'Strategic_dept__c', 'Account__c', 'QIS_number__c', 'OPDPlan__c', 'Campaign__c', 'Rental_Apply__c', 'Shipment_address__c', 'Dealer__c', 'Old_Consum_Apply__c', 'DeliverySlip__c', 'OwnerId', 'OPD__c']);
+        var userVLookUpFields = ['Person_In_Charge__c', 'applyUser__c', 'CC_EmailUser__c', 'Assign_Person__c', 'Consum_Assistant__c', 'Consum_Assistant2__c', 'Consum_Assistant3__c', 'SalesManager__c', 'ZongjianApprovalManager__c', 'BuchangApprovalManagerSales__c', 'TongkuoZongjian__c'];
+        var redirectMode = 'Save';
+
+        //Redirect Required Parameter
+        var redirectCallBack = function redirectCallBack(sfId,errorMessage) {
+            if(sfId){
+                if (redirectMode == 'Save') {
+                window.open('/' + sfId, '_self');
+            } else if (redirectMode == 'SaveAndNew') {
+                window.open('/a3i/e', '_self');
+            }
+            }else{
+                // alert(errorMessage);
+                alertErrorMessage(errorMessage);
+            }
+        }
+
+        //Query Required Parameter
+        var queryBack = function queryBack(data) {
+            console.log('data = ' + data);
+            document.querySelector("[data-id='Phone_number__c']").value = data.object.phoneNumber;
+            document.querySelector("[data-id='direct_shippment_address__c']").value = data.object.directShippmentAddress;
+            unblockUI();
+        };
+
+        //Check If Insert Or Update
+        var insertOrUpdateBack = function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            debugger
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + JSON.stringify(r));
+            console.log('payloadJson=' + JSON.stringify(payloadJson));
+            payloadJson.Phone_number__c = r.object[0].phoneNumber;
+            payloadJson.direct_shippment_address__c = r.object[0].directShippmentAddress;
+            payloadJson.Phone_Number_Encrypt__c = r.object[0].phoneNumberEncrypt;
+            payloadJson.Direct_Shippment_Address_Encrypt__c = r.object[0].directShippmentAddressEncrypt;
+            payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            if (isNewMode) {
+                payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+            } else {
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            }
+            debugger
+            return payloadJson;
+        }
+
+        // New Or Edit
+        function ProcessPI(consumApplyJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode
+            }) {
+                NewPIToAWS(consumApplyJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(consumApplyJson, payloadForNewPI)
+            }
+        }
+
+        //Get Sensitive Information
+        function getPIPayload(consumApplyJson) {
+            let consumApplyPayloadList = [];
+            let phoneNumber = consumApplyJson.Phone_number__c;
+            let directShippmentAddress = consumApplyJson.direct_shippment_address__c;
+            let consumApplyPIData = new Object();
+            consumApplyPIData.phoneNumber = phoneNumber;
+            consumApplyPIData.directShippmentAddress = directShippmentAddress;
+            consumApplyPIData.sfRecordId = '';
+            console.log('consumApply PI Data:' + JSON.stringify(consumApplyPIData));
+            consumApplyPayloadList.push(consumApplyPIData);
+            console.log(JSON.stringify(consumApplyPayloadList));
+            return JSON.stringify(consumApplyPayloadList);
+        }
+
+        //Check Validate Field Value
+        function validateFieldValueFormate() {
+            return true;
+            // let textEmail = "[data-id='Loaner_centre_mail_address__c']";
+            // let textPhone = "[data-id='Phone_number__c']";
+            // //Email
+            // let email = document.querySelector(textEmail).value;
+            // let phone = document.querySelector(textPhone).value;
+
+            // let regEmail = /^[\w-]{3,12}@[\da-zA-Z]{2,6}\.[a-zA-Z]+$/;
+            // let regPhone = /^1[3|5|8|7][0-9]\d{4,8}$/;
+
+            // let emailFormate = regEmail.test(email);
+            // let phoneFormate = regPhone.test(phone);
+
+            // console.log(emailFormate);
+            // console.log(phoneFormate);
+
+            // if (emailFormate == true && phoneFormate == true) {
+            //     return true;
+            // } else {
+            //     return false;
+            // }
+        }
+
+        //Get Page Information
+        function getConsumApplyInformation() {
+            let nodelist = document.querySelectorAll("[data-id]");
+            let result = {}
+            //瀵屾枃鏈�
+            if(document.querySelector("[aria-describedby = 'cke_34']")){
+                result.HP_received_sign_rich__c = document.querySelector("[aria-describedby = 'cke_34']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }           
+            for (let index = 0; index < nodelist.length; index++) {
+                if (VLookUpFields.has(nodelist[index].getAttribute("data-id"))) {
+                    console.log(nodelist[index].id.indexOf('lkwgt'));
+                    if (nodelist[index].id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = nodelist[index].id + '_lkid';
+                        let vlookUpNodeValue = document.getElementById(vlookUpNodeId).value;
+                        result[nodelist[index].getAttribute("data-id")] = vlookUpNodeValue;
+                    }
+                } else if (nodelist[index].type == 'checkbox') {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].checked;
+                } else if (nodelist[index].type == 'select-multiple') {
+                    //nodelist[index].getAttribute("data-id")
+                    let multiple = nodelist[index].getAttribute("data-id");
+                    let targets = document.querySelector("[data-id=" + multiple + "]").parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[nodelist[index].getAttribute("data-id")] = targets;
+                } else {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].value;
+                }
+                let x = index + 1;
+                if (x <= nodelist.length - 1 && (nodelist[x].getAttribute("data-id") == nodelist[index].getAttribute("data-id"))) {
+                    index++;
+                }
+            }
+            for (let i = 0; i < userVLookUpFields.length; i++) {
+                let userVlookUpNodeValue = document.querySelector("[data-id='" + userVLookUpFields[i] + "']").children[1].value;
+                console.log('userVlookUpNodeValue:'+userVlookUpNodeValue);
+                if(userVlookUpNodeValue!='000000000000000'){
+                    result[userVLookUpFields[i]] = userVlookUpNodeValue;
+                }               
+            }
+            console.log(JSON.stringify(result));
+            return result;
+        }
+
+        //Query from AWS
+        function QueryConsumApplyFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+
+        //Update Sensitive Information to AWS
+        function UpdatePIToAWS(consumApplyJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewConsumApplyController.saveConsumApply}';
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, consumApplyJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack, redirectCallBack);
+        }
+
+        //Insert Sensitive Information to AWS
+        function NewPIToAWS(consumApplyJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewConsumApplyController.saveConsumApply}';
+            AWSService.insert(staticResources.newUrl, consumApplyJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack, redirectCallBack);
+        }
+
+        //Check Required Fields
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for (i = 0; i < requiredFieldAPIList.length; i++) {
+                if (formData[requiredFieldAPIList[i]]) {
+                    continue;
+                } else {
+                    if (blankRequiredFields == '') {
+                        blankRequiredFields = blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    } else {
+                        blankRequiredFields = blankRequiredFields + ',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+
+                }
+            }
+            return blankRequiredFields;
+        }
+
+        //Base Process
+        function saveConsumApplyProcess(saveMode) {
+            redirectMode = saveMode;
+            console.log('redirectMode' + redirectMode);
+            hiddenErrorMsgNode();
+            //1. Get consumApply Information from Form
+            let consumApplyJson = getConsumApplyInformation();
+            //2. Validate the consumApply field value formate, for example the email formate or phone formate
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (!validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage('閭鏍煎紡杈撳叆鏈夎锛岃閲嶆柊杈撳叆锛�');
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(consumApplyJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('{!Input_Required_Field_Msg}' + checkRequiredFieldMsgResult);
+                return
+            }
+            //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(consumApplyJson);
+
+            //4. consumApply to AWS 
+            ProcessPI(consumApplyJson, payloadForNewPI);
+        }
+
+        //Alert Error Message
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:msgContent");
+            errorMsg = '閿欒锛氭棤鏁堟暟鎹��' + '\n' + errorMsg;
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+            unblockUI();
+        }
+
+        //Hide Error Message
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+        //鏇挎崲vlookup
+        function replaceSearchContactLookup() {
+            let lookUpNode = htmlToElement(contactHtmlString);
+            console.log(lookUpNode);
+            if (!{!isNewMode}) {
+                queryContactName();
+            }           
+            let parentNode = document.querySelector("[data-id='Loaner_medical_Staff__c']").parentNode;
+            document.querySelector("[data-id='Loaner_medical_Staff__c']").removeAttribute("onchange");
+            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Loaner_medical_Staff__c']").parentNode.children[2]);
+        }
+        var newSearchContactWindow = null;  
+        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+        function htmlToElement(html) {
+            var template = document.createElement('template');
+            html = html.trim(); // Never return a text node of whitespace as the result
+            template.innerHTML = html;
+            return template.content.firstChild;
+        }
+        function queryContactName() {
+            let sfId = document.getElementById(document.querySelector("[data-id='Loaner_medical_Staff__c']").id + '_lkid').value;
+            let contactsInfo = JSON.parse('{!contactsInfo}');
+            let dataId = contactsInfo[sfId];
+            let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+            fetch(url, {
+                method: 'GET',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then((result) => {
+                document.querySelector("[data-id='Loaner_medical_Staff__c']").value = result.object.lastName;
+            })
+        }
+        //鑷畾涔塴ookup鏌ヨ
+        function searchContact(contactNodeId){
+            let accountValue = "";
+            if (document.querySelector("[data-id='Account__c']")) {
+                let accountNodeId = document.querySelector("[data-id='Account__c']").id + '_lkid';
+                accountValue = document.getElementById(accountNodeId).value;   
+            } 
+            console.log(accountValue);
+            if(accountValue !='000000000000000'){
+                let baseUrl = "/apex/SearchContactPage";
+                let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
+                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
+                newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
+                if (window.focus) {
+                    newSearchContactWindow.focus();
+                }
+                return false;
+            }else{
+                alertErrorMessage('{!PIPL_Input_Account_Error_Msg}');
+            }
+        }
+        //绐楀彛鍏抽棴鏃跺彂鐢�
+        function closePopupWindow() {
+            if (null != newSearchContactWindow) {
+                newSearchContactWindow.close();
+            }
+            let contactInfoStr = document.getElementById('page:form:contactId').value;
+            console.log('closePopup:'+contactInfoStr);
+            let contactInfo = JSON.parse(contactInfoStr);
+            let contactNodeId = document.querySelector("[data-id='Loaner_medical_Staff__c']").id + '_lkid';
+            document.getElementById(contactNodeId).value = contactInfo.ContactId;
+            document.querySelector("[data-id='Loaner_medical_Staff__c']").value = contactInfo.Name;
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="鑰楁潗澶囧搧鐢宠" class="pageTitleIcon" title="鑰楁潗澶囧搧鐢宠" />
+                <h1 class="pageType">鑰楁潗澶囧搧鐢宠缂栬緫
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> 鏂板缓鑰楁潗澶囧搧鐢宠</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target=consumApplys_edit.htm&amp;section=consumApplys&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <apex:inputHidden value="{!contactId}" id="contactId"/>
+        <!-- Error Msg-->
+        <apex:outputPanel id="errorMsg">
+            <apex:pageMessages id="msgContent" escape="false" />
+        </apex:outputPanel>
+        <apex:pageblock >
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">鑰楁潗澶囧搧鐢宠缂栬緫</h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveConsumApplyProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveConsumApplyProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField html-data-id="{!layoutField.fieldAPI}" value="{!Consum_Apply__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                //Append Page
+                sfdcPage.appendToOnloadQueue(function () {
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for consumApply Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();
+                        QueryConsumApplyFromAWS();
+                    };
+                    //Replace Vlookup Field
+                    replaceSearchContactLookup();
+                    document.querySelector("[data-id='OwnerId']").classList.add("disabledbutton");
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveConsumApplyProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveConsumApplyProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewConsumApply.page-meta.xml b/force-app/main/default/pages/NewConsumApply.page-meta.xml
new file mode 100644
index 0000000..51a02be
--- /dev/null
+++ b/force-app/main/default/pages/NewConsumApply.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewConsumApply</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page b/force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page
new file mode 100644
index 0000000..044e42b
--- /dev/null
+++ b/force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page
@@ -0,0 +1,300 @@
+<apex:page standardController="Consum_Apply_Equipment_Set_Detail__c" extensions="NewConsumApplyEquipSetDetailController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <style>
+        .disabledbutton {
+            pointer-events: none;
+            opacity: 0.4;
+        }
+    </style>
+    <script>
+        //Initial Required Information
+        var staticResources = JSON.parse('{!staticResource}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        var VLookUpFields = new Set(['Consum_Apply__c','Consum_Apply_Equipment_Set__c','Asset__c','Canceled__c','DeliverySlip__c','Return_DeliverySlip__c']);
+        var userVLookUpFields = ['Follower_User__c','Consum_Assign_Person__c','Asset_Center_Confirm_Staff__c','Return_Operator__c','Return_wh_chenk_staff__c','Cancel_Mem__c','Lost_item_check_staff__c','Lost_item_check_staff_Final__c'];
+        var redirectMode = 'Save';
+
+        //Redirect Required Parameter
+        var redirectCallBack = function redirectCallBack(sfId, errorMessage) {
+            if (sfId) {
+                if (redirectMode == 'Save') {
+                    window.open('/' + sfId, '_self');
+                } else if (redirectMode == 'SaveAndNew') {
+                    window.open('/setup/ui/recordtypeselect.jsp?ent=' + '{!sobjecttypeForFrontEnd}' + '&retURL=/' + '{!sobjectPrefix}' + '/o&save_new_url=/' + '{!sobjectPrefix}' + '/e?retURL=%2F' + '{!sobjectPrefix}' + '%2Fo', '_self');
+                }
+            } else {
+                // alert(errorMessage);
+                alertErrorMessage(errorMessage);
+            }
+        }
+
+        //Query Required Parameter
+        var queryBack = function queryBack(data) {
+            console.log('data = ' + data);
+            document.querySelector("[data-id='Trial_User__c']").value = data.object.trialUser;
+            unblockUI();
+        };
+
+        //Check If Insert Or Update
+        var insertOrUpdateBack = function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            debugger
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + JSON.stringify(r));
+            console.log('payloadJson=' + JSON.stringify(payloadJson));
+            payloadJson.Trial_User__c = r.object[0].trialUser;
+            payloadJson.Trail_User_Encrypt__c = r.object[0].trialUserEncrypt;
+            payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            if (isNewMode) {
+                payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+            } else {
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            }
+            debugger
+            return payloadJson;
+        }
+
+        // New Or Edit
+        function ProcessPI(consumApplyJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode
+            }) {
+                NewPIToAWS(consumApplyJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(consumApplyJson, payloadForNewPI)
+            }
+        }
+
+        //Get Sensitive Information
+        function getPIPayload(consumApplyJson) {
+            let consumApplyPayloadList = [];
+            let trialUser = consumApplyJson.Trial_User__c;
+            let consumApplyPIData = new Object();
+            consumApplyPIData.trialUser = trialUser;
+            consumApplyPIData.sfRecordId = '';
+            console.log('consumApply PI Data:' + JSON.stringify(consumApplyPIData));
+            consumApplyPayloadList.push(consumApplyPIData);
+            console.log(JSON.stringify(consumApplyPayloadList));
+            return JSON.stringify(consumApplyPayloadList);
+        }
+
+        //Check Validate Field Value
+        function validateFieldValueFormate() {
+            return true;
+        }
+
+        //Get Page Information
+        function getConsumApplyInformation() {
+            let nodelist = document.querySelectorAll("[data-id]");
+            let result = {}           
+            for (let index = 0; index < nodelist.length; index++) {
+                if (VLookUpFields.has(nodelist[index].getAttribute("data-id"))) {
+                    console.log(nodelist[index].id.indexOf('lkwgt'));
+                    if (nodelist[index].id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = nodelist[index].id + '_lkid';
+                        let vlookUpNodeValue = document.getElementById(vlookUpNodeId).value;
+                        result[nodelist[index].getAttribute("data-id")] = vlookUpNodeValue;
+                    }
+                } else if (nodelist[index].type == 'checkbox') {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].checked;
+                } else if (nodelist[index].type == 'select-multiple') {
+                    //nodelist[index].getAttribute("data-id")
+                    let multiple = nodelist[index].getAttribute("data-id");
+                    let targets = document.querySelector("[data-id=" + multiple + "]").parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[nodelist[index].getAttribute("data-id")] = targets;
+                } else {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].value;
+                }
+                let x = index + 1;
+                if (x <= nodelist.length - 1 && (nodelist[x].getAttribute("data-id") == nodelist[index].getAttribute("data-id"))) {
+                    index++;
+                }
+            }
+            for (let i = 0; i < userVLookUpFields.length; i++) {
+                let userVlookUpNodeValue = document.querySelector("[data-id='" + userVLookUpFields[i] + "']").children[1].value;
+                console.log('userVlookUpNodeValue:'+userVlookUpNodeValue);
+                if(userVlookUpNodeValue!='000000000000000'){
+                    result[userVLookUpFields[i]] = userVlookUpNodeValue;
+                }               
+            }
+            console.log(JSON.stringify(result));
+            return result;
+        }
+
+        //Query from AWS
+        function QueryConsumApplyFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+
+        //Update Sensitive Information to AWS
+        function UpdatePIToAWS(consumApplyJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewConsumApplyEquipSetDetailController.saveConsumApply}';
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, consumApplyJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack, redirectCallBack);
+        }
+
+        //Insert Sensitive Information to AWS
+        function NewPIToAWS(consumApplyJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewConsumApplyEquipSetDetailController.saveConsumApply}';
+            AWSService.insert(staticResources.newUrl, consumApplyJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack, redirectCallBack);
+        }
+
+        //Check Required Fields
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for (i = 0; i < requiredFieldAPIList.length; i++) {
+                if (formData[requiredFieldAPIList[i]]) {
+                    continue;
+                } else {
+                    if (blankRequiredFields == '') {
+                        blankRequiredFields = blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    } else {
+                        blankRequiredFields = blankRequiredFields + ',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+
+                }
+            }
+            return blankRequiredFields;
+        }
+
+        //Base Process
+        function saveConsumApplyProcess(saveMode) {
+            redirectMode = saveMode;
+            console.log('redirectMode' + redirectMode);
+            hiddenErrorMsgNode();
+            //1. Get consumApply Information from Form
+            let consumApplyJson = getConsumApplyInformation();
+            //2. Validate the consumApply field value formate, for example the email formate or phone formate
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (!validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage('閭鏍煎紡杈撳叆鏈夎锛岃閲嶆柊杈撳叆锛�');
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(consumApplyJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('{!Input_Required_Field_Msg}' + checkRequiredFieldMsgResult);
+                return
+            }
+            //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(consumApplyJson);
+
+            //4. consumApply to AWS 
+            ProcessPI(consumApplyJson, payloadForNewPI);
+        }
+
+        //Alert Error Message
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:msgContent");
+            errorMsg = '閿欒锛氭棤鏁堟暟鎹��' + '\n' + errorMsg;
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+            unblockUI();
+        }
+
+        //Hide Error Message
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="鑰楁潗澶囧搧閰嶅涓�瑙堟槑缁�" class="pageTitleIcon" title="鑰楁潗澶囧搧閰嶅涓�瑙堟槑缁�" />
+                <h1 class="pageType">鑰楁潗澶囧搧閰嶅涓�瑙堟槑缁嗙紪杈�
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription">鏂板缓鑰楁潗澶囧搧閰嶅涓�瑙堟槑缁�</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target=consumApplys_edit.htm&amp;section=consumApplys&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <!-- Error Msg-->
+        <apex:outputPanel id="errorMsg">
+            <apex:pageMessages id="msgContent" escape="false" />
+        </apex:outputPanel>
+        <apex:pageblock >
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">鑰楁潗澶囧搧閰嶅涓�瑙堟槑缁嗙紪杈�</h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveConsumApplyProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveConsumApplyProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField html-data-id="{!layoutField.fieldAPI}" value="{!Consum_Apply_Equipment_Set_Detail__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                //Append Page
+                sfdcPage.appendToOnloadQueue(function () {
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for consumApply Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();
+                        QueryConsumApplyFromAWS();
+                    };
+                    document.querySelector("[data-id='OwnerId']").classList.add("disabledbutton");
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveConsumApplyProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveConsumApplyProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page-meta.xml b/force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page-meta.xml
new file mode 100644
index 0000000..abb57fa
--- /dev/null
+++ b/force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewConsumApplyEquipmentSetDetail</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewListOfConsumables.page b/force-app/main/default/pages/NewListOfConsumables.page
new file mode 100644
index 0000000..f654d6a
--- /dev/null
+++ b/force-app/main/default/pages/NewListOfConsumables.page
@@ -0,0 +1,2 @@
+<apex:page >
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewListOfConsumables.page-meta.xml b/force-app/main/default/pages/NewListOfConsumables.page-meta.xml
new file mode 100644
index 0000000..39b292b
--- /dev/null
+++ b/force-app/main/default/pages/NewListOfConsumables.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewListOfConsumables</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewOnCall.page b/force-app/main/default/pages/NewOnCall.page
new file mode 100644
index 0000000..8e63d39
--- /dev/null
+++ b/force-app/main/default/pages/NewOnCall.page
@@ -0,0 +1,298 @@
+<apex:page standardController="On_Call__c" extensions="OnCallController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <style>
+        .disabledbutton {
+            pointer-events: none;
+            opacity: 0.4;
+        }
+    </style>
+    <script>
+        //Initial Required Information
+        AWSService.sfSessionId = '{!GETSESSIONID()}';
+        var staticResources = JSON.parse('{!staticResource}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        var VLookUpFields = new Set(['segment__c','Hospital__c','Oncall_Equipment__c','OwnerId']);
+        var redirectMode = 'Save';
+
+        //Redirect Required Parameter
+        var redirectCallBack = function redirectCallBack(sfId, errorMessage) {
+            if (sfId) {
+                if (redirectMode == 'Save') {
+                    window.open('/' + sfId, '_self');
+                } else if (redirectMode == 'SaveAndNew') {
+                    window.open('/setup/ui/recordtypeselect.jsp?ent=' + '{!sobjecttypeForFrontEnd}' + '&retURL=/' + '{!sobjectPrefix}' + '/o&save_new_url=/' + '{!sobjectPrefix}' + '/e?retURL=%2F' + '{!sobjectPrefix}' + '%2Fo', '_self');
+                }
+            } else {
+                // alert(errorMessage);
+                alertErrorMessage(errorMessage);
+            }
+        }
+
+        //Query Required Parameter
+        var queryBack = function queryBack(data) {
+            console.log('data = ' + data);
+            document.querySelector("[id='page:form:pageBlock:pageBlockSection:j_id1:0:j_id2']").value = data.object.callerPhone;
+            document.querySelector("[data-id='Responsible_Person_HP__c']").value = data.object.responsiblePersonHP;
+            unblockUI();
+        };
+
+        //Check If Insert Or Update
+        var insertOrUpdateBack = function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            debugger
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + JSON.stringify(r));
+            console.log('payloadJson=' + JSON.stringify(payloadJson));
+            payloadJson.Caller_phone__c = r.object[0].callerPhone;
+            payloadJson.Responsible_Person_HP__c = r.object[0].responsiblePersonHP;
+            payloadJson.Caller_Phone_Encrypt__c = r.object[0].callerPhoneEncrypt;
+            payloadJson.Responsible_PersonHP_Encrypt__c = r.object[0].responsiblePersonHPEncrypt;
+            payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            if (isNewMode) {
+                payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+            } else {
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            }
+            debugger
+            return payloadJson;
+        }
+
+        // New Or Edit
+        function ProcessPI(onCallJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode
+            }) {
+                NewPIToAWS(onCallJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(onCallJson, payloadForNewPI)
+            }
+        }
+
+        //Get Sensitive Information
+        function getPIPayload(onCallJson) {
+            let onCallPayloadList = [];
+            let callerPhone = onCallJson.Caller_phone__c;
+            let responsiblePersonHP = onCallJson.Responsible_Person_HP__c;
+            let onCallPIData = new Object();
+            onCallPIData.callerPhone = callerPhone;
+            onCallPIData.responsiblePersonHP = responsiblePersonHP;
+            onCallPIData.sfRecordId = '';
+            console.log('onCall PI Data:' + JSON.stringify(onCallPIData));
+            onCallPayloadList.push(onCallPIData);
+            console.log(JSON.stringify(onCallPayloadList));
+            return JSON.stringify(onCallPayloadList);
+        }
+
+        //Check Validate Field Value
+        function validateFieldValueFormate() {
+            return true;
+        }
+
+        //Get Page Information
+        function getOnCallInformation() {
+            let nodelist = document.querySelectorAll("[data-id]");
+            let result = {}         
+            for (let index = 0; index < nodelist.length; index++) {
+                if (VLookUpFields.has(nodelist[index].getAttribute("data-id"))) {
+                    console.log(nodelist[index].id.indexOf('lkwgt'));
+                    if (nodelist[index].id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = nodelist[index].id + '_lkid';
+                        let vlookUpNodeValue = document.getElementById(vlookUpNodeId).value;
+                        result[nodelist[index].getAttribute("data-id")] = vlookUpNodeValue;
+                    }
+                } else if (nodelist[index].type == 'checkbox') {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].checked;
+                } else if (nodelist[index].type == 'select-multiple') {
+                    //nodelist[index].getAttribute("data-id")
+                    let multiple = nodelist[index].getAttribute("data-id");
+                    let targets = document.querySelector("[data-id=" + multiple + "]").parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[nodelist[index].getAttribute("data-id")] = targets;
+                } else {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].value;
+                }
+                let x = index + 1;
+                if (x <= nodelist.length - 1 && (nodelist[x].getAttribute("data-id") == nodelist[index].getAttribute("data-id"))) {
+                    index++;
+                }
+            }
+            console.log(JSON.stringify(result));
+            return result;
+        }
+
+        //Query from AWS
+        function QueryOnCallFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+
+        //Update Sensitive Information to AWS
+        function UpdatePIToAWS(onCallJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.OnCallController.saveOnCall}';
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, onCallJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack, redirectCallBack);
+        }
+
+        //Insert Sensitive Information to AWS
+        function NewPIToAWS(onCallJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.OnCallController.saveOnCall}';
+            AWSService.insert(staticResources.newUrl, onCallJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack, redirectCallBack);
+        }
+
+        //Check Required Fields
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for (i = 0; i < requiredFieldAPIList.length; i++) {
+                if (formData[requiredFieldAPIList[i]]) {
+                    continue;
+                } else {
+                    if (blankRequiredFields == '') {
+                        blankRequiredFields = blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    } else {
+                        blankRequiredFields = blankRequiredFields + ',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+
+                }
+            }
+            return blankRequiredFields;
+        }
+
+        //Base Process
+        function saveOnCallProcess(saveMode) {
+            redirectMode = saveMode;
+            console.log('redirectMode' + redirectMode);
+            hiddenErrorMsgNode();
+            //1. Get onCall Information from Form
+            let onCallJson = getOnCallInformation();
+            //2. Validate the onCall field value formate, for example the email formate or phone formate
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (!validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage('閭鏍煎紡杈撳叆鏈夎锛岃閲嶆柊杈撳叆锛�');
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(onCallJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('{!Input_Required_Field_Msg}' + checkRequiredFieldMsgResult);
+                return
+            }
+            //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(onCallJson);
+
+            //4. onCall to AWS 
+            ProcessPI(onCallJson, payloadForNewPI);
+        }
+
+        //Alert Error Message
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:msgContent");
+            errorMsg = '閿欒锛氭棤鏁堟暟鎹��' + '\n' + errorMsg;
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+            unblockUI();
+        }
+
+        //Hide Error Message
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="OnCall" class="pageTitleIcon" title="OnCall" />
+                <h1 class="pageType">OnCall缂栬緫
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription">鏂板缓OnCall</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target=onCalls_edit.htm&amp;section=onCalls&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <!-- Error Msg-->
+        <apex:outputPanel id="errorMsg">
+            <apex:pageMessages id="msgContent" escape="false" />
+        </apex:outputPanel>
+        <apex:pageblock >
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">OnCall缂栬緫</h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveOnCallProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveOnCallProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField html-data-id="{!layoutField.fieldAPI}" value="{!On_Call__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                //Append Page
+                sfdcPage.appendToOnloadQueue(function () {
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for onCall Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();
+                        QueryOnCallFromAWS();
+                    };
+                    document.querySelector("[data-id='OwnerId']").classList.add("disabledbutton");
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveOnCallProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveOnCallProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewOnCall.page-meta.xml b/force-app/main/default/pages/NewOnCall.page-meta.xml
new file mode 100644
index 0000000..276c499
--- /dev/null
+++ b/force-app/main/default/pages/NewOnCall.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewOnCall</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewRentalApply.page b/force-app/main/default/pages/NewRentalApply.page
new file mode 100644
index 0000000..02d03e3
--- /dev/null
+++ b/force-app/main/default/pages/NewRentalApply.page
@@ -0,0 +1,387 @@
+<apex:page standardController="Rental_Apply__c" extensions="RentalApplyController" id="page">
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <style>
+        .disabledbutton {
+            pointer-events: none;
+            opacity: 0.4;
+        }
+    </style>
+    <script>
+        //Initial Required Information
+        var staticResources = JSON.parse('{!staticResource}');
+        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        var VLookUpFields = new Set(['OwnerId','OPDPlan__c','Zsq_Rental_Apply__c','Loaner_medical_Staff__c','Hospital__c','Strategic_dept__c','Account__c','Repair__c','Campaign__c','QIS_number__c','QISRepair__c','NewRepair__c','Follow_UP_Opp__c','Statu_Achievements__c','Shipment_address__c','Dealer__c','Old_Rental_Apply__c','OPD__c']);
+        var userVLookUpFields = ['Person_In_Charge__c','applyUser__c','Rental_Assistant__c','Assign_Person__c','ZongjianApprovalManager__c','BuchangApprovalManager__c','JingliApprovalManager__c','BuchangApprovalManagerSales__c','SalesManager__c'];
+        var redirectMode = 'Save';
+
+        //Redirect Required Parameter
+        var redirectCallBack = function redirectCallBack(sfId,errorMessage) {
+            if(sfId){
+                if (redirectMode == 'Save') {
+                window.open('/' + sfId, '_self');
+            } else if (redirectMode == 'SaveAndNew') {
+                window.open('/a3i/e', '_self');
+            }
+            }else{
+                // alert(errorMessage);
+                alertErrorMessage(errorMessage);
+            }
+        }
+
+        //Query Required Parameter
+        var queryBack = function queryBack(data) {
+            console.log('data = ' + data);
+            document.querySelector("[data-id='Phone_number__c']").value = data.object.phoneNumber;
+            document.querySelector("[data-id='direct_shippment_address__c']").value = data.object.directShippmentAddress;
+            unblockUI();
+        };
+
+        //Check If Insert Or Update
+        var insertOrUpdateBack = function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            debugger
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + JSON.stringify(r));
+            console.log('payloadJson=' + JSON.stringify(payloadJson));
+            payloadJson.Phone_number__c = r.object[0].phoneNumber;
+            payloadJson.direct_shippment_address__c = r.object[0].directShippmentAddress;
+            payloadJson.Phone_Number_Encrypt__c = r.object[0].phoneNumberEncrypt;
+            payloadJson.Direct_Shippment_Address_Encrypt__c = r.object[0].directShippmentAddressEncrypt;
+            payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            if (isNewMode) {
+                payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+            } else {
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            }
+            debugger
+            return payloadJson;
+        }
+
+        // New Or Edit
+        function ProcessPI(rentalApplyJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode
+            }) {
+                NewPIToAWS(rentalApplyJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(rentalApplyJson, payloadForNewPI)
+            }
+        }
+
+        //Get Sensitive Information
+        function getPIPayload(rentalApplyJson) {
+            let rentalApplyPayloadList = [];
+            let phoneNumber = rentalApplyJson.Phone_number__c;
+            let directShippmentAddress = rentalApplyJson.direct_shippment_address__c;
+            let rentalApplyPIData = new Object();
+            rentalApplyPIData.phoneNumber = phoneNumber;
+            rentalApplyPIData.directShippmentAddress = directShippmentAddress;
+            rentalApplyPIData.sfRecordId = '';
+            console.log('rentalApply PI Data:' + JSON.stringify(rentalApplyPIData));
+            rentalApplyPayloadList.push(rentalApplyPIData);
+            console.log(JSON.stringify(rentalApplyPayloadList));
+            return JSON.stringify(rentalApplyPayloadList);
+        }
+
+        //Check Validate Field Value
+        function validateFieldValueFormate() {
+            return true;
+        }
+
+        //Get Page Information
+        function getRentalApplyInformation() {
+            let nodelist = document.querySelectorAll("[data-id]");
+            let result = {}
+            //瀵屾枃鏈�
+            if(document.querySelector("[aria-describedby = 'cke_34']")){
+                result.HP_received_sign_rich__c = document.querySelector("[aria-describedby = 'cke_34']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            }           
+            for (let index = 0; index < nodelist.length; index++) {
+                if (VLookUpFields.has(nodelist[index].getAttribute("data-id"))) {
+                    console.log(nodelist[index].id.indexOf('lkwgt'));
+                    if (nodelist[index].id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = nodelist[index].id + '_lkid';
+                        let vlookUpNodeValue = document.getElementById(vlookUpNodeId).value;
+                        result[nodelist[index].getAttribute("data-id")] = vlookUpNodeValue;
+                    }
+                } else if (nodelist[index].type == 'checkbox') {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].checked;
+                } else if (nodelist[index].type == 'select-multiple') {
+                    //nodelist[index].getAttribute("data-id")
+                    let multiple = nodelist[index].getAttribute("data-id");
+                    let targets = document.querySelector("[data-id=" + multiple + "]").parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[nodelist[index].getAttribute("data-id")] = targets;
+                } else {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].value;
+                }
+                let x = index + 1;
+                if (x <= nodelist.length - 1 && (nodelist[x].getAttribute("data-id") == nodelist[index].getAttribute("data-id"))) {
+                    index++;
+                }
+            }
+            for (let i = 0; i < userVLookUpFields.length; i++) {
+                let userVlookUpNodeValue = document.querySelector("[data-id='" + userVLookUpFields[i] + "']").children[1].value;
+                console.log('userVlookUpNodeValue:'+userVlookUpNodeValue);
+                if(userVlookUpNodeValue!='000000000000000'){
+                    result[userVLookUpFields[i]] = userVlookUpNodeValue;
+                }               
+            }
+            //page:form:j_id30:j_id34:2:j_id35:j_id36:2:j_id37
+            //page:form:j_id27:j_id31:2:j_id32:j_id33:2:j_id34
+            result.demo_purpose2__c = document.querySelector("[id='page:form:j_id30:j_id34:2:j_id35:j_id36:2:j_id37']").value;
+            result.ToAgency__c = document.querySelector("[id='page:form:j_id30:j_id34:0:j_id35:j_id36:14:j_id37']").value;
+            result.Loaner_cancel_reason__c = document.querySelector("[id='page:form:j_id30:j_id34:0:j_id35:j_id36:14:j_id37']").value;
+            console.log(JSON.stringify(result));
+            return result;
+        }
+
+        //Query from AWS
+        function QueryRentalApplyFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+
+        //Update Sensitive Information to AWS
+        function UpdatePIToAWS(rentalApplyJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.RentalApplyController.saveRentalApply}';
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, rentalApplyJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack, redirectCallBack);
+        }
+
+        //Insert Sensitive Information to AWS
+        function NewPIToAWS(rentalApplyJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.RentalApplyController.saveRentalApply}';
+            AWSService.insert(staticResources.newUrl, rentalApplyJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack, redirectCallBack);
+        }
+
+        //Check Required Fields
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for (i = 0; i < requiredFieldAPIList.length; i++) {
+                if (formData[requiredFieldAPIList[i]]) {
+                    continue;
+                } else {
+                    if (blankRequiredFields == '') {
+                        blankRequiredFields = blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    } else {
+                        blankRequiredFields = blankRequiredFields + ',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+
+                }
+            }
+            return blankRequiredFields;
+        }
+
+        //Base Process
+        function saveRentalApplyProcess(saveMode) {
+            redirectMode = saveMode;
+            console.log('redirectMode' + redirectMode);
+            hiddenErrorMsgNode();
+            //1. Get rentalApply Information from Form
+            let rentalApplyJson = getRentalApplyInformation();
+            //2. Validate the rentalApply field value formate, for example the email formate or phone formate
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (!validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage('閭鏍煎紡杈撳叆鏈夎锛岃閲嶆柊杈撳叆锛�');
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(rentalApplyJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('{!Input_Required_Field_Msg}' + checkRequiredFieldMsgResult);
+                return
+            }
+            //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(rentalApplyJson);
+
+            //4. rentalApply to AWS 
+            ProcessPI(rentalApplyJson, payloadForNewPI);
+        }
+
+        //Alert Error Message
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:msgContent");
+            errorMsg = '閿欒锛氭棤鏁堟暟鎹��' + '\n' + errorMsg;
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+            unblockUI();
+        }
+
+        //Hide Error Message
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+        //鏇挎崲vlookup
+        function replaceSearchContactLookup() {
+            let lookUpNode = htmlToElement(contactHtmlString);
+            console.log(lookUpNode);
+            if (!{!isNewMode}) {
+                queryContactName();
+            }           
+            let parentNode = document.querySelector("[data-id='Loaner_medical_Staff__c']").parentNode;
+            document.querySelector("[data-id='Loaner_medical_Staff__c']").removeAttribute("onchange");
+            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Loaner_medical_Staff__c']").parentNode.children[2]);
+        }
+        var newSearchContactWindow = null;  
+        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
+        function htmlToElement(html) {
+            var template = document.createElement('template');
+            html = html.trim(); // Never return a text node of whitespace as the result
+            template.innerHTML = html;
+            return template.content.firstChild;
+        }
+        function queryContactName() {
+            let sfId = document.getElementById(document.querySelector("[data-id='Loaner_medical_Staff__c']").id + '_lkid').value;
+            let contactsInfo = JSON.parse('{!contactsInfo}');
+            let dataId = contactsInfo[sfId];
+            let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
+            fetch(url, {
+                method: 'GET',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then((result) => {
+                document.querySelector("[data-id='Loaner_medical_Staff__c']").value = result.object.lastName;
+            })
+        }
+        //鑷畾涔塴ookup鏌ヨ
+        function searchContact(contactNodeId){
+            let accountValue = "";
+            if (document.querySelector("[data-id='Account__c']")) {
+                let accountNodeId = document.querySelector("[data-id='Account__c']").id + '_lkid';
+                accountValue = document.getElementById(accountNodeId).value;   
+            } 
+            console.log(accountValue);
+            if(accountValue !='000000000000000'){
+                let baseUrl = "/apex/SearchContactPage";
+                let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
+                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
+                newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
+                if (window.focus) {
+                    newSearchContactWindow.focus();
+                }
+                return false;
+            }else{
+                alertErrorMessage('{!PIPL_Input_Account_Error_Msg}');
+            }
+        }
+        //绐楀彛鍏抽棴鏃跺彂鐢�
+        function closePopupWindow() {
+            if (null != newSearchContactWindow) {
+                newSearchContactWindow.close();
+            }
+            let contactInfoStr = document.getElementById('page:form:contactId').value;
+            console.log('closePopup:'+contactInfoStr);
+            let contactInfo = JSON.parse(contactInfoStr);
+            let contactNodeId = document.querySelector("[data-id='Loaner_medical_Staff__c']").id + '_lkid';
+            document.getElementById(contactNodeId).value = contactInfo.ContactId;
+            document.querySelector("[data-id='Loaner_medical_Staff__c']").value = contactInfo.Name;
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="澶囧搧鍊熷嚭鐢宠" class="pageTitleIcon" title="澶囧搧鍊熷嚭鐢宠" />
+                <h1 class="pageType">澶囧搧鍊熷嚭鐢宠缂栬緫
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription"> 鏂板缓澶囧搧鍊熷嚭鐢宠</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target=rentalApplys_edit.htm&amp;section=rentalApplys&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <apex:inputHidden value="{!contactId}" id="contactId"/>
+        <!-- Error Msg-->
+        <apex:outputPanel id="errorMsg">
+            <apex:pageMessages id="msgContent" escape="false" />
+        </apex:outputPanel>
+        <apex:pageblock >
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">澶囧搧鍊熷嚭鐢宠缂栬緫</h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveRentalApplyProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveRentalApplyProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField html-data-id="{!layoutField.fieldAPI}" value="{!Rental_Apply__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                //Append Page
+                sfdcPage.appendToOnloadQueue(function () {
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for rentalApply Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();
+                        QueryRentalApplyFromAWS();
+                    };
+                    //Replace Vlookup Field
+                    replaceSearchContactLookup();
+                    document.querySelector("[data-id='OwnerId']").classList.add("disabledbutton");
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveRentalApplyProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveRentalApplyProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewRentalApply.page-meta.xml b/force-app/main/default/pages/NewRentalApply.page-meta.xml
new file mode 100644
index 0000000..e5ffeb2
--- /dev/null
+++ b/force-app/main/default/pages/NewRentalApply.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewRentalApply</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewRepair.page b/force-app/main/default/pages/NewRepair.page
new file mode 100644
index 0000000..a47b202
--- /dev/null
+++ b/force-app/main/default/pages/NewRepair.page
@@ -0,0 +1,327 @@
+<apex:page standardController="Repair__c" extensions="NewRepairController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
+    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <style>
+        .disabledbutton {
+            pointer-events: none;
+            opacity: 0.4;
+        }
+    </style>
+    <script>
+        //Initial Required Information
+        var staticResources = JSON.parse('{!staticResource}');
+        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
+        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
+        var VLookUpFields = new Set(['Delivered_Product__c','Hospital__c','Department_Class__c','Account__c','Dealer__c','Incharge_Staff_Contact__c','Maintenance_Contract__c','VM_Maintenance_Contract__c','Repair_Quotation_Id__c','RepairSubOrder__c','On_Call_ID__c','QIS_ID__c','InsReport__c','NFM108_Receipt__c','Rental_Apply_Equipment_Set_Detail__c']);
+        var userVLookUpFields = ['Incharge_Staff__c','Repair_Authenticator__c','OCSM_RC_CordingUser__c','OSH_Affirmant__c','OSHRAConfirmUser__c'];
+        var redirectMode = 'Save';
+
+        //Redirect Required Parameter
+        var redirectCallBack = function redirectCallBack(sfId, errorMessage) {
+            if (sfId) {
+                if (redirectMode == 'Save') {
+                    window.open('/' + sfId, '_self');
+                } else if (redirectMode == 'SaveAndNew') {
+                    window.open('/setup/ui/recordtypeselect.jsp?ent=' + '{!sobjectId}' + '&retURL=/' + '{!sobjectPrefix}' + '/o&save_new_url=/' + '{!sobjectPrefix}' + '/e?retURL=%2F' + '{!sobjectPrefix}' + '%2Fo', '_self');
+                }
+            } else {
+                // alert(errorMessage);
+                alertErrorMessage(errorMessage);
+            }
+        }
+
+        //Query Required Parameter
+        var queryBack = function queryBack(data) {
+            console.log('data = ' + data);
+            document.querySelector("[data-id='address_Contacts__c']").value = data.object.addressContacts;
+            document.querySelector("[data-id='address_Contacts_Name__c']").value = data.object.addressContactsName;
+            document.querySelector("[data-id='address_Telephone__c']").value = data.object.addressTelephone;
+            document.querySelector("[data-id='address_ZipCode__c']").value = data.object.addressZipCode;
+            document.querySelector("[data-id='Detailed_Address__c']").value = data.object.detailedAddress;
+            document.querySelector("[data-id='RepairApplicant__c']").value = data.object.repairApplicant;
+            unblockUI();
+        };
+
+        //Check If Insert Or Update
+        var insertOrUpdateBack = function insertOrUpdateBack(payloadJson, result, isNewMode) {
+            debugger
+            console.log(result);
+            let r = result;
+            console.log('Result from AWS' + JSON.stringify(r));
+            console.log('payloadJson=' + JSON.stringify(payloadJson));
+            payloadJson.address_Contacts__c = r.object[0].addressContacts;
+            payloadJson.address_Contacts_Name__c = r.object[0].addressContactsName;
+            payloadJson.address_Telephone__c = r.object[0].addressTelephone;
+            payloadJson.address_ZipCode__c = r.object[0].addressZipCode;
+            payloadJson.Detailed_Address__c = r.object[0].detailedAddress;
+            payloadJson.RepairApplicant__c = r.object[0].repairApplicant;
+            payloadJson.Address_Contacts_Encrypt__c = r.object[0].addressContactsEncrypt;
+            payloadJson.Address_Contacts_Name_Encrypt__c = r.object[0].addressContactsNameEncrypt;
+            payloadJson.Address_Telephone_Encrypt__c = r.object[0].addressTelephoneEncrypt;
+            payloadJson.Address_ZipCode_Encrypt__c = r.object[0].addressZipCodeEncrypt;
+            payloadJson.Detailed_Address_Encrypt__c = r.object[0].detailedAddressEncrypt;
+            payloadJson.Repair_Applicant_Encrypt__c = r.object[0].repairApplicantEncrypt;
+            payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            if (isNewMode) {
+                payloadJson.AWS_Data_Id__c = r.object[0].dataId;
+            } else {
+                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
+            }
+            debugger
+            return payloadJson;
+        }
+
+        // New Or Edit
+        function ProcessPI(repairJson, payloadForNewPI) {
+            blockme();
+            if ({!isNewMode
+            }) {
+                NewPIToAWS(repairJson, payloadForNewPI)
+            }else {
+                UpdatePIToAWS(repairJson, payloadForNewPI)
+            }
+        }
+
+        //Get Sensitive Information
+        function getPIPayload(repairJson) {
+            let repairPayloadList = [];
+            let addressContacts = repairJson.address_Contacts__c;
+            let addressContactsName = repairJson.address_Contacts_Name__c;
+            let addressTelephone = repairJson.address_Telephone__c;
+            let addressZipCode = repairJson.address_ZipCode__c;
+            let detailedAddress = repairJson.Detailed_Address__c;
+            let repairApplicant = repairJson.RepairApplicant__c;
+            let repairPIData = new Object();
+            repairPIData.addressContacts = addressContacts;
+            repairPIData.addressContactsName = addressContactsName;
+            repairPIData.addressTelephone = addressTelephone;
+            repairPIData.addressZipCode = addressZipCode;
+            repairPIData.detailedAddress = detailedAddress;
+            repairPIData.repairApplicant = repairApplicant;
+            repairPIData.sfRecordId = '';
+            console.log('repair PI Data:' + JSON.stringify(repairPIData));
+            repairPayloadList.push(repairPIData);
+            console.log(JSON.stringify(repairPayloadList));
+            return JSON.stringify(repairPayloadList);
+        }
+
+        //Check Validate Field Value
+        function validateFieldValueFormate() {
+            return true;
+        }
+
+        //Get Page Information
+        function getRepairInformation() {
+            let nodelist = document.querySelectorAll("[data-id]");
+            let result = {}         
+            for (let index = 0; index < nodelist.length; index++) {
+                if (VLookUpFields.has(nodelist[index].getAttribute("data-id"))) {
+                    console.log(nodelist[index].id.indexOf('lkwgt'));
+                    if (nodelist[index].id.indexOf('lkwgt') == -1) {
+                        let vlookUpNodeId = nodelist[index].id + '_lkid';
+                        let vlookUpNodeValue = document.getElementById(vlookUpNodeId).value;
+                        result[nodelist[index].getAttribute("data-id")] = vlookUpNodeValue;
+                    }
+                } else if (nodelist[index].type == 'checkbox') {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].checked;
+                } else if (nodelist[index].type == 'select-multiple') {
+                    //nodelist[index].getAttribute("data-id")
+                    let multiple = nodelist[index].getAttribute("data-id");
+                    let targets = document.querySelector("[data-id=" + multiple + "]").parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
+                    targets = targets.replace(/\n/g, ";");
+                    console.log('targets = ' + targets);
+                    result[nodelist[index].getAttribute("data-id")] = targets;
+                } else {
+                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].value;
+                }
+                let x = index + 1;
+                if (x <= nodelist.length - 1 && (nodelist[x].getAttribute("data-id") == nodelist[index].getAttribute("data-id"))) {
+                    index++;
+                }
+            }
+            for (let i = 0; i < userVLookUpFields.length; i++) {
+                let userVlookUpNodeValue = document.querySelector("[data-id='" + userVLookUpFields[i] + "']").children[1].value;
+                console.log('userVlookUpNodeValue:'+userVlookUpNodeValue);
+                if(userVlookUpNodeValue!='000000000000000'){
+                    result[userVLookUpFields[i]] = userVlookUpNodeValue;
+                }               
+            }
+            result.work_location_select__c = document.querySelector("[id='page:form:j_id30:j_id34:0:j_id35:j_id36:18:j_id37']").value;
+            // result.ProblemDescription__c = document.querySelector("[aria-describedby = 'cke_34']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
+            console.log(JSON.stringify(result));
+            return result;
+        }
+
+        //Query from AWS
+        function QueryRepairFromAWS() {
+            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+        }
+
+        //Update Sensitive Information to AWS
+        function UpdatePIToAWS(repairJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewRepairController.saveRepair}';
+            let obj = JSON.parse(payloadForNewPI);
+            obj[0].dataId = '{!AWSDataId}';
+            let payloadForNewPIJson = JSON.stringify(obj);
+            AWSService.update(staticResources.updateUrl, repairJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack, redirectCallBack);
+        }
+
+        //Insert Sensitive Information to AWS
+        function NewPIToAWS(repairJson, payloadForNewPI) {
+            let controllerSaveMethod = '{!$RemoteAction.NewRepairController.saveRepair}';
+            AWSService.insert(staticResources.newUrl, repairJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack, redirectCallBack);
+        }
+
+        //Check Required Fields
+        function checkRequiredFieldMsg(formData) {
+            let blankRequiredFields = '';
+            for (i = 0; i < requiredFieldAPIList.length; i++) {
+                if (formData[requiredFieldAPIList[i]]) {
+                    continue;
+                } else {
+                    if (blankRequiredFields == '') {
+                        blankRequiredFields = blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    } else {
+                        blankRequiredFields = blankRequiredFields + ',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
+                    }
+
+                }
+            }
+            return blankRequiredFields;
+        }
+
+        //Base Process
+        function saveRepairProcess(saveMode) {
+            redirectMode = saveMode;
+            console.log('redirectMode' + redirectMode);
+            hiddenErrorMsgNode();
+            //1. Get repair Information from Form
+            let repairJson = getRepairInformation();
+            //2. Validate the repair field value formate, for example the email formate or phone formate
+            let validationResultMessage = validateFieldValueFormate();
+            console.log(validationResultMessage);
+            if (!validationResultMessage) {
+                //Popup error message.  - To Do After POC
+                alertErrorMessage('閭鏍煎紡杈撳叆鏈夎锛岃閲嶆柊杈撳叆锛�');
+                return
+            }
+            // Check Required Field
+            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(repairJson);
+            if (checkRequiredFieldMsgResult) {
+                alertErrorMessage('{!Input_Required_Field_Msg}' + checkRequiredFieldMsgResult);
+                return
+            }
+            //3. Prepare the payload for New PI API To AWS - To Do
+            let payloadForNewPI = getPIPayload(repairJson);
+
+            //4. repair to AWS 
+            ProcessPI(repairJson, payloadForNewPI);
+        }
+
+        //Alert Error Message
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:form:msgContent");
+            errorMsg = '閿欒锛氭棤鏁堟暟鎹��' + '\n' + errorMsg;
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'pbError';
+            unblockUI();
+        }
+
+        //Hide Error Message
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:form:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+    </script>
+    <div class="bPageTitle">
+        <div class="ptBody">
+            <div class="content">
+                <img src="/img/s.gif" alt="淇悊" class="pageTitleIcon" title="淇悊" />
+                <h1 class="pageType">淇悊缂栬緫
+                    <span class="titleSeparatingColon">:</span>
+                </h1>
+                <h2 class="pageDescription">鏂板缓淇悊</h2>
+                <div class="blank">&nbsp;</div>
+            </div>
+            <div class="links">
+                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target=repairs_edit.htm&amp;section=repairs&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
+                    title="姝ら〉闈㈢殑甯姪 锛堟柊绐楀彛锛�">
+                    <span class="helpLink">姝ら〉闈㈢殑甯姪</span>
+                    <img src="/img/s.gif" alt="" class="helpIcon" />
+                </a>
+            </div>
+        </div>
+        <div class="ptBreadcrumb"></div>
+    </div>
+    <apex:form id="form">
+        <!-- Error Msg-->
+        <apex:outputPanel id="errorMsg">
+            <apex:pageMessages id="msgContent" escape="false" />
+        </apex:outputPanel>
+        <apex:pageblock >
+            <div class="pbHeader">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
+                                <h2 class="mainTitle">淇悊缂栬緫</h2>
+                            </td>
+                            <td class="pbButton" id="topButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveRepairProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveRepairProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+            <!-- Iterate the layoutSections, which is a list of sections -->
+            <apex:repeat value="{!layoutSections}" var="layoutSection">
+                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
+
+                    <!--Each section has layoutFields, let's iterate them as well-->
+                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
+                        <apex:inputField html-data-id="{!layoutField.fieldAPI}" value="{!Repair__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
+                            required="{!layoutField.isRequired}" />
+                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
+                        </apex:pageblocksectionitem>
+                    </apex:repeat>
+
+                </apex:pageBlockSection>
+            </apex:repeat>
+            <script>
+                //Append Page
+                sfdcPage.appendToOnloadQueue(function () {
+                    //2. Query AWS Data by dataId 
+                    console.log('Mode for repair Page:' + {!isNewMode});
+                    if (!{!isNewMode}) {
+                        blockme();
+                        QueryRepairFromAWS();
+                    };
+                    document.querySelector("[data-id='OwnerId']").classList.add("disabledbutton");
+                });
+            </script>
+            <div class="pbBottomButtons">
+                <table cellspacing="0" cellpadding="0" border="0">
+                    <tbody>
+                        <tr>
+                            <td class="pbTitle">
+                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
+                            <td class="pbButtonb" id="bottomButtonRow">
+                                <input class="btn" type="Button" value="淇濆瓨" onclick="saveRepairProcess('Save')" />
+                                <input class="btn" type="Button" value="淇濆瓨骞舵柊寤�" onclick="saveRepairProcess('SaveAndNew')" />
+                                <apex:commandButton action="{!cancel}" value="鍙栨秷" />
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </apex:pageblock>
+
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewRepair.page-meta.xml b/force-app/main/default/pages/NewRepair.page-meta.xml
new file mode 100644
index 0000000..5e9380c
--- /dev/null
+++ b/force-app/main/default/pages/NewRepair.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewRepair</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/NewRepairPage.page b/force-app/main/default/pages/NewRepairPage.page
new file mode 100644
index 0000000..f654d6a
--- /dev/null
+++ b/force-app/main/default/pages/NewRepairPage.page
@@ -0,0 +1,2 @@
+<apex:page >
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/NewRepairPage.page-meta.xml b/force-app/main/default/pages/NewRepairPage.page-meta.xml
new file mode 100644
index 0000000..5dd0293
--- /dev/null
+++ b/force-app/main/default/pages/NewRepairPage.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>NewRepairPage</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/RentalApplyUploadPdf.page b/force-app/main/default/pages/RentalApplyUploadPdf.page
new file mode 100644
index 0000000..c749a53
--- /dev/null
+++ b/force-app/main/default/pages/RentalApplyUploadPdf.page
@@ -0,0 +1,190 @@
+<!-- 璇ラ〉闈㈢敤浜嶭ead瀵硅薄涓婁紶PDF锛屾湭鏉ュ鏋滆娣诲姞鍏朵粬瀵硅薄鐨勪笂浼燩DF鍔熻兘锛屽鍒惰椤甸潰锛屽皢**standardController**淇敼涓哄叾浠栧璞PI鍚嶇О鍗冲彲 -->
+<apex:page standardController="Rental_Apply__c" extensions="FileUploadController" id="page" lightningStyleSheets="true">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script>
+        var staticResources = JSON.parse('{!staticResource}');
+        var parentId = '{!parentId}';
+        var uploadUrl = staticResources.newUrl;
+        var key;
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:theForm:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'message errorM3';
+        }
+
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:theForm:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+        function getFileContent(event) {
+            var fileObject = document.getElementById("page:theForm:block:uploadSection:file");
+            var reader = new FileReader();
+            var data = reader.readAsDataURL(fileObject.files[0]);
+            debugger
+            console.log(event);
+        }
+        function getBase64(file) {
+            return new Promise((resolve, reject) => {
+                const reader = new FileReader();
+                reader.readAsDataURL(file);
+                reader.onload = () => resolve(reader.result);
+                reader.onerror = error => reject(error);
+            });
+        }
+        function disableButtonStatus() {
+            let btnNode = document.getElementById('uploadFileId');
+            btnNode.classList.add("btnDisabled");
+        }
+
+        function enableButtonStatus() {
+            let btnNode = document.getElementById('uploadFileId');
+            btnNode.classList.remove("btnDisabled");
+        }
+
+        function uploadFile() {
+            disableButtonStatus();
+            var fileObject = document.getElementById("file").files[0];
+            getBase64(fileObject).then(
+                data => {
+                    console.log(data);
+                    uploadFileToAWS(data, (fileObject.size).toString(), fileObject.name);
+                    
+                }
+            );
+        }
+        function confirmTrans(transId, isSuccess) {
+            
+            fetch(staticResources.updateUrl, {
+                method: 'POST',
+                body: JSON.stringify({ 'txId': transId, "isSuccess": isSuccess }),
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then(data => {
+                console.log("confirmTrans-" + JSON.stringify(data));
+                document.getElementById("file").files[0].name = '';
+                enableButtonStatus();
+                refreshFiles();            
+                return data.status;
+            })
+            
+        }
+        function calculateFileSize(fileObject) {
+            if (fileObject.size > 20971520) {
+                alertErrorMessage('鏂囦欢杩囧ぇ锛岃閫夋嫨灏忎簬20mb鐨勬枃浠�');
+            }
+        }
+        function uploadFileToAWS(data, size, fileName) {
+            console.log("body=" + JSON.stringify({ 'file': data, "size": size, 'fileName': fileName }));
+            
+            fetch(uploadUrl, {
+                method: 'POST',
+                body: JSON.stringify({ 'file': data, "size": size, 'fileName': fileName }),
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then(result => {
+
+                console.log("result" + JSON.stringify(result));
+                
+                if (result.success == true) {
+                    key = result.object;
+
+                    Visualforce.remoting.Manager.invokeAction(
+                        '{!$RemoteAction.FileUploadController.saveFile}',
+                        fileName, key, result.txId, parentId,
+                        function (resultvalue, event) {
+
+
+                            
+                            //2. show file list
+                            if (resultvalue.status == 'fail') {
+                                alertErrorMessage(resultvalue.message);
+                                //1. Confirm trans
+                                confirmTrans(result.txId, 0);                              
+                            } else {
+                                alertErrorMessage('涓婁紶鎴愬姛');
+                                confirmTrans(result.txId, 1);
+                            }
+                            
+                            // window.location.reload();
+                        },
+                        { escape: true }
+                    );
+                   
+                    console.log('key' + key);
+                } else {
+                    alertErrorMessage('涓婁紶澶辫触璇风◢鍚庡啀璇曪紒');
+                }
+            }).catch((error) => {
+                console.error('Error:', error);
+            })
+            debugger
+        }
+        function downPdf(fileUrl) {
+            window.open(fileUrl,'_blank');
+        }
+
+    </script>
+    <style>
+        .pdf .num {
+            width: 30%;
+        }
+
+        .pdf.name {
+            width: 30%
+        }
+
+        .pdf.downLink {
+            width: 40%
+        }
+    </style>
+    <apex:form id="theForm">
+        <apex:actionFunction name="refreshFiles" action="{!refreshFiles}" reRender="pdf,uploadSection"/>      
+        <br/>
+        <br/>
+        <apex:pageBlock id="block">
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            <apex:pageBlockSection id="uploadSection">
+                <!-- <apex:inputFile id="file" value="{!documentData.body}" filename="{!documentData.name}" /> -->
+                <input type="file" id="file" name="filename"/>
+                <input class="btn" id='uploadFileId' type="Button" value="纭涓婁紶" onclick="uploadFile()" />
+            </apex:pageBlockSection>
+        </apex:pageBlock>
+        <apex:pageBlock title="PDF鍒楄〃" id="pdf">
+            <!-- <apex:pageBlockSection > -->
+            <!-- show uploated file list -->
+            <apex:pageBlockTable value="{!fileList}" var="file" align="center" columns="3" columnsWidth="30%,30%,40%">
+                <apex:column id="name" headerValue="鏂囦欢鍚嶇О">
+                    <apex:outputLink value="/{!file.Id}" target="_blank">{!file.FileName__c}</apex:outputLink>
+                </apex:column>
+                <!-- <apex:column id="num" headerValue="鐖惰褰曢摼鎺�">
+                    <apex:outputLink value="/{!file.ParentRecordId__c}" target="_blank">{!file.ParentRecordId__c}</apex:outputLink>
+                </apex:column> -->
+                <apex:column id="previewLink" headerValue="棰勮閾炬帴">
+                    <apex:outputLink value="{!file.ViewLink__c}" target="{!file.ViewLink__c}">棰勮閾炬帴
+                    </apex:outputLink>
+                </apex:column>
+                <apex:column id="downLink" headerValue="涓嬭浇閾炬帴">
+                    <!-- <apex:outputLink value= "{!file.DownloadLink__c}" target="{!file.DownloadLink__c}">涓嬭浇閾炬帴
+                    </apex:outputLink> -->
+                    <input class="btn" id='downloadFileButton' type="Button" value="涓嬭浇" onclick="downPdf('{!file.DownloadLink__c}')" />
+                </apex:column>
+            </apex:pageBlockTable>
+            <!-- </apex:pageBlockSection> -->
+        </apex:pageBlock>
+    </apex:form>
+
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/RentalApplyUploadPdf.page-meta.xml b/force-app/main/default/pages/RentalApplyUploadPdf.page-meta.xml
new file mode 100644
index 0000000..b5f6910
--- /dev/null
+++ b/force-app/main/default/pages/RentalApplyUploadPdf.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>RentalApplyUploadPdf</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/SearchContactPage.page b/force-app/main/default/pages/SearchContactPage.page
new file mode 100644
index 0000000..b88431b
--- /dev/null
+++ b/force-app/main/default/pages/SearchContactPage.page
@@ -0,0 +1,185 @@
+<apex:page controller="SearchContactController" showHeader="false" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+
+    <head>
+    </head>
+    <style>
+        /* 1. 瀹氫箟琛ㄥ崟鏍峰紡 To Do Later*/
+
+        table {
+            border-collapse: collapse;
+            border-spacing: 0;
+            width: 98%;
+            margin-left: 5px;
+        }
+    </style>
+
+    <body id="body" class="lookupTab">
+        <script type="text/javascript">
+            var staticResources = JSON.parse('{!staticResource}');
+            var contactAWSIds = JSON.parse('{!contactAWSIds}');
+            var contactsInfo = JSON.parse('{!contactsInfo}');
+            var searchContactName = '';
+            queryLeadFromAWS();
+            function searchAWSContact(){
+                console.log('Search process!');
+                //1. reset table;             
+                resetTable();
+                //2. get contact name value 
+                searchContactName = document.getElementById('page:form:lksrch').value;
+                queryLeadFromAWS();
+
+            }
+            function resetTable(){
+                let queryResult = document.getElementById('QueryResult');
+                let table = document.getElementById('table');
+                if(table){
+                    queryResult.removeChild(table);
+                }               
+            }
+            function preparePayloadForSearchContact(){
+                let searchPayload = new Object();
+                searchPayload.dataIds = contactAWSIds;
+                searchPayload.contactName = searchContactName;
+                return JSON.stringify(searchPayload);
+            }
+            function queryLeadFromAWS() {
+                //1. Prepare the payload for contact search
+                let requestSearchPayload = preparePayloadForSearchContact();
+                console.log('request payload body:'+requestSearchPayload);
+                //2. Invoke AWS Service
+                fetch(staticResources.searchUrl, {
+                    method: 'POST',
+                    body: requestSearchPayload,
+                    headers: {
+                        'Content-Type': 'application/json',
+                        'pi-token': staticResources.token
+                    }
+                }).then((data) => {
+                    return data.json();
+                }).then((result) => {
+                    if(result.object&&result.object.length>0){
+                        initContactTable(result);
+                    }                   
+                })
+            }
+            
+            function redirectToParentPage(obj) {
+                var winMain = window.opener;
+                if (null == winMain) {
+                    winMain = window.parent.opener;
+                }
+                let value = obj.currentTarget.innerText;
+                let contactInfo = new Object();
+                contactInfo.Name = obj.currentTarget.innerText;
+                contactInfo.ContactId = obj.currentTarget.id;
+                var selectedContactNode = winMain.document.getElementById('{!JSENCODE($CurrentPage.parameters.contactId)}');
+                selectedContactNode.value = JSON.stringify(contactInfo);
+                closeWindow();
+            }
+
+            function closeWindow() {
+                var winMain = window.opener;
+                if (null == winMain) {
+                    winMain = window.parent.opener;
+                }
+                winMain.closePopupWindow();
+                window.close();
+            }
+            function refreshTable(cols,contactInfoList){
+                let myTableDiv = document.getElementById("QueryResult");
+                let table = document.createElement('TABLE');
+                table.border = '1';
+                table.id = 'table'
+                let tableBody = document.createElement('TBODY');
+                table.appendChild(tableBody);
+                let headerTR = document.createElement('TR');
+                tableBody.appendChild(headerTR);
+                for (let i = 0; i < cols.length; i++) {
+                    let td = document.createElement('TH');
+                    td.width = '75';
+                    td.appendChild(document.createTextNode(cols[i]));
+                    headerTR.appendChild(td);
+                }
+                //3. Init the AWS data
+                for (let i = 0; i < contactInfoList.length; i++) {
+                    let tr = document.createElement('TR');
+                    tableBody.appendChild(tr);
+                    let contactInfoTemp = contactInfoList[i]
+                    for (let j = 0; j < cols.length; j++) {
+                        let td = document.createElement('TD');
+                        td.width = '75';
+                        if(j == 0){
+                            td.id = contactsInfo[contactInfoTemp.AWSDataId].Id;
+                        }                        
+                        td.appendChild(document.createTextNode(contactInfoTemp[cols[j]]));
+                        if (cols[j] == 'Name') {
+                            td.addEventListener("click", function (obj) {
+                                redirectToParentPage(obj);
+                            });
+                        }
+                        tr.appendChild(td);
+                    }
+                }
+                myTableDiv.appendChild(table);
+            }
+            function initContactTable(data) {            
+                let cols = ['Name', 'Email', 'Phone'];
+                let contactInfoList = [];
+                let awsDataIds = [];
+                for(var i=0;i<data.object.length;i++){
+                    if(data.object[i].dataId){
+                        let contactInfo = new Object();
+                        contactInfo.Name = data.object[i].lastName;
+                        contactInfo.Email = data.object[i].email;
+                        contactInfo.Phone = data.object[i].phone;
+                        contactInfo.AWSDataId = data.object[i].dataId;
+                        awsDataIds.push(contactInfo.AWSDataId);
+                        contactInfo.sfRecordId = '';
+                        contactInfoList.push(contactInfo);
+                    }                    
+                }
+                let AWSIdToSFIdMapValue = {};
+                console.log(awsDataIds);
+                //Invoke SF BackEnd
+                Visualforce.remoting.Manager.invokeAction(
+                    '{!$RemoteAction.SearchContactController.searchContacts}',
+                    JSON.stringify(awsDataIds),
+                    function (result, event) {
+                        if(event.status){
+                            if(result.status = 'success'){
+                                contactsInfo = JSON.parse(result.message.replace(/(&quot\;)/g,"\""));
+                                refreshTable(cols,contactInfoList);
+                            }else{
+                                console.log('No result');
+                            }                                               
+                        }
+                    },
+                    { escape: true }
+                );
+            }
+        </script>
+        <apex:form id="form">
+            <!-- Search Filter-->
+            <div class="lookup">
+                <div class="bPageTitle">
+                    <div class="ptBody secondaryPalette">
+                        <div class="content">
+                            <img src="/img/s.gif" alt="" class="pageTitleIcon" title="" />
+                            <h1>Lookup</h1>
+                        </div>
+                    </div>
+                </div>
+                <div class="pBody">
+                    <label class="assistiveText" for="lksrch">Search</label>
+                    <apex:inputText id="lksrch" html-placeholder="{!PIPL_Search_Contact_Label}" value="{!searchKeyWord}" />
+                    <input value=" Go! " type="Button"  onclick="searchAWSContact()" styleClass="btn" />
+                    <div class="bDescription">You can use "*" as a wildcard next to other characters to improve your search results.
+                    </div>
+                </div>
+            </div>
+            <div id="QueryResult">
+            </div>
+        </apex:form>
+    </body>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/SearchContactPage.page-meta.xml b/force-app/main/default/pages/SearchContactPage.page-meta.xml
new file mode 100644
index 0000000..1fdc8c1
--- /dev/null
+++ b/force-app/main/default/pages/SearchContactPage.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>SearchContactPage</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/SearchLeadPage.page b/force-app/main/default/pages/SearchLeadPage.page
new file mode 100644
index 0000000..64275ca
--- /dev/null
+++ b/force-app/main/default/pages/SearchLeadPage.page
@@ -0,0 +1,185 @@
+<apex:page controller="SearchLeadController" showHeader="false" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+
+    <head>
+    </head>
+    <style>
+        /* 1. 瀹氫箟琛ㄥ崟鏍峰紡 To Do Later*/
+
+        table {
+            border-collapse: collapse;
+            border-spacing: 0;
+            width: 98%;
+            margin-left: 5px;
+        }
+    </style>
+
+    <body id="body" class="lookupTab">
+        <script type="text/javascript">
+            var staticResources = JSON.parse('{!staticResource}');
+            var leadAWSIds = JSON.parse('{!leadAWSIds}');
+            var leadsInfo = JSON.parse('{!leadsInfo}');
+            var searchContactName = '';
+            queryLeadFromAWS();
+            function searchAWSContact(){
+                console.log('Search process!');
+                //1. reset table;             
+                resetTable();
+                //2. get contact name value 
+                searchContactName = document.getElementById('page:form:lksrch').value;
+                queryLeadFromAWS();
+
+            }
+            function resetTable(){
+                let queryResult = document.getElementById('QueryResult');
+                let table = document.getElementById('table');
+                if(table){
+                    queryResult.removeChild(table);
+                }               
+            }
+            function preparePayloadForSearchLead(){
+                let searchPayload = new Object();
+                searchPayload.dataIds = leadAWSIds;
+                searchPayload.contactName = searchContactName;
+                return JSON.stringify(searchPayload);
+            }
+            function queryLeadFromAWS() {
+                //1. Prepare the payload for contact search
+                let requestSearchPayload = preparePayloadForSearchLead();
+                console.log('request payload body:'+requestSearchPayload);
+                //2. Invoke AWS Service
+                fetch(staticResources.searchUrl, {
+                    method: 'POST',
+                    body: requestSearchPayload,
+                    headers: {
+                        'Content-Type': 'application/json',
+                        'pi-token': staticResources.token
+                    }
+                }).then((data) => {
+                    return data.json();
+                }).then((result) => {
+                    if(result.object&&result.object.length>0){
+                        initContactTable(result);
+                    }                   
+                })
+            }
+            
+            function redirectToParentPage(obj) {
+                var winMain = window.opener;
+                if (null == winMain) {
+                    winMain = window.parent.opener;
+                }
+                let value = obj.currentTarget.innerText;
+                let leadInfo = new Object();
+                leadInfo.Name = obj.currentTarget.innerText;
+                leadInfo.LeadId = obj.currentTarget.id;
+                var selectedContactNode = winMain.document.getElementById('{!JSENCODE($CurrentPage.parameters.leadId)}');
+                selectedContactNode.value = JSON.stringify(leadInfo);
+                closeWindow();
+            }
+
+            function closeWindow() {
+                var winMain = window.opener;
+                if (null == winMain) {
+                    winMain = window.parent.opener;
+                }
+                winMain.closeLeadPopupWindow();
+                window.close();
+            }
+            function refreshTable(cols,contactInfoList){
+                let myTableDiv = document.getElementById("QueryResult");
+                let table = document.createElement('TABLE');
+                table.border = '1';
+                table.id = 'table'
+                let tableBody = document.createElement('TBODY');
+                table.appendChild(tableBody);
+                let headerTR = document.createElement('TR');
+                tableBody.appendChild(headerTR);
+                for (let i = 0; i < cols.length; i++) {
+                    let td = document.createElement('TH');
+                    td.width = '75';
+                    td.appendChild(document.createTextNode(cols[i]));
+                    headerTR.appendChild(td);
+                }
+                //3. Init the AWS data
+                for (let i = 0; i < contactInfoList.length; i++) {
+                    let tr = document.createElement('TR');
+                    tableBody.appendChild(tr);
+                    let contactInfoTemp = contactInfoList[i]
+                    for (let j = 0; j < cols.length; j++) {
+                        let td = document.createElement('TD');
+                        td.width = '75';
+                        if(j == 0){
+                            td.id = leadsInfo[contactInfoTemp.AWSDataId].Id;
+                        }                        
+                        td.appendChild(document.createTextNode(contactInfoTemp[cols[j]]));
+                        if (cols[j] == 'Name') {
+                            td.addEventListener("click", function (obj) {
+                                redirectToParentPage(obj);
+                            });
+                        }
+                        tr.appendChild(td);
+                    }
+                }
+                myTableDiv.appendChild(table);
+            }
+            function initContactTable(data) {            
+                let cols = ['Name', 'Email', 'Phone'];
+                let contactInfoList = [];
+                let awsDataIds = [];
+                for(var i=0;i<data.object.length;i++){
+                    if(data.object[i].dataId){
+                        let contactInfo = new Object();
+                        contactInfo.Name = data.object[i].lastName;
+                        contactInfo.Email = data.object[i].email;
+                        contactInfo.Phone = data.object[i].phone;
+                        contactInfo.AWSDataId = data.object[i].dataId;
+                        awsDataIds.push(contactInfo.AWSDataId);
+                        contactInfo.sfRecordId = '';
+                        contactInfoList.push(contactInfo);
+                    }                    
+                }
+                let AWSIdToSFIdMapValue = {};
+                console.log(awsDataIds);
+                //Invoke SF BackEnd
+                Visualforce.remoting.Manager.invokeAction(
+                    '{!$RemoteAction.SearchLeadController.searchLeads}',
+                    JSON.stringify(awsDataIds),
+                    function (result, event) {
+                        if(event.status){
+                            if(result.status = 'success'){
+                                leadsInfo = JSON.parse(result.message.replace(/(&quot\;)/g,"\""));
+                                refreshTable(cols,contactInfoList);
+                            }else{
+                                console.log('No result');
+                            }                                               
+                        }
+                    },
+                    { escape: true }
+                );
+            }
+        </script>
+        <apex:form id="form">
+            <!-- Search Filter-->
+            <div class="lookup">
+                <div class="bPageTitle">
+                    <div class="ptBody secondaryPalette">
+                        <div class="content">
+                            <img src="/img/s.gif" alt="" class="pageTitleIcon" title="" />
+                            <h1>Lookup</h1>
+                        </div>
+                    </div>
+                </div>
+                <div class="pBody">
+                    <label class="assistiveText" for="lksrch">Search</label>
+                    <apex:inputText id="lksrch" html-placeholder="{!PIPL_Search_Contact_Label}" value="{!searchKeyWord}" />
+                    <input value=" Go! " type="Button"  onclick="searchAWSContact()" styleClass="btn" />
+                    <div class="bDescription">You can use "*" as a wildcard next to other characters to improve your search results.
+                    </div>
+                </div>
+            </div>
+            <div id="QueryResult">
+            </div>
+        </apex:form>
+    </body>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/SearchLeadPage.page-meta.xml b/force-app/main/default/pages/SearchLeadPage.page-meta.xml
new file mode 100644
index 0000000..8b5307c
--- /dev/null
+++ b/force-app/main/default/pages/SearchLeadPage.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>SearchLeadPage</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/TenderInformationUploadPdf.page b/force-app/main/default/pages/TenderInformationUploadPdf.page
new file mode 100644
index 0000000..4937eb4
--- /dev/null
+++ b/force-app/main/default/pages/TenderInformationUploadPdf.page
@@ -0,0 +1,190 @@
+<!-- 璇ラ〉闈㈢敤浜嶭ead瀵硅薄涓婁紶PDF锛屾湭鏉ュ鏋滆娣诲姞鍏朵粬瀵硅薄鐨勪笂浼燩DF鍔熻兘锛屽鍒惰椤甸潰锛屽皢**standardController**淇敼涓哄叾浠栧璞PI鍚嶇О鍗冲彲 -->
+<apex:page standardController="Tender_information__c" extensions="FileUploadController" id="page" lightningStyleSheets="true">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script>
+        var staticResources = JSON.parse('{!staticResource}');
+        var parentId = '{!parentId}';
+        var uploadUrl = staticResources.newUrl;
+        var key;
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:theForm:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'message errorM3';
+        }
+
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:theForm:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+        function getFileContent(event) {
+            var fileObject = document.getElementById("page:theForm:block:uploadSection:file");
+            var reader = new FileReader();
+            var data = reader.readAsDataURL(fileObject.files[0]);
+            debugger
+            console.log(event);
+        }
+        function getBase64(file) {
+            return new Promise((resolve, reject) => {
+                const reader = new FileReader();
+                reader.readAsDataURL(file);
+                reader.onload = () => resolve(reader.result);
+                reader.onerror = error => reject(error);
+            });
+        }
+        function disableButtonStatus() {
+            let btnNode = document.getElementById('uploadFileId');
+            btnNode.classList.add("btnDisabled");
+        }
+
+        function enableButtonStatus() {
+            let btnNode = document.getElementById('uploadFileId');
+            btnNode.classList.remove("btnDisabled");
+        }
+
+        function uploadFile() {
+            disableButtonStatus();
+            var fileObject = document.getElementById("file").files[0];
+            getBase64(fileObject).then(
+                data => {
+                    console.log(data);
+                    uploadFileToAWS(data, (fileObject.size).toString(), fileObject.name);
+                    
+                }
+            );
+        }
+        function confirmTrans(transId, isSuccess) {
+            
+            fetch(staticResources.updateUrl, {
+                method: 'POST',
+                body: JSON.stringify({ 'txId': transId, "isSuccess": isSuccess }),
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then(data => {
+                console.log("confirmTrans-" + JSON.stringify(data));
+                document.getElementById("file").files[0].name = '';
+                enableButtonStatus();
+                refreshFiles();            
+                return data.status;
+            })
+            
+        }
+        function calculateFileSize(fileObject) {
+            if (fileObject.size > 20971520) {
+                alertErrorMessage('鏂囦欢杩囧ぇ锛岃閫夋嫨灏忎簬20mb鐨勬枃浠�');
+            }
+        }
+        function uploadFileToAWS(data, size, fileName) {
+            console.log("body=" + JSON.stringify({ 'file': data, "size": size, 'fileName': fileName }));
+            
+            fetch(uploadUrl, {
+                method: 'POST',
+                body: JSON.stringify({ 'file': data, "size": size, 'fileName': fileName }),
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then(result => {
+
+                console.log("result" + JSON.stringify(result));
+                
+                if (result.success == true) {
+                    key = result.object;
+
+                    Visualforce.remoting.Manager.invokeAction(
+                        '{!$RemoteAction.FileUploadController.saveFile}',
+                        fileName, key, result.txId, parentId,
+                        function (resultvalue, event) {
+
+
+                            
+                            //2. show file list
+                            if (resultvalue.status == 'fail') {
+                                alertErrorMessage(resultvalue.message);
+                                //1. Confirm trans
+                                confirmTrans(result.txId, 0);                              
+                            } else {
+                                alertErrorMessage('涓婁紶鎴愬姛');
+                                confirmTrans(result.txId, 1);
+                            }
+                            
+                            // window.location.reload();
+                        },
+                        { escape: true }
+                    );
+                   
+                    console.log('key' + key);
+                } else {
+                    alertErrorMessage('涓婁紶澶辫触璇风◢鍚庡啀璇曪紒');
+                }
+            }).catch((error) => {
+                console.error('Error:', error);
+            })
+            debugger
+        }
+        function downPdf(fileUrl) {
+            window.open(fileUrl,'_blank');
+        }
+
+    </script>
+    <style>
+        .pdf .num {
+            width: 30%;
+        }
+
+        .pdf.name {
+            width: 30%
+        }
+
+        .pdf.downLink {
+            width: 40%
+        }
+    </style>
+    <apex:form id="theForm">
+        <apex:actionFunction name="refreshFiles" action="{!refreshFiles}" reRender="pdf,uploadSection"/>      
+        <br/>
+        <br/>
+        <apex:pageBlock id="block">
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            <apex:pageBlockSection id="uploadSection">
+                <!-- <apex:inputFile id="file" value="{!documentData.body}" filename="{!documentData.name}" /> -->
+                <input type="file" id="file" name="filename"/>
+                <input class="btn" id='uploadFileId' type="Button" value="纭涓婁紶" onclick="uploadFile()" />
+            </apex:pageBlockSection>
+        </apex:pageBlock>
+        <apex:pageBlock title="PDF鍒楄〃" id="pdf">
+            <!-- <apex:pageBlockSection > -->
+            <!-- show uploated file list -->
+            <apex:pageBlockTable value="{!fileList}" var="file" align="center" columns="3" columnsWidth="30%,30%,40%">
+                <apex:column id="name" headerValue="鏂囦欢鍚嶇О">
+                    <apex:outputLink value="/{!file.Id}" target="_blank">{!file.FileName__c}</apex:outputLink>
+                </apex:column>
+                <!-- <apex:column id="num" headerValue="鐖惰褰曢摼鎺�">
+                    <apex:outputLink value="/{!file.ParentRecordId__c}" target="_blank">{!file.ParentRecordId__c}</apex:outputLink>
+                </apex:column> -->
+                <apex:column id="previewLink" headerValue="棰勮閾炬帴">
+                    <apex:outputLink value="{!file.ViewLink__c}" target="{!file.ViewLink__c}">棰勮閾炬帴
+                    </apex:outputLink>
+                </apex:column>
+                <apex:column id="downLink" headerValue="涓嬭浇閾炬帴">
+                    <!-- <apex:outputLink value= "{!file.DownloadLink__c}" target="{!file.DownloadLink__c}">涓嬭浇閾炬帴
+                    </apex:outputLink> -->
+                    <input class="btn" id='downloadFileButton' type="Button" value="涓嬭浇" onclick="downPdf('{!file.DownloadLink__c}')" />
+                </apex:column>
+            </apex:pageBlockTable>
+            <!-- </apex:pageBlockSection> -->
+        </apex:pageBlock>
+    </apex:form>
+
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/TenderInformationUploadPdf.page-meta.xml b/force-app/main/default/pages/TenderInformationUploadPdf.page-meta.xml
new file mode 100644
index 0000000..22f22e5
--- /dev/null
+++ b/force-app/main/default/pages/TenderInformationUploadPdf.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>TenderInformationUploadPdf</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/TestClass.page b/force-app/main/default/pages/TestClass.page
new file mode 100644
index 0000000..f654d6a
--- /dev/null
+++ b/force-app/main/default/pages/TestClass.page
@@ -0,0 +1,2 @@
+<apex:page >
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/TestClass.page-meta.xml b/force-app/main/default/pages/TestClass.page-meta.xml
new file mode 100644
index 0000000..aef9406
--- /dev/null
+++ b/force-app/main/default/pages/TestClass.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>TestClass</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/TestVfPage.page b/force-app/main/default/pages/TestVfPage.page
new file mode 100644
index 0000000..b88cd2d
--- /dev/null
+++ b/force-app/main/default/pages/TestVfPage.page
@@ -0,0 +1,3 @@
+<apex:page id="page" sidebar="false" showHeader="false"  standardController="Inquiry_form__c" extensions="TestController">
+    {!LookUpOverrideFieldsMapJson}
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/TestVfPage.page-meta.xml b/force-app/main/default/pages/TestVfPage.page-meta.xml
new file mode 100644
index 0000000..5363745
--- /dev/null
+++ b/force-app/main/default/pages/TestVfPage.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>TestVfPage</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/UploadPdf.page b/force-app/main/default/pages/UploadPdf.page
new file mode 100644
index 0000000..431ef8e
--- /dev/null
+++ b/force-app/main/default/pages/UploadPdf.page
@@ -0,0 +1,190 @@
+<!-- 璇ラ〉闈㈢敤浜嶭ead瀵硅薄涓婁紶PDF锛屾湭鏉ュ鏋滆娣诲姞鍏朵粬瀵硅薄鐨勪笂浼燩DF鍔熻兘锛屽鍒惰椤甸潰锛屽皢**standardController**淇敼涓哄叾浠栧璞PI鍚嶇О鍗冲彲 -->
+<apex:page standardController="Lead" extensions="FileUploadController" id="page" lightningStyleSheets="true">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <script>
+        var staticResources = JSON.parse('{!staticResource}');
+        var parentId = '{!parentId}';
+        var uploadUrl = staticResources.newUrl;
+        var key;
+
+        function alertErrorMessage(errorMsg) {
+            let errorMsgNode = document.getElementById("page:theForm:block:msgContent");
+            errorMsgNode.innerText = errorMsg;
+            errorMsgNode.className = 'message errorM3';
+        }
+
+        function hiddenErrorMsgNode() {
+            let errorMsgNode = document.getElementById("page:theForm:block:msgContent");
+            errorMsgNode.innerText = '';
+            errorMsgNode.className = '';
+        }
+        function getFileContent(event) {
+            var fileObject = document.getElementById("page:theForm:block:uploadSection:file");
+            var reader = new FileReader();
+            var data = reader.readAsDataURL(fileObject.files[0]);
+            debugger
+            console.log(event);
+        }
+        function getBase64(file) {
+            return new Promise((resolve, reject) => {
+                const reader = new FileReader();
+                reader.readAsDataURL(file);
+                reader.onload = () => resolve(reader.result);
+                reader.onerror = error => reject(error);
+            });
+        }
+        function disableButtonStatus() {
+            let btnNode = document.getElementById('uploadFileId');
+            btnNode.classList.add("btnDisabled");
+        }
+
+        function enableButtonStatus() {
+            let btnNode = document.getElementById('uploadFileId');
+            btnNode.classList.remove("btnDisabled");
+        }
+
+        function uploadFile() {
+            disableButtonStatus();
+            var fileObject = document.getElementById("file").files[0];
+            getBase64(fileObject).then(
+                data => {
+                    console.log(data);
+                    uploadFileToAWS(data, (fileObject.size).toString(), fileObject.name);
+                    
+                }
+            );
+        }
+        function confirmTrans(transId, isSuccess) {
+            
+            fetch(staticResources.updateUrl, {
+                method: 'POST',
+                body: JSON.stringify({ 'txId': transId, "isSuccess": isSuccess }),
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then(data => {
+                console.log("confirmTrans-" + JSON.stringify(data));
+                document.getElementById("file").files[0].name = '';
+                enableButtonStatus();
+                refreshFiles();            
+                return data.status;
+            })
+            
+        }
+        function calculateFileSize(fileObject) {
+            if (fileObject.size > 20971520) {
+                alertErrorMessage('鏂囦欢杩囧ぇ锛岃閫夋嫨灏忎簬20mb鐨勬枃浠�');
+            }
+        }
+        function uploadFileToAWS(data, size, fileName) {
+            console.log("body=" + JSON.stringify({ 'file': data, "size": size, 'fileName': fileName }));
+            
+            fetch(uploadUrl, {
+                method: 'POST',
+                body: JSON.stringify({ 'file': data, "size": size, 'fileName': fileName }),
+                headers: {
+                    'Content-Type': 'application/json',
+                    'pi-token': staticResources.token
+                }
+            }).then((data) => {
+                return data.json();
+            }).then(result => {
+
+                console.log("result" + JSON.stringify(result));
+                
+                if (result.success == true) {
+                    key = result.object;
+
+                    Visualforce.remoting.Manager.invokeAction(
+                        '{!$RemoteAction.FileUploadController.saveFile}',
+                        fileName, key, result.txId, parentId,
+                        function (resultvalue, event) {
+
+
+                            
+                            //2. show file list
+                            if (resultvalue.status == 'fail') {
+                                alertErrorMessage(resultvalue.message);
+                                //1. Confirm trans
+                                confirmTrans(result.txId, 0);                              
+                            } else {
+                                alertErrorMessage('涓婁紶鎴愬姛');
+                                confirmTrans(result.txId, 1);
+                            }
+                            
+                            // window.location.reload();
+                        },
+                        { escape: true }
+                    );
+                   
+                    console.log('key' + key);
+                } else {
+                    alertErrorMessage('涓婁紶澶辫触璇风◢鍚庡啀璇曪紒');
+                }
+            }).catch((error) => {
+                console.error('Error:', error);
+            })
+            debugger
+        }
+        function downPdf(fileUrl) {
+            window.open(fileUrl,'_blank');
+        }
+
+    </script>
+    <style>
+        .pdf .num {
+            width: 30%;
+        }
+
+        .pdf.name {
+            width: 30%
+        }
+
+        .pdf.downLink {
+            width: 40%
+        }
+    </style>
+    <apex:form id="theForm">
+        <apex:actionFunction name="refreshFiles" action="{!refreshFiles}" reRender="pdf,uploadSection"/>      
+        <br/>
+        <br/>
+        <apex:pageBlock id="block">
+            <div style="text-align: center;">
+                <apex:outputPanel id="errorMsg">
+                    <apex:pageMessages id="msgContent" escape="false" />
+                </apex:outputPanel>
+            </div>
+            <apex:pageBlockSection id="uploadSection">
+                <!-- <apex:inputFile id="file" value="{!documentData.body}" filename="{!documentData.name}" /> -->
+                <input type="file" id="file" name="filename"/>
+                <input class="btn" id='uploadFileId' type="Button" value="纭涓婁紶" onclick="uploadFile()" />
+            </apex:pageBlockSection>
+        </apex:pageBlock>
+        <apex:pageBlock title="PDF鍒楄〃" id="pdf">
+            <!-- <apex:pageBlockSection > -->
+            <!-- show uploated file list -->
+            <apex:pageBlockTable value="{!fileList}" var="file" align="center" columns="3" columnsWidth="30%,30%,40%">
+                <apex:column id="name" headerValue="鏂囦欢鍚嶇О">
+                    <apex:outputLink value="/{!file.Id}" target="_blank">{!file.FileName__c}</apex:outputLink>
+                </apex:column>
+                <!-- <apex:column id="num" headerValue="鐖惰褰曢摼鎺�">
+                    <apex:outputLink value="/{!file.ParentRecordId__c}" target="_blank">{!file.ParentRecordId__c}</apex:outputLink>
+                </apex:column> -->
+                <apex:column id="previewLink" headerValue="棰勮閾炬帴">
+                    <apex:outputLink value="{!file.ViewLink__c}" target="{!file.ViewLink__c}">棰勮閾炬帴
+                    </apex:outputLink>
+                </apex:column>
+                <apex:column id="downLink" headerValue="涓嬭浇閾炬帴">
+                    <!-- <apex:outputLink value= "{!file.DownloadLink__c}" target="{!file.DownloadLink__c}">涓嬭浇閾炬帴
+                    </apex:outputLink> -->
+                    <input class="btn" id='downloadFileButton' type="Button" value="涓嬭浇" onclick="downPdf('{!file.DownloadLink__c}')" />
+                </apex:column>
+            </apex:pageBlockTable>
+            <!-- </apex:pageBlockSection> -->
+        </apex:pageBlock>
+    </apex:form>
+
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/UploadPdf.page-meta.xml b/force-app/main/default/pages/UploadPdf.page-meta.xml
new file mode 100644
index 0000000..6226c0b
--- /dev/null
+++ b/force-app/main/default/pages/UploadPdf.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>UploadPdf</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewASEActivityDecryptInfo.page b/force-app/main/default/pages/ViewASEActivityDecryptInfo.page
new file mode 100644
index 0000000..2e1826e
--- /dev/null
+++ b/force-app/main/default/pages/ViewASEActivityDecryptInfo.page
@@ -0,0 +1,85 @@
+<apex:page standardController="ASEActivity__c" extensions="NewAndEditASEActivityController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!ASEActivity__c[encryptedAPI]}" />
+                </apex:repeat>
+                <apex:outputField html-data-id="ReporterASE__c}" title="{!ApiPrefix}ReporterASE__c" value="{!ASEActivity__c['ReporterASE__c']}" />
+            </apex:pageBlockSection>
+            <script>
+                var config = {
+                    SobjectName : "{!SobjectName}",
+                    ApiPrefix:"{!ApiPrefix}",
+                    AWSToSobjectMap:{!AWSToSobjectMapJson},
+                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
+                };
+                var staticResources = JSON.parse('{!staticResource}');
+                var staticResourcesContact = JSON.parse('{!staticResourceContact}');
+                function QuerySobjectFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                
+                function QueryContactFromAWS() {
+                    if('{!contactAWS}' != null && '{!contactAWS}' != ''){
+                        console.log('staticResourcesContact .queryUrl' + staticResourcesContact .queryUrl);  
+                        AWSService.query(staticResourcesContact .queryUrl, '{!contactAWS}', queryContactBack, staticResources.token);
+                    }
+                }
+                
+                var queryContactBack = function queryContactBack(data){
+                    if(!data.object){
+                        console.log('data.object is ' + data.object);
+                        return;
+                    }
+                    
+                    let t = "[title='"+config.ApiPrefix+"ReporterASE__c']";
+                    let ele = document.querySelector(t);
+                    ele.innerHTML = data.object.lastName;
+                    ele.title='';
+
+                }
+                
+                function QuerySobjectFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                
+                var queryBack = function queryBack(data) {
+                    if(!data.object){
+                        console.log('data.object is ' + data.object);
+                        return;
+                    }
+
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
+                        let ele = document.querySelector(t);
+                        console.log(ele);
+                        if(ele){
+                            ele.title = '';
+                            if(data.object.hasOwnProperty(f)){
+                                ele.innerHTML = data.object[f];
+                            }
+                            else{
+                                console.log(f + 'is not in data.object');
+                            }
+                        }else{
+                            console.log('selector='+t+' not found');
+                        }
+                        
+                    }
+                    // 褰撲笉鑳借嚜鍔ㄦ纭浛鎹㈠姞瀵嗘暟鎹椂闇�瑕佸湪姝ゅ娣诲姞js锛岀‖缂栫爜澶勭悊
+                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '濮撳悕'
+                    QuerySobjectFromAWS();
+                    QueryContactFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewASEActivityDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewASEActivityDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..35fba37
--- /dev/null
+++ b/force-app/main/default/pages/ViewASEActivityDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewASEActivityDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewAddressDecryptInfo.page b/force-app/main/default/pages/ViewAddressDecryptInfo.page
new file mode 100644
index 0000000..5b8b014
--- /dev/null
+++ b/force-app/main/default/pages/ViewAddressDecryptInfo.page
@@ -0,0 +1,32 @@
+<apex:page standardController="Address__c" extensions="NewAndEditAddressController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!encryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" value="{!Address__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                // AWSService.sfSessionId = '{!GETSESSIONID()}';
+                var staticResources = JSON.parse('{!staticResource}');
+                function QueryAddressFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    document.querySelector("[id='page:form:pageBlock:pageBlockSection:j_id1:0:j_id2']").innerHTML = data.object.telephone;
+                    document.querySelector("[data-id='ZipCode__c']").innerHTML = data.object.zipCode;
+                    document.querySelector("[data-id='Detailed_Address__c']").innerHTML = data.object.detailedAddress;
+                    
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '濮撳悕'
+                    QueryAddressFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewAddressDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewAddressDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..0253771
--- /dev/null
+++ b/force-app/main/default/pages/ViewAddressDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewAddressDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewAgencyContactDecryptInfo.page b/force-app/main/default/pages/ViewAgencyContactDecryptInfo.page
new file mode 100644
index 0000000..2584e36
--- /dev/null
+++ b/force-app/main/default/pages/ViewAgencyContactDecryptInfo.page
@@ -0,0 +1,56 @@
+<apex:page standardController="Agency_Contact__c" extensions="NewAndEditAgencyContactController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!Agency_Contact__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                var config = {
+                    SobjectName : "{!SobjectName}",
+                    ApiPrefix:"{!ApiPrefix}",
+                    AWSToSobjectMap:{!AWSToSobjectMapJson},
+                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
+                };
+                var staticResources = JSON.parse('{!staticResource}');
+                function QuerySobjectFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    if(!data.object){
+                        console.log('data.object is ' + data.object);
+                        return;
+                    }
+
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
+                        let ele = document.querySelector(t);
+                        if(ele){
+                            ele.title = '';
+                            if(data.object.hasOwnProperty(f)){
+                                ele.innerHTML = data.object[f];
+                            }
+                            else{
+                                console.log(f + 'is not in data.object');
+                            }
+                        }else{
+                            console.log('selector='+t+' not found');
+                        }
+                        
+                    }
+                    // 褰撲笉鑳借嚜鍔ㄦ纭浛鎹㈠姞瀵嗘暟鎹椂闇�瑕佸湪姝ゅ娣诲姞js锛岀‖缂栫爜澶勭悊
+                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '濮撳悕'
+                    QuerySobjectFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewAgencyContactDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewAgencyContactDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..22e6f31
--- /dev/null
+++ b/force-app/main/default/pages/ViewAgencyContactDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewAgencyContactDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewCaseDecryptInfo.page b/force-app/main/default/pages/ViewCaseDecryptInfo.page
new file mode 100644
index 0000000..f523dec
--- /dev/null
+++ b/force-app/main/default/pages/ViewCaseDecryptInfo.page
@@ -0,0 +1,30 @@
+<apex:page standardController="Case" extensions="NewAndEditCaseController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!encryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" value="{!Case[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                var staticResources = JSON.parse('{!staticResource}');
+                function QueryCaseFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    document.querySelector("[id='page:form:pageBlock:pageBlockSection:j_id1:0:j_id2']").innerHTML = data.object.cicTelephone;
+                    document.querySelector("[data-id='CASE_CUSTOMER__c']").innerHTML = data.object.caseCustomer;
+                    document.querySelector("[data-id='Customer_manual__c']").innerHTML = data.object.customerManual;
+                    
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '濮撳悕'
+                    QueryCaseFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewCaseDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewCaseDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..56646a0
--- /dev/null
+++ b/force-app/main/default/pages/ViewCaseDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewCaseDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page b/force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page
new file mode 100644
index 0000000..2b24f9d
--- /dev/null
+++ b/force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page
@@ -0,0 +1,26 @@
+<apex:page standardController="Consum_Apply_Equipment_Set_Detail__c" extensions="NewConsumApplyEquipSetDetailController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!encryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" value="{!Consum_Apply_Equipment_Set_Detail__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                var staticResources = JSON.parse('{!staticResource}');
+                function QueryConsumApplyFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    document.querySelector("[id='page:form:pageBlock:pageBlockSection:j_id1:0:j_id2']").innerHTML = data.object.trialUser;
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue');
+                    QueryConsumApplyFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page-meta.xml b/force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page-meta.xml
new file mode 100644
index 0000000..3fa8d80
--- /dev/null
+++ b/force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewConsumApplyEquipmentSetDetailDecrypt</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewContactDecryptInfo.page b/force-app/main/default/pages/ViewContactDecryptInfo.page
new file mode 100644
index 0000000..5ac4ce9
--- /dev/null
+++ b/force-app/main/default/pages/ViewContactDecryptInfo.page
@@ -0,0 +1,68 @@
+<apex:page standardController="Contact" extensions="NewAndEditContactController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!Contact[encryptedAPI]}" />
+                </apex:repeat>
+                <apex:outputText label="缁熶竴鐢ㄦ埛Id" id="viewContactId"  value="" />
+            </apex:pageBlockSection>
+            <script>
+                var config = {
+                    SobjectName : "{!SobjectName}",
+                    ApiPrefix:"{!ApiPrefix}",
+                    AWSToSobjectMap:{!AWSToSobjectMapJson},
+                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
+                };
+                var staticResources = JSON.parse('{!staticResource}');
+                console.log(staticResources)
+                function QuerySobjectFromAWS() {
+                    console.log('AWSDataId:'+'{!AWSDataId}')
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                    //鏌ユ壘viewContactId
+                    AWSService.query(staticResources.viewUnifiedContactUrl, '{!unifiedIContactID}', queryBackContactId, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    if(!data.object){
+                        console.log('data.object is ' + data.object);
+                        return;
+                    }
+
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
+                        let ele = document.querySelector(t);
+                        if(ele){
+                            ele.title = '';
+                            if(data.object.hasOwnProperty(f)){
+                                ele.innerHTML = data.object[f];
+                            }
+                            else{
+                                console.log(f + 'is not in data.object');
+                            }
+                        }else{
+                            console.log('selector='+t+' not found');
+                        }
+                        
+                    }
+                    // 褰撲笉鑳借嚜鍔ㄦ纭浛鎹㈠姞瀵嗘暟鎹椂闇�瑕佸湪姝ゅ娣诲姞js锛岀‖缂栫爜澶勭悊
+                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                };
+                var queryBackContactId = function queryBackContactId(data) {
+                    console.log('queryBackContactId:')
+                    console.log(JSON.stringify(data))
+                    if(data.status == '0'){
+                        document.getElementById('page:form:pageBlock:pageBlockSection:viewContactId').innerText = data.object.viewContactId;
+                    }
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '濮撳悕'
+                    QuerySobjectFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewContactDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewContactDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..e140d84
--- /dev/null
+++ b/force-app/main/default/pages/ViewContactDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewContactDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewDecryptConsumApply.page b/force-app/main/default/pages/ViewDecryptConsumApply.page
new file mode 100644
index 0000000..944b835
--- /dev/null
+++ b/force-app/main/default/pages/ViewDecryptConsumApply.page
@@ -0,0 +1,27 @@
+<apex:page standardController="Consum_Apply__c" extensions="NewConsumApplyController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!encryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" value="{!Consum_Apply__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                var staticResources = JSON.parse('{!staticResource}');
+                function QueryConsumApplyFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    document.querySelector("[id='page:form:pageBlock:pageBlockSection:j_id1:0:j_id2']").innerHTML = data.object.phoneNumber;
+                    document.querySelector("[data-id='direct_shippment_address__c']").innerHTML = data.object.directShippmentAddress;
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue');
+                    QueryConsumApplyFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewDecryptConsumApply.page-meta.xml b/force-app/main/default/pages/ViewDecryptConsumApply.page-meta.xml
new file mode 100644
index 0000000..f5dd129
--- /dev/null
+++ b/force-app/main/default/pages/ViewDecryptConsumApply.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewDecryptConsumApply</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewEventDecryptInfo.page b/force-app/main/default/pages/ViewEventDecryptInfo.page
new file mode 100644
index 0000000..043e210
--- /dev/null
+++ b/force-app/main/default/pages/ViewEventDecryptInfo.page
@@ -0,0 +1,93 @@
+<apex:page standardController="Event" extensions="NewAndEditEventController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!Event[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                // var config = {
+                //     SobjectName : "{!SobjectName}",
+                //     ApiPrefix:"{!ApiPrefix}",
+                //     AWSToSobjectMap:{!AWSToSobjectMapJson},
+                //     AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+                //     AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
+                // };
+                AWSService.sfSessionId = '{!GETSESSIONID()}';
+                var staticResources = JSON.parse('{!staticResources}');
+                var contactAWSIds = JSON.parse('{!contactAWSIds}'); //AWS ContactId
+                var sfIdToContactInfo = {};
+
+                function preparePayloadForSearchContact(){
+                    let searchPayload = new Object();
+                    searchPayload.dataIds = contactAWSIds;
+                    searchPayload.contactName = '';
+                    console.log('searchPayload: ' + JSON.stringify(searchPayload));
+                    return JSON.stringify(searchPayload);
+                }
+
+                function searchContactAll(){
+                    let data = preparePayloadForSearchContact();
+                    let searchCallBack = function searchCallBack(result){
+                        let contacts = result.object;
+                        console.log('contacts: ' + contacts);
+                        if(contacts == null){
+                            return;
+                        }
+                        //璧嬪�肩粰鍓嶇椤甸潰
+                        for(var i=0;i<contacts.length;i++){
+                            // let temp = {}
+                            // temp.lastName = contacts[i].lastName?contacts[i].lastName:'';
+                            // console.log('temp.lastName: ' + temp.lastName);
+                            console.log('contacts[i].lastName?contacts[i].lastName:' + contacts[i].lastName?contacts[i].lastName:'');
+                            document.querySelector("[data-id='Visitor" + (i + 1) + "__c']").innerHTML = contacts[i].lastName?contacts[i].lastName:'';
+                        //     if(contacts[i].sfRecordId){
+                        //         sfIdToContactInfo[contacts[i].sfRecordId] = temp;
+                        //     }
+                        }
+                        // console.log('AWS Result:' + JSON.stringify(sfIdToContactInfo));
+                    };
+                    AWSService.search(staticResources.searchUrl,data,searchCallBack,staticResources.token);
+                }
+                // function QuerySobjectFromAWS() {
+                //     AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                // }
+                // var queryBack = function queryBack(data) {
+                //     if(!data.object){
+                //         console.log('data.object is ' + data.object);
+                //         return;
+                //     }
+
+                //     for(let f in config.AWSToSobjectNonEncryptedMap){
+                //         let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
+                //         let ele = document.querySelector(t);
+                //         if(ele){
+                //             ele.title = '';
+                //             if(data.object.hasOwnProperty(f)){
+                //                 ele.innerHTML = data.object[f];
+                //             }
+                //             else{
+                //                 console.log(f + 'is not in data.object');
+                //             }
+                //         }else{
+                //             console.log('selector='+t+' not found');
+                //         }
+                        
+                //     }
+                //     // 褰撲笉鑳借嚜鍔ㄦ纭浛鎹㈠姞瀵嗘暟鎹椂闇�瑕佸湪姝ゅ娣诲姞js锛岀‖缂栫爜澶勭悊
+                //     // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                // };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '濮撳悕'
+                    //QuerySobjectFromAWS();
+                    searchContactAll();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewEventDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewEventDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..a6a5318
--- /dev/null
+++ b/force-app/main/default/pages/ViewEventDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewEventDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewInquiryFormDecryptInfo.page b/force-app/main/default/pages/ViewInquiryFormDecryptInfo.page
new file mode 100644
index 0000000..91fedea
--- /dev/null
+++ b/force-app/main/default/pages/ViewInquiryFormDecryptInfo.page
@@ -0,0 +1,56 @@
+<apex:page standardController="Inquiry_form__c" extensions="NewAndEditInquiryFormController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!Inquiry_form__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                var config = {
+                    SobjectName : "{!SobjectName}",
+                    ApiPrefix:"{!ApiPrefix}",
+                    AWSToSobjectMap:{!AWSToSobjectMapJson},
+                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
+                };
+                var staticResources = JSON.parse('{!staticResource}');
+                function QuerySobjectFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    if(!data.object){
+                        console.log('data.object is ' + data.object);
+                        return;
+                    }
+
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
+                        let ele = document.querySelector(t);
+                        if(ele){
+                            ele.title = '';
+                            if(data.object.hasOwnProperty(f)){
+                                ele.innerHTML = data.object[f];
+                            }
+                            else{
+                                console.log(f + 'is not in data.object');
+                            }
+                        }else{
+                            console.log('selector='+t+' not found');
+                        }
+                        
+                    }
+                    // 褰撲笉鑳借嚜鍔ㄦ纭浛鎹㈠姞瀵嗘暟鎹椂闇�瑕佸湪姝ゅ娣诲姞js锛岀‖缂栫爜澶勭悊
+                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '濮撳悕'
+                    QuerySobjectFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewInquiryFormDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewInquiryFormDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..01852b9
--- /dev/null
+++ b/force-app/main/default/pages/ViewInquiryFormDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewInquiryFormDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewInspectionReportDecryptInfo.page b/force-app/main/default/pages/ViewInspectionReportDecryptInfo.page
new file mode 100644
index 0000000..05bd695
--- /dev/null
+++ b/force-app/main/default/pages/ViewInspectionReportDecryptInfo.page
@@ -0,0 +1,56 @@
+<apex:page standardController="Inspection_Report__c" extensions="NewAndEditInspectionReportController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!Inspection_Report__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                var config = {
+                    SobjectName : "{!SobjectName}",
+                    ApiPrefix:"{!ApiPrefix}",
+                    AWSToSobjectMap:{!AWSToSobjectMapJson},
+                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
+                };
+                var staticResources = JSON.parse('{!staticResource}');
+                function QuerySobjectFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    if(!data.object){
+                        console.log('data.object is ' + data.object);
+                        return;
+                    }
+
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
+                        let ele = document.querySelector(t);
+                        if(ele){
+                            ele.title = '';
+                            if(data.object.hasOwnProperty(f)){
+                                ele.innerHTML = data.object[f];
+                            }
+                            else{
+                                console.log(f + 'is not in data.object');
+                            }
+                        }else{
+                            console.log('selector='+t+' not found');
+                        }
+                        
+                    }
+                    // 褰撲笉鑳借嚜鍔ㄦ纭浛鎹㈠姞瀵嗘暟鎹椂闇�瑕佸湪姝ゅ娣诲姞js锛岀‖缂栫爜澶勭悊
+                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '濮撳悕'
+                    QuerySobjectFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewInspectionReportDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewInspectionReportDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..55ec800
--- /dev/null
+++ b/force-app/main/default/pages/ViewInspectionReportDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>53.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewInspectionReportDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewLeadDecryptInfo.page b/force-app/main/default/pages/ViewLeadDecryptInfo.page
new file mode 100644
index 0000000..21ae11c
--- /dev/null
+++ b/force-app/main/default/pages/ViewLeadDecryptInfo.page
@@ -0,0 +1,32 @@
+<apex:page standardController="Lead" extensions="NewAndEditLeadController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!encryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" value="{!Lead[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                AWSService.sfSessionId = '{!GETSESSIONID()}';
+                var staticResources = JSON.parse('{!staticResource}');
+                function QueryLeadFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    document.querySelector("[data-id='LastName']").innerHTML = data.object.lastName;
+                    document.querySelector("[id='page:form:pageBlock:pageBlockSection:j_id2:0:j_id3']").innerHTML =  data.object.phone;
+                    document.querySelector("[data-id='Email']").innerHTML = data.object.email;
+                    
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '濮撳悕'
+                    QueryLeadFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewLeadDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewLeadDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..aa6ca52
--- /dev/null
+++ b/force-app/main/default/pages/ViewLeadDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewLeadDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewListOfConsumablesDecrypt.page b/force-app/main/default/pages/ViewListOfConsumablesDecrypt.page
new file mode 100644
index 0000000..f654d6a
--- /dev/null
+++ b/force-app/main/default/pages/ViewListOfConsumablesDecrypt.page
@@ -0,0 +1,2 @@
+<apex:page >
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewListOfConsumablesDecrypt.page-meta.xml b/force-app/main/default/pages/ViewListOfConsumablesDecrypt.page-meta.xml
new file mode 100644
index 0000000..bc48055
--- /dev/null
+++ b/force-app/main/default/pages/ViewListOfConsumablesDecrypt.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewListOfConsumablesDecrypt</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewOnCallDecrypt.page b/force-app/main/default/pages/ViewOnCallDecrypt.page
new file mode 100644
index 0000000..88fb2a1
--- /dev/null
+++ b/force-app/main/default/pages/ViewOnCallDecrypt.page
@@ -0,0 +1,27 @@
+<apex:page standardController="On_Call__c" extensions="OnCallController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!encryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" value="{!On_Call__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                var staticResources = JSON.parse('{!staticResource}');
+                function QueryConsumApplyFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    document.querySelector("[id='page:form:pageBlock:pageBlockSection:j_id1:0:j_id2']").innerHTML = data.object.callerPhone;
+                    document.querySelector("[data-id='Responsible_Person_HP__c']").innerHTML = data.object.responsiblePersonHP;
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue');
+                    QueryConsumApplyFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewOnCallDecrypt.page-meta.xml b/force-app/main/default/pages/ViewOnCallDecrypt.page-meta.xml
new file mode 100644
index 0000000..4972bde
--- /dev/null
+++ b/force-app/main/default/pages/ViewOnCallDecrypt.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewOnCallDecrypt</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewParticipantsDecryptInfo.page b/force-app/main/default/pages/ViewParticipantsDecryptInfo.page
new file mode 100644
index 0000000..2068804
--- /dev/null
+++ b/force-app/main/default/pages/ViewParticipantsDecryptInfo.page
@@ -0,0 +1,28 @@
+<apex:page standardController="CampaignMember__c" extensions="ViewParticipantsController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <apex:outputText label="缁熶竴鐢ㄦ埛Id" id="viewContactId"  value="" />
+            </apex:pageBlockSection>
+            <script>
+                
+                var staticResources = JSON.parse('{!staticResourceContact}');
+                console.log(staticResources)
+                function QuerySobjectFromAWS() {
+                    //鏌ユ壘viewContactId
+                    AWSService.query(staticResources.viewUnifiedContactUrl, '948578480969220097', queryBackContactId, staticResources.token);
+                }
+                var queryBackContactId = function queryBackContactId(data) {
+                    console.log(JSON.stringify(data))
+                    if(data.status == '0'){
+                        document.getElementById('page:form:pageBlock:pageBlockSection:viewContactId').innerText = data.object.viewContactId;
+                    }
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    QuerySobjectFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewParticipantsDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewParticipantsDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..7f43a96
--- /dev/null
+++ b/force-app/main/default/pages/ViewParticipantsDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewParticipantsDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewQISReportDecryptInfo.page b/force-app/main/default/pages/ViewQISReportDecryptInfo.page
new file mode 100644
index 0000000..f3c197d
--- /dev/null
+++ b/force-app/main/default/pages/ViewQISReportDecryptInfo.page
@@ -0,0 +1,65 @@
+<apex:page standardController="QIS_Report__c" extensions="NewAndEditQISController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!encryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!QIS_Report__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                var config = {
+                    SobjectName : "{!SobjectName}",
+                    ApiPrefix:"{!ApiPrefix}",
+                    AWSToSobjectMap:{!AWSToSobjectMapJson},
+                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
+                };
+                var staticResources = JSON.parse('{!staticResource}');
+                function QuerySobjectFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    for(let f in config.AWSToSobjectMap){
+                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectMap[f]+"']";
+                        let ele = document.querySelector(t);
+                        if(ele){
+                            ele.title = '';
+                            if(data.object.hasOwnProperty(f)){
+                                ele.innerHTML = data.object[f];
+                            }
+                            else{
+                                console.log(f + 'is not in data.object');
+                            }
+                        }else{
+                            console.log('selector='+t+' not found');
+                        }
+                        
+                    }
+
+                    for(let f in config.AWSToSobjectEncryptedMap){
+                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectMap[f]+"']";
+                        let ele = document.querySelector(t);
+                        if(ele){
+                            ele.title = '';
+                            if(data.object.hasOwnProperty(f)){
+                                ele.innerHTML = data.object[f];
+                            }
+                            else{
+                                console.log(f + 'is not in data.object');
+                            }
+                        }else{
+                            console.log('selector='+t+' not found');
+                        }
+                        
+                    }
+                    
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    QuerySobjectFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewQISReportDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewQISReportDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..cc55e06
--- /dev/null
+++ b/force-app/main/default/pages/ViewQISReportDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewQISReportDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewRentalApplyDecrypt.page b/force-app/main/default/pages/ViewRentalApplyDecrypt.page
new file mode 100644
index 0000000..40c107e
--- /dev/null
+++ b/force-app/main/default/pages/ViewRentalApplyDecrypt.page
@@ -0,0 +1,27 @@
+<apex:page standardController="Rental_Apply__c" extensions="RentalApplyController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!encryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" value="{!Rental_Apply__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                var staticResources = JSON.parse('{!staticResource}');
+                function QueryConsumApplyFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    document.querySelector("[id='page:form:pageBlock:pageBlockSection:j_id1:1:j_id2']").innerHTML = data.object.phoneNumber;
+                    document.querySelector("[data-id='direct_shippment_address__c']").innerHTML = data.object.directShippmentAddress;
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue');
+                    QueryConsumApplyFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewRentalApplyDecrypt.page-meta.xml b/force-app/main/default/pages/ViewRentalApplyDecrypt.page-meta.xml
new file mode 100644
index 0000000..65140de
--- /dev/null
+++ b/force-app/main/default/pages/ViewRentalApplyDecrypt.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewRentalApplyDecrypt</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewRepairEncrypt.page b/force-app/main/default/pages/ViewRepairEncrypt.page
new file mode 100644
index 0000000..133195a
--- /dev/null
+++ b/force-app/main/default/pages/ViewRepairEncrypt.page
@@ -0,0 +1,47 @@
+<apex:page standardController="Repair__c" extensions="NewRepairController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!encryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" value="{!Repair__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                debugger;
+                var staticResources = JSON.parse('{!staticResource}');
+                var staticResourceContact = JSON.parse('{!staticResourceContact}');
+                var staticResourceAddress = JSON.parse('{!staticResourceAddress}');
+                function QueryConsumApplyFromAWS() {
+                        AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    console.log(data);
+                    document.querySelector("[data-id='address_Contacts__c']").innerHTML = data.object.addressContacts;
+                    document.querySelector("[data-id='address_Contacts_Name__c']").innerHTML = data.object.addressContactsName;
+                    document.querySelector("[data-id='address_Telephone__c']").innerHTML = data.object.addressTelephone;
+                    document.querySelector("[data-id='address_ZipCode__c']").innerHTML = data.object.addressZipCode;
+                    document.querySelector("[data-id='Detailed_Address__c']").innerHTML = data.object.detailedAddress;
+                    document.querySelector("[data-id='RepairApplicant__c']").innerHTML = data.object.repairApplicant;
+                    AWSService.query(staticResourceAddress.queryUrl, '{!DecryptAWSDataId}', queryBackDecrypt, staticResourceAddress.token);
+                };
+                var queryBackContact = function queryBack(data) {
+                    console.log(data);
+                    document.querySelector("[data-id='address_Contacts__c']").innerHTML = data.object.lastName;
+                };
+                var queryBackDecrypt = function queryBack(data) {
+                    document.querySelector("[data-id='Detailed_Address__c']").innerHTML = data.object.detailedAddress;
+                    document.querySelector("[data-id='address_ZipCode__c']").innerHTML = data.object.zipCode;
+                    document.querySelector("[data-id='address_Telephone__c']").innerHTML = data.object.telephone;
+                    AWSService.query(staticResourceContact.queryUrl, '{!ContactAWSDataId}', queryBackContact, staticResourceContact.token);
+                }
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue');
+                    debugger;
+                    QueryConsumApplyFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewRepairEncrypt.page-meta.xml b/force-app/main/default/pages/ViewRepairEncrypt.page-meta.xml
new file mode 100644
index 0000000..c7673e0
--- /dev/null
+++ b/force-app/main/default/pages/ViewRepairEncrypt.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewRepairEncrypt</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page b/force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page
new file mode 100644
index 0000000..17dd54b
--- /dev/null
+++ b/force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page
@@ -0,0 +1,56 @@
+<apex:page standardController="RepairSubOrder__c" extensions="NewAndEditRepairSubOrderController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!RepairSubOrder__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                var config = {
+                    SobjectName : "{!SobjectName}",
+                    ApiPrefix:"{!ApiPrefix}",
+                    AWSToSobjectMap:{!AWSToSobjectMapJson},
+                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
+                };
+                var staticResources = JSON.parse('{!staticResource}');
+                function QuerySobjectFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    if(!data.object){
+                        console.log('data.object is ' + data.object);
+                        return;
+                    }
+
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
+                        let ele = document.querySelector(t);
+                        if(ele){
+                            ele.title = '';
+                            if(data.object.hasOwnProperty(f)){
+                                ele.innerHTML = data.object[f];
+                            }
+                            else{
+                                console.log(f + 'is not in data.object');
+                            }
+                        }else{
+                            console.log('selector='+t+' not found');
+                        }
+                        
+                    }
+                    // 褰撲笉鑳借嚜鍔ㄦ纭浛鎹㈠姞瀵嗘暟鎹椂闇�瑕佸湪姝ゅ娣诲姞js锛岀‖缂栫爜澶勭悊
+                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '濮撳悕'
+                    QuerySobjectFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..6b0a584
--- /dev/null
+++ b/force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewRepairSubOrderDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewReportDecryptInfo.page b/force-app/main/default/pages/ViewReportDecryptInfo.page
new file mode 100644
index 0000000..fbcaf7a
--- /dev/null
+++ b/force-app/main/default/pages/ViewReportDecryptInfo.page
@@ -0,0 +1,40 @@
+<apex:page standardController="Report__c" extensions="NewAndEditReportController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!encryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" value="{!Report__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                var staticResources = JSON.parse('{!staticResource}');
+                function QueryLeadFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    document.querySelector("[data-id='VOC_Informer_Name__c']").innerHTML=data.object.vocInformerName!=null?data.object.vocInformerName.replace(/"/g,""):'';
+                    document.querySelector("[id='page:form:pageBlock:pageBlockSection:j_id1:1:j_id2']").innerHTML=data.object.callerPhone!=null?data.object.callerPhone.replace(/"/g,""):'';
+                    document.querySelector("[data-id='VOC_Informer_Contact__c']").innerHTML=data.object.vocInformerContact!=null?data.object.vocInformerContact.replace(/"/g,""):'';
+                    document.querySelector("[data-id='Person_In_Charge_Text__c']").innerHTML=data.object.personInChargeText!=null?data.object.personInChargeText.replace(/"/g,""):'';
+                    document.querySelector("[data-id='Professor_sigh_text__c']").innerHTML=data.object.professorSighText!=null?data.object.professorSighText.replace(/"/g,""):'';
+                    document.querySelector("[data-id='Staff_Info_Manual_c__c']").innerHTML=data.object.staffInfoManual!=null?data.object.staffInfoManual.replace(/"/g,""):'';
+                    document.querySelector("[data-id='Responsible_Person_HP_c__c']").innerHTML=data.object.responsiblePersonHP!=null?data.object.responsiblePersonHP.replace(/"/g,""):'';
+                    document.querySelector("[data-id='Practitioner1_Part__c']").innerHTML=data.object.practitioner1Part!=null?data.object.practitioner1Part.replace(/"/g,""):'';
+                    document.querySelector("[data-id='Practitioner2_Part__c']").innerHTML=data.object.practitioner2Part!=null?data.object.practitioner2Part.replace(/"/g,""):'';
+                    document.querySelector("[data-id='Practitioner3_Part__c']").innerHTML=data.object.practitioner3Part!=null?data.object.practitioner3Part.replace(/"/g,""):'';
+                    document.querySelector("[data-id='Practitioner4_Part__c']").innerHTML=data.object.practitioner4Part!=null?data.object.practitioner4Part.replace(/"/g,""):'';
+                    document.querySelector("[data-id='Practitioner5_Part__c']").innerHTML=data.object.practitioner5Part!=null?data.object.practitioner5Part.replace(/"/g,""):'';
+                    document.querySelector("[data-id='age__c']").innerHTML=data.object.age!=null?data.object.age.replace(/"/g,""):'';
+                    document.querySelector("[data-id='Medical_History__c']").innerHTML=data.object.medicalHistory!=null?data.object.medicalHistory.replace(/"/g,""):'';
+                    document.querySelector("[data-id='sex__c']").innerHTML=data.object.sex!=null?data.object.sex.replace(/"/g,""):'';
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('awsDataId = '+'{!AWSDataId}')
+                    QueryLeadFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewReportDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewReportDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..189df72
--- /dev/null
+++ b/force-app/main/default/pages/ViewReportDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewReportDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/pages/ViewTenderinformationDecryptInfo.page b/force-app/main/default/pages/ViewTenderinformationDecryptInfo.page
new file mode 100644
index 0000000..3deb9e6
--- /dev/null
+++ b/force-app/main/default/pages/ViewTenderinformationDecryptInfo.page
@@ -0,0 +1,58 @@
+<apex:page standardController="Tender_information__c" extensions="NewAndEditTenderinformationController" id="page">
+    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
+    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
+    <apex:form id="form">
+        <apex:pageblock id="pageBlock">
+            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
+                <!--Each section has layoutFields, let's iterate them as well-->
+                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
+                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!Tender_information__c[encryptedAPI]}" />
+                </apex:repeat>
+            </apex:pageBlockSection>
+            <script>
+                AWSService.sfSessionId = '{!GETSESSIONID()}';   
+                var config = {
+                    SobjectName : "{!SobjectName}",
+                    ApiPrefix:"{!ApiPrefix}",
+                    AWSToSobjectMap:{!AWSToSobjectMapJson},
+                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
+                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
+                };
+                var staticResources = JSON.parse('{!staticResource}');
+                function QuerySobjectFromAWS() {
+                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
+                }
+                var queryBack = function queryBack(data) {
+                    if(!data.object){
+                        console.log('data.object is ' + data.object);
+                        return;
+                    }
+
+                    for(let f in config.AWSToSobjectNonEncryptedMap){
+                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
+                        let ele = document.querySelector(t);
+                        if(ele){
+                            ele.title = '';
+                            if(data.object.hasOwnProperty(f)){
+                                ele.innerHTML = data.object[f];
+                            }
+                            else{
+                                console.log(f + 'is not in data.object');
+                            }
+                        }else{
+                            console.log('selector='+t+' not found');
+                        }
+                        
+                    }
+                    // 褰撲笉鑳借嚜鍔ㄦ纭浛鎹㈠姞瀵嗘暟鎹椂闇�瑕佸湪姝ゅ娣诲姞js锛岀‖缂栫爜澶勭悊
+                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
+                };
+                sfdcPage.appendToOnloadQueue(function () {
+                    console.log('sfdcPage.appendToOnloadQueue')
+                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '濮撳悕'
+                    QuerySobjectFromAWS();
+                });
+            </script>
+        </apex:pageblock>
+    </apex:form>
+</apex:page>
\ No newline at end of file
diff --git a/force-app/main/default/pages/ViewTenderinformationDecryptInfo.page-meta.xml b/force-app/main/default/pages/ViewTenderinformationDecryptInfo.page-meta.xml
new file mode 100644
index 0000000..371abd6
--- /dev/null
+++ b/force-app/main/default/pages/ViewTenderinformationDecryptInfo.page-meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>54.0</apiVersion>
+    <availableInTouch>false</availableInTouch>
+    <confirmationTokenRequired>false</confirmationTokenRequired>
+    <label>ViewTenderinformationDecryptInfo</label>
+</ApexPage>
diff --git a/force-app/main/default/triggers/FileAddressTrigger.trigger b/force-app/main/default/triggers/FileAddressTrigger.trigger
new file mode 100644
index 0000000..861b577
--- /dev/null
+++ b/force-app/main/default/triggers/FileAddressTrigger.trigger
@@ -0,0 +1,13 @@
+trigger FileAddressTrigger on FileAddress__c (before delete) {
+    List<FileAddress__c> fileAddressList = trigger.old;
+    Set<String> deleteFiles = new Set<String>();
+    for(FileAddress__c fd:fileAddressList){
+        if(String.isNotBlank(fd.AWS_File_Key__c)&&String.isNotEmpty(fd.AWS_File_Key__c)){
+            deleteFiles.add(fd.AWS_File_Key__c);
+        } 
+    }
+    if(!deleteFiles.isEmpty()){
+        system.debug('DeleteFiles Value:'+JSON.serialize(deleteFiles));
+        AWSServiceTool.deleteFileAddress(deleteFiles);
+    }  
+}
\ No newline at end of file
diff --git a/force-app/main/default/triggers/FileAddressTrigger.trigger-meta.xml b/force-app/main/default/triggers/FileAddressTrigger.trigger-meta.xml
new file mode 100644
index 0000000..23257e1
--- /dev/null
+++ b/force-app/main/default/triggers/FileAddressTrigger.trigger-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexTrigger xmlns="http://soap.sforce.com/2006/04/metadata">
+    <apiVersion>52.0</apiVersion>
+    <status>Active</status>
+</ApexTrigger>

--
Gitblit v1.9.1