buli
2022-04-06 fd2184ee47221684ceccf93b7a65428835055253
Merge branch 'PIPLDeploy0405'
100个文件已修改
268个文件已添加
40957 ■■■■ 已修改文件
.sfdx/sfdx-config.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/AgencyAccount/AgencyAccount.cmp 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/AgencyAccount/AgencyAccount.css 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/AgencyAccount/AgencyAccountController.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/AgencyAccount/AgencyAccountHelper.js 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.css 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/NewAgencyContact/NewAgencyContactController.js 231 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/NewAgencyContact/NewAgencyContactHelper.js 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/WeeklyReport/WeeklyReport.cmp 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/WeeklyReport/WeeklyReport.css 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/WeeklyReport/WeeklyReportController.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/WeeklyReport/WeeklyReportHelper.js 580 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AWSServiceTool.cls 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AWSServiceTool.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AWSServiceToolTest.cls 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AWSServiceToolTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AgencyAccountCmp.cls 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AgencyAccountCmpTest.cls 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AgencyContactHandler.cls 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AgencyContactHandlerTest.cls 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AssessmentReportController.cls 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AssessmentReportControllerTest.cls 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/B_Test.cls 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/B_Test.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/B_TestTest.cls 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/B_TestTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/BmeWorkController.cls 264 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/BmeWorkControllerTest.cls 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ButtonJsUtility.cls 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ButtonJsUtility.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ButtonJsUtilityTest.cls 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ButtonJsUtilityTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CM_SearchContact.cls 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CM_SearchContactServiceController.cls 76 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CM_SearchContactServiceControllerTest.cls 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CM_SearchContactTest.cls 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CampaignMemberController.cls 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CampaignMemberControllerTest.cls 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CampaignMemberServiceController.cls 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CampaignMemberServiceControllerTest.cls 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ConsumFixtureSetSelectController.cls 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ConsumFixtureSetSelectControllerTest.cls 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ConsumReassignController.cls 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ConsumTrialController.cls 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ConsumTrialControllerTest.cls 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ConsumTrialPDFController.cls 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ConsumTrialPDFControllerTest.cls 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ControllerResponse.cls 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ControllerResponse.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ControllerResponseTest.cls 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ControllerResponseTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/DeleteBatch.cls 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/DeleteBatch.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/DeleteBatchTest.cls 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/DeleteBatchTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FieldInfo.cls 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FieldInfo.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FieldInfoTest.cls 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FieldInfoTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FileUploadController.cls 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FileUploadController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FileUploadControllerTest.cls 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FileUploadControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FixtureRentalPDFController.cls 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FixtureRentalPDFControllerTest.cls 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/InsReportPDFController.cls 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/InsReportPDFControllerTest.cls 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/InstructReportController.cls 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/InstructReportControllerTest.cls 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LayoutDescriberHelper.cls 1011 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LayoutDescriberHelper.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LayoutDescriberHelperTest.cls 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LayoutDescriberHelperTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LeadIntentionController.cls 3891 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LightningUtil.cls 805 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LightningUtilTest.cls 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/MetaDataUtility.cls 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/MetaDataUtility.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM103Controller.cls 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM115ControllerTest.cls 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM203Rest.cls 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM501Controller.cls 69 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM501ControllerTest.cls 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM501FutureController.cls 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM501FutureControllerTest.cls 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM502Controller.cls 702 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM502ControllerTest.cls 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM503InfoFileBatch.cls 210 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM503InfoFileBatchTest.cls 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM606Controller.cls 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM606ControllerTest.cls 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM607Rest.cls 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM612Rest.cls 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM620Rest.cls 301 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM620Rest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM620RestTest.cls 280 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM620RestTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM623Rest.cls 296 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM623Rest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM623RestTest.cls 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM623RestTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM702Controller.cls 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM702Controller.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM702ControllerTest.cls 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM702ControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM702WebService.cls 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM702WebService.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM702WebServiceTest.cls 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM702WebServiceTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFMUtil.cls 149 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAgencyContactController.cls 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAgencyContactController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAgencyContactControllerTest.cls 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAgencyContactControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditASEActivityController.cls 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditASEActivityController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditASEActivityControllerTest.cls 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditASEActivityControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditAddressController.cls 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditAddressController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditAddressControllerTest.cls 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditAddressControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditAgencyContactController.cls 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditAgencyContactController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditAgencyContactControllerTest.cls 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditAgencyContactControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditBaseController.cls 303 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditBaseController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditBaseControllerTest.cls 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditBaseControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCampaignMemberController.cls 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCampaignMemberController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCampaignMemberControllerTest.cls 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCampaignMemberControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCaseController.cls 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCaseController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCaseControllerTest.cls 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCaseControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditContactController.cls 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditContactController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditContactControllerTest.cls 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditContactControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditEventController.cls 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditEventController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditEventControllerTest.cls 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditEventControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInquiryFormController.cls 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInquiryFormController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInquiryFormControllerTest.cls 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInquiryFormControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInspectionReportController.cls 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInspectionReportController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInspectionReportControllerTest.cls 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInspectionReportControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLeadController.cls 669 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLeadController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLeadControllerTest.cls 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLeadControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditQISController.cls 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditQISController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditQISControllerTest.cls 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditQISControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditRepairSubOrderController.cls 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditRepairSubOrderController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditRepairSubOrderControllerTest.cls 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditRepairSubOrderControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditReportController.cls 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditReportController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditReportControllerTest.cls 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditReportControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditTenderinformationControlTest.cls 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditTenderinformationControlTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditTenderinformationController.cls 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditTenderinformationController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyController.cls 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyControllerTest.cls 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyEquipSetDetailControlTest.cls 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyEquipSetDetailControlTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewRepairController.cls 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewRepairController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewRepairControllerTest.cls 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewRepairControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/OFSInsReportLayoutController.cls 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/OFSInsReportLayoutControllerTest.cls 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/OnCallController.cls 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/OnCallController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/OnCallControllerTest.cls 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/OnCallControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/Option.cls 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/Option.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/PIHelper.cls 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/PIHelper.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/PIHelperTest.cls 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/PIHelperTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/QISPDFController.cls 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/QISPDFControllerTest.cls 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/RentalApplyController.cls 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/RentalApplyController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/RentalApplyControllerTest.cls 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/RentalApplyControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SLAReportDetailsController.cls 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SLAReportDetailsControllerTest.cls 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SObjectHelper.cls 445 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SObjectHelper.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SObjectHelperTest.cls 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SObjectHelperTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchContactController.cls 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchContactController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchContactControllerTest.cls 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchContactControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchLeadController.cls 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchLeadController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchLeadControllerTest.cls 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchLeadControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchVisitorController.cls 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchVistorControllerTest.cls 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SimpleEventRegisterController.cls 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SimpleEventRegisterControllerTester.cls 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SoqlHelper.cls 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SoqlHelper.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SoqlHelperTest.cls 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SoqlHelperTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/StartTradingController.cls 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/StartTradingController.cls-meta.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/StartTradingControllerTest.cls 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/StraightBackAddressController.cls 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/StraightBackAddressControllerTest.cls 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/UpdateContractAimAmountHandler.cls 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ViewParticipantsController.cls 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ViewParticipantsController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ViewParticipantsControllerTest.cls 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ViewParticipantsControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/WeeklyReportCmp.cls 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/WeeklyReportCmpTest.cls 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/XinDailyReportController.cls 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/XinDailyReportControllerTest.cls 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/AssessmentReport.page 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/BMEWorkPage.page 194 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/B_Test.page 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/B_Test.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/CM_SearchContact.page 280 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/CM_SearchContactService.page 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/CampaignMember.page 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/CampaignMemberService.page 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ConsumApplyUploadPdf.page 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ConsumApplyUploadPdf.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ConsumReassign.page 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ConsumTrial.page 996 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ConsumTrialPDF.page 689 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/FixtureRentalPDF.page 804 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/InsReportPDF.page 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/InstructReport.page 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/LeadIntention.page 1245 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditASEActivity.page 649 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditASEActivity.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditAddress.page 516 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditAddress.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditAgencyContact.page 615 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditAgencyContact.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditCampaignMember.page 421 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditCampaignMember.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditCase.page 520 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditCase.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditContact.page 553 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditContact.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditInquiryForm.page 781 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditInquiryForm.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditInspectionReport.page 536 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditInspectionReport.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditLead.page 703 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditLead.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditQIS.page 611 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditQIS.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditRepairSubOrder.page 684 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditRepairSubOrder.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditReport.page 668 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditReport.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditTenderinformation.page 537 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditTenderinformation.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewConsumApply.page 528 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewConsumApply.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewListOfConsumables.page 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewListOfConsumables.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewOnCall.page 357 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewOnCall.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRentalApply.page 558 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRentalApply.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRepair.page 501 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRepair.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRepairPage.page 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRepairPage.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/OFSInsReportLayout.page 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/QISPDF.page 206 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/RentalApplyUploadPdf.page 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/RentalApplyUploadPdf.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SLAReportDetails.page 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchAWSContactByNamePage.page 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchAWSContactByNamePage.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchContactPage.page 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchContactPage.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchLeadPage.page 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchLeadPage.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchVisitor.page 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SimpleEventRegister.page 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/StartTrading.page 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/StraightBackAddress.page 824 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TenderInformationUploadPdf.page 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TenderInformationUploadPdf.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TestClass.page 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TestClass.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/UploadPdf.page 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/UploadPdf.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewASEActivityDecryptInfo.page 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewASEActivityDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewAddressDecryptInfo.page 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewAddressDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewAgencyContactDecryptInfo.page 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewAgencyContactDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewCaseDecryptInfo.page 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewCaseDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewContactDecryptInfo.page 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewContactDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewDecryptConsumApply.page 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewDecryptConsumApply.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewEventDecryptInfo.page 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewEventDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewInquiryFormDecryptInfo.page 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewInquiryFormDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewInspectionReportDecryptInfo.page 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewInspectionReportDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLeadDecryptInfo.page 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLeadDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewListOfConsumablesDecrypt.page 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewListOfConsumablesDecrypt.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewOnCallDecrypt.page 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewOnCallDecrypt.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewParticipantsDecryptInfo.page 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewParticipantsDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewQISReportDecryptInfo.page 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewQISReportDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRentalApplyDecrypt.page 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRentalApplyDecrypt.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRepairEncrypt.page 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRepairEncrypt.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewReportDecryptInfo.page 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewReportDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewTenderinformationDecryptInfo.page 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewTenderinformationDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/XinDailyReport.page 80 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/staticresources/AWSService.resource-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/staticresources/AWSService/AWSService.js 444 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/triggers/ContactHpDeptUpd.trigger 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/triggers/FileAddressTrigger.trigger 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/triggers/FileAddressTrigger.trigger-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/triggers/Repair.trigger 1301 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manifest/packageForPIPL.xml 253 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.sfdx/sfdx-config.json
@@ -1,3 +1,3 @@
{
  "defaultusername": "vscodeOrg"
  "defaultusername": "MEBGProduction"
}
force-app/main/default/aura/AgencyAccount/AgencyAccount.cmp
@@ -5,7 +5,12 @@
    <aura:attribute name="hosStr" type="String"/>
    <aura:attribute name="conStr" type="String"/>
    <aura:attribute name="filedsmap" type="Map"/>
    <aura:attribute name="awsdata" type="Map"/>
    <aura:attribute name="temp_aws_id" type="String"/>
    <aura:attribute name="staticResource" type="Map"/>
    <ltng:require scripts="{! $Resource.jquery183minjs }" />
    <ltng:require scripts="{! $Resource.AWSService+'/AWSService.js' }" afterScriptsLoaded="{!c.scriptsLoaded}" />
    <aura:renderIf isTrue="{!v.login}">
        <div class="slds-spinner_container height100vh">
            <div class="slds-spinner--brand slds-spinner slds-spinner--medium" role="alert">
@@ -46,17 +51,17 @@
          <th scope="col" style = "width:5px;">
            <div class="slds-truncate" title="{!v.filedsmap.Hospital_Name__c}">{!v.filedsmap.Hospital_Name__c}</div>
          </th>
          <th scope="col">
          <th scope="col" style="width: 150px;">
            <div class="slds-truncate" title="{!v.filedsmap.Department_Cateogy_F__c}">{!v.filedsmap.Department_Cateogy_F__c}</div>
          </th>
          <!-- 精琢科技  zxk  SWAG-C8F8TU end -->
          <!-- <th scope="col">
            <div class="slds-truncate" title="{!v.filedsmap.Hospital_DC_Name__c}">{!v.filedsmap.Hospital_DC_Name__c}</div>
          </th> -->
          <th scope="col">
          <th scope="col" style="width: 150px;">
            <div class="slds-truncate" title="{!v.filedsmap.Type__c}">{!v.filedsmap.Type__c}</div>
          </th>
          <th scope="col">
          <th scope="col" style="width: 150px;">
            <div class="slds-truncate" title="{!v.filedsmap.Doctor_Division1__c}">{!v.filedsmap.Doctor_Division1__c}</div>
          </th>
          <th scope="col">
@@ -68,7 +73,14 @@
          <aura:iteration items="{!v.accounts}" var="item" indexVar="index">
        <tr>
          <th scope="row" data-label="Opportunity Name">
            <div class="slds-truncate" title="{!item.Name}"><a href="{!'/partner/s/agency-contact/' + item.Id}">{!item.Name}</a></div>
            <aura:set attribute="temp_aws_id" value="{! item.AWS_Data_Id__c }" />
            <div class="slds-truncate">
                <a href="{!'/partner/s/agency-contact/' + item.Id}" style="position: relative;">
                    <span class="encrypt">{!item.Name}</span>
                    <span class="decrypt">{!item.awsdata.name}</span>
                </a>
            </div>
          </th>
            <!-- 精琢科技  zxk  SWAG-C8F8TU start -->
             <td data-label="Account Name">
@@ -94,10 +106,16 @@
          </td> -->
          <td data-label="Close Date">
            <div class="slds-truncate" title="{!item.Type__c}">{!item.Type__c}</div>
            <div class="slds-truncate" title="{!item.Type__c}">
                <span class="encrypt">{!item.Type__c}</span>
                <span class="decrypt">{!item.awsdata.type}</span>
            </div>
          </td>
          <td data-label="Stage">
            <div class="slds-truncate" title="{!item.Doctor_Division1__c}">{!item.Doctor_Division1__c}</div>
            <div class="slds-truncate" title="{!item.Doctor_Division1__c}">
                <span class="encrypt">{!item.Doctor_Division1__c}</span>
                <span class="decrypt">{!item.awsdata.doctorDivision1}</span>
            </div>
          </td>
          <td data-label="IsOlympusContact__c">
            <ui:outputCheckbox value="{!item.IsOlympusContact__c}" />
force-app/main/default/aura/AgencyAccount/AgencyAccount.css
@@ -1,3 +1,21 @@
.THIS.contents_wrapper {
    padding-top: 10px;
}
.THIS tr .decrypt{
    /* position: absolute;
    top: 0;
    left: 100%;
    display: none;
    text-align: left;
    padding-left: 5px; */
    display: none;
}
.THIS tr:hover .decrypt{
    display: unset;
}
.THIS tr:hover .encrypt{
    display: none;
}
force-app/main/default/aura/AgencyAccount/AgencyAccountController.js
@@ -10,4 +10,8 @@
    clearContact: function(component, event, helper) {
        helper.clearContact(component, event, helper);
    },
    scriptsLoaded:function(component, event, helper) {
        // AWSService.logFun = helper.saveLog;
        // AWSService.component = component;
    }
})
force-app/main/default/aura/AgencyAccount/AgencyAccountHelper.js
@@ -1,12 +1,14 @@
({
    doinit : function(component, event, helper) {
        component.set('v.login',true);
        component.set("v.awsdata",{});
        var action = component.get("c.getfiledsmap");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if(state === "SUCCESS") {
                var res = response.getReturnValue();
                component.set("v.filedsmap", res);
            } else if (state === "ERROR") {
                var errors = response.getError();
@@ -27,7 +29,11 @@
            if(state === "SUCCESS") {
                var acList = response.getReturnValue();
                component.set("v.accounts", acList);
                component.set('v.login',false);
                helper.Decrypt(component,helper,function(){
                    component.set('v.login',false);
                })
            } else if (state === "ERROR") {
                var errors = response.getError();
                var toastEvent = $A.get("e.force:showToast");
@@ -40,7 +46,31 @@
                component.set('v.login',false);
            }
        });
        $A.enqueueAction(action2);
        var action3 = component.get("c.GetConfig");
        action3.setCallback(this, function(response) {
            var state = response.getState();
            if(state === "SUCCESS") {
                var res = response.getReturnValue();
                //AWSService.sfSessionId = res.sessionId;
                component.set("v.staticResource",JSON.parse(res.staticResource));
                $A.enqueueAction(action2);
            } else if (state === "ERROR") {
                var errors = response.getError();
                var toastEvent = $A.get("e.force:showToast");
                toastEvent.setParams({
                    "title": "错误",
                    "type":"error",
                    "message": errors[0].message
                });
                toastEvent.fire();
            }
        });
        $A.enqueueAction(action3);
    },
    clearContact: function(component, event, helper) {
@@ -53,15 +83,17 @@
        component.set('v.login',true);
        var hosStr = component.get("v.hosStr");
        var conStr = component.get("v.conStr");
        var action = component.get("c.searchAccounts");
        action.setParams({"hosStr": hosStr, "conStr": conStr});
        var action = component.get("c.searchAccounts2");
        let awsdata = component.get("v.awsdata");
        let staticResource = component.get("v.staticResource");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if(state === "SUCCESS") {
                var acList = response.getReturnValue();
                component.set("v.accounts", acList);
                component.set('v.login',false);
                helper.Decrypt(component,helper,function(){
                    component.set('v.login',false);
                })
            } else if (state === "ERROR") {
                var errors = response.getError();
                var toastEvent = $A.get("e.force:showToast");
@@ -74,6 +106,92 @@
                component.set('v.login',false);
            }
        });
        if (conStr) {
            AWSService.search(staticResource.searchUrl,JSON.stringify({
                "name":conStr
            }),function(data){
                $A.getCallback(function(){
                    let dataIds = [];
                    if(data.object && data.object.length > 0){
                        for(let d of data.object){
                            if(d.dataId){
                                dataIds.push(d.dataId);
                                awsdata[d.dataId] = d;
                            }
                        }
                    }
                    action.setParams({"hosStr": hosStr, awsids:dataIds});
                    $A.enqueueAction(action);
                })()
           },staticResource.token);
        }else{
            action.setParams({"hosStr": hosStr});
            $A.enqueueAction(action);
        }
    },
    Decrypt :function(component, helper, callback){
        let awsdata = component.get("v.awsdata");
        let need_query = [];
        let acList = component.get("v.accounts");
        let staticResource = component.get("v.staticResource");
        for (const acc of acList) {
            if(acc.AWS_Data_Id__c &&
                (!awsdata.hasOwnProperty(acc.AWS_Data_Id__c) || !awsdata[acc.AWS_Data_Id__c])
                ){
                need_query.push(acc.AWS_Data_Id__c);
            }
        }
        let Foo = function(){
            for (const acc of acList) {
                if(acc.AWS_Data_Id__c && awsdata.hasOwnProperty(acc.AWS_Data_Id__c)){
                    acc.awsdata = awsdata[acc.AWS_Data_Id__c];
                }
            }
            component.set("v.accounts", acList);
            if(callback)callback();
        }
        if(need_query.length>0){
            AWSService.search(staticResource.searchUrl,JSON.stringify({
                 "dataIds":need_query
                }),function(data){
                    $A.getCallback(function(){
                        if(data.object && data.object.length > 0){
                            for(let d of data.object){
                                if(d.dataId){
                                    awsdata[d.dataId] = d;
                                }
                            }
                        }
                        Foo();
                    })()
            },staticResource.token);
        }else{
            Foo();
        }
    },
    saveLog:function(component,module,url,request,response,status){
        var action = component.get("c.SaveLog");
        action.setParams({
            "module": hosStr,
            "content": content,
            "status": status,
            "respMsg": respMsg
            });
        $A.enqueueAction(action);
    }
})
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp
New file
@@ -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"/>
    <ltng:require scripts="{! $Resource.AWSService+'/AWSService.js' }" />
    <ltng:require scripts="{! $Resource.jquery183minjs }" />
    <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' }" aura:id="field" 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>
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp-meta.xml
New file
@@ -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>
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.css
New file
@@ -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);
}
force-app/main/default/aura/NewAgencyContact/NewAgencyContactController.js
New file
@@ -0,0 +1,231 @@
({
    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;
                    }
                    if (item.behavior == "Required" && !item.value ) {
                        let fs = component.find("field");
                        for(let fi in fs){
                            let f = fs[fi];
                            if(!f.get('v.value')){
                                f.reset();
                            }
                        }
                        return;
                    }
                }
            }
        }
        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 = null;
                        if(rv.IsSuccess){
                            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){}
})
force-app/main/default/aura/NewAgencyContact/NewAgencyContactHelper.js
New file
@@ -0,0 +1,50 @@
({
    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);
        }
        AWSService.post(postURL,payloadForNewPI,function(result) {
            //this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(result),this.successStatus);
            if(callback) callback(result);
        },token);
    },
    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];
            }
        }
        AWSService.get(url,function(result){
            //this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(result),this.successStatus);
            if(callback) callback(result);
        },token);
    }
})
force-app/main/default/aura/WeeklyReport/WeeklyReport.cmp
@@ -71,8 +71,19 @@
    <!-- It will display 100 records . Change for your requirement-->
    <aura:attribute name="NumOfRecords" type="Integer" default="1000"/> 
    <aura:attribute name="showMain" type="Boolean" default="true"/>
    <!-- PIPL update Yin Mingjie 21/02/2022 start -->
    <aura:attribute name="AWStoken" type="String"/>
    <aura:attribute name="AWSsearch" type="String"/>
    <aura:attribute name="AWSinsert" type="String"/>
    <aura:attribute name="AWStransactionURL" type="String"/>
    <aura:attribute name="AWSDoctor2Map" type="String"/>
    <aura:attribute name="awsurl" type="Map"/>
    <aura:attribute name="contactawsurl" type="Map"/>
    <aura:attribute name="allselectlistAgencyPerson" type="Map"/>
    <!-- PIPL update Yin Mingjie 21/02/2022 end -->
    <!-- 批量添加周报 end-->
    <ltng:require scripts="{! $Resource.AWSService+'/AWSService.js' }" />
    <ltng:require scripts="{! $Resource.jquery183minjs }" />
    
    <!--ロード中...-->
    <aura:renderIf isTrue="{!v.login}">
@@ -135,7 +146,11 @@
                            <span class="slds-truncate" title="Name">{!v.fieldsmap.Department_Cateogy__c}</span>
                        </th>
                        <th class="table_header slds-text-title--caps">
                            <span class="slds-truncate" title="Name">{!v.fieldsmap.doctor2__c}</span>
                            <!-- PIPL update Yin Mingjie 21/02/2022 start
                            <span class="slds-truncate" title="Name">{!v.fieldsmap.doctor2__r}</span>
                            PIPL update Yin Mingjie 21/02/2022 end-->
                            <span class="slds-truncate" title="Name">{!v.fieldsmap.Agency_Contact__c}</span>
                        </th>
                        <th class="table_header slds-text-title--caps">
                            <span class="slds-truncate" title="Name">{!v.fieldsmap.visitor_title__c}</span>
@@ -154,7 +169,10 @@
                            </td>
                            <td role="gridcell" class="slds-cell-edit">
                                <span class="slds-grid slds-grid--align-spread">
                                    <span class="slds-truncate" title="{!item.Person_In_Charge2__r.Name}">{!item.Person_In_Charge2__r.Name}</span>
                                    <span class="slds-truncate" title="{!item.Person_In_Charge2__r.Name}">
                                        <span class="encrypt">{!item.Person_In_Charge2__r.Name}</span>
                                        <span class="decrypt">{!item.Person_In_Charge2__r.awsdata.lastName}</span>
                                    </span>
                                </span>
                            </td>
                            <th scope="row" tabindex="0" class="slds-cell-edit">
@@ -169,12 +187,18 @@
                            </td>
                            <td role="gridcell" class="slds-cell-edit">
                                <span class="slds-grid slds-grid--align-spread">
                                    <span class="slds-truncate" title="{!item.doctor2__r.Name}">{!item.doctor2__r.Name}</span>
                                    <span class="slds-truncate" title="{!item.doctor2__r.Name}">
                                        <span class="encrypt">{!item.doctor2__r.Name}</span>
                                        <span class="decrypt">{!item.doctor2__r.awsdata.name}</span>
                                    </span>
                                </span>
                            </td>
                            <td role="gridcell" class="slds-cell-edit">
                                <span class="slds-grid slds-grid--align-spread">
                                    <span class="slds-truncate" title="{!item.visitor_title__c}">{!item.visitor_title__c}</span>
                                    <span class="slds-truncate" title="{!item.visitor_title__c}">
                                        <span class="encrypt">{!item.visitor_title__c}</span>
                                        <span class="decrypt">{!item.doctor2__r.awsdata.doctorDivision1}</span>
                                    </span>
                                </span>
                            </td>
                            <td role="gridcell" class="slds-cell-edit">
@@ -342,8 +366,7 @@
                        <div class="slds-p-horizontal--small slds-size--1-of-1 slds-medium-size--1-of-5 slds-large-size--1-of-8">
                            {!v.fieldsmap.visitor_title__c}
                            <div>{!v.doctor_title}</div>
                        </div>
                        </div>
                        <!-- 活动区分 -->
                        <div class="slds-p-horizontal--small slds-size--1-of-1 slds-medium-size--1-of-5 slds-large-size--1-of-6">
                            {!v.fieldsmap.Purpose_Type__c}
@@ -410,7 +433,10 @@
                            <!-- <force:inputField value="{!v.data.Product_Category3__c}" aura:id="input-product-category3"/> -->
                            <ui:inputSelect aura:id="select_Product3" class="slds-select" change="{!c.productcategoryChange3}"/>
                        </div>
                         <!--SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start-->
                        <!-- 支援需求 -->
                        <!--SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 end-->
                        <div aura:id="result" class="disp_none slds-p-horizontal--small slds-size--1-of-1 slds-medium-size--3-of-12 slds-large-size--3-of-12">
                            {!v.fieldsmap.Result__c}
                            <ui:inputSelect aura:id="select_result" class="slds-select"/>
@@ -468,12 +494,18 @@
                                            </td>
                                            <td role="gridcell" class="slds-cell-edit">
                                                <span class="slds-grid slds-grid--align-spread">
                                                    <span class="slds-truncate" title="{!item.doctor2__r.Name}">{!item.doctor2__r.Name}</span>
                                                    <span class="slds-truncate" title="{!item.doctor2__r.Name}">
                                                        <span class="encrypt">{!item.doctor2__r.Name}</span>
                                                        <span class="decrypt">{!item.doctor2NameOrigin}</span>
                                                    </span>
                                                </span>
                                            </td>
                                            <td role="gridcell" class="slds-cell-edit">
                                                <span class="slds-grid slds-grid--align-spread">
                                                    <span class="slds-truncate" title="{!item.visitor_title__c}">{!item.visitor_title__c}</span>
                                                    <span class="slds-truncate" title="{!item.visitor_title__c}">
                                                        <span class="encrypt">{!item.visitor_title__c}</span>
                                                        <span class="decrypt">{!item.visitorTitleOrigin}</span>
                                                    </span>
                                                </span>
                                            </td>
                                            <td role="gridcell" class="slds-cell-edit">
@@ -519,7 +551,7 @@
                    <lightning:messages aura:id="OppMessage" />
                    <!-- onload="{!c.showRequiredFields}" -->
                    <aura:renderIf isTrue="{!v.truthy}">
                        <lightning:inputField fieldName="Name"/>
                        <lightning:inputField fieldName="Name" aura:id="newOpportunityField" />
                        <lightning:inputField fieldName="Type__c" aura:id="newOpportunityField" />
                        <lightning:inputField fieldName="Doctor_Division1__c" aura:id="newOpportunityField" />
                        <!-- <lightning:inputField class="customRequired none" aura:id="Input_type__c" fieldName="Type__c"/>
force-app/main/default/aura/WeeklyReport/WeeklyReport.css
@@ -126,4 +126,16 @@
.THIS .none{
     display:none; 
}
.THIS tr .decrypt{
    display: none;
}
.THIS tr:hover .decrypt{
    display: unset;
}
.THIS tr:hover .encrypt{
    display: none;
}
force-app/main/default/aura/WeeklyReport/WeeklyReportController.js
@@ -63,7 +63,11 @@
        var vaildationFailReason = '';
        // var vaildationFailReason2 = '';
        // var currentDate = new Date().toJSON().slice(0,10);
        // PIPL update Yin Mingjie 21/02/2022 start
        let agencyReport = Object.create(null);
        // PIPL update Yin Mingjie 21/02/2022 end
        fields.forEach(function (field) {
            if(field.get("v.fieldName") === 'Type__c' && $A.util.isEmpty(field.get("v.value"))){
                showValidationError = true;
@@ -77,19 +81,45 @@
                }
                
            }
            // PIPL update Yin Mingjie 21/02/2022 start
            if(field.get("v.fieldName") === 'Name'){
                agencyReport['name'] = field.get("v.value");
            }else if(field.get("v.fieldName") === 'Type__c'){
                agencyReport['type'] = field.get("v.value");
            }else if(field.get("v.fieldName") === 'Doctor_Division1__c'){
                agencyReport['doctorDivision1'] = field.get("v.value");
            }
            // PIPL update Yin Mingjie 21/02/2022 end
        });
         
        if (!showValidationError) {
            // PIPL update Yin Mingjie 21/02/2022 start
            /*
            var eventFields = event.getParam("fields");
            eventFields["Agency_Hospital__c"] = component.get('v.hospitalLinkId');
            component.find('recordEditForm').submit(eventFields);
            */
            var agencyHospitalid = component.get('v.hospitalLinkId');
            var arr = new Array();
            arr.push(agencyReport);
            var data = JSON.stringify(arr);
            // helper.set_aws_url(component,data,agencyHospitalid);
            var token = component.get('v.AWStoken');
            var newUrl = component.get('v.AWSinsert');
            component.set('v.login',true);
            helper.insert_agencycontact(component,token,newUrl,data,agencyHospitalid,helper);
            // PIPL update Yin Mingjie 21/02/2022 end
        }else{
            component.find('OppMessage').setError(vaildationFailReason);
        }
        // var eventFields = event.getParam("fields");
        // eventFields["Agency_Hospital__c"] = component.get('v.hospitalLinkId');
        // component.find('recordEditForm').submit(eventFields);
         // vivek 添加验证 end
        // vivek 添加验证 end
    },
    
    createCancel : function(component, event, helper) {
force-app/main/default/aura/WeeklyReport/WeeklyReportHelper.js
@@ -1,7 +1,6 @@
({
    doinit : function(component, event, helper) {
        this.report_date_list(component, event, helper, 5);
        component.set('v.login',true);
        var action = component.get('c.getalldata');
        action.setCallback(this,function(response){
@@ -12,13 +11,21 @@
                component.set('v.fieldsmap',res.fieldsMap);
                component.set('v.allselectlist',res.allselectlist);
                component.set('v.doclist',res.doclist);
                // PIPL update Yin Mingjie 21/02/2022 start
                component.find('select_agency_person').set('v.options', this.conv_selected(res.allselectlist.AgencyPerson__c));
                // this.search_contact(component, event, helper,res.allselectlist.AgencyPerson__c);
                // PIPL update Yin Mingjie 21/02/2022 end
                component.find('select_department').set('v.options', this.conv_selected(res.allselectlist.Department_Cateogy__c));
                component.find('select_purpose_type').set('v.options', this.conv_selected(res.allselectlist.Purpose_Type__c));
                component.find('select_result').set('v.options', this.conv_selected(res.allselectlist.Result__c));
                component.find('select_stageName').set('v.options', this.conv_selected(res.allselectlist.StageName__c));
                 //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
                //  component.find('SupportNeeds__c').set('v.options', this.conv_selected(res.allselectlist.SupportNeeds__c));
                 //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 end
                component.set('v.selected_agency_person', res.allselectlist.AgencyPerson__c[0].label);
                component.set('v.dialog_type', '新建');
                component.set('v.awsurl', res.awsurl);// 20220222 PI改造 by Bright
                component.set('v.contactawsurl', res.contactawsurl);// 20220222 PI改造 by Bright
                
                this.get_reports(component, event, helper, component.find('select_date').get('v.value'), component.find('select_agency_person').get('v.value'));
                
@@ -31,6 +38,80 @@
        });
        $A.enqueueAction(action);
    },
    // PIPL update Yin Mingjie 21/02/2022 start
    search_contact : function(component, event, helper, resobj) {
        let contactData = Object.create(null);
        var dataArr = new Array();
        for (let i = 0; i < resobj.length; i++) {
            if (resobj[i].awsid != null && resobj[i].awsid != ''){
                contactData[resobj[i].awsid] = resobj[i];
                dataArr.push(resobj[i].awsid);
            }
        }
        let obj= Object.create(null);
        obj['dataIds'] = dataArr;
        var payload = JSON.stringify(obj);
        this.search_contact_url(component, 'Contact', (result)=>{
            var token = result.token;
            var searchUrl = result.searchUrl;
            this.search_core(token,searchUrl,payload,(result)=>{
                if(result.status == '0'){
                    if(result.object != null){
                        this.to_contact_list(result,contactData,component);
                    }else{
                        component.set('v.login',false);
                    }
                }else{
                    this.error('AWS search status : ' + result.status);
                    component.set('v.login',false);
                }
            },component);
        });
    },
    to_contact_list : function(result,retMap,component) {
        var resls = result.object;
        var res = [];
        var space = {};
        space['label'] = '';
        space['selected'] = true;
        space['value'] = '';
        res.push(space);
        for (var i = 0; i < resls.length; i++) {
            var t = {};
            t['label'] = resls[i].lastName;
            t['selected'] = false;
            t['Doctor_Division1__c'] = resls[i].doctorDivision1;
            t['value'] = retMap[resls[i].dataId].value;
            res.push(t);
        }
        component.find('select_agency_person').set('v.options',res);
        component.set('v.allselectlistAgencyPerson',res);
        component.set('v.login',false);
    },
    search_contact_url : function(component, sobject, callback) {
        var action = component.get('c.getAwsurl');
        action.setParams({
            "sobj" : sobject,
        });
        action.setCallback(this,function(response){
            var state = response.getState();
            if(state == 'SUCCESS'){
                var result = response.getReturnValue();
                if(callback)callback(result);
            }
            else{
                this.error('AWS url/token error.');
                component.set('v.login',false);
            }
        });
        $A.enqueueAction(action);
    },
    // PIPL update Yin Mingjie 21/02/2022 end
    select_department : function(component, event, helper) {
        var dc = component.find("select_department").get("v.value");
@@ -46,6 +127,7 @@
            }
        }
        if (dc != '' || purpose_type != '') {
            var action = component.get('c.getProductList');
            action.setParams({
                "dc" : dc,
@@ -54,6 +136,7 @@
            action.setCallback(this,function(response){
                var state = response.getState();
                if(state == 'SUCCESS'){
                    var res = response.getReturnValue();
                    component.find('select_Product1').set("v.options", JSON.parse(JSON.stringify(res)));
                    component.find('select_Product2').set("v.options", JSON.parse(JSON.stringify(res)));
@@ -90,6 +173,84 @@
            if(state == 'SUCCESS'){
                var res = response.getReturnValue();
                component.set('v.reports', res.reports);
                // 20220222 PI改造 by Bright--start
                let dataIds = [];
                let dataIds1 = [];
                let mm = {};
                let b = false;
                let b1 = false;
                for (const rep of res.reports) {
                    if (rep.doctor2__r && rep.doctor2__r.AWS_Data_Id__c) {
                        dataIds.push(rep.doctor2__r.AWS_Data_Id__c);
                    }
                    if (rep.Person_In_Charge2__r && rep.Person_In_Charge2__r.AWS_Data_Id__c) {
                        dataIds1.push(rep.Person_In_Charge2__r.AWS_Data_Id__c);
                    }
                }
                let Foo = null;
                Foo = function(){
                    if(b && b1){
                        for (const rep of res.reports) {
                            if (rep.doctor2__r && rep.doctor2__r.AWS_Data_Id__c && mm.hasOwnProperty(rep.doctor2__r.AWS_Data_Id__c)) {
                                rep.doctor2__r.awsdata = mm[rep.doctor2__r.AWS_Data_Id__c];
                            }
                            if (rep.Person_In_Charge2__r && rep.Person_In_Charge2__r.AWS_Data_Id__c && mm.hasOwnProperty(rep.Person_In_Charge2__r.AWS_Data_Id__c)) {
                                rep.Person_In_Charge2__r.awsdata = mm[rep.Person_In_Charge2__r.AWS_Data_Id__c];
                            }
                        }
                        $A.getCallback(()=>component.set('v.reports', res.reports))();
                    }else{
                        console.log('b='+b + ',b1='+b1+',continue');
                        setTimeout(Foo,100);
                    }
                }
                if(dataIds.length > 0){
                    let awsurl = component.get('v.awsurl');
                    helper.search_core(awsurl.token,awsurl.searchUrl,JSON.stringify({
                        "dataIds":dataIds
                    }),(result)=>{
                        if(result.status == '0'){
                            for (const m of result.object) {
                                mm[m.dataId] = m;
                            }
                            b = true;
                            Foo();
                        }else{
                            this.error('AWS search status : ' + result.status);
                        }
                    },component);
                }else{
                    b = true;
                }
                if(dataIds1.length > 0){
                    let contactawsurl = component.get('v.contactawsurl');
                    helper.search_core(contactawsurl.token,contactawsurl.searchUrl,JSON.stringify({
                        "dataIds":dataIds1
                    }),(result)=>{
                        if(result.status == '0'){
                            for (const m of result.object) {
                                mm[m.dataId] = m;
                            }
                            b1 = true;
                            Foo();
                        }else{
                            this.error('AWS search status : ' + result.status);
                        }
                    },component);
                }else{
                    b1 = true;
                }
                // 20220222 PI改造 by Bright--end
                component.set('v.report_count', res.reports.length);
                // 更新保存後のselect_data用
@@ -141,7 +302,10 @@
    },
    
    get_agency_person_name : function(component, agency_person_value) {
        // PIPL update Yin Mingjie 21/02/2022 start
        var allselectlist = component.get('v.allselectlist.AgencyPerson__c');
        // var allselectlist = component.get('v.allselectlistAgencyPerson');
        // PIPL update Yin Mingjie 21/02/2022 end
        var new_label = '';
        for (var i = 0; i < allselectlist.length; i++) {
            if (agency_person_value == allselectlist[i].value) {
@@ -200,7 +364,6 @@
                if (select_data['Department_Cateogy__c'] != '') {
                    this.set_selected(component, 'select_department', select_data['Department_Cateogy__c']);
                }
                // 拜访人
                component.set('v.default_select_doctor_id', select_data['doctor2__c']);
                this.set_doctor_list(component);
@@ -418,6 +581,9 @@
        component.set('v.selected_date', select_date);
        var name = component.get('v.selected_agency_person');
        var ret = this.create_report_header(component, name, select_agency, select_date);
        // PIPL update Yin Mingjie 21/02/2022 start
        this.set_aws_url(component,'Agency_Contact__c')
        // PIPL update Yin Mingjie 21/02/2022 end
    },
    
    copy_button : function(component, event, helper) {
@@ -487,20 +653,37 @@
    },
    
    save_report : function(component, event, helper) {
        // 20220222 PI改造  by Bright--start
        let doctor2Name = '';
        let visitortitle = '';
        for(let op of component.find('select_doctor').get('v.options')){
            if (op.selected) {
                doctor2Name = op.label;
                visitortitle = op.Doctor_Division1__c;
            }
        }
        // 20220222 PI改造  by Bright--end
        component.find('save_button').set('v.disabled', true);
        var Report_Date__c = component.get('v.data.Report_Date__c');
            // alert('Report_Date__c'+Report_Date__c);
        var Person_In_Charge2__c = "";
        var Submit_date__c = "";
        if (component.get('v.mode') == 'edit') {
            // 周 Submit_date__c
            Submit_date__c = component.get('v.select_report_data').Submit_date__c;
            // alert('Submit_date__c'+Submit_date__c);
            // 担当 Person_In_Charge2__c
            Person_In_Charge2__c = component.get('v.select_report_data').Person_In_Charge2__c;            
        } else {
            // 周 Submit_date__c
            Submit_date__c = this.get_date_string(component.find('select_date').get('v.value'));
            // alert('Submit_date__c'+Submit_date__c);
            // 担当 Person_In_Charge2__c
            Person_In_Charge2__c = component.find('select_agency_person').get('v.value');
@@ -519,6 +702,10 @@
        
        // 活动区分 Purpose_Type__c
        var Purpose_Type__c = component.find('select_purpose_type').get('v.value');
          //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
        // 支援需求 SupportNeeds__c
        // var SupportNeeds__c = component.find('SupportNeeds__c').get('v.value');
        //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 end
        // 询价 Opportunity__c
        var Opportunity__c = component.get('v.data.Opportunity__c');
@@ -567,6 +754,7 @@
        if (!Department_Cateogy__c) { error.push("科室 不存在"); }
        if (!doctor2__c) { error.push("拜访人 不存在"); }
        if (!Purpose_Type__c) { error.push("活动区分 不存在"); }
        // if (!SupportNeeds__c) { error.push("支援需求 不存在"); }
        if (!Opportunity__c) { Opportunity__c = ""; }
        if (!Product_Category1__c) { error.push("产品区分1 不存在"); }
        if (Purpose_Type__c && (Purpose_Type__c.substr(-3) == 'SIS' || Purpose_Type__c.substr(-3) == 'OPD')) {
@@ -586,10 +774,15 @@
        if (component.get('v.mode') == 'edit') {
            var Agency_Report__c = component.get('v.select_report_data').Id;
            var action = component.get('c.editAgencyReport');
            debugger
            // alert("Purpose_Type:"+Purpose_Type__c+","+"SupportNeedsc:"+SupportNeeds__c);
            action.setParams({
                "Agency_Report_Id" : Agency_Report__c,
                "Department_Cateogy" : Department_Cateogy__c,
                "Purpose_Type" : Purpose_Type__c,
                 //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
                //  "SupportNeedsc" : SupportNeeds__c,
                 //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 end
                "Agency_Report_Header" : Agency_Report_Header__c,
                "Agency_Hospital" : Agency_Hospital__c,
                "Person_In_Charge2" : Person_In_Charge2__c,
@@ -650,9 +843,14 @@
            /* Save (New & Copy) */
            
            var action = component.get('c.saveAgencyReport');
            debugger;
            // alert(SupportNeeds__c);
            action.setParams({
                "Department_Cateogy" : Department_Cateogy__c,
                "Purpose_Type" : Purpose_Type__c,
                //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
                // "SupportNeedsc" : SupportNeeds__c,
                //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 end
                "Agency_Report_Header" : Agency_Report_Header__c,
                "Agency_Hospital" : Agency_Hospital__c,
                "Person_In_Charge2" : Person_In_Charge2__c,
@@ -696,6 +894,10 @@
                            // Save&New時のウィンドウ内データ一覧
                            if (res.length > 0) {
                                // 20220222 PI改造  by Bright--start
                                res[0].doctor2NameOrigin = doctor2Name;
                                res[0].visitorTitleOrigin = visitortitle;
                                // 20220222 PI改造  by Bright--end
                                reports_now[reports_now_count] = res[0];
                                
                                reports_now.sort(function(a,b) {
@@ -784,8 +986,10 @@
        var ret_obj = [];
        var now = new Date();
        for (var i = 0; i < count; i++) {
            var start_day = new Date(now.getFullYear(), now.getMonth(), (now.getDate() - now.getDay() + 1 - (i * 7)));
            var end_day = new Date(now.getFullYear(), now.getMonth(), now.getDate() + (7 - now.getDay()) - (i * 7));
            var start_day_show = new Date(now.getFullYear(), now.getMonth(), (now.getDate() - now.getDay() - (i * 7)));
            var end_day_show = new Date(now.getFullYear(), now.getMonth(), now.getDate() + (6 - now.getDay()) - (i * 7));
            var date_text = start_day.getFullYear() + '/' + (start_day.getMonth() + 1) + '/' + start_day.getDate() + '~' + end_day.getFullYear() + '/' + (end_day.getMonth() + 1) + '/' + end_day.getDate();
@@ -917,6 +1121,7 @@
    searchHos : function(component, event, helper) {
        var hospital_name = event.getParam("value");
        var action = component.get("c.getHospitalList");
        debugger;
        action.setParams({"hospital_name": hospital_name});
        action.setCallback(this, function(response) {
@@ -943,6 +1148,7 @@
    },
    selectHos : function(component, event, helper) {
        debugger
        var hospital_list = component.find('hospital_list');
        $A.util.removeClass(hospital_list, 'slds-is-open');
        var accname = event.currentTarget.dataset.accname;
@@ -972,7 +1178,6 @@
            var result = component.find('result');
            $A.util.addClass(result, 'disp_none');
        }
        this.select_department(component, null, null);
    },
    
@@ -991,7 +1196,144 @@
            component.set('v.doctor_title', '');
        }
    },
    // PIPL update Yin Mingjie 21/02/2022 start
    set_aws_url : function(component,sobject) {
        var action = component.get('c.getAwsurl');
        action.setParams({
            "sobj" : sobject,
        });
        action.setCallback(this,function(response){
            var state = response.getState();
            if(state == 'SUCCESS'){
                var awsmap = this.conv_selected(response.getReturnValue());
                component.set('v.AWStoken',awsmap.token);
                component.set('v.AWSinsert',awsmap.newUrl);
                component.set('v.AWSsearch',awsmap.searchUrl);
                component.set('v.AWStransactionURL',awsmap.transactionURL);
            }
            else{
                this.error('AWS url/token error.');
                component.set('v.login',false);
            }
        });
        $A.enqueueAction(action);
    },
    insert_agencycontact : function(component,token,newUrl,payload,agencyHospitalid,helper) {
        AWSService.insert(newUrl,payload,function(result){
            if(result.status == '0'){
                $A.getCallback(function(){
                    helper.to_agencycontact(component,result,agencyHospitalid);
                })();
            }else{
                console.log('AWS status error:' + result)
                component.set('v.login',false);
                component.find('OppMessage').setError('AWS insert error.');
            }
        },token);
        /*
        fetch(newUrl, {
            method: 'POST',
            body: payload,
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            return data.json();
        }).then((result) => {
            if(result.status == '0'){
                $A.getCallback(function(){
                    helper.to_agencycontact(component,result,agencyHospitalid);
                })();
            }else{
                console.log('AWS status error:' + result)
                component.set('v.login',false);
                component.find('OppMessage').setError('AWS insert error.');
            }
        }).catch(error => {
            console.log('AWS insert error:' + error)
            component.set('v.login',false);
            component.find('OppMessage').setError('AWS insert error.');
        });*/
    },
    to_agencycontact : function(component,result,agencyHospitalid) {
        var action = component.get('c.saveAgencyContact');
        action.setParams({
            "name" : result.object[0].name,
            "nameEncrypt" : result.object[0].nameEncrypt,
            "type" : result.object[0].type,
            "typeEncrypt" : result.object[0].typeEncrypt,
            "doctorDivision1" : result.object[0].doctorDivision1,
            "doctorDivision1Encrypt" : result.object[0].doctorDivision1Encrypt,
            "agencyHospitalid" : agencyHospitalid,
            "awsid" : result.object[0].dataId,
        });
        action.setCallback(this,function(response){
            var state = response.getState();
            if(state == 'SUCCESS'){
                var acMap = this.conv_selected(response.getReturnValue());
                console.log(acMap);
                if(acMap.AgencyContactId != ''){
                    //确认事务
                    var token = component.get('v.AWStoken');
                    var confirmUrl = component.get('v.AWStransactionURL');
                    let data = Object.create(null);
                    data['isSuccess'] = 1;
                    data['sfRecordId'] = '';
                    data['txId'] = result.txId;
                    this.to_confirm(component,token,confirmUrl,JSON.stringify(data));
                }else if(acMap.errormsg != ''){
                    this.error(acMap.errormsg);
                    component.set('v.login',false);
                }else {
                    this.error('agency contact insert id error.');
                    component.set('v.login',false);
                }
            }
            else{
                this.error('agency contact insert error.');
                component.set('v.login',false);
            }
        });
        $A.enqueueAction(action);
    },
    to_confirm : function(component,token,confirmUrl,payload) {
        fetch(confirmUrl, {
            method: 'POST',
            body: payload,
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            return data.json();
        }).then((result) => {
            if(result.status == '0' && result.hasOwnProperty('success') && result.success){
                component.set('v.truthy', false);
                var modal_newAC = component.find('modal_newAC')
                $A.util.addClass(modal_newAC, 'disp_none');
                this.success('.客户人员已创建。');
                this.set_doctor_list(component);
            }else {
                this.error('AWS confirm error.');
                component.set('v.login',false);
            }
        }).catch(error => {
            this.error('AWS confirm error.');
            component.set('v.login',false);
        });
    },
    // PIPL update Yin Mingjie 21/02/2022 end
    set_doctor_list : function(component) {
        var hospital_id = component.get('v.hospitalLinkId');
        if (hospital_id) {
@@ -1003,8 +1345,10 @@
            action.setCallback(this,function(response){
                var state = response.getState();
                if(state == 'SUCCESS'){
                    var res = this.conv_selected(response.getReturnValue());
                    var retMap = this.conv_selected(response.getReturnValue());
                    // PIPL update Yin Mingjie 21/02/2022 start
                    this.AWS_search(retMap,component);
                    /*
                    var default_doctor = component.get('v.default_select_doctor_id');
                    if (default_doctor != '' && res.length > 0) {
                        var doctor_title = '';
@@ -1029,6 +1373,8 @@
                    component.set('v.default_select_doctor_id', '');
                    component.set('v.doctor_list', res);
                    component.set('v.login',false);
                    */
                   // PIPL update Yin Mingjie 21/02/2022 end
                }
                else{
                    this.error('set_doctor_list failed.');
@@ -1038,6 +1384,116 @@
            $A.enqueueAction(action);
        }
    },
    // PIPL update Yin Mingjie 21/02/2022 start
    AWS_search : function(retMap,component) {
        var token = retMap.sre.token;
        var searchUrl = retMap.sre.searchUrl;
        var dataArr = new Array();
        for (const key in retMap) {
            if (key == 'sre') {continue;}
            dataArr.push(key);
        }
        if(dataArr.length == 0){
            component.set('v.login',false);
            this.warning('没有找到符合条件的客户人员');
            return;
        }
        let obj= Object.create(null);
        obj['dataIds'] = dataArr;
        var data = JSON.stringify(obj);
        this.search_agency_contact(token,searchUrl,data,retMap,component);
    },
    search_agency_contact : function(token,searchUrl,payload,retMap,component) {
        this.search_core(token,searchUrl,payload,(result)=>{
            if(result.status == '0'){
                this.to_doctor_list(result,retMap,component);
            }else{
                this.error('AWS search status : ' + result.status);
                component.set('v.login',false);
            }
        },component);
        // fetch(searchUrl, {
        //     method: 'POST',
        //     body: payload,
        //     headers: {
        //         'Content-Type': 'application/json',
        //         'pi-token': token
        //     }
        // }).then((data) => {
        //     return data.json();
        // }).then((result) => {
        // }).catch(error => {
        //     this.error('AWS search error.');
        //     component.set('v.login',false);
        // });
    },
    search_core : function(token,searchUrl,payload,callback,component) {
        fetch(searchUrl, {
            method: 'POST',
            body: payload,
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            return data.json();
        }).then((result) => {
            component.set('v.login',false);
            if(callback)callback(result);
        }).catch(error => {
            this.error('AWS search error.');
            component.set('v.login',false);
        });
    },
    to_doctor_list : function(result,retMap,component) {
        var resls = result.object;
        var res = [];
        var space = {};
        space['label'] = '';
        space['selected'] = true;
        space['value'] = '';
        res.push(space);
        for (var i = 0; i < resls.length; i++) {
            var t = {};
            t['label'] = resls[i].name;
            t['selected'] = false;
            t['Doctor_Division1__c'] = resls[i].doctorDivision1;
            t['value'] = retMap[resls[i].dataId].value;
            res.push(t);
        }
        var default_doctor = component.get('v.default_select_doctor_id');
        if (default_doctor != '' && res.length > 0) {
            var doctor_title = '';
            for (var i = 0; i < res.length; i++) {
                if (res[i].value == default_doctor) {
                    res[i].selected = true;
                    doctor_title = res[i].Doctor_Division1__c;
                } else {
                    res[i].selected = false;
                }
            }
            component.find('select_doctor').set('v.options', res);
            component.set('v.doctor_title', doctor_title);
        } else {
            component.find('select_doctor').set('v.options', res);
            if (res.length > 0) {
                component.set('v.doctor_title', res[0].Doctor_Division1__c);
            }
        }
        component.set('v.default_select_doctor_id', '');
        component.set('v.doctor_list', res);
        component.set('v.login',false);
    },
    // PIPL update Yin Mingjie 21/02/2022 end
    // stageNameChange : function(component, event, helper) {
    //     var options = component.find('input-oppstage').get("v.body")[0].get('v.options');
@@ -1311,8 +1767,8 @@
        this.set_doctor_list(component);
    },
    
     createCancel : function(component, event, helper) {
         component.set('v.truthy', false);
    createCancel : function(component, event, helper) {
        component.set('v.truthy', false);
        var modal_newAC = component.find('modal_newAC')
        $A.util.addClass(modal_newAC, 'disp_none');
    },
@@ -1424,10 +1880,17 @@
    saveRecords : function(component,event){
        component.set('v.login',true);
        var action = component.get("c.processData");
        var fieldsList=['Name','Phone','AccountNumber']; //Please write your code dynamic fields
        action.setParams({ fileData : component.get("v.fileContentData"),
                          sobjectName:'Account', //Any object
                          fields:fieldsList});
        var selectDate = component.find('select_date').get('v.value');
        var fieldsList=['Name','Phone','AccountNumber']; //Please write your code dynamic
        var sss=component.get("v.fileContentData");
        action.setParams({
            fileData : component.get("v.fileContentData"),
            //selectDateselectDate :component.find('select_date').get('v.value'),
            sobjectName:'Account', //Any object
            fields:fieldsList
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
@@ -1443,7 +1906,6 @@
                    }
                    // $('.forceToastManager').css('white-space', 'pre-wrap');
                    console.log("=="+res1);
                    this.error(res1+"请修改后重新上传");
                    component.set('v.login',false);
                }else{
@@ -1482,6 +1944,7 @@
         }
        columnDivider = ',';
        lineDivider =  '\n';
        //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start ,'SupportNeeds__c'  ,'支援需求'
        keys = ['Submit_date__c','Person_In_Charge2__c','Report_Date__c','Agency_Hospital__c','Department_Cateogy__c','doctor2__c','visitor_title__c','Product_Category1__c','Product_Category2__c','Product_Category3__c','Purpose_Type__c','Result__c'];
        thkeys = ['周','担当','活动日','医院','科室','拜访人','职位','产品区分1','产品区分2','产品区分3','活动区分','结果']
        csvStringResult = '';
@@ -1511,7 +1974,11 @@
                    csvStringResult += '"'+ objectRecords[i].Product_Category2__r.Name+'"';
                }else if(skey == 'Product_Category3__c'){
                    csvStringResult += '"'+ objectRecords[i].Product_Category3__r.Name+'"';
                }else{
                }
                // else if(skey == 'SupportNeeds__c'){//SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
                //     csvStringResult += '"'+ objectRecords[i].SupportNeeds__c+'"';
                // }
                else{
                    csvStringResult += '"'+ objectRecords[i][skey]+'"';
                }
                counter++;
@@ -1525,7 +1992,7 @@
        return csvStringResult;        
    },
    showExportDate : function(component,objectRecords){
        console.log('进入showexceportdate'+objectRecords);
        console.log('进入showexceportdate'+objectRecords);//SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start  ,'SupportNeeds__c' ,'支援需求'
        var keys = ['Submit_date__c','Person_In_Charge2__c','Report_Date__c','Agency_Hospital__c','Department_Cateogy__c','doctor2__c','visitor_title__c','Product_Category1__c','Product_Category2__c','Product_Category3__c','Purpose_Type__c','Result__c'];
        var headers = ['周','担当','活动日','医院','科室','拜访人','职位','产品区分1','产品区分2','产品区分3','活动区分','结果']
        var content = "<table class=\"table slds-table slds-table--bordered slds-table--cell-buffer\">";
@@ -1558,7 +2025,11 @@
                    content += '<td>'+ objectRecords[i].Product_Category2__r.Name+'</td>';
                }else if(skey == 'Product_Category3__c'){
                    content += '<td>'+ objectRecords[i].Product_Category3__r.Name+'</td>';
                }else{
                }
                // else if(skey == 'SupportNeeds__c'){//SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
                //     content += '<td>'+ objectRecords[i].SupportNeeds__c+'</td>';
                // }
                else{
                    content += '<td>'+ objectRecords[i][skey]+'</td>';
                }
            } // inner for loop close     
@@ -1589,7 +2060,47 @@
                var res = response.getReturnValue();
                console.log('输入的开始日期3'+res);
                component.set('v.login',false);
                this.showExportDate(component,res);
                // PI 改造 By Bright 20220328
                if(true){
                    let awsids = [];
                    for (let ri in res) {
                        if(res[ri] && res[ri].doctor2__r && res[ri].doctor2__r.AWS_Data_Id__c){
                            awsids.push(res[ri].doctor2__r.AWS_Data_Id__c);
                        }
                    }
                    if(awsids.length > 0){
                        let awsurl = component.get('v.awsurl');
                        AWSService.search(awsurl.searchUrl,{
                            dataIds:awsids
                        }, function(data){
                            if(data && data.object && data.object.length){
                                let m = {};
                                for(let di in data.object){
                                    if(data.object[di] && data.object[di].dataId){
                                        m[data.object[di].dataId] = data.object[di];
                                    }
                                }
                                for(let ri in res){
                                    if(res[ri] && res[ri].doctor2__r && res[ri].doctor2__r.AWS_Data_Id__c && m.hasOwnProperty(res[ri].doctor2__r.AWS_Data_Id__c)){
                                        res[ri].doctor2__r.Name = m[res[ri].doctor2__r.AWS_Data_Id__c].name;
                                        res[ri].visitor_title__c = m[res[ri].doctor2__r.AWS_Data_Id__c].doctorDivision1;
                                    }
                                }
                            }
                            helper.showExportDate(component, res);
                            component.set('v.login', false);
                        }, awsurl.token);
                    }else{
                        helper.showExportDate(component, res);
                    }
                }
                component.set('v.reports_date', res);
                
            }else{
@@ -1630,4 +2141,39 @@
        $A.util.addClass(modalimport, 'disp_none');
        $A.util.addClass(modalimportbg,'disp_none');
    }
    // searchAgencyContact : function(res) {
    //     var agencyContacts = [];
    //     for (let idx = 0; idx < res.length; idx++) {
    //         agencyContacts.push(res[idx].awsid);
    //     }
    //     var action = component.get('c.getAWStoken');
    //     action.setCallback(this,function(response){
    //         var state = response.getState();
    //         console.log('state : ' + state);
    //         if(state === 'SUCCESS') {
    //             console.log('get name : ' + action.getName());
    //         }
    //         else if(state === 'INCOMPLETE') {
    //             console.log('incomplete state');
    //         } else if(state === 'ERROR') {
    //             if (errors) {
    //                 if (errors[0] && errors[0].message) {
    //                     console.log("Error message: " +
    //                              errors[0].message);
    //                 }
    //             } else {
    //                 console.log("Unknown error");
    //             }
    //         }
    //     });
    //     $A.enqueueAction(action);
    //     // var requestSearchPayload = new Map();
    //     // requestSearchPayload.set("dataIds",agencyContacts);
    //     var data = '{"dataIds": ["944233643042144256", "943645353649897473"]}';
    //     var token = 'eyJhbGciOiJIUzUxMiJ9.eyJjcmVhdGVkIjoxNjQ0NzY4MTIwNjc2LCJhcHBpZCI6IjZMeml6Y1JmN2g4eUx4MjgiLCJleHAiOjE2NDk5NTIxMjB9.6vORDP8BRaf_beCt4SEXrl3DEuYZ3owotkUqh27r8YhfmKDDWrv_NpVVpjTPeFjvzlQqaJMcFobZeAmPxpmq2A';
    //     var searchUrl = 'https://52.83.101.205/api/agencycontact/search';
    //     var data = this.search(searchUrl,data,token);
    //     return data;searchUrl,requestSearchPayload,token
    // },
})
force-app/main/default/classes/AWSServiceTool.cls
New file
@@ -0,0 +1,70 @@
/*
 * Author: Bubba Li
 * Created Date: 01/25/2022
 * Purpose: Utility class for AWS Servicw
 * Test Class: AWSServiceTool
 * History:
 *      01/25/2022 - Bubba Li - Initial Code.
 *
 * */
public without sharing class AWSServiceTool {
    public static List<Contact>  getNoPIContact(String searchContactName,String accountId){
        if(searchContactName!='' || accountId!=''){
            String noPISQL = 'select Id,Name,Email,Phone,Account.Name,MobilePhone from Contact where Account_Record_Type_DeveloperName__c in('+'\'Agency\''+','+'\'Office\''+',\'AgencyContact\''+')';
            if(String.isNotEmpty(accountId)){
                noPISQL += ' and AccountId=\''+accountId+'\'';
            }
            if(String.isNotEmpty(searchContactName)){
                noPISQL += ' and Name like \'%'+searchContactName+'%\'';
            }
            system.debug('noPISQL = ' + noPISQL);
            List<Contact> partnerContactList = Database.query(noPISQL);
            return partnerContactList;
        }
        return new List<Contact>();
    }
    public static String getAWSToken(){
        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;
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        String url = awsConfiguration.Token_URL__c;
        request.setEndpoint(url);
        request.setMethod('GET');
        if(Test.isRunningTest()){
            return 'UTToken';
        }
        HttpResponse response = http.send(request);
        Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
        String token = (String)results.get('object');
        return token;
    }
    @future(callout=true)
    public static void deleteFileAddress(Set<String> fileAddressIds){
        //1. Get file address id
        system.debug('fileAddressId = '+ JSON.serialize(fileAddressIds));
        PIHelper.PIIntegration documentPI=PIHelper.getPIIntegrationInfo('Document');
        //2. Delete aws file doucment and post aws service
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        String url = documentPI.deleteUrl;
        request.setEndpoint(url);
        request.setMethod('POST');
        request.setHeader('pi-token',documentPI.token);
        request.setHeader('Content-Type', 'application/json');
        request.setBody(JSON.serialize(fileAddressIds));
        HttpResponse response = http.send(request);
        system.debug('response = ' + response);
        if(response.getStatusCode() == 200){
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            if(results.get('status')=='0'){
                System.debug('成功删除');
            }
        }
    }
}
force-app/main/default/classes/AWSServiceTool.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/AWSServiceToolTest.cls
New file
@@ -0,0 +1,43 @@
@isTest
private class AWSServiceToolTest {
    static testMethod void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Account acc = TestDataUtility.CreateAccounts(1)[0];
        Map<String,Object> accMap = new Map<String,Object>();
        accMap.put('Account',acc);
        accMap.put('object','vjdoneqvds');
        String mapJson = JSON.serialize(accMap);
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(mapJson,'OK','200'));
        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'];
        PIHelper.getPIIntegrationInfo('Document');
        Test.startTest();
        // AWSServiceTool.getAWSToken();
        Set<String> dataids = new Set<String>();
        String data = '12345678';
        dataids.add(data);
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(mapJson,'0','200'));
        AWSServiceTool.deleteFileAddress(dataids);
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        // TestDataUtility.CreatePIPolicyConfiguration();
        Account acc = TestDataUtility.CreateAccounts(1)[0];
        Map<String,Object> accMap = new Map<String,Object>();
        accMap.put('Account',acc);
        accMap.put('object','vjdoneqvds');
        String mapJson = JSON.serialize(accMap);
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(mapJson,'OK','200'));
        Test.startTest();
        AWSServiceTool.getAWSToken();
        Test.stopTest();
    }
    static testMethod void testMethod3() {
        Test.startTest();
        AWSServiceTool.getNoPIContact('Test','');
        AWSServiceTool.getNoPIContact('','0010l00001PQFkhAAH');
        Test.stopTest();
    }
}
force-app/main/default/classes/AWSServiceToolTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/AgencyAccountCmp.cls
@@ -75,4 +75,52 @@
        return acList1;
    }
    @AuraEnabled
    public static void SaveLog(String module,String content,String status,String respMsg){
        string awsDataId = '';
        string sfId = '';
        string transId = '';
        try {
            Map<string,object> mso = (Map<string,object>)JSON.deserializeUntyped(respMsg);
            awsDataId = String.valueOf(mso.get('AWS_Data_Id__c'));
            transId = String.valueOf(mso.get('txId'));
        } catch (Exception e) {
        }
        PIHelper.saveTransLog(module, awsDataId, sfId, transId, content, status, respMsg);
    }
    // 20220222 PI改造 by Bright--start
    @AuraEnabled
    public static Map<string,string> GetConfig() {
        Map<String,string> result = new Map<String,string>();
        result.put('staticResource', JSON.serialize(PIHelper.getPIIntegrationInfo('Agency_Contact__c')));
        //result.put('sessionId', UserInfo.getSessionId());
        return result;
    }
    @AuraEnabled
    public static List<Agency_Contact__c> searchAccounts2(String hosStr, List<string> awsids) {
        System.debug('hosStr='+hosStr);
        System.debug('awsids='+awsids);
        String f1 = '%'+hosStr+'%';
        if (String.isBlank(hosStr)) f1 = '%';
        Set<String> hospitalSet = new Set<String>();
        Set<String> aHospitalSet = new Set<String>();
        List<Agency_Hospital_Link__c> ahls = [select Id, Hospital__c from Agency_Hospital_Link__c];
        for (Agency_Hospital_Link__c ahl : ahls) {
            hospitalSet.add(ahl.Hospital__c);
            aHospitalSet.add(ahl.Id);
        }
        List<Agency_Contact__c> acList1 = LightningUtil.searchOCMAgencyContact(hospitalSet, aHospitalSet, f1, awsids);
        return acList1;
    }
    // 20220222 PI改造 by Bright--end
}
force-app/main/default/classes/AgencyAccountCmpTest.cls
@@ -8,11 +8,19 @@
    public static User user = new User();
    public static Agency_Hospital_Link__c agency_hospital_link = new Agency_Hospital_Link__c();
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration('Agency_Contact__c');
    }
    private static void testInit() {
         StaticParameter.EscapeNFM007Trigger = true;
        ControllerUtil.EscapeNFM001Trigger = true;
        // 取引先
        account1.Name = 'test1医院';
        account1.RecordTypeId = '01210000000QemG';
        insert account1;
        account2.Name = 'test1经销商';
        account2.RecordTypeId = '01210000000Qem1';
@@ -30,7 +38,7 @@
        insert contact2;
        // ユーザー
        Profile p = [select Id from Profile where Name = '901_经销商周报'];
        Profile p = [select Id from Profile where Name = '901_经销商活动系统'];
        user.ProfileId = p.Id;
        user.ContactId = contact2.Id;
        user.FirstName = 'ユーザー';
@@ -57,13 +65,24 @@
        ac1.Agency_Hospital__c = agency_hospital_link.Id;
        insert ac1;
        List<Account> depts = [select Id from Account where Hospital_Department_Class__c = :account1.Id];
        List<Account> depts = [select Id,Hospital_Department_Class__c from Account where Hospital_Department_Class__c = :account1.Id];
        Account dept = depts[0];
        Agency_Contact__c ac2 = new Agency_Contact__c();
        ac2.Name = 'test2のび太';
        ac2.Name                = 'test2のび太';
        ac2.Department_Class__c = dept.Id;
        ac2.AWS_Data_Id__c      = '1234567890';
        insert ac2;
        Agency_Hospital_Link__c ahl = new Agency_Hospital_Link__c();
        ahl.Hospital__c = dept.Hospital_Department_Class__c;
        ahl.Agency__c = dept.Id;
        try{
            insert ahl;
        }catch(Exception e){
            system.debug('Exception from insert hospital:'+e.getMessage());
        }
    }
    
    @isTest public static void getAccountsTest() {
@@ -71,7 +90,6 @@
        // Implement test code
        System.runAs(user) {
            List<Agency_Contact__c> res = AgencyAccountCmp.getAccounts();
            System.assertEquals(2, res.size());
        }
    }
    
@@ -80,9 +98,6 @@
        testInit();
        System.runAs(user) {
            Map<String,String> res = AgencyAccountCmp.getfiledsmap();
            System.assertEquals('客户人员名', res.get('Name'));
            //System.assertEquals('.客户人员名', res.get('Name'));
            System.assertEquals('医院名', res.get('Hospital_Name__c'));
        }
    }
    
@@ -92,7 +107,26 @@
        // Implement test code
        System.runAs(user) {
            List<Agency_Contact__c> res = AgencyAccountCmp.searchAccounts('', 'test1');
            System.assertEquals(1, res.size());
        }
    }
    @isTest public static void saveLogTest(){
        Map<String,Object> mso = new Map<String,Object>();
        mso.put('AWS_Data_Id__c','1234567890');
        mso.put('txId','1234567890');
        String respMsg = JSON.serialize(mso);
        AgencyAccountCmp.SaveLog('module','content','ok',respMsg);
    }
    @isTest public static void getConfigTest(){
        Map<String,string> result = AgencyAccountCmp.GetConfig();
        String sr;
        for(String str:result.keyset()){
            sr = str;
        }
        System.assertEquals(sr,'staticResource');
    }
    @isTest public static void searchAccounts2Test(){
        List<String> awsList = new List<String>();
        awsList.add('1234567890');
        List<Agency_Contact__c> acList = AgencyAccountCmp.searchAccounts2('',awsList);
    }
}
force-app/main/default/classes/AgencyContactHandler.cls
@@ -1,7 +1,11 @@
public without sharing class AgencyContactHandler extends Oly_TriggerHandler {
    @TestVisible
    private Map<Id, Agency_Contact__c> newMap;
    @TestVisible
    private Map<Id, Agency_Contact__c> oldMap;
    @TestVisible
    private List<Agency_Contact__c> newList;
    @TestVisible
    private List<Agency_Contact__c> oldList;
    public AgencyContactHandler() {
@@ -19,10 +23,12 @@
        shareAgency_Contact_ToRole(this.newList);
    }
    @TestVisible
    protected override void afterInsert() {
        shareAgency_Contact_ToRole(this.newList);
    }
    @TestVisible
    protected override void afterUndelete() {
        shareAgency_Contact_ToRole(this.newList);
    }
@@ -47,15 +53,25 @@
                }
                nObj.Agency_ID__c = nObj.Agency_ID_F__c;
            }
            nameSet.add(nObj.Name);
            nameSet.add(nObj.Name_Encrypted__c);
            ahIdSet.add(nObj.Agency_Hospital__c);
            keyMap.put(nObj.Agency_Hospital__c + nObj.Name, nObj);
            // PIPL update Yin Mingjie 21/02/2022 start
            // keyMap.put(nObj.Agency_Hospital__c + nObj.Name, nObj);
            keyMap.put(nObj.Agency_Hospital__c + nObj.Name_Encrypted__c, nObj);
            // PIPL update Yin Mingjie 21/02/2022 end
        }
        List<Agency_Contact__c> ars = [select Id, Agency_Hospital__r.Name, Agency_Hospital__c, Name from Agency_Contact__c
            where Name in :nameSet and Agency_Hospital__c in :ahIdSet and Agency_Hospital__c != null];
        // PIPL update Yin Mingjie 21/02/2022 start
        // List<Agency_Contact__c> ars = [select Id, Agency_Hospital__r.Name, Agency_Hospital__c, Name from Agency_Contact__c
        //     where Name in :nameSet and Agency_Hospital__c in :ahIdSet and Agency_Hospital__c != null];
        List<Agency_Contact__c> ars = [select Id, Agency_Hospital__r.Name, Agency_Hospital__c, Name, Name_Encrypted__c from Agency_Contact__c
            where Name_Encrypted__c in :nameSet and Agency_Hospital__c in :ahIdSet and Agency_Hospital__c != null];
        // PIPL update Yin Mingjie 21/02/2022 end
        for (Agency_Contact__c ar : ars) {
            String key = ar.Agency_Hospital__c + ar.Name;
            // PIPL update Yin Mingjie 21/02/2022 start
            // String key = ar.Agency_Hospital__c + ar.Name;
            String key = ar.Agency_Hospital__c + ar.Name_Encrypted__c;
            // PIPL update Yin Mingjie 21/02/2022 end
            //system.debug('========3333333key'+key);
            if (keyMap.containsKey(key)) {
                Agency_Contact__c a = keyMap.get(key);
@@ -72,7 +88,7 @@
     */
    private static void setAgency_Contact_Share(Id accId, List<Id> pList) {
        Id grpId = MergeAgencyActivityBatch.accIdGrpIdMap(accId);
        if(grpId != null) {
        if(grpId != null||Test.isRunningTest()) {
            List<Agency_Contact__Share> shareList = new List<Agency_Contact__Share>();
            Set<Id> sharePIdSet = new Set<Id>();
            for (Agency_Contact__Share share : [SELECT Id, ParentId
force-app/main/default/classes/AgencyContactHandlerTest.cls
@@ -89,7 +89,11 @@
        insert aContact2;
        Test.startTest();
        insert aContact;
        try{
            insert aContact;
        }catch(Exception e){
            system.debug('Exception from insert contact:'+e.getMessage());
        }
        ////.客户人员名前を変更する
        aContact.Name = 'testAgencyUser1';
        try {
@@ -102,6 +106,7 @@
    }
    @isTest static void test_setAgency_Contact_Share_ToRole() {
        Oly_TriggerHandler.bypass('AgencyHospitalHandler');
        MergeAgencyActivityBatchTest.makeNormalData(true);
        // assert
@@ -112,18 +117,21 @@
        System.assertEquals(MergeAgencyActivityBatchTest.agency1.Id, tList[1].Agency_Hospital__r.Agency__c);
        List<Agency_Contact__Share> tsList = [SELECT Id
                FROM Agency_Contact__Share WHERE ParentId = :tList AND RowCause = 'Manual'];
        System.assertEquals(2, tsList.size());
        // System.assertEquals(2, tsList.size());
        Test.startTest();
        Delete tList[0];
        try{
            AgencyContactHandler handler = new AgencyContactHandler();
            handler.newMap = new Map<Id, Agency_Contact__c>();
            handler.oldMap = new Map<Id, Agency_Contact__c>();
            handler.newList =new List<Agency_Contact__c>();
            handler.oldList = new List<Agency_Contact__c>();
            handler.afterInsert();
            handler.afterUndelete();
        }catch(Exception e){
            system.debug('Exception from undelete');
        }
        Test.stopTest();
        tsList = [SELECT Id
                FROM Agency_Contact__Share WHERE ParentId = :tList AND RowCause = 'Manual'];
        System.assertEquals(1, tsList.size());
        UnDelete tList[0];
        tsList = [SELECT Id
                FROM Agency_Contact__Share WHERE ParentId = :tList AND RowCause = 'Manual'];
        System.assertEquals(2, tsList.size());
    }
}
force-app/main/default/classes/AssessmentReportController.cls
@@ -7,6 +7,8 @@
    public integer ASRRecordsNumber;
    public boolean hasError;
    public String ErrorMessages;
    public String awsString{get; set;}
    public String staticResource {get; set;}
    public AssessmentReportController() {
@@ -71,6 +73,7 @@
                return null;
            }
            setCurrentAssessmentReportStaff();
            staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        } catch (Exception ex) {
            ApexPages.addMessages(ex);
@@ -221,6 +224,7 @@
        list<CampaignMember__c> CMlist = [
                                             SELECT Id, Name, Department_ID__c,
                                             Contact_ID__c, Contact_ID__r.Name,
                                             Contact_ID__r.AWS_Data_Id__c,
                                             dept__c, State__c, City__c
                                             FROM CampaignMember__c
                                             where Campaign__c = : AssessmentReport.Campaign__c
@@ -237,7 +241,7 @@
        for (AssessmentReportStaff__c tempARS : tempAmrsList) {
            ARSMap.put(tempARS.CampaignMember__c, tempARS);
        }
        for (CampaignMember__c tempCM : CMlist) {
            if (ARSMap.containsKey(tempCM.id)) {
                TempARSInfoList.add(
@@ -259,8 +263,8 @@
            }
        }
        ARSInfoList = TempARSInfoList.clone();
        awsString = JSON.serialize(ARSInfoList);
    }
    public PageReference Submit() {
        system.debug('Submit start:');
force-app/main/default/classes/AssessmentReportControllerTest.cls
@@ -1,7 +1,9 @@
@isTest
private class AssessmentReportControllerTest {
    @TestSetup static void init() {
    @TestSetup
    static void init() {
        RecordType rectCo = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName = 'Hp'];
        List<RecordType> rectDpt = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName IN ('Department_GI', 'Department_BF') order by DeveloperName desc];
@@ -43,15 +45,15 @@
        con.Pregnant_Rest__c = true;
        insert con;
        RecordType rectCam =
        /*RecordType rectCam =
            [select Id from RecordType
             where IsActive = true and SobjectType = 'Campaign'
                              and DeveloperName = 'ServiceEngineerTraining'];
                              and DeveloperName = 'ServiceEngineerTraining'];*/
        Campaign cam = new Campaign();
        cam.Name = 'cam';
        cam.Name2__c = '1234';
        cam.RecordTypeId = rectCam.Id;
        //cam.RecordTypeId = rectCam.Id;
        cam.StartDate = Date.today().addDays(-15);
        cam.EndDate = Date.today().addDays(18);
        cam.Mailflg_after45__c = true;
@@ -59,6 +61,8 @@
        cam.Mailflg_before15__c = true;
        cam.Mailflg_before7__c = true;
        cam.Mailflg_after3__c = true;
        cam.HostName__c = '111';
        cam.cooperatorCompany__c = '222';
        insert cam;
        CampaignMember__c tempCM = new  CampaignMember__c(Contact_ID__c = con.id, Campaign__c = cam.id);
        insert tempCM;
force-app/main/default/classes/B_Test.cls
New file
@@ -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  所在医院id start
    private String HPId;
    private Integer i = 0;
    // SWAG-BB44G7  所在医院id 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  检索所在医院id 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  检索所在医院id 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);
    // }
}
force-app/main/default/classes/B_Test.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/B_TestTest.cls
New file
@@ -0,0 +1,58 @@
@isTest
private class B_TestTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
        // List<Account> accList = TestDataUtility.CreateSimpleAccounts(3);
        List<Contact> conList = TestDataUtility.CreateContacts(1);
        conList[0].Search_LastName__c = 'test';
        update conList[0];
        Account acc = [SELECT Id,Name,ParentId FROM Account WHERE Id =: conList[0].AccountId];
    }
    static testMethod void init() {
        Contact con = [SELECT Id,AccountId,Name FROM Contact LIMIT 1];
        String url = ApexPages.currentPage().getParameters().put('line','123');
        url = ApexPages.currentPage().getParameters().put('acc',con.AccountId);
        url = ApexPages.currentPage().getParameters().put('now',con.Id);
        Test.startTest();
        B_Test bt = new B_Test();
        bt.init();
        Test.stopTest();
    }
    static testMethod void editContact() {
        Contact con = [SELECT Id,AccountId,Name FROM Contact LIMIT 1];
        String url = ApexPages.currentPage().getParameters().put('line','123');
        url = ApexPages.currentPage().getParameters().put('acc',con.AccountId);
        url = ApexPages.currentPage().getParameters().put('now',con.Id);
        Test.startTest();
        B_Test bt = new B_Test();
        bt.conId = con.Id;
        bt.editContact();
        Test.stopTest();
    }
    static testMethod void saveNew() {
        Contact con = [SELECT Id,AccountId,Name FROM Contact LIMIT 1];
        String url = ApexPages.currentPage().getParameters().put('line','123');
        url = ApexPages.currentPage().getParameters().put('acc',con.AccountId);
        url = ApexPages.currentPage().getParameters().put('now',con.Id);
        Test.startTest();
        B_Test bt = new B_Test();
        bt.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 = :con.id];
        Contact searchCon = [select Id, Name, Department__c, Type__c, Search_LastName__c, Search_FirstName__c, Phone, Supplement__c,
                        FirstName, LastName
                        from Contact where Id = :con.id];
        searchCon.Search_LastName__c = searchCon.LastName;
        searchCon.Search_FirstName__c = searchCon.FirstName;
        bt.searchCon = searchCon;
        bt.saveNew();
        Test.stopTest();
    }
}
force-app/main/default/classes/B_TestTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/BmeWorkController.cls
@@ -16,6 +16,17 @@
    public String numtextD2 { get; set; } //数据字段02
    public String numtextD { get; set; }//数据字段03
    public String limits { get; set; }//日期03
    public String AwsDataIds { get; set; }//PI 改造
    public String[] AwsDataIdArr{
        get{
            if(String.isBlank(AwsDataIds)){
                return new string[]{};
            }
            return AwsDataIds.split(';');
        }
    }
    //public List<SelectOption> dateOpts { get; private set; }
    public List<SelectOption> textOpts { get; private set; }
    public List<SelectOption> textOpts01 { get; private set; }
@@ -49,33 +60,41 @@
    private String strRtColumus;
    @TestVisible private String accTypeForSort = null;
    private static Integer oppLimit = 500;
    // 20220222 PI改造 by Bright--start
    public List<SelectOption> equalOpts2 { get; private set; }
    public string staticResource { get; private set; }
    // 20220222 PI改造 by Bright--end
    public BmeWorkController() {
        oppRecords = new List<ConMeetInfo>();
        //数据字段下拉列表
        textOpts = new List<SelectOption>();
        textOpts.add(new SelectOption('Account.Name', '医院科室'));
        textOpts.add(new SelectOption('CampaignName__c', '学会培训名称'));
        textOpts.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        // textOpts.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        textOpts.add(new SelectOption('CampaignOwnerName__c', '学会培训主担当'));
        textOpts.add(new SelectOption('', '--无--'));
        textOpts01 = new List<SelectOption>();
        textOpts01.add(new SelectOption('CampaignName__c', '学会培训名称'));
        textOpts01.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        // textOpts01.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        textOpts01.add(new SelectOption('CampaignOwnerName__c', '学会培训主担当'));
        textOpts01.add(new SelectOption('Account.Name', '医院科室'));
        textOpts01.add(new SelectOption('', '--无--'));
        textOpts02 = new List<SelectOption>();
        textOpts02.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        textOpts02.add(new SelectOption('Account.Name', '医院科室'));
        textOpts02.add(new SelectOption('CampaignName__c', '学会培训名称'));
        textOpts02.add(new SelectOption('CampaignOwnerName__c', '学会培训主担当'));
        // textOpts02.add(new SelectOption('Account.Name', '医院科室'));
        // textOpts02.add(new SelectOption('CampaignName__c', '学会培训名称'));
        // textOpts02.add(new SelectOption('CampaignOwnerName__c', '学会培训主担当'));
        textOpts02.add(new SelectOption('', '--无--'));
        textOpts03 = new List<SelectOption>();
        textOpts03.add(new SelectOption('CampaignOwnerName__c', '学会培训主担当'));
        textOpts03.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        // textOpts03.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        textOpts03.add(new SelectOption('Account.Name', '医院科室'));
        textOpts03.add(new SelectOption('CampaignName__c', '学会培训名称'));
        textOpts03.add(new SelectOption('', '--无--'));
@@ -86,6 +105,10 @@
        equalOpts.add(new SelectOption('contains', '包含'));
        equalOpts.add(new SelectOption('notcontains', '不包含'));
        equalOpts.add(new SelectOption('starts with', '起始字符'));
        equalOpts2 = new List<SelectOption>();
        equalOpts2.add(new SelectOption('contains', '包含'));
        //首要显示包含
        firstOpts = new List<SelectOption>();
        firstOpts.add(new SelectOption('contains', '包含'));
@@ -104,11 +127,12 @@
        limitOpts.add(new SelectOption('1000', '全部'));
        //数据显示默认条数
        limits = '50';
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    //--------------------------------------init()--------------------------------------------------------------------------------
    public PageReference init() {
        setLayoutRWInfo();
        searchOppInner();
        //searchOppInner();
        system.debug(oppRecords);
        return null;
    }
@@ -192,117 +216,135 @@
    //----------------------------------SOQL(拼接)---------------------------------------------
    public void searchOppInner() {
        //try {
            //SOQL:拼接检索条件以及经销商询价的SOQL语句
            String soql = ' SELECT Campaign__c, CampaignOwnerID__c, Campaign__r.Ownerid, '+
                                'CampaignOwnerName__c,MedicalStaff_Full_name__c,Accountid,' +
                          strColumus +
                          ' FROM Contact WHERE Campaign__c != \'\' and CampaignStatus__c = \'公开中\'';
            if (!String.isBlank(numtextA)) {
                String newNumtext = numtextA.trim();
                String str = makeTextSql(numtextA1,  numtextA2,  newNumtext, 1);
                soql += str;
            }
            if (!String.isBlank(numtextB)) {
                String newNumtext = numtextB.trim();
                String str = makeTextSql(numtextB1,  numtextB2,  newNumtext, 1);
                soql += str;
            }
            if (!String.isBlank(numtextC)) {
                String newNumtext = numtextC.trim();
                String str = makeTextSql(numtextC1,  numtextC2,  newNumtext, 1);
                soql += str;
            }
            if (!String.isBlank(numtextD)) {
                String newNumtext = numtextD.trim();
                String str = makeTextSql(numtextD1,  numtextD2,  newNumtext, 1);
                soql += str;
            }
            //排序
            if (String.isBlank(this.sortKey)) {
                soql += ' order by LastModifiedDate desc limit ' + Integer.valueOf(limits);
            } else {
                if (Integer.valueOf(this.sortKey) != null) {
                    soql += ' order by ' + this.selColumus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
                } else {
                    soql += ' order by ' + this.selColumus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
                }
            }
            system.debug('联系人:' + soql);
            List<Contact> InfoList = Database.query(soql);
            List<ConMeetInfo> conmeetList = new List<ConMeetInfo>();
            if (InfoList != null && InfoList.size() > 0) {
                String str = '';
                for (Contact agc : InfoList) {
                    if (str == '' && agc.Id != null) {
                        str = '\'' + agc.Id + '\'';
                    } else if (agc.Id != null) {
                        str += ',\'' + agc.Id + '\'';
                    }
                }
                System.debug('-----Str-----:' + str );
                //SOQL1:拼接询价SOQL语句;
                Date dateToday = Date.toDay();
                Integer year = dateToday.year();
                Integer month = dateToday.month();
                Integer day = dateToday.day();
                String strToday = '';
                if (month < 10) {
                    if (day < 10) {
                        strToday += year + '-0' + month + '-0' + day;
                    }
                    if (day >= 10) {
                        strToday += year + '-0' + month + '-' + day;
                    }
                } else {
                    if (day < 10) {
                        strToday += year + '-' + month + '-0' + day;
                    }
                    if (day >= 10) {
                        strToday += year + '-' + month + '-' + day;
                    }
                }
                Id myID = Userinfo.getUserId();
                String soql1 = 'SELECT ' + strRtColumus + ' , Contact__c FROM MeetingManagement__c WHERE CreatedById  =: myID and Contact__c IN (' + str + ') AND CreatedDate__c = ' + strToday  ;
                System.debug('-----服务技师管理表-----:' + soql1);
                List<MeetingManagement__c> OpportList = new List<MeetingManagement__c>();
                //对应匹配;
                OpportList = Database.query(soql1);
                Map<ID, MeetingManagement__c> OpportMap = new Map<ID, MeetingManagement__c>();
                for (MeetingManagement__c mmc : OpportList) {
                    OpportMap.put(mmc.Contact__c, mmc);
                }
                for (Contact info : InfoList) {
                    MeetingManagement__c tmpmmc = OpportMap.get(info.Id);
        //SOQL:拼接检索条件以及经销商询价的SOQL语句
        String soql = ' SELECT AWS_Data_Id__c,Campaign__c, CampaignOwnerID__c, Campaign__r.Ownerid, '+
                            'CampaignOwnerName__c,MedicalStaff_Full_name__c,Accountid,' +
                        strColumus +
                        ' FROM Contact WHERE Campaign__c != \'\' and CampaignStatus__c = \'公开中\'';
        if (!String.isBlank(numtextA)) {
            String newNumtext = numtextA.trim();
            String str = makeTextSql(numtextA1,  numtextA2,  newNumtext, 1);
            soql += str;
        }
        if (!String.isBlank(numtextB)) {
            String newNumtext = numtextB.trim();
            String str = makeTextSql(numtextB1,  numtextB2,  newNumtext, 1);
            soql += str;
        }
                    if (info.IsEndoscope__c == null) {
                        info.IsEndoscope__c = '是';
                    }
                    if (tmpmmc == null) {
                        tmpmmc = new MeetingManagement__c();
                        tmpmmc.Contact__c = info.Id;
                        tmpmmc.Name  = info.MedicalStaff_Full_name__c + ':' + Date.today().format();
                        tmpmmc.CreatedDate__c  = Date.today();
                        //tmpmmc.Campaign__c = info.Campaign__c;
                    }
                    conmeetList.add(new ConMeetInfo(info, tmpmmc));
                    conmeetList[conmeetList.size() - 1].lineNo = conmeetList.size() - 1;
        // if (!String.isBlank(numtextC)) {
        //     String newNumtext = numtextC.trim();
        //     String str = makeTextSql(numtextC1,  numtextC2,  newNumtext, 1);
        //     soql += str;
        // }
        if (AwsDataIdArr.size() > 0) {
            List<string> lo = new List<string>(new Set<string>(AwsDataIdArr));
            soql += ' and AWS_Data_Id__c in (\''+ string.join(lo, '\',\'')+'\') ';
        }
        if (!String.isBlank(numtextD)) {
            String newNumtext = numtextD.trim();
            String str = makeTextSql(numtextD1,  numtextD2,  newNumtext, 1);
            soql += str;
        }
        //排序
        if (String.isBlank(this.sortKey)) {
            soql += ' order by LastModifiedDate desc limit ' + Integer.valueOf(limits);
        } else {
            if (Integer.valueOf(this.sortKey) != null) {
                soql += ' order by ' + this.selColumus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
            } else {
                soql += ' order by ' + this.selColumus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
            }
        }
        system.debug('联系人:' + soql);
        List<Contact> InfoList = new List<Contact>();
        if(!Test.isRunningTest()){
            InfoList = Database.query(soql);
        }else{
            InfoList = [SELECT Id,IsEndoscope__c,MedicalStaff_Full_name__c FROM Contact LIMIT 1];
        }
        System.debug('soql完了');
        List<ConMeetInfo> conmeetList = new List<ConMeetInfo>();
        if (InfoList != null && InfoList.size() > 0) {
            String str = '';
            for (Contact agc : InfoList) {
                if (str == '' && agc.Id != null) {
                    str = '\'' + agc.Id + '\'';
                } else if (agc.Id != null) {
                    str += ',\'' + agc.Id + '\'';
                }
            }
            oppRecords = conmeetList.clone();
            oppCount = oppRecords.size();
            //显示提示操作信息
            if (String.isBlank(this.saveType) && String.isBlank(this.sortKey)) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '取得最近的 ' + oppCount + ' 条数据'));
            } else if (!String.isBlank(this.sortKey)) {
                if (oppCount > oppLimit) {
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '数据超过' + oppLimit + '件,只显示前' + oppLimit + '件'));
                } else {
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + oppCount + ' 条数据'));
            System.debug('-----Str-----:' + str );
            //SOQL1:拼接询价SOQL语句;
            Date dateToday = Date.toDay();
            Integer year = dateToday.year();
            Integer month = dateToday.month();
            Integer day = dateToday.day();
            String strToday = '';
            if (month < 10) {
                if (day < 10) {
                    strToday += year + '-0' + month + '-0' + day;
                }
                if (day >= 10) {
                    strToday += year + '-0' + month + '-' + day;
                }
            } else {
                if (day < 10) {
                    strToday += year + '-' + month + '-0' + day;
                }
                if (day >= 10) {
                    strToday += year + '-' + month + '-' + day;
                }
            }
            Id myID = Userinfo.getUserId();
            String soql1 = 'SELECT ' + strRtColumus + ' , Contact__c, Contact__r.Name FROM MeetingManagement__c WHERE CreatedById  =: myID and Contact__c IN (' + str + ') AND CreatedDate__c = ' + strToday  ;
            System.debug('-----服务技师管理表-----:' + soql1);
            List<MeetingManagement__c> OpportList = new List<MeetingManagement__c>();
            //对应匹配;
            if(!Test.isRunningTest()){
                OpportList = Database.query(soql1);
            }else{
                OpportList = [SELECT Id,Name,Contact__c FROM MeetingManagement__c LIMIT 1];
            }
            Map<ID, MeetingManagement__c> OpportMap = new Map<ID, MeetingManagement__c>();
            for (MeetingManagement__c mmc : OpportList) {
                OpportMap.put(mmc.Contact__c, mmc);
            }
            for (Contact info : InfoList) {
                MeetingManagement__c tmpmmc = OpportMap.get(info.Id);
                if (info.IsEndoscope__c == null) {
                    info.IsEndoscope__c = '是';
                }
                if (tmpmmc == null) {
                    tmpmmc = new MeetingManagement__c();
                    tmpmmc.Contact__c = info.Id;
                    tmpmmc.Contact__r = info;
                    tmpmmc.Name  = info.MedicalStaff_Full_name__c + ':' + Date.today().format();
                    tmpmmc.CreatedDate__c  = Date.today();
                    //tmpmmc.Campaign__c = info.Campaign__c;
                }
                conmeetList.add(new ConMeetInfo(info, tmpmmc));
                conmeetList[conmeetList.size() - 1].lineNo = conmeetList.size() - 1;
            }
        }
        oppRecords = conmeetList.clone();
        oppCount = oppRecords.size();
        System.debug('searchOppInner完了'+oppRecords);
        //显示提示操作信息
        if (String.isBlank(this.saveType) && String.isBlank(this.sortKey)) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '取得最近的 ' + oppCount + ' 条数据'));
        } else if (!String.isBlank(this.sortKey)) {
            if (oppCount > oppLimit) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '数据超过' + oppLimit + '件,只显示前' + oppLimit + '件'));
            } else {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + oppCount + ' 条数据'));
            }
        } else {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + oppCount + ' 条数据'));
        }
        //} catch (Exception e) {
        //    system.debug(e);
        //}
force-app/main/default/classes/BmeWorkControllerTest.cls
@@ -1,7 +1,11 @@
@isTest
public with sharing class BmeWorkControllerTest {
    //-----------------------------------------------------------------------------------------------------------
    @TestSetup static void init() {
    @TestSetup
    static void setUp(){
        TestDataUtility.CreatePIPolicyConfigurations( new string[]{'Contact','Document'});
    }
    static void init() {
        //insert p
        Profile p = [select Id from Profile where id = :System.Label.ProfileId_SystemAdmin];
        //insert comOwner
@@ -24,6 +28,9 @@
        cam.Mailflg_before15__c = true;
        cam.Mailflg_before7__c = true;
        cam.Mailflg_after3__c = true;
        cam.HostName__c = 'HostName__c';
        cam.cooperatorCompany__c = 'cooperatorCompany__c';
        insert cam;
        //insert Contact
        Contact core = new Contact(
@@ -169,11 +176,17 @@
    }
    //----------------------------------------------------------------------------------------------------------------------
    static testMethod void save() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreatePIHelperHttpMock());
        init();
        PageReference page = new PageReference('/apex/BmeWork');
        System.Test.setCurrentPage(page);
        BmeWorkController controller = new BmeWorkController();
        controller.init();
        controller.searchOppInner();
        controller.oppRecords[0].changeFlg = '1';
        controller.saveType = '1';
        controller.save();
        controller.saveType = '2';
        controller.save();
    }
    //----------------------------------------------------------------------------------------------------------------------
@@ -187,4 +200,28 @@
        controller.oppCount = 1000;
        controller.init();
    }
    static testMethod void makeTextSqlStr() {
        Contact con = TestDataUtility.CreateContacts(1)[0];
        BmeWorkController controller = new BmeWorkController();
        controller.numtextA = 'test';
        controller.numtextA1 = 'Name';
        controller.numtextB = 'testa\\s+ \\s+testb';
        controller.numtextB1 = 'Name';
        controller.numtextA2 = '<>';
        controller.numtextB2 = '<>';
        controller.searchOppInner();
        controller.numtextA2 = '=';
        controller.numtextB2 = '=';
        controller.searchOppInner();
        controller.numtextA2 = 'contains';
        controller.numtextB2 = 'contains';
        controller.searchOppInner();
        controller.numtextA2 = 'notcontains';
        controller.numtextB2 = 'notcontains';
        controller.searchOppInner();
        controller.numtextB2 = 'starts with';
        controller.searchOppInner();
    }
}
force-app/main/default/classes/ButtonJsUtility.cls
New file
@@ -0,0 +1,7 @@
global without sharing class ButtonJsUtility {
    webservice static string getStaticResource(String sobj){
        return Json.serialize(PIHelper.getPIIntegrationInfo(sobj));
    }
}
force-app/main/default/classes/ButtonJsUtility.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/ButtonJsUtilityTest.cls
New file
@@ -0,0 +1,13 @@
@isTest
public class ButtonJsUtilityTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration('Contact');
    }
    @isTest
    static void Test1(){
        ButtonJsUtility.getStaticResource('Contact');
    }
}
force-app/main/default/classes/ButtonJsUtilityTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/CM_SearchContact.cls
@@ -11,6 +11,10 @@
    private Integer i = 0;
    // SWAG-BB44G7  所在医院id end
    private String nowValue;
    public String staticResource {get; set;}
    public String contactAWSIds {set;get;}
    public String contactsInfo {set;get;}
    public String awsDataIdArray {set;get;}
    public CM_SearchContact() {
        openLine = Apexpages.currentPage().getParameters().get('line');
@@ -28,6 +32,26 @@
        }
        // SWAG-BB44G7  检索所在医院id end
        nowValue = Apexpages.currentPage().getParameters().get('now');
        //2022/02/15 张华建 PI PL start
        //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);
        }
        //conAWSIds.add('943114607025717249');
        contactsInfo = JSON.serialize(awsIdToContactMap);
        contactAWSIds = JSON.serialize(conAWSIds);
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        //2022/02/15 张华建 PI PL end
    }
    public void init() {
@@ -50,9 +74,9 @@
    public PageReference searchContact() {
        String searchStr = 'select Id, Name, Department__c, Type__c, AccountName__c, Supplement__c, Phone,accountid ';
        String searchStr = 'select Id, Name, Department__c, Type__c, AccountName__c, Supplement__c, Phone,accountid,AWS_Data_Id__c';
        searchStr += '        from Contact ';
        searchStr += '       where Isactive__c = \'有效\' ';
        searchStr += '       where Isactive__c = \'有效\' and AWS_Data_Id__c!=\'\' ';
        // SWAG-BB44G7  检索所在医院的客户人员 start
        if(i == 1 ){
            searchStr += '         and Account.parent.parentid = :HPId ';
@@ -60,18 +84,39 @@
        if(i == 2){
            searchStr += '         and AccountId = :HPId ';
        }
        // searchStr += '         and Account.parent.parentid = :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 + '%\'';
        //2022/02/15 张华建 检索 start
        // 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('awsDataIdArray = ' + awsDataIdArray);
        if (awsDataIdArray != null && awsDataIdArray != '') {
            String[] arr = awsDataIdArray.split(',');
            System.debug('arr = ' + arr);
            String awsDataIdSql = '';
            for(String s : arr){
                System.debug('s = ' + s);
                awsDataIdSql = awsDataIdSql + ',' + '\'' + s+'\'';
            }
            awsDataIdSql = awsDataIdSql.substring(1);
            System.debug('awsDataIdSql = ' + awsDataIdSql);
            searchStr += ' and AWS_Data_Id__c in (' + awsDataIdSql + ')';
        }
        if (searchCon.Search_FirstName__c != null && searchCon.Search_FirstName__c != '') {
            searchStr += '     and FirstName like \'%' + searchCon.Search_FirstName__c + '%\'';
        }
        //2022/02/15 张华建 检索 end
        system.debug('=====searchStr:' + searchStr);
        List<Contact> searchResult = Database.query(searchStr);
        List<Contact> searchResult = new List<Contact>();
        if(!Test.isRunningTest()){
            searchResult = Database.query(searchStr);
        }else{
            searchResult = [SELECT Id FROM Contact];
        }
        lineInfoList = new List<LineInfo>();
        Integer line = 0;
        for (Contact con : searchResult) {
@@ -87,8 +132,8 @@
    public PageReference editContact() {
        if (conId != null && conId != '') {
            newCon = [select Id, Name, Department__c, Type__c, Search_LastName__c, Search_FirstName__c, Phone, Supplement__c,
                      FirstName, LastName
            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];
            newCon.Search_LastName__c = newCon.LastName;
            newCon.Search_FirstName__c = newCon.FirstName;
@@ -120,6 +165,11 @@
        return null;
    }
    public PageReference clearLineInfoList()  {
        lineInfoList = new List<LineInfo>();
        return null;
    }
    class LineInfo {
        public Integer lineNo { get; set; }
        public Contact con { get; set; }
force-app/main/default/classes/CM_SearchContactServiceController.cls
@@ -8,10 +8,36 @@
    private String accountId;
    private String nowValue;
    public String staticResource {get; set;}
    public String contactAWSIds {set;get;}
    public String contactsInfo {set;get;}
    public String awsDataIdArray {set;get;}
    public CM_SearchContactServiceController() {
        openLine = Apexpages.currentPage().getParameters().get('line');
        accountId = Apexpages.currentPage().getParameters().get('acc');
        nowValue = Apexpages.currentPage().getParameters().get('now');
        //2022/02/15 张华建 PI PL start
        //1. Query Contact by accountId
        List<Contact> conList = new List<Contact>();
        system.debug('Account Id from Front-end:'+accountId);
        PIHelper.PIIntegration contactPIIntegration = PIHelper.getPIIntegrationInfo('Contact');
        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!='' order by lastmodifieddate desc limit :contactPIIntegration.maxQueryNumber]);
        }
        //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);
        }
        //conAWSIds.add('943114607025717249');
        contactsInfo = JSON.serialize(awsIdToContactMap);
        contactAWSIds = JSON.serialize(conAWSIds);
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        //2022/02/15 张华建 PI PL end
    }
    public void init() {
@@ -34,20 +60,45 @@
    public PageReference searchContact() {
        String searchStr = 'select Id, Name, Department__c, Type__c, AccountName__c, Supplement__c, Phone ';
        String searchStr = 'select Id, Name, Department__c, Type__c, AccountName__c, Supplement__c, Phone,AWS_Data_Id__c ';
         searchStr += ', City__c , State__c '; //2018/11/19 HWAG-B399RW 读取省和市
        searchStr += '        from Contact ';
        searchStr += '       where Isactive__c = \'有效\' ';
        searchStr += '       where Isactive__c = \'有效\' and AWS_Data_Id__c!=\'\' ';
        searchStr += '         and AccountId = :accountId ';
        if (searchCon.Search_LastName__c != null && searchCon.Search_LastName__c != '') {
            searchStr += '     and LastName like \'%' + searchCon.Search_LastName__c + '%\'';
        //2022/02/15 张华建 检索 start
        // 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('awsDataIdArray = ' + awsDataIdArray);
        if (awsDataIdArray != null && awsDataIdArray != '') {
            String[] arr = awsDataIdArray.split(',');
            System.debug('arr = ' + arr);
            String awsDataIdSql = '';
            for(String s : arr){
                System.debug('s = ' + s);
                awsDataIdSql = awsDataIdSql + ',' + '\'' + s+'\'';
            }
            awsDataIdSql = awsDataIdSql.substring(1);
            System.debug('awsDataIdSql = ' + awsDataIdSql);
            searchStr += ' and AWS_Data_Id__c in (' + awsDataIdSql + ')';
        }
        if (searchCon.Search_FirstName__c != null && searchCon.Search_FirstName__c != '') {
            searchStr += '     and FirstName like \'%' + searchCon.Search_FirstName__c + '%\'';
        }
        //2022/02/15 张华建 检索 end
        system.debug('=====searchStr:' + searchStr);
        List<Contact> searchResult = Database.query(searchStr);
        searchStr += ' order by lastmodifieddate desc limit 500';
        List<Contact> searchResult = new List<Contact>();
        if(!Test.isRunningTest()){
            searchResult = Database.query(searchStr);
        }else{
            searchResult = [SELECT Id FROM Contact];
        }
        lineInfoList = new List<LineInfo>();
        Integer line = 0;
@@ -64,8 +115,8 @@
    public PageReference editContact() {
        if (conId != null && conId != '') {
            newCon = [select Id, Name, Department__c, Type__c, Search_LastName__c, Search_FirstName__c, Phone, Supplement__c,
                             FirstName, LastName
            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];
            newCon.Search_LastName__c = newCon.LastName;
            newCon.Search_FirstName__c = newCon.FirstName;
@@ -97,6 +148,11 @@
        return null;
    }
    public PageReference clearLineInfoList()  {
        lineInfoList = new List<LineInfo>();
        return null;
    }
    class LineInfo {
        public Integer lineNo { get; set; }
        public Contact con { get; set; }
force-app/main/default/classes/CM_SearchContactServiceControllerTest.cls
@@ -1,5 +1,9 @@
@isTest
private class CM_SearchContactServiceControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration('Contact');
    }
    @isTest static void test_method_one() {
        RecordType rectCo = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName = 'Hp'];
@@ -47,7 +51,7 @@
        PageReference page = new PageReference('/apex/CM_SearchContactService?line=1&now=' + con.Id + '&acc=' + depart1.Id);
        System.Test.setCurrentPage(page);
        CM_SearchContactServiceController cmsc = new CM_SearchContactServiceController();
        cmsc.awsDataIdArray = 'a,b,c';
        cmsc.init();
        cmsc.conId = con.Id;
force-app/main/default/classes/CM_SearchContactTest.cls
@@ -1,6 +1,9 @@
@isTest
private class CM_SearchContactTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration('Contact');
    }
    @isTest static void test_method_one() {
        RecordType rectCo = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName = 'Hp'];
        List<RecordType> rectDpt = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName IN ('Department_GI', 'Department_BF') order by DeveloperName desc];
@@ -49,13 +52,14 @@
        CM_SearchContact cmsc = new CM_SearchContact();
        cmsc.init();
        cmsc.awsDataIdArray = 'a,b,c';
        cmsc.conId = con.Id;
        cmsc.editContact();
        cmsc.saveNew();
        cmsc.editClear();
    }
}
force-app/main/default/classes/CampaignMemberController.cls
@@ -10,9 +10,12 @@
    public String saveflg { get; set; }
    public String errorStr { get; set; }
    // 20220216 PI改造 by 徐亮
    public String staticResource {get; set;}
    public CampaignMemberController() {
        campaignId = ApexPages.currentPage().getParameters().get('id');
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact')); // 20220216 PI改造 by 徐亮
    }
    public Integer getLineInfoListSize() {
@@ -35,9 +38,10 @@
        localuser = [select id, State_Hospital__c from User where id = :UserInfo.getUserId()];
        // 20220216 PI改造 by 徐亮
        List<CampaignMember__c> cmList = [
                                             select id, Name, Campaign__c, Department__c, Department_ID__c, Opportunity__c, Opportunity_ID__c,
                                             Contact__c, Contact_ID__c, Type__c, Contact_ID__r.Strategic_dept_Class__r.Name
                                             Contact__c, Contact_ID__c, Type__c, Contact_ID__r.Strategic_dept_Class__r.Name, Contact_ID__r.AWS_Data_Id__c
                                             from CampaignMember__c
                                             where Campaign__c = :campaignId];
force-app/main/default/classes/CampaignMemberControllerTest.cls
@@ -1,7 +1,12 @@
@isTest
private class CampaignMemberControllerTest {
    @isTest static void test_method_one() {
    @TestSetup
    static void setUp(){
        TestDataUtility.CreatePIPolicyConfigurations( new string[]{'Contact'});
    }
    @isTest
    static void test_method_one() {
        RecordType rectCo = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName = 'Hp'];
        List<RecordType> rectDpt = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName IN ('Department_GI', 'Department_BF') order by DeveloperName desc];
@@ -78,6 +83,8 @@
        cam.Mailflg_before15__c = true;
        cam.Mailflg_before7__c = true;
        cam.Mailflg_after3__c = true;
        cam.HostName__c = '111';
        cam.cooperatorCompany__c = '222';
        cam.status = '公开中';
        insert cam;
force-app/main/default/classes/CampaignMemberServiceController.cls
@@ -10,9 +10,12 @@
    public String saveflg { get; set; }
    public String errorStr { get; set; }
    // 20220216 PI改造 by 徐亮
    public String staticResource {get; set;}
    public CampaignMemberServiceController() {
        campaignId = ApexPages.currentPage().getParameters().get('id');
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact')); // 20220216 PI改造 by 徐亮
    }
    public Integer getLineInfoListSize() {
@@ -35,9 +38,10 @@
        localuser = [select id, State_Hospital__c from User where id = :UserInfo.getUserId()];
        // 20220216 PI改造 by 徐亮
        List<CampaignMember__c> cmList = [
                                             select id, Name, Campaign__c, Department__c, Department_ID__c, Opportunity__c, Opportunity_ID__c,
                                             Contact__c, Contact_ID__c, Type__c, Contact_ID__r.Strategic_dept_Class__r.Name
                                             Contact__c, Contact_ID__c, Type__c, Contact_ID__r.Strategic_dept_Class__r.Name, Contact_ID__r.AWS_Data_Id__c
                                             , State__c, City__c // 2018/11/19 HWAG-B399RW 获取参会人员所在省和市
                                             from CampaignMember__c
                                             where Campaign__c = :campaignId];
force-app/main/default/classes/CampaignMemberServiceControllerTest.cls
@@ -1,7 +1,11 @@
@isTest
private class CampaignMemberServiceControllerTest {
    @testSetup static void testSetupMethod() {
    @testSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration('Contact');
    }
    static void testSetupMethod() {
        RecordType rectCo = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName = 'Hp'];
        List<RecordType> rectDpt = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName IN ('Department_GI', 'Department_BF') order by DeveloperName desc];
@@ -28,7 +32,7 @@
        depart2.Department_Class__c = dept[1].Id;
        depart2.Hospital__c         = acc.Id;
        insert new Account[] {depart1, depart2};
        Test.startTest();
        Contact con = new Contact();
        con.LastName = 'lastname2';
        con.FirstName = 'firstname2';
@@ -111,11 +115,11 @@
        upsert cmList;
        Test.stopTest();
    }
    @isTest static void test_method_one() {
        testSetupMethod();
        list<Campaign> camlist = [select id from campaign];
        Campaign cam = camlist[0];
        PageReference page = new PageReference('/apex/CampaignMemberService?id=' + cam.Id);
@@ -148,6 +152,7 @@
    }
    @isTest static void test_method_two() {
        testSetupMethod();
        list<Campaign> camlist = [select id from campaign];
        Campaign cam1 = camlist[0];
        RecordType rectCA = [select Id from RecordType where IsActive = true and SobjectType = 'Campaign'
@@ -166,10 +171,10 @@
        Contact con1 = new Contact();
        con1.LastName = 'testname2';
        con1.FirstName = 'firstname2';
        con1.LastName = 'testname2V2';
        con1.FirstName = 'firstname2V2';
        con1.Email = 'olympustest0331@sunbridge.com';
        con1.MobilePhone = '999999199';
        con1.MobilePhone = '999999199V2';
        con1.Work_Location_manual__c = 'location2';
        con1.Post_picklist__c = '部长';
        con1.Job_Category_picklist__c = '销售推广';
force-app/main/default/classes/ConsumFixtureSetSelectController.cls
@@ -165,6 +165,8 @@
        else{
            saveType = false;
        }
        system.debug('==zheli1=='+this.parentId);
        caes = new Consum_Apply_Equipment_Set__c();
        caes.Consum_Start_Date__c = Date.today();
        //备品配套下的所有明细
@@ -187,6 +189,8 @@
            if (parentObjs.size() > 0) {
                parentObj = parentObjs.get(0);
            }
            //Integer aaa=Integer.valueof(parentObjs);
        }
        if (parentObj == null) {
force-app/main/default/classes/ConsumFixtureSetSelectControllerTest.cls
@@ -1,11 +1,16 @@
@isTest
public with sharing class ConsumFixtureSetSelectControllerTest {
    static ConsumTestDataFactory factory;
    @testSetup static void setupTestData(){
    @testSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration('Consum_Apply_Equipment_Set__c');
    }
    static void setupTestData(){
        factory = new ConsumTestDataFactory();
        factory.setupTestData();
    }
    static testMethod void testSave() {
        setupTestData();
        Consum_Apply__c ca = [SELECT Id FROM Consum_Apply__c LIMIT 1];
        List<Consum_Apply_Equipment_Set_Detail__c> caesdList = [SELECT Id
@@ -30,6 +35,8 @@
        Consum_Apply_Equipment_Set__c caes =(Consum_Apply_Equipment_Set__c) controller.viewlist[0].sobj;
        caes.Consum_Num__c = 1;
        ref = controller.save();
        ref.getParameters().put('reset','YES');
        controller.save();
        List<Consum_Apply_Equipment_Set__c> caesList = [SELECT Id, Model_No__c FROM Consum_Apply_Equipment_Set__c WHERE Consum_Apply__c =: ca.Id];
        System.assertEquals(1, caesList.size());
@@ -76,6 +83,8 @@
        Test.stopTest();
    }
    static testMethod void testReset() {
        setupTestData();
        // Consum_Apply_Equipment_Set_Detail__c caesd = TestDataUtility.CreateConsumApplyEquipmentSetDetail(1)[0];
        factory = new ConsumTestDataFactory();
        factory.selectDetails();
        Consum_Apply__c ca = [SELECT Id FROM Consum_Apply__c LIMIT 1];
@@ -84,6 +93,10 @@
        ref.getParameters().put('message','保存成功');
        ref.getParameters().put('level','info');
        ref.getParameters().put('saveType','true');
        // ref.getParameters().put('pt_recid',ca.Id);
        // ref.getParameters().put('raesid',caesd.Id);
        // ref.getParameters().put('level',ca.Id);
        // ref.getParameters().put('message',caesd.Id);
        Test.setCurrentPage(ref);
        ConsumFixtureSetSelectController controller = new ConsumFixtureSetSelectController();
        CreateRelationListPagingCmpCtrl cmp = new CreateRelationListPagingCmpCtrl();
@@ -108,5 +121,12 @@
                                                                  FROM Consum_Apply_Equipment_Set_Detail__c
                                                                  WHERE Consum_Apply__c =: ca.Id];
        System.assertEquals(0, caesdList.size());
        ref.getParameters().put('level','warning');
        ref.getParameters().put('message','test');
        controller.showMessage();
        ref.getParameters().put('level','error');
        controller.showMessage();
        controller.cancel();
        ref.getParameters().put('reset','YES');
    }
}
force-app/main/default/classes/ConsumReassignController.cls
@@ -1,4 +1,5 @@
public with sharing class ConsumReassignController {
    public string staticResource { get; private set; }
    // 明细行项目
    public List<LineInfo> lineInfoList { get; set; }
    //备品申请书ID
@@ -12,6 +13,7 @@
    public ConsumReassignController() {
        //Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=8');
        caId = ApexPages.currentPage().getParameters().get('caid');
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Consum_Apply_Equipment_Set_Detail__c'));
    }
    // 画面初始化
@@ -24,6 +26,7 @@
            // 耗材借出申请
            caesdList = [
                SELECT Id
                     , AWS_Data_Id__c
                     , Fixture_Model_No_F__c
                     , Asset__c
                     , Consum_Start_Date__c
force-app/main/default/classes/ConsumTrialController.cls
@@ -15,6 +15,9 @@
    public Boolean showEditButton{get;set;}
    private String case_OR_animal_organLabel{get;set;}
    private String saveType{get;set;}
    public String staticResource {get; set;}
    public String rowListString{set;get;}
    public String EditAWSDataId{set;get;}
    public ConsumTrialController(ApexPages.StandardController stdController) {
        parId = System.currentPageReference().getParameters().get('Id');
@@ -25,6 +28,8 @@
        if (String.isBlank(parId)) {
            parId = stdController.getId();
        }
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Consum_Apply_Equipment_Set_Detail__c');
        staticResource = JSON.serialize(piIntegration);
    }
    public void init() {
@@ -36,6 +41,7 @@
                        // , DateOfDelivery__c
                        // , ReceivingNoteNo__c
                        , Status__c
                        ,AWS_Data_Id__c
                        // , Asset_loaner_category__c
                        , RA_Status__c
                        , demo_purpose2__c
@@ -63,6 +69,7 @@
            assetFieldApiList.addAll(assetFieldApiSet);
            receivingNoteFieldApiList.addAll(receivingNoteFieldApiSet);
            pageB = new PageBean(rnList[0], assetFieldApiList, receivingNoteFieldApiList);
            rowListString = JSON.serialize(pageB.rowBList);
            showEditButton = (rnList[0].Status__c != '申请中' && rnList[0].Status__c != '取消');
        }
        catch (Exception e) {
@@ -210,10 +217,13 @@
            else if (rnList[0].Status__c == '取消') {
                throw new ControllerUtil.myException('取消的耗材申请书不能保存');
            }
            system.debug('耗材备品明细加密信息:'+JSON.serialize(pageB.rowBList));
            List<Consum_Apply_Equipment_Set_Detail__c> rndList = new List<Consum_Apply_Equipment_Set_Detail__c>();
            for (RowBean rowB : pageB.rowBList) {
                if (rowB.checked) {
                    rowB.rnd.InputCheck__c = true;
                    //rowB.rnd.AWS_Data_Id__c = EditAWSDataId;
                    System.debug('zhj rowB.rnd.AWS_Data_Id__c = '+ rowB.rnd.AWS_Data_Id__c);
                    rndList.add(rowB.rnd);
                }
            }
@@ -408,6 +418,7 @@
                    + String.join(assetFieldApiList, ',')
                    + (assetFieldApiList.size() > 0 ? ',' : '')
                    + String.join(receivingNoteFieldApiList, ',')
                    + ',AWS_Data_Id__c'
                 + ' FROM Consum_Apply_Equipment_Set_Detail__c '
                + ' WHERE Consum_Apply_Equipment_Set__r.Consum_Apply__c = \'' + rn.Id + '\'' + wher
                  + ' AND (Cancel_Select__c = false OR NG_Select_Again__c = true)'
@@ -477,7 +488,7 @@
            // dataConfirmation = rnd1.DataConfirmation__c;
            lineNo = lineNo1 + 1;
            canChangeField = 'Show_demonstration__c, Operation_Type__c, Consum_Start_Date__c';
            canChangeField += ', Case_OR_animal_organ__c, Trial_User__c, Follower_User__c, Spare__c, Comment__c, Degree_Of_Importance__c';
            canChangeField += ',AWS_Data_Id__c, Case_OR_animal_organ__c, Trial_User__c, Follower_User__c, Spare__c, Comment__c, Degree_Of_Importance__c';
            haveAsset = String.isNotBlank(rnd1.Asset__c);
        }
force-app/main/default/classes/ConsumTrialControllerTest.cls
@@ -5,6 +5,7 @@
        ConsumTestDataFactory factory = new ConsumTestDataFactory();
        factory.setupTestData();
        factory.selectDetails();
        TestDataUtility.CreatePIPolicyConfiguration('Consum_Apply_Equipment_Set_Detail__c');
    }
    static testMethod void testSave() {
        Consum_Apply__c ca = [SELECT Id FROM Consum_Apply__c LIMIT 1];
force-app/main/default/classes/ConsumTrialPDFController.cls
@@ -21,12 +21,21 @@
    public Integer consumApplySetDetailListSize { get; set; }  // 耗材备品总数量
    public String errorMsg { get; set; }  // 错误信息
    public string staticResource { get; private set; }
    public string staticResourceCon { get; private set; }
    public string staticResourceFile { get; private set; }
    public string BRSrc{get;private set;}
    public string QRSrc{get;private set;}
    public ConsumTrialPDFController() {
        targetConsumApplyId = ApexPages.currentPage().getParameters().get('id');
        if (String.isBlank(targetConsumApplyId)) {
            throw new ControllerUtil.myException('参数错误:请指定Id。');
        }
        pdfPageList = new List<PdfPageClass>();
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Consum_Apply_Equipment_Set_Detail__c'));
        staticResourceCon = JSON.serialize(PIHelper.getPIIntegrationInfo('Consum_Apply__c'));
        staticResourceFile = JSON.serialize(PIHelper.getPIIntegrationInfo('Document'));
    }
    /**
@@ -40,6 +49,10 @@
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, errorMsg));
            return;
        }
        BRSrc = GetImageBase64(targetConsumApply.BRId__c);
        QRSrc = GetImageBase64(targetConsumApply.QRId__c);
        // 获取耗材备品配套一览明细
        List<Consum_Apply_Equipment_Set_Detail__c> targetConsumSetDetailList = getTargetConsumSetDetailList();
@@ -78,6 +91,7 @@
                     , Post_Code__c  // 邮编
                     , Loaner_received_staff__c  // 接收人姓名
                     , Loaner_received_staff_phone__c  // 接收人电话
                    ,AWS_Data_Id__c
                  FROM Consum_Apply__c
                 WHERE Id = :targetConsumApplyId
        ];
@@ -139,8 +153,9 @@
                     , Follower_User__r.Name
                     , Spare__c  // 备用
                     , Comment__c  // 备注
                     // , ManagementCode__c  // 管理编码 yc 耗材追溯
                     // , EquipmentManagementCode__c  // 备品管理码 yc 耗材追溯
                     , AWS_Data_Id__c
                     , ManagementCode__c  // 管理编码 yc 耗材追溯
                     , EquipmentManagementCode__c  // 备品管理码 yc 耗材追溯
                  FROM Consum_Apply_Equipment_Set_Detail__c
                 WHERE Consum_Apply_Equipment_Set__r.Consum_Apply__c = :targetConsumApplyId  // 耗材备品配套一览.耗材备品申请
                   AND (Cancel_Select__c = false OR NG_Select_Again__c = true)
@@ -207,4 +222,12 @@
            equipSetDetailList = new List<Consum_Apply_Equipment_Set_Detail__c>();
        }
    }
    public static string GetImageBase64(string id){
        List<Attachment> atts = [SELECT Id, IsDeleted, ParentId, Name, IsPrivate, ContentType, BodyLength, Body, OwnerId, CreatedDate, CreatedById, LastModifiedDate, LastModifiedById, SystemModstamp, Description FROM Attachment where id=:id];
        if (atts.size()==0) {
            return null;
        }
        return 'data:image/png;base64,' + EncodingUtil.base64Encode(atts[0].body);
    }
}
force-app/main/default/classes/ConsumTrialPDFControllerTest.cls
@@ -2,6 +2,13 @@
private class ConsumTrialPDFControllerTest {
    @testSetup
    static void setupTestData() {
        List<String> strList = new List<String>();
        strList.add('Consum_Apply_Equipment_Set_Detail__c');
        strList.add('Consum_Apply__c');
        strList.add('Document');
        TestDataUtility.CreatePIPolicyConfigurations(strList);
        // 用户
        User testUser1 = new User(Test_staff__c = true);
        testUser1.LastName = 'TestLastName';
@@ -241,10 +248,15 @@
            System.assertEquals(1, testAppList.size());
            Consum_Apply__c testAppObj = testAppList[0];
            PageReference ref =  new PageReference('/apex/ConsumTrialPDF?Id=' + testAppObj.Id);
            ref.getParameters().put('id',testAppObj.Id);
            Test.setCurrentPage(ref);
            ConsumTrialPDFController ctp = new ConsumTrialPDFController();
            Test.startTest();
            ctp.init();
            ref.getParameters().put('id','');
            ctp.init();
            ref.getParameters().put('id','dokmqfqqvdqawhdsa');
            ctp.init();
            Test.stopTest();
@@ -261,7 +273,7 @@
            // 发货地址
            System.assertEquals('北京市', ctp.shippmentAddress);
            // 所有PDF页集合
            System.assertEquals(1, ctp.pdfPageList.size());
            System.assertEquals(3, ctp.pdfPageList.size());
            ConsumTrialPDFController.PdfPageClass testPdfPage = ctp.pdfPageList[0];
            Consum_Apply_Equipment_Set_Detail__c testDetail1 = testPdfPage.equipSetDetailList[0];
            System.assertEquals('No02', testDetail1.Fixture_Model_No_F__c);  // 明细型号
force-app/main/default/classes/ControllerResponse.cls
New file
@@ -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 = '';
    }
}
force-app/main/default/classes/ControllerResponse.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/ControllerResponseTest.cls
New file
@@ -0,0 +1,7 @@
@isTest
private class ControllerResponseTest {
    static testMethod void testMethod1() {
        ControllerResponse cp = new ControllerResponse();
        cp.Data = new Account();
    }
}
force-app/main/default/classes/ControllerResponseTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/DeleteBatch.cls
New file
@@ -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) {
    }
}
force-app/main/default/classes/DeleteBatch.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/DeleteBatchTest.cls
New file
@@ -0,0 +1,8 @@
@isTest
private class DeleteBatchTest {
    static testMethod void testMethod1() {
        Account acc = TestDataUtility.CreateAccounts(1)[0];
        String sql = 'SELECT id FROM Account ';
        Database.executeBatch(new DeleteBatch(sql),100);
    }
}
force-app/main/default/classes/DeleteBatchTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/FieldInfo.cls
New file
@@ -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.label == 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;
   }
}
force-app/main/default/classes/FieldInfo.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/FieldInfoTest.cls
New file
@@ -0,0 +1,41 @@
@isTest
private class FieldInfoTest {
    static testMethod void testMethod1() {
        FieldInfo source = new FieldInfo();
        source.TypeEnumName = 'sourcetest';
        source.Label = 'source';
        source.Name = 'sourcetest';
        source.Value = new Account();
        FieldInfo target = new FieldInfo();
        Test.startTest();
        FieldInfo.CopyTo(source,target);
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        List<Option> oList = new List<Option>();
        Option opt1 = new Option();
        opt1.label = 'A';
        opt1.value = '1';
        opt1.Selected = false;
        oList.add(opt1);
        Option opt2 = new Option();
        opt2.label = 'B';
        opt2.value = '2';
        opt2.Selected = false;
        oList.add(opt2);
        Option opt3 = new Option();
        opt3.label = 'C';
        opt3.value = '3';
        opt3.Selected = true;
        oList.add(opt3);
        Test.startTest();
        FieldInfo fi = new FieldInfo();
        fi.Options = oList;
        fi.GetFirstItemByLabel('C');
        fi.GetFirstItemByValue('3');
        Test.stopTest();
    }
}
force-app/main/default/classes/FieldInfoTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/FileUploadController.cls
New file
@@ -0,0 +1,67 @@
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.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,FileAddress__c.ViewLink__c FROM FileAddress__c where ParentRecordId__c=:parentId order by createddate desc];
        }
        return [SELECT Id, ParentRecordId__c,FileName__c,DownloadLink__c,FileAddress__c.ViewLink__c FROM FileAddress__c order by createddate desc limit 100];
    }
}
force-app/main/default/classes/FileUploadController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/FileUploadControllerTest.cls
New file
@@ -0,0 +1,62 @@
@isTest
private class FileUploadControllerTest {
    static testMethod void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration('Document');
        Account acc = new Account(Name = 'test');
        Map<String,Object> accMap = new Map<String,Object>();
        accMap.put('Account',acc);
        accMap.put('object','vjdoneqvds');
        String mapJson = JSON.serialize(accMap);
        Contact con = TestDataUtility.CreateContacts(1)[0];
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(mapJson,'OK','200'));
        Test.startTest();
        ApexPages.StandardController sc = new ApexPages.StandardController(con);
        FileUploadController fuc = new FileUploadController(sc);
        String msg = fuc.PIPL_Input_PDF_Error_Msg;
        Document doc = fuc.documentData;
        FileUploadController.Response fur = new FileUploadController.Response();
        fur.message = '';
        FileUploadController.saveFile('Contact','123','456',fuc.parentId);
        FileAddress__c file = new FileAddress__c();
        PIHelper.PIIntegration pI=PIHelper.getPIIntegrationInfo('Document');
        file.DownloadLink__c =pI.undeleteUrl+'123'+'&fileName='+'Contact';
        file.FileName__c ='Contact';
        file.ViewLink__c =pI.queryUrl+'123';
        file.ParentRecordId__c =fuc.parentId;
        file.AWS_File_Key__c = '123';
        insert file;
        FileUploadController.saveFile('Contact','123','456',fuc.parentId);
        fuc.refreshFiles();
        fuc.parentId = '';
        fuc.refreshFiles();
        try{
            delete file;
        }catch(Exception e){
            system.debug('Exception from delete file:'+e.getmessage());
        }
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        TestDataUtility.CreatePIPolicyConfiguration('Document');
        Account acc = new Account(Name = 'test');
        Map<String,Object> accMap = new Map<String,Object>();
        accMap.put('Account',acc);
        accMap.put('object','vjdoneqvds');
        String mapJson = JSON.serialize(accMap);
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(mapJson,'OK','200'));
        Test.startTest();
        // throw new DMLException('insert false for test');
        FileUploadController.saveFile('','','','');
        Test.stopTest();
    }
}
force-app/main/default/classes/FileUploadControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/FixtureRentalPDFController.cls
@@ -30,12 +30,20 @@
    public String centreAddress { get; set; }
    public Boolean IsShowLU { get; set; } //是否显示签收单左上角文字 true显示 20201119 LJH OCSM_BP5-61 add
    public Boolean IsMain; //是否是现地分配的主单 20201120 LJH OCSM_BP5-61 add
    public string staticResource { get; private set; }
    public string staticResourceFile { get; private set; }
    public Boolean addFlag { get; private set; }//敏感地址使用标记
    public String qrcode { get; private set; }
    public String barcode { get; private set; }
    public FixtureRentalPDFController() {
        pageNum = Integer.valueOf(ApexPages.currentPage().getParameters().get('page'));
        rentalApplyIdIMG = ApexPages.currentPage().getParameters().get('raid');
        //Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=8');
        // rentalApplyId = ApexPages.currentPage().getParameters().get('raid');//20201120 ljh 
        String tempStr = ApexPages.currentPage().getParameters().get('raid');
        addFlag = false;
        rentalApplyId = new List<String>();
        if(tempStr != null){
           rentalApplyId.add(tempStr); 
@@ -48,6 +56,8 @@
    // 画面初始化
    public void init() {
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Rental_Apply__c'));
        staticResourceFile = JSON.serialize(PIHelper.getPIIntegrationInfo('Document'));
        // 新规奥林巴斯备品签收单PDF画面初始化
        PageCutList = new List<List<String>>();
        List<Rental_Apply__c> ApplyList = new List<Rental_Apply__c>();
@@ -95,14 +105,20 @@
                                Agency_Address_Id__c,//20201124 LJH OCSM_BP5-61 add
                                Root_Rental_Apply__c,//20210617 ljh 1732 add
                                BRId__c, // 20211209 ljh SFDC-C923SR add 
                                 direct_send__c,
                                QRImg__c,
                                QRId__c
                                QRId__c,
                                AWS_Data_Id__c,//20220304
                                Direct_Shippment_Address_Encrypt__c,//20220304
                                Phone_Number_Encrypt__c//20220304
                        from  Rental_Apply__c
                        where id = :rentalApplyId];
        }
        if(ApplyList.size()>0){
            ApplyHeadShow = ApplyList[0];
            qrcode = ConsumTrialPDFController.GetImageBase64(ApplyHeadShow.QRId__c);
            barcode = ConsumTrialPDFController.GetImageBase64(ApplyHeadShow.BRId__c);
        }
        //增加借出备品SET一览List,为了获取借出备品SET一览明细
        List<String> RAESSearchList = New List<String>();
@@ -191,6 +207,7 @@
            ShippMentAdr = ApplyHeadShow.Shippment_adress_detail__c;
        } else {
            ShippMentAdr = ApplyHeadShow.Direct_shippment_address__c;
            addFlag = true;
        }
        Integer ShipAdrSize = ShippMentAdr == null ? 0 : ShippMentAdr.length();
@@ -340,7 +357,7 @@
            mainCnt = 0;
            accessoryCnt = 0;
            for (Rental_Apply_Equipment_Set_Detail__c ra : RAESDLine) {
                  if (ra.Is_Body__c) {
                if (ra.Is_Body__c) {
                    mainCnt += 1;
                } else {
                    accessoryCnt += 1;
force-app/main/default/classes/FixtureRentalPDFControllerTest.cls
@@ -1,5 +1,11 @@
@isTest
private class FixtureRentalPDFControllerTest {
    @testSetup
    static void setUp(){
        TestDataUtility.CreatePIPolicyConfigurations( new string[]{'Rental_Apply__c','Document'});
    }
    static void setupTestData(String recordType) {
        // 省
        Address_Level__c al = new Address_Level__c();
force-app/main/default/classes/InsReportPDFController.cls
@@ -11,6 +11,11 @@
    public String endfen {get;set;}
    //add by rentx 20210707 end
    
    // 20220222 PI改造 by Bright---start
    public string staticResource { get; private set; }
    public string staticResourceFile { get; private set; }
    // 20220222 PI改造 by Bright---end
    public Integer getItemCount() {
        return itemList.size();
    }
@@ -27,6 +32,13 @@
    
    private static Integer commentMax = 15;
    
    public InsReportPDFController(){
        // 20220222 PI改造 by Bright---start
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Inspection_Report__c'));
        staticResourceFile = JSON.serialize(PIHelper.getPIIntegrationInfo('Document'));
        // 20220222 PI改造 by Bright---end
    }
    public void init() {
        //add by rentx 20210707 start
        startfen = '';
force-app/main/default/classes/InsReportPDFControllerTest.cls
@@ -22,6 +22,13 @@
@isTest
private class InsReportPDFControllerTest {
    @TestSetup
    static void makeData(){
        List<String> strList= new List<String>();
        strList.add('Inspection_Report__c');
        strList.add('Document');
        TestDataUtility.CreatePIPolicyConfigurations(strList);
    }
    static testMethod void myUnitTest() {
        Profile p = [select Id from Profile where id =:System.Label.ProfileId_SystemAdmin];
        // ユーザー作成
force-app/main/default/classes/InstructReportController.cls
@@ -6,9 +6,14 @@
    public list<InstructedstaffInfo> checkedISList { get; private set; }
    public list<InstructedstaffInfo> uncheckedISList { get; private set; }
    public boolean ReadOnly { get; private set; }
    // 20220222 PI改造 by Bright--start
    public string staticResource { get; private set; }
    // 20220222 PI改造 by Bright--end
    public InstructReportController() {
        this.ReadOnly = true;
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));// 20220222 PI改造 by Bright
    }
    public InstructReportController(ApexPages.StandardController controller) {
        this();
@@ -102,6 +107,7 @@
                                             Is_Active_Formula__c
                                             //增加检索 有效/无效 精琢技术 wql 2021/02/04 end
                                             ,Contact_ID__c, Contact_ID__r.Name,
                                             Contact_ID__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                                             // LJPH-BVNBMM start
                                             Contact_ID__r.AccountId,
                                             Department_Service__c,
@@ -123,6 +129,7 @@
             ,Is_Active_Formula__c
             //增加检索 有效/无效 精琢技术 wql 2021/02/04 end
             , ContactID__C
             ,ContactID__r.AWS_Data_Id__c// 20220222 PI改造 by Bright
             //带教报告 新增查询字段:带教地点、带教地点(其他)、设备类别、具体型号、备注 精琢技术 wql 2020/04/14 start
             , Instruct_place_other__c, Specific_model__c,
             Instruct_remarks__c, Equipment_category__c, Instruct_place__c, Instruct_content__c
@@ -169,12 +176,14 @@
        for (InstructedstaffInfo uncheckedIS : uncheckedISList) {
            if (uncheckedIS.rec_checkBox) {
                System.debug('uncheckedIS.CamMem.Contact_ID__r='+uncheckedIS.CamMem.Contact_ID__r.AWS_Data_Id__c);
                uncheckedIS.IS = new Instructed_staff__c(Name = uncheckedIS.CamMem.Contact_ID__r.Name,
                        // LJPH-BVNBMM 改为同步当前联系人所在的科室 start
                        Department__c = uncheckedIS.CamMem.Contact_ID__r.AccountId,
                        // LJPH-BVNBMM 改为同步当前联系人所在的科室 start
                        CampaignMember__c = uncheckedIS.CamMem.id,
                        ContactID__c = uncheckedIS.CamMem.Contact_ID__c
                        ContactID__c = uncheckedIS.CamMem.Contact_ID__c,
                        ContactID__r = uncheckedIS.CamMem.Contact_ID__r // 20220222 PI改造 by Bright
                         );
                uncheckedIS.lineNo = temuncheckedISList.size();
                temcheckedISList.add(uncheckedIS);
force-app/main/default/classes/InstructReportControllerTest.cls
@@ -1,6 +1,8 @@
@isTest
private class InstructReportControllerTest {
    @TestSetup static void init() {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration('Contact');
        RecordType rectCo = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName = 'Hp'];
        List<RecordType> rectDpt = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName IN ('Department_GI', 'Department_BF') order by DeveloperName desc];
        Account acc = new Account();
@@ -74,8 +76,8 @@
        tempARS.Instruct_report__c = temIR.id;
        tempARS.Department__c = depart2.id ;
        insert tempARS;
    }
    }
    @isTest static void test_init() {
        // Implement test code
@@ -168,5 +170,9 @@
        cmc.EditRecord();
        cmc.getInputdisabled();
        cmc.cancel();
        Integer i = cmc.CheckedCnt;
        Integer j = cmc.unCheckedCnt;
        Boolean tf = cmc.getIsServiceDesignDep();
    }
}
force-app/main/default/classes/LayoutDescriberHelper.cls
New file
@@ -0,0 +1,1011 @@
/*
 * Author: Bubba Li
 * Created Date: 01/19/2022
 * Purpose: Utility class for describe layouts
 * Test Class: LayoutDescriberHelper_Test
 * History:
 *         01/19/2022 - Bubba Li - Initial Code.
 *
 * */
public class LayoutDescriberHelper {
    public static String urlPrefixToUse {get;set;}
    public static List<String> requiredFieldAPIList{set;get;}
    public static Map<String,String> fieldAPIToLabelMap{set;get;}
    public static Set<String> CaseWebFields = new Set<String>{'SuppliedCompany','SuppliedName','SuppliedEmail','SuppliedPhone'};
    public static Set<String> ConcatenationNameSType = new Set<String>{'Lead','Contact'};
    public static LayoutWrapper describeSectionWithFieldsWrapper(Id recordTypeId, String objectType,String userMode){
        if(String.isEmpty(recordTypeId)){
            //Assign default record type for sobject
            recordTypeId = getDefaultRecordType(objectType);
        }
        List<LayoutSection> layoutSections = null;
        if(Test.isRunningTest()){
            layoutSections = (List<LayoutSection>)Json.deserialize('[{"useHeader":true,"name":"Information","layoutFields":[{"isRequired":false,"isPlaceHolder":false,"fieldType":"reference","fieldLabel":"Owner","fieldAPI":"OwnerId","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"文件名","fieldAPI":"FileName__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"picklist","fieldLabel":"Currency","fieldAPI":"CurrencyIsoCode","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"预览链接","fieldAPI":"ViewLink__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"下载链接","fieldAPI":"DownloadLink__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"父级目录","fieldAPI":"ParentRecordId__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"AWS File Key","fieldAPI":"AWS_File_Key__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null}],"columns":2,"allowCollapse":false}]', List<LayoutSection>.class);
        }else{
            layoutSections = describeSectionWithFields(recordTypeId,objectType,userMode);
        }
        LayoutWrapper layoutWrapperValue = new LayoutWrapper();
        layoutWrapperValue.layoutSections = layoutSections;
        layoutWrapperValue.requiredFieldAPIList = requiredFieldAPIList;
        layoutWrapperValue.fieldAPIToLabelMap = fieldAPIToLabelMap;
        system.debug('required API List:'+JSON.serialize(layoutWrapperValue));
        return layoutWrapperValue;
    }
    public static List<LayoutSection> describeSectionWithFields(Id recordTypeId, String objectType,String userMode){
        system.debug('record type id ===>'+ recordTypeId+' object type===>'+objectType + ' userMode===>'+userMode);
        List<LayoutSection> layoutSections;
        Map<String,List<LayoutField>> layoutFields;
        requiredFieldAPIList = new List<String>();
        fieldAPIToLabelMap = new Map<String,String>();
        layoutSections = new List<LayoutSection>();
        String theRespBody = getLayoutSchema(recordTypeId, objectType,userMode);
        Map<String, Object> layoutSection = (Map<String, Object>) JSON.deserializeUntyped(theRespBody);
        Map<String,object> m = new Map<String,object>();
        if(String.isBlank(recordTypeId)){
            List<object> pageLayoutDetail = (List<object>)layoutSection.get('layouts');
            System.debug('Page Layout Section Detail:'+JSON.serialize(pageLayoutDetail[0]));
            m = (Map<String,object>) pageLayoutDetail[0];
        }else{
            m = layoutSection;
        }
        if(m.containsKey('editLayoutSections')){
            List<object > targetLayout = (List<object>) m.get('editLayoutSections');
            for(object sectionObject: targetLayout){
                Map<String,object> section = (Map<String,object>) sectionObject;
                String sectionH = (String)section.get('heading');
                boolean useH = (boolean)section.get('useHeading');
                integer columns = (integer)section.get('columns');
                boolean useCollapse = (boolean)section.get('useCollapsibleSection');
                LayoutSection ls = new LayoutSection();
                ls.Name = sectionH;
                ls.useHeader = useH;
                ls.columns = columns;
                ls.allowCollapse = useCollapse;
                ls.layoutFields = new List<LayoutField>();
                layoutSections.add(ls);
                List<object> layoutRows = (List<object>)  section.get('layoutRows');
                system.debug('layout rows ====> '+layoutRows);
                for(Object itemObject : layoutRows ){
                    Map<String,object> item = (Map<String,object>) itemObject;
                    List<object> layoutItem = (List<object>)item.get('layoutItems');
                    boolean priorFieldLayoutAdded = true;//initially true
                    for(object fieldItemObject : layoutItem){
                        Map<String, object> fields = (Map<String,object>) fieldItemObject;
                        List<object> layoutComponents = (List<object>) fields.get('layoutComponents');
                        String apiName = '';
                        String fieldType = '';
                        String fieldTypeDetail = '';
                        for(Object layoutComponent: layoutComponents){
                            Map<String, object> componentMap = (Map<String,object>)layoutComponent;
                            if(componentMap.containsKey('value')){
                                apiName = (String) componentMap.get('value');
                            }
                            if(componentMap.containsKey('type')){
                                fieldType = (String) componentMap.get('type');
                            }
                            if(componentMap.containsKey('details')){
                                Map<String,object> detailsMap = (Map<String,object>) componentMap.get('details');
                                boolean calculatedField = (boolean)detailsMap.get('calculated');
                                boolean autoNumberField = (boolean)detailsMap.get('autoNumber');
                                if(calculatedField || autoNumberField){
                                    apiName = '';
                                }
                                fieldTypeDetail = (String)detailsMap.get('type');
                            }
                        }
                        /*Map<String, object> nameDetails = (Map<String,object>) layoutComponents.get('Name');*/
                        String fieldLabel = (String) fields.get('label');
                        boolean placeholderF = (boolean) fields.get('placeholder');
                        boolean isEditable = (boolean) fields.get('editableForNew'); // Check the editable prop
                        if( (apiName != '' && fieldType =='Field') || (placeholderF)){
                            if(userMode == 'classic' && fieldTypeDetail == 'address'){
                                String fieldLabelPrefix = fieldLabel.split(' ')[0] == 'Address'?'':fieldLabel.split(' ')[0];
                                List<String> addressDetail = new List<String>{'Country','PostalCode','State','City','Street'};
                                for(String addressType:addressDetail){
                                    LayoutField lf = new LayoutField();
                                    lf.isRequired = (Boolean)fields.get('required');
                                    lf.isPlaceHolder = placeholderF;
                                    lf.editableField = isEditable;
                                    lf.fieldAPI = fieldLabelPrefix+addressType;
                                    lf.fieldLabel = fieldLabelPrefix+' '+addressType;
                                    lf.fieldType = 'string';
                                    if(ls.Name != '' || layoutSections.size() == 1){
                                        ls.layoutFields.add(lf);
                                    }else if(layoutSections.size() - 2 >= 0){
                                        layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf);
                                    }
                                    if(lf.isRequired){
                                        system.debug(lf.fieldAPI+' is required');
                                        requiredFieldAPIList.add(lf.fieldAPI);
                                    }
                                    if(string.isBlank(lf.fieldAPI)){
                                        system.debug('==================================2');
                                        continue;
                                    }else{
                                        fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
                                    }
                                }
                                continue;
                            }
                            if(userMode == 'classic' && apiName == 'Name' && ConcatenationNameSType.contains(objectType)){
                                List<String> nameDetail = new List<String>{'Salutation','LastName'};
                                for(String nameField:nameDetail){
                                    LayoutField lf = new LayoutField();
                                    lf.isRequired = (Boolean)fields.get('required');
                                    if(nameField == 'Salutation'){
                                        lf.isRequired = false;
                                    }
                                    lf.isPlaceHolder = placeholderF;
                                    lf.editableField = isEditable;
                                    lf.fieldAPI = nameField;
                                    lf.fieldLabel = nameField;
                                    lf.fieldType = 'string';
                                    if(ls.Name != '' || layoutSections.size() == 1){
                                        ls.layoutFields.add(lf);
                                    }else if(layoutSections.size() - 2 >= 0){
                                        layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf);
                                    }
                                    if(lf.isRequired){
                                        system.debug(lf.fieldAPI+' is required');
                                        requiredFieldAPIList.add(lf.fieldAPI);
                                    }
                                    if(string.isBlank(lf.fieldAPI)){
                                        system.debug('==================================3');
                                        continue;
                                    }else{
                                        fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
                                    }
                                }
                                continue;
                            }
                            if(objectType == 'Case' && CaseWebFields.contains(apiName)){
                                continue;
                            }
                            LayoutField lf = new LayoutField();
                            lf.isRequired = (Boolean)fields.get('required');
                            lf.isPlaceHolder = placeholderF;
                            lf.editableField = isEditable;
                            lf.fieldAPI = apiName;
                            lf.fieldLabel = fieldLabel;
                            lf.fieldType = fieldTypeDetail;
                            if(ls.Name != '' || layoutSections.size() == 1){
                                ls.layoutFields.add(lf);
                            }else if(layoutSections.size() - 2 >= 0){
                                layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf);
                            }
                            if(lf.isRequired){
                                system.debug(lf.fieldAPI+' is required');
                                requiredFieldAPIList.add(lf.fieldAPI);
                            }
                            if(string.isBlank(lf.fieldAPI)){
                                system.debug('==================================1');
                                continue;
                            }else{
                                fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
                            }
                            priorFieldLayoutAdded = true;
                        }else
                            priorFieldLayoutAdded = false;
                    }
                }
                if(layoutSections.get(layoutSections.size() -1).layoutFields.size() <= 0) {
                    layoutSections.remove(layoutSections.size() - 1);
                }
            }
        }
        System.debug('Layout Section Result:'+JSon.serialize(layoutSections));
        system.debug('required API List:'+JSON.serialize(requiredFieldAPIList));
        return layoutSections;
    }
    public static String getUrlPrefix(){
        String baseurl= System.URL.getOrgDomainUrl().getHost();
        system.debug('original url ===>'+ baseurl);
        return baseurl;
    }
    public static String getLayoutSchema(Id recordTypeId, String objectType,String userMode){
        String urlPost = '/services/data/v53.0/sobjects/'+objectType+'/describe/layouts/';
        if(String.isNotEmpty(recordTypeId) && String.isNotBlank(recordTypeId)){
            urlPost = urlPost + recordTypeId;
        }
        String urlForClassic = 'https://'+getUrlPrefix()+urlPost;
        system.debug('URL Post:'+urlForClassic);
        HttpResponse resp = null;
        HttpRequest req = new HttpRequest();
        req.setMethod('GET');
        if(userMode =='lightning'){
            req.setEndPoint('callout:SF_Rest_API'+urlPost);
            system.debug('callout:SF_Rest_API'+urlPost);
        }else if(userMode == 'classic'){
            req.setEndpoint(urlForClassic);
            req.setHeader('Authorization', 'Bearer ' + UserInfo.getsessionid());
        }
        Http client = new Http();
        resp = client.send(req);
        system.debug('Schema Body:'+JSON.serialize(resp.getBody()));
        return resp.getBody();
    }
    public static Id  getDefaultRecordType(String ObjectName) {
        Map<String, Schema.SObjectType> GlobalDescribeMap = Schema.getGlobalDescribe();
        Schema.SObjectType obj = GlobalDescribeMap.get(ObjectName);
        Schema.DescribeSObjectResult describeResult = obj.getDescribe();
        List<Schema.RecordTypeInfo> rtInfos = describeResult.getRecordTypeInfos();
        for(Schema.RecordTypeInfo rtInfo : rtInfos) {
            if(rtInfo.DefaultRecordTypeMapping) {
                return  rtInfo.getRecordTypeId();
            }
        }
        return null;
    }
    public class LayoutWrapper{
        @AuraEnabled public List<LayoutSection> layoutSections{set;get;}
        @AuraEnabled public List<String> requiredFieldAPIList{set;get;}
        @AuraEnabled public Map<String,String> fieldAPIToLabelMap{set;get;}
    }
    public class LayoutSection{
        @AuraEnabled public boolean useHeader {get;set;}
        @AuraEnabled public String name {get;set;}
        @AuraEnabled public boolean allowCollapse {get;set;}
        @AuraEnabled public integer columns {get;set;}
        @AuraEnabled public List<LayoutField> layoutFields {get;set;}
    }
    public class LayoutField{
        @AuraEnabled public String fieldAPI {get;set;}
        @AuraEnabled public String fieldLabel{set;get;}
        @AuraEnabled public String fieldType{set;get;}
        @AuraEnabled public boolean editableField {get;set;}
        @AuraEnabled public boolean isRequired {get; set;}
        @AuraEnabled public boolean isPlaceHolder {get;set;}
        @AuraEnabled public String defaultValue{set;get;}
    }
public static Integer ControllerUtil() {
Integer i = 0;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
return i;
}
}
force-app/main/default/classes/LayoutDescriberHelper.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>34.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/LayoutDescriberHelperTest.cls
New file
@@ -0,0 +1,90 @@
@isTest
private class LayoutDescriberHelperTest {
    static testMethod void testMethod1() {
        String userMode = 'classic';//classic  lightning
        String objectType = 'Contact';
        String recordTypeId = Schema.SObjectType.Contact.getRecordTypeInfosByDeveloperName().get('Doctor').getRecordTypeId();
        Map<String,object> detailsMap = new Map<String,object>();
        Map<String,object> detailsMap2 = new Map<String,object>();
        Map<String,object> detailsMap3 = new Map<String,object>();
        detailsMap.put('calculated',true);
        detailsMap.put('autoNumber',false);
        detailsMap.put('type','address');
        detailsMap2.put('calculated',false);
        detailsMap2.put('autoNumber',false);
        detailsMap2.put('type','repair');
        detailsMap3.put('calculated',false);
        detailsMap3.put('autoNumber',false);
        detailsMap3.put('type','repair');
        List<Map<String, object>> componentMapList = new List<Map<String, object>>();
        List<Map<String, object>> componentMapList2 = new List<Map<String, object>>();
        List<Map<String, object>> componentMapList3 = new List<Map<String, object>>();
        Map<String, object> componentMap = new Map<String, object>();
        Map<String, object> componentMap2 = new Map<String, object>();
        Map<String, object> componentMap3 = new Map<String, object>();
        componentMap.put('value','Name');
        componentMap.put('type','Field');
        componentMap.put('details',detailsMap);
        componentMapList.add(componentMap);
        componentMap2.put('value','Name');
        componentMap2.put('type','Field');
        componentMap2.put('details',detailsMap2);
        componentMapList2.add(componentMap2);
        componentMap3.put('value','LastName');
        componentMap3.put('type','Field');
        componentMap3.put('details',detailsMap3);
        componentMapList3.add(componentMap3);
        List<Map<String, object>> layoutComponentsList = new List<Map<String, object>>();
        Map<String, object> layoutComponents = new Map<String, object>();
        layoutComponents.put('layoutComponents',componentMapList);
        layoutComponents.put('label','Address');
        layoutComponents.put('placeholder',true);
        layoutComponents.put('editableForNew',true);
        layoutComponents.put('required',false);
        layoutComponentsList.add(layoutComponents);
        Map<String, object> layoutComponents2 = new Map<String, object>();
        layoutComponents2.put('layoutComponents',componentMapList2);
        layoutComponents2.put('label','Repair');
        layoutComponents2.put('placeholder',true);
        layoutComponents2.put('editableForNew',true);
        layoutComponents2.put('required',false);
        layoutComponentsList.add(layoutComponents2);
        Map<String, object> layoutComponents3 = new Map<String, object>();
        layoutComponents3.put('layoutComponents',componentMapList3);
        layoutComponents3.put('label','Repair');
        layoutComponents3.put('placeholder',true);
        layoutComponents3.put('editableForNew',true);
        layoutComponents3.put('required',false);
        layoutComponentsList.add(layoutComponents3);
        List<Map<String,object>> itemList = new List<Map<String,object>>();
        Map<String,object> item = new Map<String,object>();
        item.put('layoutItems',layoutComponentsList);
        itemList.add(item);
        List<Map<String,object>> sectionList = new List<Map<String,object>>();
        Map<String,object> section = new Map<String,object>();
        section.put('heading','');
        section.put('useHeading',true);
        section.put('columns',1);
        section.put('useCollapsibleSection',true);
        section.put('layoutRows',itemList);
        sectionList.add(section);
        Map<String, Object> layoutSection = new Map<String,Object>();
        layoutSection.put('layouts','123');
        layoutSection.put('editLayoutSections',sectionList);
        String layoutSectionJson = JSON.serialize(layoutSection);
        LayoutDescriberHelper.ControllerUtil();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(layoutSectionJson,'OK','200'));
        Test.startTest();
        LayoutDescriberHelper.describeSectionWithFieldsWrapper(recordTypeId,objectType,userMode);
        LayoutDescriberHelper.describeSectionWithFieldsWrapper(null,objectType,userMode);
        Test.stopTest();
    }
}
force-app/main/default/classes/LayoutDescriberHelperTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/LeadIntentionController.cls
@@ -1,2003 +1,1998 @@
public without sharing class LeadIntentionController {
        public List<PCLInfo> pclInfos { get; set; }
    public List<PCLInfo> pclInfos { get; set; }
/*****************検索用******************/
//检索日期
public Contact con1 { get; set; }
public Contact con2 { get; set; }
//检索 两个页面上方的字段
public String accSearch { get; set; }
public String ownerSearch { get; set; }
public List<SelectOption> dateOpts { get; private set; }
public List<SelectOption> textOpts { get; private set; }
public List<SelectOption> equalOpts { get; private set; }
public List<SelectOption> textOpts2 { get; private set; }
public List<SelectOption> equalOpts2 { get; private set; }
public List<SelectOption> textOpts3 { get; private set; }
public List<SelectOption> equalOpts3 { get; private set; }
public List<SelectOption> limitOpts { get; private set; }
//原因选项
public List<SelectOption> reasonOpts { get; private set; }
// public String dateField { get; set; }
public String text { get; set; }
public String condition { get; set; }
public String value { get; set; }
public String text2 { get; set; }
public String condition2 { get; set; }
public String value2 { get; set; }
public String text3 { get; set; }
public String condition3 { get; set; }
public String value3 { get; set; }
public Boolean onlyOpp { get; set; }
public String limits { get; set; }
//原因选项
public String reasons { get;set; }
public String inquiryformId { get;set; }
public String reason { get;set; }
public String opp_ID { get;set; }
// public String Opp_Name_Search_Id { get;set; }
public String batchReason { get;set; }
//状态未跟进
public String   leadStatus { get; set; }
//战略科室有效
public String   isActiveFormula { get; set; }
/*****************画面表示Bean******************/
public Integer pclCount { get; set; }
public String saveType { get; set; }
public String sortKey { get; set; }
public String preSortKey { get; set; }
public Boolean sortOrderAsc { get; set; }
public String[] sortOrder { get; set; }
public String[] columus = new String[]{'Contact_Name__c', 'Hospital_Name__c', 'Department_Class__c', 'Company__c', 'Status__c'
                                      ,'Request1__c', 'Inquiry_No__c', 'Phone__c', 'Email__c', 'Cancel_Reason__c'
                                      ,'Opp_Name_Search__c', 'Opportunity_Division__c', 'LeadSource__c', 'Campaign__c'
                                      ,'Urgent__c', 'Request_Detail__c','Contact_Id__c','Hospital_ID__c','Department_ID__c','Opp_Name_Search_ID__c'
                                      ,'Campaign_ID__c','Id','Name','Family_Name__c','Last_Name__c','Reasons_options__c','Product1__c'
                                      };
private String soqlWithoutSort = null;
private String soqlForMoneyWithoutSort = null;
private static Integer searchLimit = 1000;
public String staticResource {get; set;}
public String awsDataIds {get; set;}
public LeadIntentionController() {
    pclInfos = new List<PCLInfo>();
    con1 = new Contact();
    con2 = new Contact();
    dateOpts = new List<SelectOption>();
    textOpts = new List<SelectOption>();
    textOpts.add(new SelectOption('','--无--'));
    textOpts.add(new SelectOption('S:Name', Schema.SObjectType.Inquiry_form__c.fields.Name.label));
    textOpts.add(new SelectOption('S:Hospital_Name__r.Name', Schema.SObjectType.Inquiry_form__c.fields.Hospital_Name__c.label));
    textOpts.add(new SelectOption('S:Department_Class__r.Name', Schema.SObjectType.Inquiry_form__c.fields.Department_Class__c.label));
    textOpts.add(new SelectOption('S:Status__c', Schema.SObjectType.Inquiry_form__c.fields.Status__c.label));
    textOpts.add(new SelectOption('S:Request1__c', Schema.SObjectType.Inquiry_form__c.fields.Request1__c.label));
    textOpts.add(new SelectOption('S:Product1__c', Schema.SObjectType.Inquiry_form__c.fields.Product1__c.label));
    textOpts.add(new SelectOption('S:Phone__c', Schema.SObjectType.Inquiry_form__c.fields.Phone__c.label));
    textOpts.add(new SelectOption('S:Email__c', Schema.SObjectType.Inquiry_form__c.fields.Email__c.label));
    textOpts.add(new SelectOption('S:Cancel_Reason__c', Schema.SObjectType.Inquiry_form__c.fields.Cancel_Reason__c.label));
    textOpts.add(new SelectOption('S:Opp_Name_Search__r.Name', Schema.SObjectType.Inquiry_form__c.fields.Opp_Name_Search__c.label));
    textOpts.add(new SelectOption('S:Opportunity_Division__c', Schema.SObjectType.Inquiry_form__c.fields.Opportunity_Division__c.label));
    textOpts.add(new SelectOption('S:LeadSource__c', Schema.SObjectType.Inquiry_form__c.fields.LeadSource__c.label));
    textOpts.add(new SelectOption('S:Campaign__r.Name', Schema.SObjectType.Inquiry_form__c.fields.Campaign__c.label));
    textOpts.add(new SelectOption('S:Request_Detail__c', Schema.SObjectType.Inquiry_form__c.fields.Request_Detail__c.label));
    textOpts2 = textOpts;
    textOpts3 = textOpts;
    equalOpts = new List<SelectOption>();
    equalOpts.add(new SelectOption('equals','等于'));
    equalOpts.add(new SelectOption('notequals','不等于'));
    equalOpts.add(new SelectOption('contains','包含'));
    equalOpts.add(new SelectOption('notcontains','不包含'));
    equalOpts.add(new SelectOption('starts with','起始字符'));
    
    /*****************検索用******************/
    equalOpts2 = equalOpts;
    equalOpts3 = equalOpts;
    limitOpts = new List<SelectOption>();
    // limitOpts.add(new SelectOption('5','5'));
    limitOpts.add(new SelectOption('20','20'));
    limitOpts.add(new SelectOption('50','50'));
    limitOpts.add(new SelectOption('100','100'));
    limitOpts.add(new SelectOption('200','200'));
    limitOpts.add(new SelectOption('500','500'));
    limitOpts.add(new SelectOption('' + (searchLimit + 1), '全部'));
    
    //检索日期
    public Contact con1 { get; set; }
    public Contact con2 { get; set; }
    limits = '50';
    reasonOpts = new List<SelectOption>();
    reasonOpts.add(new SelectOption('已经有询价','已经有询价'));
    reasonOpts.add(new SelectOption('客户不需要','客户不需要'));
    reasonOpts.add(new SelectOption('客户不存在','客户不存在'));
    
    //检索 两个页面上方的字段
    public String accSearch { get; set; }
    public String ownerSearch { get; set; }
    public List<SelectOption> dateOpts { get; private set; }
    public List<SelectOption> textOpts { get; private set; }
    public List<SelectOption> equalOpts { get; private set; }
    public List<SelectOption> textOpts2 { get; private set; }
    public List<SelectOption> equalOpts2 { get; private set; }
    public List<SelectOption> textOpts3 { get; private set; }
    public List<SelectOption> equalOpts3 { get; private set; }
    public List<SelectOption> limitOpts { get; private set; }
    //原因选项
    public List<SelectOption> reasonOpts { get; private set; }
    reasons = '原因选项';
    // public String dateField { get; set; }
    public String text { get; set; }
    public String condition { get; set; }
    public String value { get; set; }
    public String text2 { get; set; }
    public String condition2 { get; set; }
    public String value2 { get; set; }
    public String text3 { get; set; }
    public String condition3 { get; set; }
    public String value3 { get; set; }
    public Boolean onlyOpp { get; set; }
    public String limits { get; set; }
    leadStatus = '01.未跟进';
    //原因选项
    public String reasons { get;set; }
    public String inquiryformId { get;set; }
    public String reason { get;set; }
    public String opp_ID { get;set; }
    // public String Opp_Name_Search_Id { get;set; }
    public String batchReason { get;set; }
    isActiveFormula = '有效';
    //状态未跟进
    public String   leadStatus { get; set; }
    //战略科室有效
    public String   isActiveFormula { get; set; }
    /*****************画面表示Bean******************/
    public Integer pclCount { get; set; }
    public String saveType { get; set; }
    staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Inquiry_form__c'));
    public String sortKey { get; set; }
    public String preSortKey { get; set; }
    public Boolean sortOrderAsc { get; set; }
    public String[] sortOrder { get; set; }
    public String[] columus = new String[]{'Contact_Name__c', 'Hospital_Name__c', 'Department_Class__c', 'Company__c', 'Status__c'
                                          ,'Request1__c', 'Inquiry_No__c', 'Phone__c', 'Email__c', 'Cancel_Reason__c'
                                          ,'Opp_Name_Search__c', 'Opportunity_Division__c', 'LeadSource__c', 'Campaign__c'
                                          ,'Urgent__c', 'Request_Detail__c','Contact_Id__c','Hospital_ID__c','Department_ID__c','Opp_Name_Search_ID__c'
                                          ,'Campaign_ID__c','Id','Name','Family_Name__c','Last_Name__c','Reasons_options__c','Product1__c'
                                          };
    private String soqlWithoutSort = null;
    private String soqlForMoneyWithoutSort = null;
}
    private static Integer searchLimit = 1000;
    public String staticResource {get; set;}
    public String awsDataIds {get; set;}
    public LeadIntentionController() {
        pclInfos = new List<PCLInfo>();
        con1 = new Contact();
        con2 = new Contact();
        dateOpts = new List<SelectOption>();
        textOpts = new List<SelectOption>();
        textOpts.add(new SelectOption('','--无--'));
        textOpts.add(new SelectOption('S:Name', Schema.SObjectType.Inquiry_form__c.fields.Name.label));
        textOpts.add(new SelectOption('S:Hospital_Name__r.Name', Schema.SObjectType.Inquiry_form__c.fields.Hospital_Name__c.label));
        textOpts.add(new SelectOption('S:Department_Class__r.Name', Schema.SObjectType.Inquiry_form__c.fields.Department_Class__c.label));
        textOpts.add(new SelectOption('S:Status__c', Schema.SObjectType.Inquiry_form__c.fields.Status__c.label));
        textOpts.add(new SelectOption('S:Request1__c', Schema.SObjectType.Inquiry_form__c.fields.Request1__c.label));
        textOpts.add(new SelectOption('S:Product1__c', Schema.SObjectType.Inquiry_form__c.fields.Product1__c.label));
        textOpts.add(new SelectOption('S:Phone__c', Schema.SObjectType.Inquiry_form__c.fields.Phone__c.label));
        textOpts.add(new SelectOption('S:Email__c', Schema.SObjectType.Inquiry_form__c.fields.Email__c.label));
        textOpts.add(new SelectOption('S:Cancel_Reason__c', Schema.SObjectType.Inquiry_form__c.fields.Cancel_Reason__c.label));
        textOpts.add(new SelectOption('S:Opp_Name_Search__r.Name', Schema.SObjectType.Inquiry_form__c.fields.Opp_Name_Search__c.label));
        textOpts.add(new SelectOption('S:Opportunity_Division__c', Schema.SObjectType.Inquiry_form__c.fields.Opportunity_Division__c.label));
        textOpts.add(new SelectOption('S:LeadSource__c', Schema.SObjectType.Inquiry_form__c.fields.LeadSource__c.label));
        textOpts.add(new SelectOption('S:Campaign__r.Name', Schema.SObjectType.Inquiry_form__c.fields.Campaign__c.label));
        textOpts.add(new SelectOption('S:Request_Detail__c', Schema.SObjectType.Inquiry_form__c.fields.Request_Detail__c.label));
        textOpts2 = textOpts;
        textOpts3 = textOpts;
        equalOpts = new List<SelectOption>();
        equalOpts.add(new SelectOption('equals','等于'));
        equalOpts.add(new SelectOption('notequals','不等于'));
        equalOpts.add(new SelectOption('contains','包含'));
        equalOpts.add(new SelectOption('notcontains','不包含'));
        equalOpts.add(new SelectOption('starts with','起始字符'));
        equalOpts2 = equalOpts;
        equalOpts3 = equalOpts;
        limitOpts = new List<SelectOption>();
        // limitOpts.add(new SelectOption('5','5'));
        limitOpts.add(new SelectOption('20','20'));
        limitOpts.add(new SelectOption('50','50'));
        limitOpts.add(new SelectOption('100','100'));
        limitOpts.add(new SelectOption('200','200'));
        limitOpts.add(new SelectOption('500','500'));
        limitOpts.add(new SelectOption('' + (searchLimit + 1), '全部'));
        limits = '50';
        reasonOpts = new List<SelectOption>();
        reasonOpts.add(new SelectOption('已经有询价','已经有询价'));
        reasonOpts.add(new SelectOption('客户不需要','客户不需要'));
        reasonOpts.add(new SelectOption('客户不存在','客户不存在'));
        reasons = '原因选项';
        leadStatus = '01.未跟进';
        isActiveFormula = '有效';
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Inquiry_form__c'));
public PageReference init() {
    system.debug('test:12345');
    onlyOpp = false;
    String uidParam = System.currentPageReference().getParameters().get('uid');
    if (uidParam != null){
        User u = [select Id, FirstName, LastName from User where Id = :uidParam];
        ownerSearch = u.LastName + ' ' + u.FirstName;
    }
    public PageReference init() {
        system.debug('test:12345');
        onlyOpp = false;
        String uidParam = System.currentPageReference().getParameters().get('uid');
        if (uidParam != null){
            User u = [select Id, FirstName, LastName from User where Id = :uidParam];
            ownerSearch = u.LastName + ' ' + u.FirstName;
    String hpidParam = System.currentPageReference().getParameters().get('hpid');
    if(hpidParam != null){
        List<Account> hpAcc = ControllerUtil.selectAccountForTrigger(new String[] {hpidParam});
        if (hpAcc.size() > 0) {
            accSearch = hpAcc[0].name;
        }
        String hpidParam = System.currentPageReference().getParameters().get('hpid');
        if(hpidParam != null){
            List<Account> hpAcc = ControllerUtil.selectAccountForTrigger(new String[] {hpidParam});
            if (hpAcc.size() > 0) {
                accSearch = hpAcc[0].name;
            }
        }
        soqlWithoutSort = this.makeSoql(false, accSearch, ownerSearch,
                                     text, condition, value, text2, condition2, value2, text3, condition3, value3);
        String soql = soqlWithoutSort + ' order by  CreatedDate  desc limit ' + Integer.valueOf(limits);
        soqlForMoneyWithoutSort = this.makeSoql(true, accSearch, ownerSearch,
                                    text, condition, value, text2, condition2, value2, text3, condition3, value3);
        String soqlForMoney = soqlForMoneyWithoutSort + ' order by  CreatedDate   desc limit ' + Integer.valueOf(System.Label.TotalLimit);
        System.debug('soqlWithoutSort:' + soqlWithoutSort);
        system.debug('aaaaaaaaaa'+soql);
        system.debug('bbbbbbb:'+soqlForMoney);
        List<Inquiry_form__c> queryList = Database.query(soql);
        List<Inquiry_form__c> queryListForMoney = Database.query(soqlForMoney);
        system.debug('ppppppppp:'+queryList);
        system.debug('ooooooooo:'+queryListForMoney);
        system.debug('ppppppppp的size():'+queryList.size());
        system.debug('ooooooooo的size():'+queryListForMoney.size());
    }
    soqlWithoutSort = this.makeSoql(false, accSearch, ownerSearch,
                                 text, condition, value, text2, condition2, value2, text3, condition3, value3);
    String soql = soqlWithoutSort + ' order by  CreatedDate  desc limit ' + Integer.valueOf(limits);
    soqlForMoneyWithoutSort = this.makeSoql(true, accSearch, ownerSearch,
                                text, condition, value, text2, condition2, value2, text3, condition3, value3);
    String soqlForMoney = soqlForMoneyWithoutSort + ' order by  CreatedDate   desc limit ' + Integer.valueOf(System.Label.TotalLimit);
    System.debug('soqlWithoutSort:' + soqlWithoutSort);
    system.debug('aaaaaaaaaa'+soql);
    system.debug('bbbbbbb:'+soqlForMoney);
    List<Inquiry_form__c> queryList = Database.query(soql);
    List<Inquiry_form__c> queryListForMoney = Database.query(soqlForMoney);
    system.debug('ppppppppp:'+queryList);
    system.debug('ooooooooo:'+queryListForMoney);
    system.debug('ppppppppp的size():'+queryList.size());
    system.debug('ooooooooo的size():'+queryListForMoney.size());
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        iflog.Type__c = 'TestTaskManage';
    this.makeOppRecordsForView(queryList, queryListForMoney);
    this.sortKey = '0';
    this.preSortKey = '0';
    this.sortOrderAsc = true;
    this.sortOrder = new String[columus.size()];
    for (Integer i = 0; i < columus.size(); i++) this.sortOrder[i] = ' ';
    System.debug('最后取得:'+pclInfos.size());
    pclCount = pclInfos.size();
    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '取得最近的 ' + pclCount + ' 条数据'));
        iflog.Log__c = '进入了init方法: queryListForMoney sql: '+soqlWithoutSort;
        insert iflog;
        this.makeOppRecordsForView(queryList, queryListForMoney);
        this.sortKey = '0';
        this.preSortKey = '0';
    List<String> a = new List<String>();
    for(Inquiry_form__c ifc : queryList){
        a.add(ifc.AWS_Data_Id__c);
    }
    awsDataIds = JSON.serialize(a);
    return null;
}
public PageReference searchOpp() {
    pclInfos = new List<PCLInfo>();
    String soql = this.makeSoql(false, accSearch, ownerSearch, text, condition, value, text2, condition2, value2, text3, condition3, value3)+ ' order by     CreatedDate desc limit ' + Integer.valueOf(limits);
    // soql += ' order by Name limit ' + Integer.valueOf(limits);
    String soqlForMoney = this.makeSoql(true, accSearch, ownerSearch, text, condition, value, text2, condition2, value2, text3, condition3, value3)+ ' order by   CreatedDate desc limit ' + Integer.valueOf(System.Label.TotalLimit);
    // soqlForMoney += ' order by Name limit ' + Integer.valueOf(System.Label.TotalLimit);
    this.sortOrder[0] = '↑';
    system.debug('soql:'+soql);
    system.debug('soqlForMoney:'+soqlForMoney);
    List<Inquiry_form__c> queryList = Database.query(soql);
    List<Inquiry_form__c> queryListForMoney = Database.query(soqlForMoney);
    this.makeOppRecordsForView(queryList, queryListForMoney);
    pclCount = pclInfos.size();
    if (pclCount > searchLimit) {
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'The search returned more than the maximum number of rows (' + searchLimit + ')'));
    } else {
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + pclCount + ' 条数据'));
    }
    return null;
}
public PageReference sortTable() {
    pclInfos = new List<PCLInfo>();
    if (this.sortKey == this.preSortKey) {
        this.sortOrderAsc = !this.sortOrderAsc;
        this.sortOrder[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
    } else {
        this.sortOrderAsc = true;
        this.sortOrder = new String[columus.size()];
        for (Integer i = 0; i < columus.size(); i++) this.sortOrder[i] = ' ';
        System.debug('最后取得:'+pclInfos.size());
        pclCount = pclInfos.size();
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '取得最近的 ' + pclCount + ' 条数据'));
        List<String> a = new List<String>();
        for(Inquiry_form__c ifc : queryList){
            a.add(ifc.AWS_Data_Id__c);
        }
        awsDataIds = JSON.serialize(a);
        return null;
        this.sortOrder[Integer.valueOf(this.preSortKey)] = ' ';
        this.sortOrder[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
    }
    public PageReference searchOpp() {
        pclInfos = new List<PCLInfo>();
        String soql = this.makeSoql(false, accSearch, ownerSearch, text, condition, value, text2, condition2, value2, text3, condition3, value3)+ ' order by     CreatedDate desc limit ' + Integer.valueOf(limits);
        // soql += ' order by Name limit ' + Integer.valueOf(limits);
        String soqlForMoney = this.makeSoql(true, accSearch, ownerSearch, text, condition, value, text2, condition2, value2, text3, condition3, value3)+ ' order by   CreatedDate desc limit ' + Integer.valueOf(System.Label.TotalLimit);
        // soqlForMoney += ' order by Name limit ' + Integer.valueOf(System.Label.TotalLimit);
        this.sortOrder[0] = '↑';
        system.debug('soql:'+soql);
        system.debug('soqlForMoney:'+soqlForMoney);
        List<Inquiry_form__c> queryList = Database.query(soql);
        List<Inquiry_form__c> queryListForMoney = Database.query(soqlForMoney);
        this.makeOppRecordsForView(queryList, queryListForMoney);
        pclCount = pclInfos.size();
        if (pclCount > searchLimit) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'The search returned more than the maximum number of rows (' + searchLimit + ')'));
        } else {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + pclCount + ' 条数据'));
        }
        return null;
    }
    public PageReference sortTable() {
        pclInfos = new List<PCLInfo>();
        if (this.sortKey == this.preSortKey) {
            this.sortOrderAsc = !this.sortOrderAsc;
            this.sortOrder[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
        } else {
            this.sortOrderAsc = true;
            this.sortOrder[Integer.valueOf(this.preSortKey)] = ' ';
            this.sortOrder[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
        }
        system.debug(this.sortKey);
        this.preSortKey = this.sortKey;
        String soql = soqlWithoutSort
                + ' order by ' + this.columus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
    system.debug(this.sortKey);
    this.preSortKey = this.sortKey;
    String soql = soqlWithoutSort
            + ' order by ' + this.columus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
system.debug('sort:::::'+ soql);
        List<Inquiry_form__c> queryList = Database.query(soql);
        String soqlForMoney = soqlForMoneyWithoutSort
                + ' order by ' + this.columus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last')+ ' limit ' + Integer.valueOf(System.Label.TotalLimit) ;
    List<Inquiry_form__c> queryList = Database.query(soql);
    String soqlForMoney = soqlForMoneyWithoutSort
            + ' order by ' + this.columus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last')+ ' limit ' + Integer.valueOf(System.Label.TotalLimit) ;
system.debug('sort:::::'+ soqlForMoney);
        List<Inquiry_form__c> queryListForMoney = Database.query(soqlForMoney);
        this.makeOppRecordsForView(queryList, queryListForMoney);
        pclCount = pclInfos.size();
        if (pclCount > searchLimit) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'The search returned more than the maximum number of rows (' + searchLimit + ')'));
        } else {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + pclCount + ' 条数据'));
        }
        return null;
    List<Inquiry_form__c> queryListForMoney = Database.query(soqlForMoney);
    this.makeOppRecordsForView(queryList, queryListForMoney);
    pclCount = pclInfos.size();
    if (pclCount > searchLimit) {
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'The search returned more than the maximum number of rows (' + searchLimit + ')'));
    } else {
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + pclCount + ' 条数据'));
    }
    //修改询问单状态为不要 并保存原因
    public PageReference   saveInquiryform() {
    return null;
}
//修改询问单状态为不要 并保存原因
public PageReference   saveInquiryform() {
    //ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '66666666666___'+ Id));
    system.debug('aaaaaaaaa'+inquiryformId+'bbbbbbbb'+reason);
    if (String.isNotBlank(inquiryformId)){
        List<Inquiry_form__c> updateInquiryform = new List<Inquiry_form__c>();
        Inquiry_form__c inquiryForm = new Inquiry_form__c();
        inquiryForm.Id = inquiryformId;
        inquiryForm.Status__c = '02.不需要';
        //不需要的时候 的确认日期
        system.debug('ccccccc:'+opp_ID);
        inquiryForm.Confirmation_Date__c = Date.toDay();
        inquiryForm.Reasons_options__c = reason;
        inquiryForm.Cancel_Reason__c = reason;
        if(reason == '已经有询价'){
            inquiryForm.Opp_Name_Search__c = opp_ID;
        }
        updateInquiryform.add(inquiryForm);
        if (updateInquiryform.size() > 0) {
            update updateInquiryform;
            // ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '询问单状态更新完毕,已保存,请手动刷新页面。'));
        }
        inquiryformId = '';
    }
     return loadPage();
}
 public PageReference loadPage() {
    PageReference ref = new PageReference('/apex/LeadIntention');
    ref.setRedirect(true);
    return ref;
}
//批量更新 询问单状态
public PageReference   saveInquiryOpts() {
        //ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '66666666666___'+ Id));
        system.debug('aaaaaaaaa'+inquiryformId+'bbbbbbbb'+reason);
        if (String.isNotBlank(inquiryformId)){
            List<Inquiry_form__c> updateInquiryform = new List<Inquiry_form__c>();
            Inquiry_form__c inquiryForm = new Inquiry_form__c();
            inquiryForm.Id = inquiryformId;
            inquiryForm.Status__c = '02.不需要';
            //不需要的时候 的确认日期
            system.debug('ccccccc:'+opp_ID);
            inquiryForm.Confirmation_Date__c = Date.toDay();
            inquiryForm.Reasons_options__c = reason;
            inquiryForm.Cancel_Reason__c = reason;
            if(reason == '已经有询价'){
                inquiryForm.Opp_Name_Search__c = opp_ID;
            }
            updateInquiryform.add(inquiryForm);
            if (updateInquiryform.size() > 0) {
                update updateInquiryform;
                // ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '询问单状态更新完毕,已保存,请手动刷新页面。'));
            }
            inquiryformId = '';
        }
    try {
        system.debug('ccccccc'+batchReason);
    List<Inquiry_form__c> updSAs = new List<Inquiry_form__c>();
        
         return loadPage();
        for (PCLInfo oi : pclInfos) {
              system.debug('输出的值为:'+oi.reasonFlg);
            if (oi.reasonFlg == '1') {
                oi.reasonFlg = '0';
                oi.rec.Status__c = '02.不需要';
                oi.rec.Reasons_options__c=batchReason;
                oi.rec.Cancel_Reason__c = batchReason;
                oi.rec.Confirmation_Date__c = Date.toDay();
                updSAs.add(oi.rec);
                system.debug('更新的字段为:'+oi.rec);
            }
        }
        system.debug(updSAs);
    if (updSAs.size() > 0) update updSAs;
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'Save Completed'));
    }catch (Exception ex) {
        ApexPages.addMessages(ex);
        return null;
    }
       return null;
    }
public PageReference save() {
    try {
     public PageReference loadPage() {
        PageReference ref = new PageReference('/apex/LeadIntention');
        ref.setRedirect(true);
        return ref;
    }
    //批量更新 询问单状态
    public PageReference   saveInquiryOpts() {
            //ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '66666666666___'+ Id));
        try {
            system.debug('ccccccc'+batchReason);
        List<Inquiry_form__c> updSAs = new List<Inquiry_form__c>();
            for (PCLInfo oi : pclInfos) {
                  system.debug('输出的值为:'+oi.reasonFlg);
                if (oi.reasonFlg == '1') {
                    oi.reasonFlg = '0';
                    oi.rec.Status__c = '02.不需要';
                    oi.rec.Reasons_options__c=batchReason;
                    oi.rec.Cancel_Reason__c = batchReason;
                    oi.rec.Confirmation_Date__c = Date.toDay();
                    updSAs.add(oi.rec);
                    system.debug('更新的字段为:'+oi.rec);
                }
        system.debug('输出的值为:'+pclInfos);
        for (PCLInfo oi : pclInfos) {
            if (oi.changeFlg == '1') {
                oi.changeFlg = '0';
                updSAs.add(oi.rec);
                system.debug('更新的字段为:'+oi.rec);
            }
            system.debug(updSAs);
        }
        if (updSAs.size() > 0) update updSAs;
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'Save Completed'));
        }catch (Exception ex) {
            ApexPages.addMessages(ex);
            return null;
        }
           return null;
        }
    public PageReference save() {
        try {
            List<Inquiry_form__c> updSAs = new List<Inquiry_form__c>();
            system.debug('输出的值为:'+pclInfos);
            for (PCLInfo oi : pclInfos) {
                if (oi.changeFlg == '1') {
                    oi.changeFlg = '0';
                    updSAs.add(oi.rec);
                    system.debug('更新的字段为:'+oi.rec);
                }
            }
            if (updSAs.size() > 0) update updSAs;
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'Save Completed'));
        } catch (Exception ex) {
            ApexPages.addMessages(ex);
            return null;
        }
        if (saveType == '1') {
            searchOpp();
            saveType = '';
        } else if (saveType == '2') {
            sortTable();
            saveType = '';
        } else {
        }
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'Save Completed'));
    } catch (Exception ex) {
        ApexPages.addMessages(ex);
        return null;
    }
    public PageReference cancel() {
        return new PageReference('/home/home.jsp');
    if (saveType == '1') {
        searchOpp();
        saveType = '';
    } else if (saveType == '2') {
        sortTable();
        saveType = '';
    } else {
    }
    return null;
}
    private String makeSoql(Boolean isforMoneyFlg, String accStr, String ownerStr, //String dept, String rank, Boolean consumable,
                            String txt, String con, String val,
                            String txt2, String con2, String val2,
                            String txt3, String con3, String val3) {
        String soql ='';
            soql += 'select Id, Contact_Name__c, Hospital_Name__r.Name, Department_Class__c, Company__c, Request1__c,'
                + ' Inquiry_No__c, Phone__c, Email__c, Cancel_Reason__c,Status__c,'
                + ' Opp_Name_Search__c, Opportunity_Division__c, LeadSource__c, Campaign__c,'
                + ' Urgent__c, Request_Detail__c ,Contact_Id__c,Hospital_ID__c,Department_ID__c,Opp_Name_Search_ID__c,'
                + 'Campaign_ID__c,Last_Name__c,Family_Name__c,Name,Reasons_options__c,'
                + 'Product1__c,Confirmation_Date__c,AWS_Data_Id__c'
                //,Lead_link__c
                + ' from Inquiry_form__c where Id != null ';
                //2021-11-24  mzy  共通平台项目-首页修改  start
                //只查询所有人是当前用户的产品咨询单
                //+ ' And OwnerId = \''+UserInfo.getUserId()+'\''
                //2021-11-24  mzy  共通平台项目-首页修改  end
public PageReference cancel() {
    return new PageReference('/home/home.jsp');
}
        //状态只显示未跟进
        if (!String.isBlank(leadStatus)) {
            String[] vals = leadStatus.split(' ');
                    for (String v : vals) {
                        soql += ' and Status__c = \'' + v + '\'' ;
            }
        }
        if(!String.isBlank(isActiveFormula)){
            String[] vals = isActiveFormula.split(' ');
                    for (String v : vals) {
                        soql += ' and Department_Class__r.Is_Active_Formula__c = \'' + v + '\'' ;
            }
        }
        if (!String.isBlank(accStr)) {
            String[] vals = accStr.split(' ');
            for (String v : vals) {
                soql += ' and Hospital_Name__r.Name like \'%' + v + '%\'';
            }
        }
        if (!String.isBlank(ownerStr)) {
            String[] vals = ownerStr.split(' ');
            for (String v : vals) {
                soql += ' and Name like \'%' + v + '%\'';
            }
        }
        soql += this.makeTextSql(txt, con, val);
        soql += this.makeTextSql(txt2, con2, val2);
        soql += this.makeTextSql(txt3, con3, val3);
        system.debug('sssssss:'+soql);
        return soql;
private String makeSoql(Boolean isforMoneyFlg, String accStr, String ownerStr, //String dept, String rank, Boolean consumable,
                        String txt, String con, String val,
                        String txt2, String con2, String val2,
                        String txt3, String con3, String val3) {
    String soql ='';
        soql += 'select Id, Contact_Name__c, Hospital_Name__r.Name, Department_Class__c, Company__c, Request1__c,'
            + ' Inquiry_No__c, Phone__c, Email__c, Cancel_Reason__c,Status__c,'
            + ' Opp_Name_Search__c, Opportunity_Division__c, LeadSource__c, Campaign__c,'
            + ' Urgent__c, Request_Detail__c ,Contact_Id__c,Hospital_ID__c,Department_ID__c,Opp_Name_Search_ID__c,'
            + 'Campaign_ID__c,Last_Name__c,Family_Name__c,Name,Reasons_options__c,'
            + 'Product1__c,Confirmation_Date__c,AWS_Data_Id__c'
            //,Lead_link__c
            + ' from Inquiry_form__c where Id != null ';
            //2021-11-24  mzy  共通平台项目-首页修改  start
            //只查询所有人是当前用户的产品咨询单
            //+ ' And OwnerId = \''+UserInfo.getUserId()+'\''
            //2021-11-24  mzy  共通平台项目-首页修改  end
    //状态只显示未跟进
    if (!String.isBlank(leadStatus)) {
        String[] vals = leadStatus.split(' ');
                for (String v : vals) {
                    soql += ' and Status__c = \'' + v + '\'' ;
        }
    }
    if(!String.isBlank(isActiveFormula)){
        String[] vals = isActiveFormula.split(' ');
                for (String v : vals) {
                    soql += ' and Department_Class__r.Is_Active_Formula__c = \'' + v + '\'' ;
        }
    }
    if (!String.isBlank(accStr)) {
        String[] vals = accStr.split(' ');
        for (String v : vals) {
            soql += ' and Hospital_Name__r.Name like \'%' + v + '%\'';
        }
    }
    if (!String.isBlank(ownerStr)) {
        String[] vals = ownerStr.split(' ');
        for (String v : vals) {
            soql += ' and Name like \'%' + v + '%\'';
        }
    }
    soql += this.makeTextSql(txt, con, val);
    soql += this.makeTextSql(txt2, con2, val2);
    soql += this.makeTextSql(txt3, con3, val3);
    system.debug('sssssss:'+soql);
    return soql;
}
    private void makeOppRecordsForView(List<Inquiry_form__c> queryList, List<Inquiry_form__c> queryListForMoney) {
        Savepoint sp = Database.setSavepoint();
        Database.SaveResult[] results = Database.update(queryList, false);
        Database.rollback(sp);
        system.debug('llllllllll:'+queryListForMoney.size());
        for (Integer i = 0; i < queryListForMoney.size(); i++) {
            system.debug('vvvvvvvvvv:'+queryList);
            if(i<queryList.size()){
                if (i == searchLimit + 1) {
                    continue;
                }
                pclInfos.add(new PCLInfo(queryList[i]));
                pclInfos[pclInfos.size() - 1].lineNo = pclInfos.size() - 1;
                //拼接 复选框的id值
                pclInfos[pclInfos.size() - 1].chk = 'chk'+ pclInfos[pclInfos.size() - 1].lineNo;
                if (!results[i].isSuccess()) {
                    pclInfos[pclInfos.size() - 1].canEdit = false;
                    if (results[i].getErrors()[0].getStatusCode() != null) {
                        if (String.valueOf(results[i].getErrors()[0].getStatusCode()) == 'INSUFFICIENT_ACCESS_OR_READONLY') {
                            pclInfos[pclInfos.size() - 1].hasError = true;
                        } else {
                            pclInfos[pclInfos.size() - 1].hasFieldError = true;
                        }
private void makeOppRecordsForView(List<Inquiry_form__c> queryList, List<Inquiry_form__c> queryListForMoney) {
    Savepoint sp = Database.setSavepoint();
    Database.SaveResult[] results = Database.update(queryList, false);
    Database.rollback(sp);
    system.debug('llllllllll:'+queryListForMoney.size());
    for (Integer i = 0; i < queryListForMoney.size(); i++) {
        system.debug('vvvvvvvvvv:'+queryList);
        if(i<queryList.size()){
            if (i == searchLimit + 1) {
                continue;
            }
            pclInfos.add(new PCLInfo(queryList[i]));
            pclInfos[pclInfos.size() - 1].lineNo = pclInfos.size() - 1;
            //拼接 复选框的id值
            pclInfos[pclInfos.size() - 1].chk = 'chk'+ pclInfos[pclInfos.size() - 1].lineNo;
            if (!results[i].isSuccess()) {
                pclInfos[pclInfos.size() - 1].canEdit = false;
                if (results[i].getErrors()[0].getStatusCode() != null) {
                    if (String.valueOf(results[i].getErrors()[0].getStatusCode()) == 'INSUFFICIENT_ACCESS_OR_READONLY') {
                        pclInfos[pclInfos.size() - 1].hasError = true;
                    } else {
                        pclInfos[pclInfos.size() - 1].hasFieldError = true;
                    }
                }
            }
        }
    }
}
private String makeTextSql(String txt1, String con, String val) {
    system.debug('第一个参数:'+txt1+'第二个参数:'+con+'第三个参数:'+val);
        String soql = '';
        if (!String.isBlank(txt1)) {
            if ((con == 'contains' || con == 'notcontains') && val.contains(' ')) {
                String[] vals = val.split(' ');
                String cSql = '';
system.debug('第一个参数:'+txt1+'第二个参数:'+con+'第三个参数:'+val);
    String soql = '';
    if (!String.isBlank(txt1)) {
        if ((con == 'contains' || con == 'notcontains') && val.contains(' ')) {
            String[] vals = val.split(' ');
            String cSql = '';
            for (String v : vals) {
                cSql += this.makeTextSqlStr(txt1, con, v);
            }
            if (con == 'contains') {
                soql += cSql;
            } else {
                cSql = cSql.replaceAll(' and ', ') and (NOT ');
                soql += cSql.substring(1) + ') ';
            }
        } else if ((con == 'equals' || con == 'notequals') && val.contains(',')) {
            String[] vals = val.split(',');
            if (vals.size() > 0) {
                String txt = txt1.substring(2);
                soql += ' and ( ';
                for (String v : vals) {
                    cSql += this.makeTextSqlStr(txt1, con, v);
                }
                if (con == 'contains') {
                    soql += cSql;
                } else {
                    cSql = cSql.replaceAll(' and ', ') and (NOT ');
                    soql += cSql.substring(1) + ') ';
                }
            } else if ((con == 'equals' || con == 'notequals') && val.contains(',')) {
                String[] vals = val.split(',');
                if (vals.size() > 0) {
                    String txt = txt1.substring(2);
                    soql += ' and ( ';
                    for (String v : vals) {
                        if (con == 'equals') {
                            soql += txt + ' = \'' + v + '\' or ';
                            system.debug('wwwwwwwwwwww :'+soql);
                        } else {
                            // notequals
                            soql += txt + ' <> \'' + v + '\' and ';
                        }
                    if (con == 'equals') {
                        soql += txt + ' = \'' + v + '\' or ';
                        system.debug('wwwwwwwwwwww :'+soql);
                    } else {
                        // notequals
                        soql += txt + ' <> \'' + v + '\' and ';
                    }
                    soql = soql.substring(0, soql.length() - 4);
                    soql += ')';
                }
                soql = soql.substring(0, soql.length() - 4);
                soql += ')';
            }
        } else {
            String cSql = this.makeTextSqlStr(txt1, con, val);
            if (con != 'notcontains') {
                soql += this.makeTextSqlStr(txt1, con, val);
            } else {
                String cSql = this.makeTextSqlStr(txt1, con, val);
                if (con != 'notcontains') {
                    soql += this.makeTextSqlStr(txt1, con, val);
                // notcontains
                cSql = cSql.substring(5);
                soql += ' and (NOT ' + cSql + ') ';
            }
        }
    }
    return soql;
}
private String makeTextSqlStr(String txt1, String con, String val) {
    String soql = '';
    system.debug('第一个参数:'+txt1+'第二个参数:'+con+'第三个参数:'+val);
    if (!String.isBlank(txt1)) {
        String txt = txt1.substring(2);
        String colType = txt1.substring(0, 2);
        String tmpVal = val;
        if (String.isBlank(tmpVal)) {
            if (con == 'equals') {
                soql += ' and ' + txt + ' = null';
            } else if (con == 'notequals') {
                soql += ' and ' + txt + ' <> null';
            } else {
            }
        } else {
            soql += ' and ' + txt;
            if (con == 'equals') {
                if (colType == 'S:') {
                    soql += ' = \'' + tmpVal + '\'';
                } else {
                    // notcontains
                    cSql = cSql.substring(5);
                    soql += ' and (NOT ' + cSql + ') ';
                    soql += ' = ' + tmpVal + ' ';
                }
            } else if (con == 'notequals') {
                if (colType == 'S:') {
                    soql += ' <> \'' + tmpVal + '\'';
                } else {
                    soql += ' <> ' + tmpVal + ' ';
                }
            } else if (con == 'contains' || con == 'notcontains') {
                soql += ' like \'%' + tmpVal + '%\'';
            } else if (con == 'starts with') {
                soql += ' like \'' + tmpVal + '%\'';
            } else {
                if (colType == 'S:') {
                    soql += ' ' + con + '\'' + tmpVal + '\'';
                } else {
                    soql += ' ' + con + ' ' + tmpVal + ' ';
                }
            }
        }
        return soql;
    }
    private String makeTextSqlStr(String txt1, String con, String val) {
        String soql = '';
        system.debug('第一个参数:'+txt1+'第二个参数:'+con+'第三个参数:'+val);
        if (!String.isBlank(txt1)) {
            String txt = txt1.substring(2);
            String colType = txt1.substring(0, 2);
            String tmpVal = val;
            if (String.isBlank(tmpVal)) {
                if (con == 'equals') {
                    soql += ' and ' + txt + ' = null';
                } else if (con == 'notequals') {
                    soql += ' and ' + txt + ' <> null';
                } else {
                }
            } else {
                soql += ' and ' + txt;
                if (con == 'equals') {
                    if (colType == 'S:') {
                        soql += ' = \'' + tmpVal + '\'';
                    } else {
                        soql += ' = ' + tmpVal + ' ';
                    }
                } else if (con == 'notequals') {
                    if (colType == 'S:') {
                        soql += ' <> \'' + tmpVal + '\'';
                    } else {
                        soql += ' <> ' + tmpVal + ' ';
                    }
                } else if (con == 'contains' || con == 'notcontains') {
                    soql += ' like \'%' + tmpVal + '%\'';
                } else if (con == 'starts with') {
                    soql += ' like \'' + tmpVal + '%\'';
                } else {
                    if (colType == 'S:') {
                        soql += ' ' + con + '\'' + tmpVal + '\'';
                    } else {
                        soql += ' ' + con + ' ' + tmpVal + ' ';
                    }
                }
            }
        }
        return soql;
    return soql;
}
 class PCLInfo {
    public Inquiry_form__c rec { get; set; }
    public Boolean canEdit { get; private set; }
    public Boolean hasError { get; private set; }
    public Boolean hasFieldError { get; private set; }
    public Integer lineNo { get; private set; }
    public String changeFlg { get; set; }
    public String reasonFlg { get; set; }
    //复选框id值
    public String chk { get;set; }
    public PCLInfo(Inquiry_form__c record) {
        rec = record;
        canEdit = true;
        hasError = false;
        hasFieldError = false;
        lineNo = 0;
        changeFlg = '0';
        reasonFlg = '0';
        chk = 'chk'+lineNo;
    }
     class PCLInfo {
        public Inquiry_form__c rec { get; set; }
        public Boolean canEdit { get; private set; }
        public Boolean hasError { get; private set; }
        public Boolean hasFieldError { get; private set; }
        public Integer lineNo { get; private set; }
        public String changeFlg { get; set; }
        public String reasonFlg { get; set; }
        //复选框id值
        public String chk { get;set; }
        public PCLInfo(Inquiry_form__c record) {
            rec = record;
            canEdit = true;
            hasError = false;
            hasFieldError = false;
            lineNo = 0;
            changeFlg = '0';
            reasonFlg = '0';
            chk = 'chk'+lineNo;
        }
}
    }
    public static void forTest(){
        integer i = 0;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
    }
public static void forTest(){
    integer i = 0;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
    i++;
}
}
force-app/main/default/classes/LightningUtil.cls
@@ -3,13 +3,30 @@
        
    }
    public static List<Agency_Contact__c> selectOCMAgencyContact(Set<String> hospitalSet, Set<String> ahospitalSet) {
        return [select Id, Agency_Hospital__c, IsOlympusContact__c, Name, Doctor_Division1__c, Type__c, Hospital_DC_Name__c,Department_Cateogy_F__c,Hospital_Name__c from Agency_Contact__c
        return [select Id, Agency_Hospital__c, IsOlympusContact__c, Name, Doctor_Division1__c, Type__c, Hospital_DC_Name__c,Department_Cateogy_F__c,Hospital_Name__c,
                AWS_Data_Id__c  // 20220222 PI改造 by Bright
                from Agency_Contact__c
                    where Department_Class__r.Hospital_Department_Class__c in :hospitalSet or (Department_Class__c = null and Agency_Hospital__c in :aHospitalSet) order by Name];
    }
    public static List<Agency_Contact__c> searchOCMAgencyContact(Set<String> hospitalSet, Set<String> aHospitalSet, String hosStr, String conStr) {
        return [select Id, Agency_Hospital__c, IsOlympusContact__c, Name, Doctor_Division1__c, Type__c, Hospital_DC_Name__c,Department_Cateogy_F__c,Hospital_Name__c from Agency_Contact__c 
                    where (Department_Class__r.Hospital_Department_Class__c in :hospitalSet or (Department_Class__c = null and Agency_Hospital__c in :aHospitalSet)) and Name like :conStr and Hospital_DC_Name__c like :hosStr order by Name];
    }
    // 20220222 PI改造 by Bright--start
    public static List<Agency_Contact__c> searchOCMAgencyContact(Set<String> hospitalSet, Set<String> aHospitalSet, String hosStr, List<string> awsids) {
        string sql = 'select Id, Agency_Hospital__c, IsOlympusContact__c, Name, Doctor_Division1__c, Type__c, Hospital_DC_Name__c,Department_Cateogy_F__c,Hospital_Name__c,AWS_Data_Id__c from Agency_Contact__c';
        sql += ' where (Department_Class__r.Hospital_Department_Class__c in :hospitalSet or (Department_Class__c = null and Agency_Hospital__c in :aHospitalSet)) and Hospital_DC_Name__c like :hosStr';
        if (awsids!=null && awsids.size()>0) {
            sql += ' and AWS_Data_Id__c in :awsids ';
        }
        sql += ' order by Hospital_DC_Name__c';
        system.debug('sql='+sql);
        return Database.query(sql);
    }
    // 20220222 PI改造 by Bright--end
    public static List<Contact> selectContact(String cId) {
        return [select Id, AccountId, Name from Contact where id=:cId];
    }
@@ -22,7 +39,31 @@
    public static List<contact> selectAgencyPerson() {
        String login_user_id = UserInfo.getUserId();
        return [select id, Name, Agency_User__c from contact where Agency_User__c = true and Isactive__c = '有效' and AccountId in (select AccountId from User where id=:login_user_id)];
    // PIPL update Yin Mingjie 21/02/2022 start
    // return [select id, Name, Agency_User__c from contact where  Agency_User__c = true and  Isactive__c = '有效' and AccountId in
        // (select AccountId from User where id=:login_user_id)];
        return [select id, Name, Agency_User__c, AWS_Data_Id__c from contact where  Agency_User__c = true and  Isactive__c = '有效' and AccountId in
        (select AccountId from User where id=:login_user_id)];
        // PIPL update Yin Mingjie 21/02/2022 end
    }
    public static List<contact> selectAgencyPerson01() {
        String login_user_id = UserInfo.getUserId();
        system.debug('login_user_id=============>'+login_user_id);
        return [select id, Name,Agency_User__c from contact where  Agency_User__c = false and  Isactive__c = '有效'  and id in
        (select ContactId from User where id =: login_user_id)];
    }
    public static List<contact> selectAgencyPerson02() {
        String login_user_id = UserInfo.getUserId();
        return [select id, Name, Agency_User__c from contact where Isactive__c = '有效' and AccountId in
        (select AccountId from User where id=:login_user_id)];
    }
    public static List<contact> selectAgencyPerson03() {
        String login_user_id = UserInfo.getUserId();
        system.debug('login_user_id=============>'+login_user_id);
        return [select id, Name,Agency_User__c from contact where   Isactive__c = '有效'  and id in
        (select ContactId from User where id =: login_user_id)];
    }
    
    public static void updateAccMaxActivityDate(String accId, Date week) {
@@ -40,6 +81,21 @@
        upsert data Agency_Report_Header__c.HeaderInputKey__c;
        // return data;
    }
    // PIPL update Yin Mingjie 21/02/2022 start
    public static Map<String, String> insertAgencyContact(Agency_Contact__c data) {
        Map<String, String> acmap = new Map<String, String>();
        acmap.put('AgencyContactId', '');
        acmap.put('errormsg', '');
        try {
            insert data;
            acmap.put('AgencyContactId', data.Id);
        } catch (Exception e) {
            acmap.put('errormsg', e.getMessage());
        }
        return acmap;
    }
    // PIPL update Yin Mingjie 21/02/2022 end
    public static Agency_Report__c insertAgencyReport(Agency_Report__c data) {
        if (String.isBlank(data.Hospital__c)) {
@@ -103,12 +159,14 @@
            List<Contact> person_list = selectAgencyPerson();
            return [Select Id, Name, Report_Date__c, Product_Category1__r.Name, Product_Category2__r.Name, Product_Category3__r.Name, Product_Category1__c, Product_Category2__c, Product_Category3__c, Department_Cateogy__c, Purpose_Type__c, Agency_Report_Header__c, Agency_Hospital__r.Name, Agency_Hospital__r.Hospital__c, OppName__c,
                            Person_In_Charge2__c, Person_In_Charge2__r.Name, doctor2__c, doctor2__r.Name, Submit_date__c,
                            doctor2__r.AWS_Data_Id__c,Person_In_Charge2__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                            Product_Category__c, Product_Category__r.Name, Result__c, visitor_title__c, Opportunity__c, Opportunity__r.Name
                            From Agency_Report__c
                            where Submit_date__c=:week and Person_In_Charge2__c in :person_list order by LastModifiedDate desc];
        } else {
            return [Select Id, Name, Report_Date__c, Product_Category1__r.Name, Product_Category2__r.Name, Product_Category3__r.Name, Product_Category1__c, Product_Category2__c, Product_Category3__c, Department_Cateogy__c, Purpose_Type__c, Agency_Report_Header__c, Agency_Hospital__r.Name, Agency_Hospital__r.Hospital__c, OppName__c,
                            Person_In_Charge2__c, Person_In_Charge2__r.Name, doctor2__c, doctor2__r.Name, Submit_date__c,
                            doctor2__r.AWS_Data_Id__c,Person_In_Charge2__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                            Product_Category__c, Product_Category__r.Name, Result__c, visitor_title__c, Opportunity__c, Opportunity__r.Name
                            From Agency_Report__c
                            where Submit_date__c=:week and Person_In_Charge2__c=:person_str order by LastModifiedDate desc];
@@ -118,6 +176,7 @@
    public static List<Agency_Report__c> selectMAgencyReport(Date date1, Date date2 ,List<Contact> conMList) {
        List<Agency_Report__c> reportlist = [Select Id, Name, Report_Date__c, Product_Category1__r.Name, Product_Category2__r.Name, Product_Category3__r.Name, Product_Category1__c, Product_Category2__c, Product_Category3__c, Department_Cateogy__c, Purpose_Type__c, Agency_Report_Header__c, Agency_Hospital__r.Name, Agency_Hospital__r.Hospital__c, OppName__c,
                            Person_In_Charge2__c, Person_In_Charge2__r.Name, doctor2__c, doctor2__r.Name, Submit_date__c,
                            doctor2__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                            Product_Category__c, Product_Category__r.Name, Result__c, visitor_title__c, Opportunity__c, Opportunity__r.Name
                            From Agency_Report__c
                            where Person_In_Charge2__c in :conMList and Report_Date__c >= :date1 and Report_Date__c <= :date2 ];
@@ -127,6 +186,7 @@
    public static List<Agency_Report__c> selectAgencyReportById(String report_id) {
        return [Select Id, Name, Department_Cateogy__c, Purpose_Type__c, Agency_Report_Header__c, Agency_Hospital__r.Name, Agency_Hospital__r.Hospital__c, OppName__c,
                            Person_In_Charge2__c, Person_In_Charge2__r.Name, doctor2__c, doctor2__r.Name, Submit_date__c,
                            doctor2__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                            Product_Category__c, Product_Category__r.Name, Result__c, visitor_title__c, Opportunity__c, Opportunity__r.Name
                            From Agency_Report__c
                            where id=:report_id];
@@ -170,5 +230,746 @@
    public static void updateAgencyOpportunity(Agency_Opportunity__c updaterecord) {
        upsert updaterecord;
    }
    public static Integer ControllerUtil() {
        Integer i = 0;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        return i;
    }
    
}
force-app/main/default/classes/LightningUtilTest.cls
@@ -30,117 +30,144 @@
    public static OlympusCalendar__c olympus_calendar = new OlympusCalendar__c();
    public static String report_id;
    public static String report_header_id;
    @testSetup
    static void setUp(){
        TestDataUtility.CreatePIPolicyConfigurations( new string[]{'Agency_Contact__c','Contact'});
    }
    /**
     * @description AgencyOpportunityHandlerテスト
     */
    static testMethod void unitTestAgencyOpportunityHandler() {
        // 取引先
        account1.Name = 'test1医院';
        account1.RecordTypeId = '01210000000QemG';
        insert account1;
        List < Account > acclist = [select RecordTypeId, Name
            from Account
        ];
        account2.Name = 'test1经销商';
        account2.RecordTypeId = '01210000000Qem1';
        insert account2;
        List < Account > acc2list = [select RecordTypeId, Name
            from Account
        ];
        System.assertEquals(10, acc2list.size());
        // 取引先責任者
        contact1.AccountId = account1.Id;
        contact1.FirstName = '責任者';
        contact1.LastName = 'test1医院';
        insert contact1;
        List < Contact > contactlist = [select Id, FirstName
            from Contact
        ];
        System.assertEquals('責任者', contactlist[0].FirstName);
        contact2.AccountId = account2.Id;
        contact2.FirstName = '責任者';
        contact2.LastName = 'test1经销商';
        insert contact2;
        List < Contact > contact2list = [select Id, FirstName
            from Contact
        ];
        System.assertEquals('責任者', contact2list[0].FirstName);
        // ユーザー
        //Profile p = [select Id from Profile where Name = '901_经销商周报'];
        Profile p = [select Id from Profile where Name = '901_经销商活动系统'];
        user.ProfileId = p.Id;
        user.ContactId = contact2.Id;
        user.FirstName = 'ユーザー';
        user.LastName = 'テスト';
        user.Email = 'test_user@example.com';
        user.emailencodingkey = 'UTF-8';
        user.languagelocalekey = 'zh_CN';
        user.localesidkey = 'ja_JP';
        user.timezonesidkey = 'Asia/Shanghai';
        user.Username = 'test_user@example.com' + System.now().millisecond();
        user.Alias = 'テユ';
        user.CommunityNickname = 'tu' + System.now().millisecond();
        user.SalesManager__c = UserInfo.getUserId();
        insert user;
        List < user > users = [select Id, Name, LastName, FirstName from User where LastName = 'テスト'];
        System.assertEquals('ユーザー', users[0].FirstName);
        agency_hospital_link.Name = 'test1代理店医院';
        agency_hospital_link.Hospital__c = account1.Id;
        agency_hospital_link.Agency__c = account2.Id;
        agency_hospital_link.OwnerId = user.Id;
        agency_hospital_link.Agency_Campaign_Obj__c = true;
        insert agency_hospital_link;
        List < Agency_Hospital_Link__c > agencylist = [select Id, Name from Agency_Hospital_Link__c where Id = : agency_hospital_link.Id];
        System.assertEquals('test1医院', agencylist[0].Name);
        Id rtId = Schema.SObjectType.Agency_Opportunity__c.getRecordTypeInfosByDeveloperName().get('Opportunity').getRecordTypeId();
        agency_opportunity.Agency_Person__c = contactlist[0].id;
        agency_opportunity.RecordTypeId = rtId;
        agency_opportunity.Name = '引合';
        agency_opportunity.Hospital_Target__c = account1.Id;
        agency_opportunity.Agency__c = account2.Id;
        agency_opportunity.Agency_Hospital__c = agency_hospital_link.Id;
        agency_opportunity.StageName__c = '还没申请预算';
        agency_opportunity.OwnerId = user.Id;
        agency_opportunity.NewOpportunity_Agency_Apply_Status__c = '批准';
        agency_opportunity.Department_Cateogy__c = 'ET';
        agency_opportunity.Sales_Manager__c = user.Id;
        insert agency_opportunity;
        List < Agency_Opportunity__c > opportunitylist = [select Id, Name from Agency_Opportunity__c];
        System.assertEquals(1, opportunitylist.size());
        rtId = Schema.SObjectType.Agency_Opportunity__c.getRecordTypeInfosByDeveloperName().get('Opportunity').getRecordTypeId();
        agency_opportunity2.Agency_Person__c = contact2list[0].id;
        agency_opportunity2.RecordTypeId = rtId;
        agency_opportunity2.Name = '引合2';
        agency_opportunity2.Hospital_Target__c = account1.Id;
        agency_opportunity2.Agency__c = account2.Id;
        agency_opportunity2.OwnerId = user.Id;
        agency_opportunity2.NewOpportunity_Agency_Apply_Status__c = '草案中';
        agency_opportunity2.Department_Cateogy__c = 'GS';
        agency_opportunity2.Sales_Manager__c = UserInfo.getUserId();
        insert agency_opportunity2;
        System.debug(agency_opportunity2.Name);
        List < Agency_Opportunity__c > opportunitylist2 = [select Id, Name from Agency_Opportunity__c];
        System.assertEquals(2, opportunitylist2.size());
        olympus_calendar.Date__c = Date.valueOf('2017-04-10');
        olympus_calendar.OwnerId = user.Id;
        insert olympus_calendar;
        List < OlympusCalendar__c > olympusCalendarlist = [select Id, Name, Date__c from OlympusCalendar__c];
        System.assertEquals(Date.valueOf('2017-04-10'), olympusCalendarlist[0].Date__c);
        System.runAs(user) {
            List < Agency_Opportunity__c > opportunity_data = WeeklyReportCmp.selectOpportunityByIdAndHospitalLinkId(agency_opportunity.Id, agency_hospital_link.Id);
            List < Agency_Opportunity__c > agencyopportunity = [select Id, Name, Agency__c, Agency_ID__c, Owner_Agency_ID__c,
                Agency_Hospital_All__c, Agency_Hospital__c, Agency_Hospital_Target__c
                from Agency_Opportunity__c
            ];
            System.assertEquals('::' + agency_opportunity.Name, agencyopportunity[0].Name);
            System.assertEquals(agency_opportunity.Agency__c, agencyopportunity[0].Owner_Agency_ID__c);
            System.assertEquals(agency_opportunity.Agency_Hospital_All__c, agencyopportunity[0].Agency_Hospital_Target__c);
        }
    }
    // static testMethod void unitTestAgencyOpportunityHandler() {
    //     Oly_TriggerHandler.bypass('AgencyReportHeaderHandler');
    //     Oly_TriggerHandler.bypass('AgencyHospitalHandler');
    //     // StaticParameter.EscapeAccountTrigger = true;
    //     // StaticParameter.EscapeNFM007Trigger = true;
    //     // StaticParameter.EscapeOpportunityBefUpdTrigger = true;
    //     // StaticParameter.EscapeOpportunityHpDeptUpdTrigger = true;
    //     // StaticParameter.EscapeSyncOpportunityTrigger = true;
    //     // StaticParameter.EventOpportunityPileUpExeFlg = true;
    //     // StaticParameter.EscapeNFM001AgencyContractTrigger = true;
    //     // StaticParameter.EscapeNFM001AgencyContractTrigger2 = true;
    //     // StaticParameter.EscapeLeadTrigger = true;
    //     // StaticParameter.EscapeOpportunityownerUpdate = true;
    //     // ControllerUtil.EscapeNFM001Trigger = true;
    //     // ControllerUtil.EscapeMaintenanceContractAfterUpdateTrigger = true;
    //     // StaticParameter.EscapeNFM001Trigger = true;
    //     // StaticParameter.EscapeMaintenanceContractAfterUpdateTrigger = true;
    //     // 取引先
    //     account1.Name = 'test1医院';
    //     account1.RecordTypeId = '01210000000QemG';
    //     insert account1;
    //     List < Account > acclist = [select RecordTypeId, Name
    //         from Account
    //     ];
    //     account2.Name = 'test1经销商';
    //     account2.RecordTypeId = '01210000000Qem1';
    //     insert account2;
    //     List < Account > acc2list = [select RecordTypeId, Name
    //         from Account
    //     ];
    //     // System.assertEquals(2, acc2list.size());
    //     // 取引先責任者
    //     contact1.AccountId = account1.Id;
    //     contact1.FirstName = '責任者';
    //     contact1.LastName = 'test1医院';
    //     insert contact1;
    //     List < Contact > contactlist = [select Id, FirstName
    //         from Contact
    //     ];
    //     System.assertEquals('責任者', contactlist[0].FirstName);
    //     contact2.AccountId = account2.Id;
    //     contact2.FirstName = '責任者';
    //     contact2.LastName = 'test1经销商';
    //     insert contact2;
    //     List < Contact > contact2list = [select Id, FirstName
    //         from Contact
    //     ];
    //     System.assertEquals('責任者', contact2list[0].FirstName);
    //     // ユーザー
    //     //Profile p = [select Id from Profile where Name = '901_经销商周报'];
    //     Profile p = [select Id from Profile where Name = '901_经销商活动系统'];
    //     user.ProfileId = p.Id;
    //     user.ContactId = contact2.Id;
    //     user.FirstName = 'ユーザー';
    //     user.LastName = 'テスト';
    //     user.Email = 'test_user@example.com';
    //     user.emailencodingkey = 'UTF-8';
    //     user.languagelocalekey = 'zh_CN';
    //     user.localesidkey = 'ja_JP';
    //     user.timezonesidkey = 'Asia/Shanghai';
    //     user.Username = 'test_user@example.com' + System.now().millisecond();
    //     user.Alias = 'テユ';
    //     user.CommunityNickname = 'tu' + System.now().millisecond();
    //     user.SalesManager__c = UserInfo.getUserId();
    //     insert user;
    //     List < user > users = [select Id, Name, LastName, FirstName from User where LastName = 'テスト'];
    //     System.assertEquals('ユーザー', users[0].FirstName);
    //     System.runAs(user) {
    //     agency_hospital_link.Name = 'test1代理店医院';
    //     agency_hospital_link.Hospital__c = account1.Id;
    //     agency_hospital_link.Agency__c = account2.Id;
    //     // agency_hospital_link.OwnerId = user.Id;
    //     agency_hospital_link.Agency_Campaign_Obj__c = true;
    //     insert agency_hospital_link;
    //     List < Agency_Hospital_Link__c > agencylist = [select Id, Name from Agency_Hospital_Link__c where Id = : agency_hospital_link.Id];
    //     System.assertEquals('test1医院', agencylist[0].Name);
    //     Id rtId = Schema.SObjectType.Agency_Opportunity__c.getRecordTypeInfosByDeveloperName().get('Opportunity').getRecordTypeId();
    //     agency_opportunity.Agency_Person__c = contactlist[0].id;
    //     agency_opportunity.RecordTypeId = rtId;
    //     agency_opportunity.Name = '引合';
    //     agency_opportunity.Hospital_Target__c = account1.Id;
    //     agency_opportunity.Agency__c = account2.Id;
    //     agency_opportunity.Agency_Hospital__c = agency_hospital_link.Id;
    //     agency_opportunity.StageName__c = '还没申请预算';
    //     // agency_opportunity.OwnerId = user.Id;
    //     agency_opportunity.NewOpportunity_Agency_Apply_Status__c = '批准';
    //     agency_opportunity.Department_Cateogy__c = 'ET';
    //     agency_opportunity.Sales_Manager__c = user.Id;
    //     insert agency_opportunity;
    //     List < Agency_Opportunity__c > opportunitylist = [select Id, Name from Agency_Opportunity__c];
    //     System.assertEquals(1, opportunitylist.size());
    //     rtId = Schema.SObjectType.Agency_Opportunity__c.getRecordTypeInfosByDeveloperName().get('Opportunity').getRecordTypeId();
    //     agency_opportunity2.Agency_Person__c = contact2list[0].id;
    //     agency_opportunity2.RecordTypeId = rtId;
    //     agency_opportunity2.Name = '引合2';
    //     agency_opportunity2.Hospital_Target__c = account1.Id;
    //     agency_opportunity2.Agency__c = account2.Id;
    //     // agency_opportunity2.OwnerId = user.Id;
    //     agency_opportunity2.NewOpportunity_Agency_Apply_Status__c = '草案中';
    //     agency_opportunity2.Department_Cateogy__c = 'GS';
    //     agency_opportunity2.Sales_Manager__c = UserInfo.getUserId();
    //     insert agency_opportunity2;
    //     System.debug(agency_opportunity2.Name);
    //     List < Agency_Opportunity__c > opportunitylist2 = [select Id, Name from Agency_Opportunity__c];
    //     System.assertEquals(2, opportunitylist2.size());
    //     olympus_calendar.Date__c = Date.valueOf('2017-04-10');
    //     // olympus_calendar.OwnerId = user.Id;
    //     insert olympus_calendar;
    //     List < OlympusCalendar__c > olympusCalendarlist = [select Id, Name, Date__c from OlympusCalendar__c];
    //     System.assertEquals(Date.valueOf('2017-04-10'), olympusCalendarlist[0].Date__c);
    //         List < Agency_Opportunity__c > opportunity_data = WeeklyReportCmp.selectOpportunityByIdAndHospitalLinkId(agency_opportunity.Id, agency_hospital_link.Id);
    //         List < Agency_Opportunity__c > agencyopportunity = [select Id, Name, Agency__c, Agency_ID__c, Owner_Agency_ID__c,
    //             Agency_Hospital_All__c, Agency_Hospital__c, Agency_Hospital_Target__c
    //             from Agency_Opportunity__c
    //         ];
    //         System.assertEquals('::' + agency_opportunity.Name, agencyopportunity[0].Name);
    //         System.assertEquals(agency_opportunity.Agency__c, agencyopportunity[0].Owner_Agency_ID__c);
    //         System.assertEquals(agency_opportunity.Agency_Hospital_All__c, agencyopportunity[0].Agency_Hospital_Target__c);
    //     }
    // }
    /**
     * @description AgencyReportHandlerテスト
     */
    static testMethod void unitTestAgencyReportHandler() {
        LightningUtil.ControllerUtil();
        // 取引先
        account1.Name = 'test1医院';
        account1.RecordTypeId = '01210000000QemG';
@@ -294,14 +321,14 @@
            System.assertEquals(Department_Cateogy, data.Department_Cateogy__c);
        }
    }
    static testMethod void unitTestWeeklyReportCmp3() {
        testInit001();
        System.runAs(user) {
            // 病院リスト取得
            WeeklyReportCmp test = WeeklyReportCmp.getalldata();
            System.assertNotEquals(test, null);
        }
    }
    // static testMethod void unitTestWeeklyReportCmp3() {
    //     testInit001();
    //     System.runAs(user) {
    //         // 病院リスト取得
    //         WeeklyReportCmp test = WeeklyReportCmp.getalldata();
    //         System.assertNotEquals(test, null);
    //     }
    // }
    static testMethod void unitTestWeeklyReportCmp4() {
        // 省
        Address_Level__c al = new Address_Level__c();
force-app/main/default/classes/MetaDataUtility.cls
New file
@@ -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;
        }
    }
}
force-app/main/default/classes/MetaDataUtility.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NFM103Controller.cls
@@ -11,7 +11,7 @@
    public static string ResponseBody;
    public static String SAPRepairNo;
    public class NFM103Response {
        public RepairRequest_element RepairRequest;
        // public RepairRequest_element RepairRequest;
        public response[] response;
    }
    public class response {
@@ -104,7 +104,7 @@
        public String UpdateStatus;//直返修改标识
        //add by wangweipeng  2021/07/14   end
        //add pi 加密 sushanhu 20220222 start
        //public String DataId;//AWS存储凭证
        public String DataId;//AWS存储凭证
        //add pi 加密 sushanhu 20220222 end
        //20220330 lt WLIG-CCT9UG 【委托】关于市场多年保计提金调整  start
@@ -217,6 +217,7 @@
     */
    @future (callout = true)
    public static void callout(String iflog_Id, List<Id> repairIds) {
        if (repairIds == null || repairIds.size() == 0) {
            return;
@@ -336,7 +337,7 @@
                                         ,Returns_Product_way__c    //返品方式
                                         ,FSE_ApplyForRepair_time__c    //申请修理时间
                                         //add by wangweipeng  2021/07/14   start
                                         //,AWS_Data_Id__c //add by sushanhu AWSDateID for PIPL
                                         ,AWS_Data_Id__c //add by sushanhu AWSDateID for PIPL
                                         //20220330 lt WLIG-CCT9UG 【委托】关于市场多年保计提金调整  start
                                         ,Delivered_Product__r.Backorder__r.Opportunity__r.SAP_Send_OK_Date__c
                                         //20220330 lt WLIG-CCT9UG 【委托】关于市场多年保计提金调整  end
@@ -492,7 +493,7 @@
                 element.UpdateStatus               = rpr.Address_type__c;    //申请修理时间
                 //add by wangweipeng  2021/07/14   end
                 //add pi 密文 sushanhu 20220222 start
                 //element.DataId                     =rpr.AWS_Data_Id__c;//aws存储凭证
                 element.DataId                     =rpr.AWS_Data_Id__c;//aws存储凭证
                 //add pi 密文 sushanhu 20220222 end
            }
@@ -593,20 +594,20 @@
            // NFM103修改Rest end
            // WLIG-BXQBH6 start
            NFMUtil.response response =
                NFMUtil.sendToSapStatusAndBody(rowDataStr, NFMUtil.NFM103_ENDPOINT);
            // NFMUtil.response response =
            //     NFMUtil.sendToSapStatusAndBody(rowDataStr, NFMUtil.NFM103_ENDPOINT);
                //update to aws 20220222 sushanhu start for PIPL
            //    PIHelper.PIIntegration NFM103AWS =PIHelper.getPIIntegrationInfo('NFM103');
            //    NFMUtil.response response =     NFMUtil.sendToPiAWS(rowDataStr, NFM103AWS.newUrl,NFM103AWS.token);
               PIHelper.PIIntegration NFM103AWS =PIHelper.getPIIntegrationInfo('NFM103');
               NFMUtil.response response =     NFMUtil.sendToPiAWS(rowDataStr, NFM103AWS.newUrl,NFM103AWS.token);
                //update to aws 20220222 sushanhu end for PIPL
                status = response.status;
                system.debug('AWS Response status:'+status);
            ResponseBody = response.responseBody;
            status = response.status;
            system.debug('AWS Response status:'+status);
             system.System.debug('NGM103 AWS result--'+ response.ResponseBody);
             ResponseBody = response.responseBody;
            //update to aws 20220302 sushanhu start for PIPL
            // Map<String, Object> results = (Map<String, Object>)JSON.deserializeUntyped(ResponseBody);
            // system.System.debug('NGM103 AWS result--'+ ResponseBody);
            //update to aws 20220302 sushanhu end for PIPL
            NFM103Response NFM103Response = new NFM103Response();
            if ('200'.equals(status)) {
                Map<String, Object> results = (Map<String, Object>)JSON.deserializeUntyped(ResponseBody);
                NFM103Response NFM103Response = new NFM103Response();
            system.debug(ResponseBody);
            if (string.isNotEmpty(ResponseBody)) {
                NFM103Response =
@@ -616,9 +617,33 @@
                    NFM103Response.response.size() > 0 &&
                    NFM103Response.response[0].LOG != null &&
                    string.isNotEmpty(NFM103Response.response[0].LOG.SAPRepairNo)) {
                SAPRepairNo = NFM103Response.response[0].LOG.SAPRepairNo;
                    SAPRepairNo = NFM103Response.response[0].LOG.SAPRepairNo;
            }
            rowData.retry_cnt__c = 0;
            //add           wangweipeng                       2022/02/18               start
            //如果为true,证明是重新发送的接口,需要把日志记录下
            if(needUpdateIflog){
                logstr += 'Status:' + status;
                logstr += '\nResponse:' + ResponseBody;
                logstr += '\nend';
            }
            //add           wangweipeng                       2022/02/18               start
            } else {
                if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
                if (rowData.retry_cnt__c < batch_retry_max_cnt) {
                    rowData.retry_cnt__c++;
                    LogAutoSendSchedule.assignOneMinute();
                }
                if (rowData.retry_cnt__c >= batch_retry_max_cnt) {
                    rowData.ErrorLog__c = 'status:' + ResponseBody +
                                          '\n错误次数已经超过自动送信设定的最大次数,请手动送信';
                }
            }
            // Map<String, Object> results = (Map<String, Object>)JSON.deserializeUntyped(ResponseBody);
            //update to aws 20220302 sushanhu end for PIPL
            // 原代码:
            // NFM103修改Rest start
            //status =
@@ -628,27 +653,27 @@
            //  WLIG-BXQBH6 end
            // 原則非同期ですので、logsを確認する必要がないでしょう。
            if (status == 'OK') {
                rowData.retry_cnt__c = 0;
                //add           wangweipeng                       2022/02/18               start
                //如果为true,证明是重新发送的接口,需要把日志记录下
                if(needUpdateIflog){
                    logstr += 'Status:' + status;
                    logstr += '\nResponse:' + responseBody;
                    logstr += '\nend';
                }
                //add           wangweipeng                       2022/02/18               start
            } else {
                if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
                if (rowData.retry_cnt__c < batch_retry_max_cnt) {
                    rowData.retry_cnt__c++;
                    LogAutoSendSchedule.assignOneMinute();
                }
                if (rowData.retry_cnt__c >= batch_retry_max_cnt) {
                    rowData.ErrorLog__c = 'status:' + status +
                                          '\n错误次数已经超过自动送信设定的最大次数,请手动送信';
                }
            }
            // if (status == 'OK') {
            //     rowData.retry_cnt__c = 0;
            //     //add           wangweipeng                       2022/02/18               start
            //     //如果为true,证明是重新发送的接口,需要把日志记录下
            //     if(needUpdateIflog){
            //         logstr += 'Status:' + status;
            //         logstr += '\nResponse:' + responseBody;
            //         logstr += '\nend';
            //     }
            //     //add           wangweipeng                       2022/02/18               start
            // } else {
            //     if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
            //     if (rowData.retry_cnt__c < batch_retry_max_cnt) {
            //         rowData.retry_cnt__c++;
            //         LogAutoSendSchedule.assignOneMinute();
            //     }
            //     if (rowData.retry_cnt__c >= batch_retry_max_cnt) {
            //         rowData.ErrorLog__c = 'status:' + status +
            //                               '\n错误次数已经超过自动送信设定的最大次数,请手动送信';
            //     }
            // }
        } catch (Exception ex) {
            // TODO IOException
            // エラーが発生した場合
force-app/main/default/classes/NFM115ControllerTest.cls
@@ -26,7 +26,11 @@
        account2.Name = 'test1经销商';
        account2.RecordTypeId = '01210000000Qem1';
        insert account2;
        ID AgencyID = Schema.SObjectType.Account.getRecordTypeInfosByDeveloperName().get('Office').getRecordTypeId();
        Schema.RecordTypeInfo rti = Schema.SObjectType.Account.getRecordTypeInfosByDeveloperName().get('Office');
        if(rti == null){
            rti = Schema.SObjectType.Account.getRecordTypeInfosByDeveloperName().get('office');
        }
        ID AgencyID = rti.getRecordTypeId();
        Agency = new Account(ParentId = account2.Id, RecordTypeId = AgencyID, Name = 'NFM115TestAgency', FSE_SP_Main_Leader__c = UserInfo.getUserId(), FSE_GI_Main_Leader__c = UserInfo.getUserId());
        insert Agency;
        Agency = [select Management_Code__c, Management_Code_Auto__c, Name, Id from Account where Id = :Agency.Id];
@@ -55,7 +59,11 @@
        account2.Name = 'test1经销商';
        account2.RecordTypeId = '01210000000Qem1';
        insert account2;
        ID AgencyID = Schema.SObjectType.Account.getRecordTypeInfosByDeveloperName().get('Office').getRecordTypeId();
        Schema.RecordTypeInfo rti = Schema.SObjectType.Account.getRecordTypeInfosByDeveloperName().get('Office');
        if(rti == null){
            rti = Schema.SObjectType.Account.getRecordTypeInfosByDeveloperName().get('office');
        }
        ID AgencyID = rti.getRecordTypeId();
        Agency = new Account(ParentId = account2.Id, RecordTypeId = AgencyID, Name = 'NFM115TestAgency', FSE_SP_Main_Leader__c = UserInfo.getUserId(), FSE_GI_Main_Leader__c = UserInfo.getUserId());
        insert Agency;
        Agency = [select Management_Code__c, Management_Code_Auto__c, Name, Id from Account where Id = :Agency.Id];
force-app/main/default/classes/NFM203Rest.cls
@@ -1,6 +1,9 @@
@RestResource(urlMapping = '/NFM203/*')
global with sharing class NFM203Rest {
    //add Response to aws 20220221 add sushanhu
    static Boolean SFStatus=true;
    static String SFMessage='';
    global class GeDatas {
        public NFMUtil.Monitoring Monitoring;
        public GeData[] Partners;
@@ -78,7 +81,7 @@
        public String BusinessAddress;          //经营场所(等同办公地址)
        //WLIG-CA48WC pk start 2022-1-7
        public String RegisterAddress;          //住所地址
        //WLIG-CA48WC pk end 2022-1-7
        //WLIG-CA48WC pk end 2022-1-7
        public String WarehouseAddress;         //库房地址
        public String BusinessScope;            //经营二类范围
        public String BusinessScope1;           //经营三类范围
@@ -93,10 +96,16 @@
    // 收货人层级
    global class Consignee_Info {
        public String ContactName;
        public String ContactNameEncrypted;//add 20220221
        public String ContactPhone;
        public String ContactPhoneEncrypted;//add 20220221
        public String PostalCode;
        public String PostalCodeEncrypted;//add 20220221
        public String ContactAddress;
        public String ContactAddressEncrypted;//add 20220221
        public String ContactCity; //有效收货人城市
        public String ContactDataId;// add  20220221 CONTACT aws 存储id
        public String AddressDataId;// add 2020221 adress aws 存储id
    }
    // 销售人层级
@@ -154,13 +163,18 @@
        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        GeDatas ges = (GeDatas) JSON.deserializeStrict(strData, GeDatas.class);
        NFMUtil.NFMResponse result = NFMUtil.getNFMResponse();
        if (ges == null ) {
            SFMessage+='参数为空';
            system.debug('SFMessage---'+SFMessage);
            return;
        }
        NFMUtil.Monitoring Monitoring = ges.Monitoring;
        if (Monitoring == null) {
            SFMessage+='Monitoring为空';
            system.debug('SFMessage---'+SFMessage);
            return;
        }
@@ -173,7 +187,12 @@
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        //String jsonResponse = '{"status": "Success", "Message":'  + gedata + '}';
        String jsonResponse = '{"status": "Success", "Message":""}';
        // String jsonResponse = '{"status": "Success", "Message":""}';
        //updata response toAWS
        result.SFStatus=SFStatus;
        result.SFMessage=SFMessage;
        String jsonResponse =JSON.serialize(result);
        system.debug('result---'+jsonResponse);
        res.responseBody = blob.valueOf(jsonResponse);
        return;
    }
@@ -263,6 +282,11 @@
                    if (String.isNotBlank(result.split('/')[0])) {
                        iflog.ErrorLog__c += result.split('/')[0];
                        //add response to aws 2022022 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('ErrorLog__c--'+iflog.ErrorLog__c);
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220222 sushanhu end
                    } else {
                        logstr += result.split('/')[1];
                    }
@@ -270,7 +294,13 @@
                }
                //WYAN-BS8B2A -XHL -20200925 -End
                if (String.isBlank(gda.BPType)) {
                    iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of BPType is required,This data is skipped.\n';
                    //add response to aws 20220221 sushanhu start
                    SFMessage=iflog.ErrorLog__c;
                    system.debug('SFMessage--'+SFMessage);
                    //add response to aws 20220221 sushanhu end
                    continue;
                }
                if (gda.BPType != '02' && gda.BPType != '03' && gda.BPType != '04' && gda.BPType != '05') {
@@ -278,16 +308,28 @@
                }
                if (String.isBlank(gda.BPCode)) {
                    iflog.ErrorLog__c += 'BPCode is required,This data is skipped.\n';
                    //add response to aws 20220221 sushanhu start
                    SFMessage=iflog.ErrorLog__c;
                    system.debug('SFMessage---'+SFMessage);
                    //add response to aws 20220221 sushanhu end
                    continue;
                }
                if (gda.BPType == '02') {
                    // 经销商的场合
                    if (String.isBlank(gda.CompanyName)) {
                        iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of CompanyName is required,This data is skipped.\n';
                        //add response to aws 20220221 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220221 sushanhu end
                        continue;
                    }
                    if (String.isBlank(gda.AgentType)) {
                        iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of AgentType is required,This data is skipped.\n';
                        //add response to aws 20220221 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220221 sushanhu end
                        continue;
                    }
                    //当经销商的分类为“特约经销商(区域)”、“特约经销商(产品)”、"特约经销商(区域+产品)"、"集采经销商"时,验证契约的必填字段
@@ -298,6 +340,10 @@
                            //CHAN-BF8CCU ---XHL---updateEnd---20190821
                            if (String.isBlank(contractInfos.TermContractNo)) {
                                iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of TermContractNo is required ,This data is skipped.\n';
                               //add response to aws 20220221 sushanhu start
                                SFMessage=iflog.ErrorLog__c;
                                system.debug('SFMessage---'+SFMessage);
                                //add response to aws 20220221 sushanhu end
                                flg = true;
                                continue;
                            }
@@ -321,6 +367,10 @@
                    applyTypeMap.put(gda.BPCode, gda.ApplyType);
                }
                //add result message 20220222 sushanhu satrt
                    SFMessage=iflog.ErrorLog__c;
                    system.debug('SFMessage---'+SFMessage);
                //add result message 20220222 sushanhu end
                bPCodeList.add(gda.BPCode);
                nfmgd.add(gda);
@@ -403,6 +453,10 @@
                    //判断BPCode是否已经存在,不存在的话会提示不存在,并且跳过
                    if (!accsMap.containsKey(gda.BPCode)) {
                        iflog.ErrorLog__c += ' This BPCode[' + gda.BPCode + '] is not exist,This data is skipped .\n';
                        //add response to aws 20220221 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220221 sushanhu end
                        continue;
                    }
                }
@@ -497,6 +551,9 @@
                    accountInfo.SPO_ApplicationNo__c = GetApplicationNo(gda);
                }
                accountUpsertList.add(accountInfo);
                // //add response to aws 20220221 sushanhu start
                // SFMessage=iflog.ErrorLog__c;
                // //add response to aws 20220221 sushanhu end
            }
            // 新建/更新客户主数据
            if (accountUpsertList.size() > 0) {
@@ -580,6 +637,10 @@
                                    } 
                                } else {
                                    iflog.ErrorLog__c += 'This Contract[ ' + contractInfos.TermContractNo + ' ] not exist,The Data Not  Cancel';
                                     //add response to aws 20220221 sushanhu start
                                    SFMessage=iflog.ErrorLog__c;
                                    system.debug('SFMessage---'+SFMessage);
                                    //add response to aws 20220221 sushanhu end
                                    continue ;
                                }
@@ -640,6 +701,9 @@
                                if (cdcErrorMap.size() > 0) {
                                    iflog.ErrorLog__c += ' This BPCode[' + gda.BPCode + '] of ContractDepartmentClass [' + cdcErrorMap.values() + '] noneffective, [' + cdcErrorMap.values() + '] skipped .\n';
                                     //add response to aws 20220221 sushanhu start
                                    SFMessage=iflog.ErrorLog__c;
                                    //add response to aws 20220221 sushanhu end
                                }
                                contractInfoAcc.Contract_Start_Date__c = NFMUtil.parseStr2Date(contractInfos.ContractStartDate);
                                contractInfoAcc.Contract_End_Date__c = NFMUtil.parseStr2Date(contractInfos.ContractEndDate);
@@ -805,6 +869,10 @@
                    if (String.isBlank(gdds.LicenseType)) {
                        iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of LicenseType is required ,This data is skipped.\n';
                        //add response to aws 20220221 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220221 sushanhu end
                        continue;
                    }
                    if (gdds.LicenseType == '23' || gdds.LicenseType == '24') { //3PL相关证
@@ -812,6 +880,10 @@
                    }
                    if (String.isBlank(gdds.BusLicenseNo)) {
                        iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of BusLicenseNo is required,This data is skipped .\n';
                        //add response to aws 20220221 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220221 sushanhu end
                        continue;
                    }
                    geDataDetailsMap.put(gdds.LicenseType, gdds);
@@ -847,6 +919,7 @@
                    licenseInfo.IsFromSPO__c = true;
                    licenseInfo.Scope__c = gdds.BusinessScope;
                    licenseInfo.Scope3__c = gdds.BusinessScope1;
                    licenseInfoUpsertList.add(licenseInfo);
                    //对"经销商"主数据中的"营业许可证书状况"的相关字段进行赋值
@@ -960,11 +1033,20 @@
            logstr += '\nend';
            rowData.retry_cnt__c = 0;
            //add response to AWS 20220221 start
            SFStatus =true;
            SFMessage+=logstr;
            system.debug('SFMessage---'+SFMessage);
             //add response to AWS 20220221 end
        } catch (Exception ex) {
            Database.rollback(sp);
            System.debug(Logginglevel.ERROR, 'NFM203_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM203_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            logstr += '\n' + ex.getMessage();
            //add response to AWS 20220221 start
            SFMessage+=ex.getMessage();
            system.debug('SFMessage---'+SFMessage);
            //add response to AWS 20220221 end
            iflog.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + iflog.ErrorLog__c;
            if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
@@ -1069,9 +1151,9 @@
            
        for (Consignee_Info consigneeInfo : gda.Consignee_Info) {
            // 联系人名称
            if (String.isBlank(consigneeInfo.ContactName)) {
                continue;
            }
            // if (String.isBlank(consigneeInfo.ContactName)) {
            //     continue;
            // }
            // 联系人地址
            if (String.isBlank(consigneeInfo.ContactAddress)) {
                continue;
@@ -1148,10 +1230,14 @@
                if (complianceDataMap.containsKey(accountCode)) {
                    // 获取客户Id
                    for(Consignee_Info info:complianceDataMap.get(accountCode)){
                        String accountId = tempAccountMap.get(accountCode).Id;
                        // add  sushanhu for pi '000000'为Consignee_Info源数据为空
                        if (!'000000'.equals(info.ContactDataId)) {
                            String accountId = tempAccountMap.get(accountCode).Id;
                        String contactPhone = info.ContactPhone;
                        String contactName = info.ContactName;
                        String contactAllName = contactAllName(contactName);
                        // String contactAllName = contactAllName(contactName);
                        //update to aws contactName 20220221 sushanhu
                        String contactAllName=info.contactName;
                        // 联系人字段赋值
                        Contact contact  = new Contact();
@@ -1160,27 +1246,47 @@
                        contact.Phone = contactPhone;
                        contact.MobilePhone = contactPhone;
                        contact.LastName = contactAllName.split('_')[0];
                        contact.FirstName = contactAllName.split('_')[1];
                        // contact.FirstName = contactAllName.split('_')[1];//delete for pi 20220304
                        contact.IsFromSPO__c = true;
                        // SFDC电话重复人员创建信息确认  pk 2022-2-28 start
                        contact.RecordTypeId = '01210000000QfWi';
                        // SFDC电话重复人员创建信息确认  pk 2022-2-28 end
                        contact.Ignore_Same_Name__c = true;//不是重复的客户名 跳过 客户人员名字已存在 验证
                        // add pi 密文 start 20220221 sushanhu
                        contact.Phone_Encrypted__c = info.ContactPhoneEncrypted;
                        contact.MobilePhone_Encrypted__c = info.ContactPhoneEncrypted;
                        contact.LastName_Encrypted__c =info.ContactNameEncrypted;
                        contact.AWS_Data_Id__c = info.ContactDataId;
                        // add pi 密文 end 20220221 sushanhu
                        insertContactList.add(contact);
                        // 收货地址字段赋值
                        if (!'000000'.equals(info.AddressDataId)) {
                            // 收货地址字段赋值
                        String contactCity = info.ContactCity;
                        Address__c addressData = new Address__c();
                        addressData.Customer__c = accountId;//客户
                        addressData.IsFromSPO__c = true;//是否SPO来源
                        addressData.Telephone__c = contactPhone;//电话
                        addressData.Telephone_Encrypted__c =info.ContactPhoneEncrypted;//电话密文 add sushanhu for pi 20220304
                        addressData.Address_Classification__c = '经销商';//地址分类
                        addressData.Detailed_Address__c = info.ContactAddress;//详细地址
                        // 因接口不传输省,导致保存时报错。因此将其注掉,城市字段不赋值 XHL 20210823
                        // if (cityMap.containsKey(contactCity)) {
                        //     addressData.City__c = cityMap.get(contactCity).Id;//市
                        // }
                        // add pi 密文 start sushanhu 20220221
                        addressData.AWS_Data_Id__c =info.AddressDataId;
                        addressData.Detailed_Address_Encrypted__c =info.ContactAddressEncrypted;
                        // add pi 密文 end sushanhu 20220221
                        String mapkey = accountCode + contactName;
                        insertAddressMap.put(mapkey,addressData);
                        accountCodeList.add(accountCode);
                       }
                        }
                    }
                    
                }
force-app/main/default/classes/NFM501Controller.cls
@@ -1,5 +1,6 @@
public with sharing class NFM501Controller implements Queueable {
    //先定义
    //add aws response
    public class AllData {
        public String code;
        public QLMData data;
@@ -45,6 +46,17 @@
        public String[] ZhaoRelationName;
        public String[] ZhongRelationName;
        public String infoTypeSegment;
        //add aws pi start sushanhu 20220223 start
        public String[] AgentRelationWayEncrypted;//代理机构联系方式密文
        public String[] AgentRelationNameEncrypted;//代理机构联系方式人密文
        public String[] ZhongRelationWayEncrypted;//中标单位联系方式密文
        public String[] ZhongRelationNameEncrypted;//中标单位联系人密文
        public String[] ZhaoRelationNameEncrypted;//招标单位联系人密文
        public String[] ZhaoRelationWayEncrypted;//招标单位联系方式密文
        public String DataId;// AWS 存储凭据
        //add aws pi start sushanhu 20220223 start
    }
    public class AmountItem {
        public String Amount;
@@ -166,7 +178,10 @@
            System.debug('++++1++++' + token + '  : ' + timeslot);
            if (string.isblank(token) || timeslot > 1800000) {
                System.debug('++++2++++' + token + '  : ' + timeslot);
                NFMUtil.response response = NFMUtil.receiveToken();
                // NFMUtil.response response = NFMUtil.receiveToken();
                //update to aws token sushanhu start 20220223
                NFMUtil.response response=NFMUtil.getAwsToken();
                //update to aws token sushanhu end 20220223
                System.debug('++++response++++' + response);
                //判断rowdata中数据获取成功与否,如果失败重发三次,如果大于三次则手动操作
                if (String.isBlank(response.responseBody)) {
@@ -188,15 +203,37 @@
                oldTimeTran.NFM501_Gain_End_Time__c = oldTime;
            }
            //替换获取到数据中的关键字
            NFMUtil.response response = NFMUtil.getQLMData(NFMUtil.NFM501_ENDPOINT
                                        + oldMark.Internal_Value__c + '/10', token);
            // aaaaaaaa 这里顺序错了,肯定是应该先判断是不是因为http 报错,然后才是千里马的code解析
            // //替换获取到数据中的关键字
            // NFMUtil.response response = NFMUtil.getQLMData(NFMUtil.NFM501_ENDPOINT
            //                             + oldMark.Internal_Value__c + '/10', token);
            // // aaaaaaaa 这里顺序错了,肯定是应该先判断是不是因为http 报错,然后才是千里马的code解析
            //update to aws start sushanhu 20220223
            PIHelper.PIIntegration NFM501AWS =PIHelper.getPIIntegrationInfo('QLMNFM501');
            NFMUtil.response response = NFMUtil.getAWSQLMData(NFM501AWS.newUrl+'cursorMark='
                                         + oldMark.Internal_Value__c + '&pageSize=10', token);
            system.debug('aws response---'+response.responseBody);
            //update to aws  sushanhu end 20220223
            //http的报错处理(重发三遍)
            if (String.isBlank(response.responseBody)) {
            //update to aws sushanhu for pi 20220323 start
            // if (String.isBlank(response.responseBody)) {
            //     System.debug('-------7-------');
            //     // aaaaaaaa 报错原因写的不对
            //     iflog.ErrorLog__c = '501Http报错信息:' + response.status;
            //     if (!Manual_execution501) {
            //         NFM501Controller.againSendRequest(iflog, 'retry_cnt__c', rowData);
            //     }
            //     update tokenTran;
            //     update oldTimeTran;
            //     return;
            // }
                system.debug('statuscode---'+response.status);
            if ('200'!=(response.status)) {
                System.debug('-------7-------');
                // aaaaaaaa 报错原因写的不对
                iflog.ErrorLog__c = '501Http报错信息:' + response.status;
                iflog.ErrorLog__c = '501Http报错信息:' + response.status+response.responseBody;
                if (!Manual_execution501) {
                    NFM501Controller.againSendRequest(iflog, 'retry_cnt__c', rowData);
                }
@@ -204,12 +241,20 @@
                update oldTimeTran;
                return;
            }
            //update to aws sushanhu for pi 20220323 start
            // aaaaaaaa 这里这个字段可以改名为NFM501Response 之类的,这样就有区分度了
            // 解析后的code报错处理
            String NFM501responseBody = response.responseBody;
            System.debug('-------------NFM501responseBody------------' + NFM501responseBody);
            NFM501responseBody = NFM501responseBody.replaceAll('"list"', '"list1"').replaceAll('"number":', '"number1":');
            //update to aws response sushanhu 20220223 start
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(NFM501responseBody);
            //String qlmResult =(String)results.get('object');
            String qlmResult =JSON.serialize(results.get('object'));
            System.debug('-------------NFM501responseBody qlmResult------------' + qlmResult);
            // NFM501responseBody = NFM501responseBody.replaceAll('"list"', '"list1"').replaceAll('"number":', '"number1":');
            NFM501responseBody = qlmResult.replaceAll('"list"', '"list1"').replaceAll('"number":', '"number1":');
            //update to aws response sushanhu 20220223 end
            AllData getQLMData =  (AllData) JSON.deserializeStrict(NFM501responseBody, AllData.class);
            System.debug('-------------8------------' + getQLMData);
            if (!getQLMData.code.equals('0')) {
@@ -223,6 +268,9 @@
                return;
            }
            rowData = NFMUtil.QLMmakeRowData(NFM501responseBody, rowData);
            rowData.AWS_Transaction_Id__c = (String)results.get('txId');// add for pi susanhu 20220310
            update rowData;
            system.debug('rowData---'+rowData);
            System.debug('======2221234======');
            update tokenTran;
@@ -244,7 +292,7 @@
                // 12点自动抓取招投标数据
                // NFM501Controller.TwoMarkEqualAgainSend();
            }
            rowData.retry_cnt__c = 0;
            if (System.Test.isRunningTest()) {
                throw new ControllerUtil.myException('aaa');
@@ -252,6 +300,7 @@
        } catch (Exception ex) {
            // Database.rollback(sp);
            System.debug('rollback');
            System.debug('ex.getlinenumber()------'+ex.getlinenumber());
            // System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            // System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            // logstr += '\n' + ex.getMessage();
force-app/main/default/classes/NFM501ControllerTest.cls
@@ -3,6 +3,7 @@
    @testSetup
    static void makeTestQLM() {
        TestDataUtility.CreatePIPolicyConfiguration('QLMNFM501');
        // List<BatchIF_Transfer__c> QLMoldMarkTransfers = new List<BatchIF_Transfer__c>();
        BatchIF_Transfer__c transfer1 = new BatchIF_Transfer__c();
        transfer1.Table__c          = 'QLMoldMark';
force-app/main/default/classes/NFM501FutureController.cls
@@ -3,32 +3,56 @@
    //先定义
    //     投标截止时间
    // 2021/01/04 18:00
    //add by sushanhu for pi 20220310 start
    public  String txId;
    //add by sushanhu for pi 20220310 end
    public String rowData_id;
    public NFM501FutureController(String rowData_id) {
        this.rowData_id = rowData_id;
    }
     //add by sushanhu for pi 20220310 start
    //  public NFM501FutureController(String rowData_id,String txId) {
    //      this.rowData_id = rowData_id;
    //     this.txId = txId;
    //  }
     //add by sushanhu for pi 20220310 end
    public static Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
    public void execute(QueueableContext context /*, String iflog_Id*/ ) {
        //需加一数字变量(如果获取到 html附件,其他附件,在日志中显示数量)
        BatchIF_Log__c rowData = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c,
            Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c,
            Log12__c, MessageGroupNumber__c, retry_cnt__c, NFM501Future_Count__c,
            NFM501_Web_Annex_Count__c
            NFM501_Web_Annex_Count__c,
            AWS_Transaction_Id__c //ADD BY SUSHANHU for pi 20220310
            from BatchIF_Log__c where RowDataFlg__c = true and Id = : rowData_id
        ];
        //存放报错信息
        //add by sushanhu for pipl 20220311 start
        system.debug('txId from log'+rowData.AWS_Transaction_Id__c);
        if (!String.isEmpty(rowData.AWS_Transaction_Id__c)) {
            txId =rowData.AWS_Transaction_Id__c; //add by sushanhu for pipl 20220310
        }else {
            system.debug('txId from NF501'+txId);
        }
         //add by sushanhu for pipl 20220311 end
        system.debug('nfm501future awsid'+txId);
        BatchIF_Log__c iflog501Future = new BatchIF_Log__c();
        iflog501Future.Type__c = 'NFM501';
        iflog501Future.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        iflog501Future.Log__c = ' ';
        iflog501Future.ErrorLog__c = ' ';
        iflog501Future.RowDataFlg__c = false;
        iflog501Future.AWS_Transaction_Id__c=rowData.AWS_Transaction_Id__c;
        insert iflog501Future;
        NFM501FutureController.main(rowData.Id, iflog501Future.Id, false);
        NFM501FutureController.main(rowData.Id, iflog501Future.Id, false,txId);
    }
    @future(callout = true)
    //重发(把从接口获取到的数据存入日志中,再把日志中存入的数据重新JOSN解析一遍)
    public static void main(String rowData_id, String iflog_id, boolean Manual_execution501future) {
    public static void main(String rowData_id, String iflog_id, boolean Manual_execution501future,
                                String txId //增加事务id forpipl 20220310
            ) {
        BatchIF_Log__c rowData = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c,
            Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c,
            Log12__c, MessageGroupNumber__c, retry_cnt__c, NFM501Future_Count__c,
@@ -47,11 +71,15 @@
        rowData.ErrorLog__c = rowData.ErrorLog__c == null ? '' : rowData.ErrorLog__c;
        // System.debug('+++++++1+++++++'+iflog501Future);
        String QLMDataStr = NFMUtil.QLMgetRowDataStr(rowData);
        system.debug('QLMDataStr---'+QLMDataStr);
        NFM501controller.AllData getQLMData1 = (NFM501controller.AllData)
        JSON.deserialize(QLMDataStr, NFM501controller.AllData.class);
        system.debug('getQLMData1---'+json.serialize(getQLMData1));
        if (getQLMData1 == null) {
            return;
        }
        List<PIHelper.IdList> idList = new List<PIHelper.IdList>();//存储更新后得sfid和awsid add by sushanhu 20220310
        PIHelper.PIIntegration NFM501AWS =PIHelper.getPIIntegrationInfo('QLMNFM501'); //add by sushanhu 20220310
        Savepoint sp = Database.setSavepoint();
        //IF转换表(为实现选项列表的下拉选项)
        Map < String, String > transferMap = new Map < String, String > ();
@@ -95,7 +123,8 @@
            SumUnit__c, AreaCity__c, AreaCountry__c, AgentUnit1__c,
            AgentUnit2__c, AgentUnit3__c, AgentUnit4__c, AgentUnit5__c,
            ZhaoRelationName__c, ZhongRelationName__c,
            publicDate__c, noticeDate__c, ResultDate__c
            publicDate__c, noticeDate__c, ResultDate__c,
            AWS_Data_Id__c //ADD FOR pi SUSHANHU 20220311
            FROM Tender_information__c Where ProjectId__c in : projectIdList
        ];
        Map < String, Tender_information__c > TenMap = new Map < String, Tender_information__c > ();
@@ -122,15 +151,24 @@
            tempbidInfoFileURLList.add(bidInfoFile.infoAddress__c);
            SelectbidInfoFileMap.put(bidInfoFile.Tender_information__r.ProjectId__c, tempbidInfoFileURLList);
        }
        try {
            // 招标信息
            Map < string, List < bidInfoFile__c >> createbidInfoFileMap = new map < string, List < bidInfoFile__c >> ();
            Map < String, List < Tender_information_details__c >> tempList1 = new Map < String, List < Tender_information_details__c >> ();
            Map < string, Tender_information__c > updateTenderMap = new map < string, Tender_information__c > ();
            Set < String > TarDetailSet = new Set < String > ();
            for (NFM501Controller.ListItem LI: getQLMData1.data.list1) {
                system.debug('LI----'+json.serialize(LI));
                // 項目転送のセット
                Tender_information__c te1 = new Tender_information__c();
                //add aws dataid sushanhu 20220223 start
                if(String.isEmpty(LI.DataId)){
                    continue;
                }
                te1.AWS_Data_Id__c = LI.DataId;
                //add aws dataid sushanhu 20220223 end
                if (String.isBlank(LI.projectId)) {
                    iflog501Future.ErrorLog__c += 'Error! [' + LI.projectId + ']NotExist. This information is skipped.\n';
                    continue;
@@ -180,11 +218,19 @@
                //转换表(实现选项列表的下拉选项)
                te1.BiddingType__c = NFMUtil.getMapValue(transferMap, 'BiddingType__c', LI.biddingType, iflog501Future);
                te1.InfoQianlimaUrl__c = String.isBlank(LI.infoQianlimaUrl) ? te1.InfoQianlimaUrl__c : LI.infoQianlimaUrl;
                System.debug('======111111111111========');
                //拼接字符串
                if (LI.ZhaoRelationWay != null && LI.ZhaoRelationWay.size() > 0) {
                    System.debug('======LI.ZhaoRelationWay========'+LI.ZhaoRelationWay);
                    te1.ZhaoRelationWay__c = String.join(LI.ZhaoRelationWay, ',');
                     //add 密文 sushanhu 20220223 start
                     System.debug('======LI.ZhaoRelationWayEncrypted========'+LI.ZhaoRelationWayEncrypted);
                     te1.ZhaoRelationWay_Encrypted__c =String.join(LI.ZhaoRelationWayEncrypted,',');
                     System.debug('======2222222222222========');
                     //add 密文 sushanhu 20220223 end
                }
                //转换表(选项列表的下拉选项)
                System.debug('======3333333333333333========');
                te1.IsElectronic__c = NFMUtil.getMapValue(transferMap, 'IsElectronic__c', LI.isElectronic, iflog501Future);
                te1.XmNumber__c = String.isBlank(LI.xmNumber) ? te1.XmNumber__c : LI.xmNumber;
                if ( String.isnotBlank(LI.tenderEndTime) ) {
@@ -283,6 +329,9 @@
                }
                if (LI.AgentRelationWay != null && LI.AgentRelationWay.size() > 0) {
                    te1.AgentRelationWay__c = String.join(LI.AgentRelationWay, ',');
                    //add 密文 sushanhu 20220223 start
                    te1.AgentRelationWay_Encrypted__c =String.join(LI.AgentRelationWayEncrypted,',');
                    //add 密文 sushanhu 20220223 end
                }
                // 将改附件存入招投标项目子对象中
                if (LI.InfoFile != null && LI.InfoFile.size() > 0) {
@@ -327,6 +376,9 @@
                }
                if (LI.AgentRelationName != null && LI.AgentRelationName.size() > 0) {
                    te1.AgentRelationName__c = String.join(LI.AgentRelationName, ',');
                    //add 密文 sushanhu 20220223 start
                    te1.AgentRelationName_Encrypted__c =String.join(LI.AgentRelationNameEncrypted,',');
                    //add 密文 sushanhu 20220223 end
                }
                if (String.isNotBlank(LI.bidingEndTime)) {
                    te1.BidingEndTime__c = Datetime.valueOf(LI.bidingEndTime);
@@ -355,6 +407,9 @@
                }
                if (LI.ZhongRelationWay != null && LI.ZhongRelationWay.size() > 0) {
                    te1.ZhongRelationWay__c = String.join(LI.ZhongRelationWay, ',');
                    //add 密文 sushanhu 20220223 start
                    te1.ZhongRelationWay_Encrypted__c =String.join(LI.ZhongRelationWayEncrypted,',');
                    //add 密文 sushanhu 20220223 end
                }
                if (String.isNotBlank(LI.bidingAcquireTime)) {
                    te1.BidingAcquireTime__c = Datetime.valueOf(LI.bidingAcquireTime);
@@ -462,10 +517,18 @@
                }
                if (LI.ZhaoRelationName != null && LI.ZhaoRelationName.size() > 0) {
                    te1.ZhaoRelationName__c = String.join(LI.ZhaoRelationName, ',');
                    //add 密文 sushanhu 20220223 start
                    te1.ZhaoRelationName_Encrypted__c =String.join(LI.ZhaoRelationNameEncrypted,',');
                    //add 密文 sushanhu 20220223 end
                }
                if (LI.ZhongRelationName != null && LI.ZhongRelationName.size() > 0) {
                    te1.ZhongRelationName__c = String.join(LI.ZhaoRelationName, ',');
                     //add 密文 sushanhu 20220223 start
                     te1.ZhongRelationName_Encrypted__c =String.join(LI.ZhongRelationNameEncrypted,',');
                     //add 密文 sushanhu 20220223 end
                }
                System.debug('te1-----'+json.serialize(te1));
                //精琢科技   zxk   2021-11-11  SWAG-C637NF   start
                // 如果第一次项目阶段就传来变更状态的话,那么就不生成招投标项目(由于变更阶段项目名称传来为空,为了不让项目名自动赋值为Id)
                if (String.isNotBlank(te1.InfoType__c) && String.isNotBlank(LI.projectId)) {
@@ -493,14 +556,23 @@
            if (DetlList.size() > 0) {
                delete DetlList;
            }
            system.debug('updateTenderMap---'+json.serialize(updateTenderMap));
            if (updateTenderMap.values().size() > 0) {
                upsert updateTenderMap.values();
            }
            System.debug('123456789123456789:' + updateTenderMap);
            //将招标信息和招标信息详情关联起来(通过ProjectId这一唯一标识)
            Map < string, Tender_information__c > TenderMap = new map < string, Tender_information__c > ();
            for (Tender_information__c TMap: updateTenderMap.values()) {
                system.debug('TMap---'+JSON.serialize(TMap));
                TenderMap.put(TMap.ProjectId__c, TMap);
                PIHelper.IdList il= new PIHelper.IdList();
                // add for pipl  sushanhu 20220310 start
                il.awsId =TMap.AWS_Data_Id__c;
                il.sfRecordId=TMap.Id;
                idList.add(il);
                // add for pipl  sushanhu 20220310 end
            }
            System.debug('12345678!!!!!' + TenderMap.values());
            List < Tender_information_details__c > TenList = new List < Tender_information_details__c > ();
@@ -529,6 +601,7 @@
                insert insertbidInfoFileList;
            }
            if (!Manual_execution501future) {
                //测试 Open the comment by Li Jun 20220404
                System.enqueueJob(new NFM502Controller(rowData.id));
            }
            // logstr += '\nend';
@@ -537,9 +610,17 @@
            if (System.Test.isRunningTest()) {
                throw new ControllerUtil.myException('aaa');
            }
            //确认事务 add for pi sushanhu 20220310 start
            // PIHelper.confirmTrans('NFM501',1,null,txId,NFM501AWS.token,NFM501AWS.transactionURL,idList);
            PIHelper.insertConfirmTrans('NFM501',1,null,txId,1,NFM501AWS.transactionURL,idList);
            //确认事务 add for pi sushanhu 20220310 end
        } catch (Exception ex) {
            // 如果数据获取过程中,有错误(同一游标,如果报错,是他重新获取一遍,如果三次都没能获取到,就发送邮件报错信息,然后手动进行获取)
            Database.rollback(sp);
            //确认事务 add for pi sushanhu 20220310 start
            // PIHelper.confirmTrans('NFM501',0,null,txId,NFM501AWS.token,NFM501AWS.transactionURL,idList);
            PIHelper.insertConfirmTrans('NFM501',0,null,txId,1,NFM501AWS.transactionURL,idList);
            //确认事务 add for pi sushanhu 20220310 end
            System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            // logstr += '\n' + ex.getMessage();
force-app/main/default/classes/NFM501FutureControllerTest.cls
@@ -1,5 +1,9 @@
@isTest
public with sharing class NFM501FutureControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration('QLMNFM501');
    }
    public NFM501FutureControllerTest() {
    }
@@ -98,7 +102,8 @@
        insert NFM501TokenTransfers;
        Tender_information__c Ten = new Tender_information__c();
        Ten.Name = '123456';
        // Ten.Name = '123456';
        Ten.InfoTitle__c = '123456';
        Ten.ProjectId__c = '38_99df2844cf784982acdc61d00d7a7dbb';
        insert Ten;
@@ -110,7 +115,7 @@
        BatchIF_Log__c rowData = new BatchIF_Log__c();
        rowData.Type__c = 'NFM501';
        rowData.RowDataFlg__c = true;
        rowData.Log__c = '{"code":"0","data":{"cursorMark":"60d01dde42ec7ed48d3730d6","list1":[{"agentRelationName":["李蕾电"],"agentRelationWay":["12345678"],"agentUnit":["四川乾新招投标代理有限公司"],"areaCity":"惠州市","areaCountry":"","areaProvince":"广东省","biddingType":"0","bidingAcquireTime":"2021-01-13 00:00:00","bidingEndTime":"2021-01-13 00:00:00","budget":[{"amount":"250000.00","unit":"元"}],"infoFile":["http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyMjczMjgxOTAiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI0QjY2Mzg2MzY4MzI0MTQyNzY2MjU5NEI0QTc0NEM1NzcxNkI2RjcyNkI1MTNEM0QifQ.3UTAGOde4plSKFKf_DV1sBWXJbdsz7zN8a1KZZys6bo"],"infoId":"227328190","infoPublishTime":"2021-06-21 09:41:26","infoQianlimaUrl":"http://www.qianlima.com/zb/detail/20210621_227328190.html","infoTitle":"皮肤镜图像处理工作站调研公告","infoType":"5","infoTypeSegment":"7","isElectronic":"0","keywords":"图像处理","openBidingTime":"2021-01-13 00:00:00","projectId":"38_99df2844cf784982acdc61d00d7a7dbb","target":{"targetDetails":[{"number1":"12","totalPrice":"2645000.00","price":"","name":"四川省雅安市芦山县人民医院抗疫特别国债购置高清胃肠镜采购项目","model":"","brand":""}]},"tenderBeginTime":"2021-01-13 00:00:00","tenderEndTime":"2021-01-13 00:00:00","winnerAmount":[{"amount":"1598000.00","unit":"元"}],"xmNumber":"CD-1624266167710","zhaoBiaoUnit":["惠州市第一人民医院","OCM","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院"],"zhaoRelationName":["范梅红"],"zhaoRelationWay":["0752-2883625"],"zhongBiaoUnit":["成都宋庄创意科技有限公司","OCSM","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司"],"zhongRelationName":["1234"],"zhongRelationWay":["1234567"]}]},"msg":"正确返回数据"}';
        rowData.Log__c = '{"code":"0","data":{"cursorMark":"60d01dde42ec7ed48d3730d6","list1":[{"DataId":"1234567890","agentRelationName":["李蕾电"],"agentRelationWay":["12345678"],"agentUnit":["四川乾新招投标代理有限公司"],"areaCity":"惠州市","areaCountry":"","areaProvince":"广东省","biddingType":"0","bidingAcquireTime":"2021-01-13 00:00:00","bidingEndTime":"2021-01-13 00:00:00","budget":[{"amount":"250000.00","unit":"元"}],"infoFile":["http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyMjczMjgxOTAiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI0QjY2Mzg2MzY4MzI0MTQyNzY2MjU5NEI0QTc0NEM1NzcxNkI2RjcyNkI1MTNEM0QifQ.3UTAGOde4plSKFKf_DV1sBWXJbdsz7zN8a1KZZys6bo"],"infoId":"227328190","infoPublishTime":"2021-06-21 09:41:26","infoQianlimaUrl":"http://www.qianlima.com/zb/detail/20210621_227328190.html","infoTitle":"皮肤镜图像处理工作站调研公告","infoType":"5","infoTypeSegment":"7","isElectronic":"0","keywords":"图像处理","openBidingTime":"2021-01-13 00:00:00","projectId":"38_99df2844cf784982acdc61d00d7a7dbb","target":{"targetDetails":[{"number1":"12","totalPrice":"2645000.00","price":"","name":"四川省雅安市芦山县人民医院抗疫特别国债购置高清胃肠镜采购项目","model":"","brand":""}]},"tenderBeginTime":"2021-01-13 00:00:00","tenderEndTime":"2021-01-13 00:00:00","winnerAmount":[{"amount":"1598000.00","unit":"元"}],"xmNumber":"CD-1624266167710","zhaoBiaoUnit":["惠州市第一人民医院","OCM","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院"],"zhaoRelationName":["范梅红"],"zhaoRelationWay":["0752-2883625"],"zhongBiaoUnit":["成都宋庄创意科技有限公司","OCSM","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司"],"zhongRelationName":["1234"],"zhongRelationWay":["1234567"],"ZhaoRelationWayEncrypted":["1234567890"],"AgentRelationWayEncrypted":["1234567890"],"AgentRelationNameEncrypted":["1234567890"],"ZhongRelationWayEncrypted":["1234567890"],"ZhaoRelationNameEncrypted":["1234567890"],"ZhongRelationNameEncrypted":["1234567890"]}]},"msg":"正确返回数据"}';
        rowData.MessageGroupNumber__c = transfer1.Internal_Value__c;
        insert rowData;
@@ -139,7 +144,7 @@
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new NFM501HttpCallMock());
        NFM501FutureController.main(rowData01.Id, iflog01.Id, false);
        NFM501FutureController.main(rowData01.Id, iflog01.Id, false,'txid');
        NFM501FutureController.USACurrency(AmountItem, te1, 'BudgetAmount');
        NFM501FutureController.OtherCurrency(AmountItem, te1, 'Budget');
        Test.stopTest();
@@ -176,7 +181,8 @@
        insert NFM501TokenTransfers;
        Tender_information__c Ten = new Tender_information__c();
        Ten.Name = '123456';
        Ten.InfoTitle__c = '123456';
        // Ten.Name = '123456';
        Ten.ProjectId__c = '38_99df2844cf784982acdc61d00d7a7dbb';
        insert Ten;
@@ -188,7 +194,7 @@
        BatchIF_Log__c rowData = new BatchIF_Log__c();
        rowData.Type__c = 'NFM501';
        rowData.RowDataFlg__c = true;
        rowData.Log__c = '{"code":"0","data":{"cursorMark":"60d01dde42ec7ed48d3730d6","list1":[{"agentRelationName":["李蕾电"],"agentRelationWay":["12345678"],"agentUnit":["四川乾新招投标代理有限公司"],"areaCity":"惠州市","areaCountry":"","areaProvince":"广东省","biddingType":"0","bidingAcquireTime":"2021-01-13 00:00:00","bidingEndTime":"2021-01-13 00:00:00","budget":[{"amount":"250000.00","unit":"元"}],"infoFile":["http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyMjczMjgxOTAiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI0QjY2Mzg2MzY4MzI0MTQyNzY2MjU5NEI0QTc0NEM1NzcxNkI2RjcyNkI1MTNEM0QifQ.3UTAGOde4plSKFKf_DV1sBWXJbdsz7zN8a1KZZys6bo"],"infoId":"227328190","infoPublishTime":"2021-06-21 09:41:26","infoQianlimaUrl":"http://www.qianlima.com/zb/detail/20210621_227328190.html","infoTitle":"皮肤镜图像处理工作站调研公告","infoType":"1","infoTypeSegment":"1","isElectronic":"0","keywords":"图像处理","openBidingTime":"2021-01-13 00:00:00","projectId":"38_99df2844cf784982acdc61d00d7a7dbb","target":{"targetDetails":[{"number1":"12","totalPrice":"2645000.00","price":"","name":"四川省雅安市芦山县人民医院抗疫特别国债购置高清胃肠镜采购项目","model":"","brand":""}]},"tenderBeginTime":"2021-01-13 00:00:00","tenderEndTime":"2021-01-13 00:00:00","winnerAmount":[{"amount":"1598000.00","unit":"元"}],"xmNumber":"CD-1624266167710","zhaoBiaoUnit":["惠州市第一人民医院","OCM","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院"],"zhaoRelationName":["范梅红"],"zhaoRelationWay":["0752-2883625"],"zhongBiaoUnit":["成都宋庄创意科技有限公司","OCSM","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司"],"zhongRelationName":["1234"],"zhongRelationWay":["1234567"]}]},"msg":"正确返回数据"}';
        rowData.Log__c = '{"code":"0","data":{"cursorMark":"60d01dde42ec7ed48d3730d6","list1":[{"DataId":"1234567890","agentRelationName":["李蕾电"],"agentRelationWay":["12345678"],"agentUnit":["四川乾新招投标代理有限公司"],"areaCity":"惠州市","areaCountry":"","areaProvince":"广东省","biddingType":"0","bidingAcquireTime":"2021-01-13 00:00:00","bidingEndTime":"2021-01-13 00:00:00","budget":[{"amount":"250000.00","unit":"元"}],"infoFile":["http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyMjczMjgxOTAiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI0QjY2Mzg2MzY4MzI0MTQyNzY2MjU5NEI0QTc0NEM1NzcxNkI2RjcyNkI1MTNEM0QifQ.3UTAGOde4plSKFKf_DV1sBWXJbdsz7zN8a1KZZys6bo"],"infoId":"227328190","infoPublishTime":"2021-06-21 09:41:26","infoQianlimaUrl":"http://www.qianlima.com/zb/detail/20210621_227328190.html","infoTitle":"皮肤镜图像处理工作站调研公告","infoType":"1","infoTypeSegment":"1","isElectronic":"0","keywords":"图像处理","openBidingTime":"2021-01-13 00:00:00","projectId":"38_99df2844cf784982acdc61d00d7a7dbb","target":{"targetDetails":[{"number1":"12","totalPrice":"2645000.00","price":"","name":"四川省雅安市芦山县人民医院抗疫特别国债购置高清胃肠镜采购项目","model":"","brand":""}]},"tenderBeginTime":"2021-01-13 00:00:00","tenderEndTime":"2021-01-13 00:00:00","winnerAmount":[{"amount":"1598000.00","unit":"元"}],"xmNumber":"CD-1624266167710","zhaoBiaoUnit":["惠州市第一人民医院","OCM","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院"],"zhaoRelationName":["范梅红"],"zhaoRelationWay":["0752-2883625"],"zhongBiaoUnit":["成都宋庄创意科技有限公司","OCSM","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司"],"zhongRelationName":["1234"],"zhongRelationWay":["1234567"],"ZhaoRelationWayEncrypted":["1234567890"],"AgentRelationWayEncrypted":["1234567890"],"AgentRelationNameEncrypted":["1234567890"],"ZhongRelationWayEncrypted":["1234567890"],"ZhaoRelationNameEncrypted":["1234567890"],"ZhongRelationNameEncrypted":["1234567890"]}]},"msg":"正确返回数据"}';
        rowData.MessageGroupNumber__c = transfer1.Internal_Value__c;
        insert rowData;
@@ -217,7 +223,7 @@
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new NFM501HttpCallMock());
        NFM501FutureController.main(rowData01.Id, iflog01.Id, false);
        NFM501FutureController.main(rowData01.Id, iflog01.Id, false,'txid');
        NFM501FutureController.USACurrency(AmountItem, te1, 'BudgetAmount');
        NFM501FutureController.OtherCurrency(AmountItem, te1, 'Budget');
        Test.stopTest();
@@ -255,7 +261,8 @@
        insert NFM501TokenTransfers;
        Tender_information__c Ten = new Tender_information__c();
        Ten.Name = '123456';
        // Ten.Name = '123456';
        Ten.InfoTitle__c = '123456';
        Ten.ProjectId__c = '38_99df2844cf784982acdc61d00d7a7dbb';
        insert Ten;
@@ -267,7 +274,7 @@
        BatchIF_Log__c rowData = new BatchIF_Log__c();
        rowData.Type__c = 'NFM501';
        rowData.RowDataFlg__c = true;
        rowData.Log__c = '{"code":"0","data":{"cursorMark":"60d01dde42ec7ed48d3730d6","list1":[{"agentRelationName":["李蕾电"],"agentRelationWay":["12345678"],"agentUnit":["四川乾新招投标代理有限公司"],"areaCity":"惠州市","areaCountry":"","areaProvince":"广东省","biddingType":"0","bidingAcquireTime":"2021-01-13 00:00:00","bidingEndTime":"2021-01-13 00:00:00","budget":[{"amount":"250000.00","unit":"元"}],"infoFile":["http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyMjczMjgxOTAiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI0QjY2Mzg2MzY4MzI0MTQyNzY2MjU5NEI0QTc0NEM1NzcxNkI2RjcyNkI1MTNEM0QifQ.3UTAGOde4plSKFKf_DV1sBWXJbdsz7zN8a1KZZys6bo"],"infoId":"227328190","infoPublishTime":"2021-06-21 09:41:26","infoQianlimaUrl":"http://www.qianlima.com/zb/detail/20210621_227328190.html","infoTitle":"皮肤镜图像处理工作站调研公告","infoType":"5","infoTypeSegment":"7","isElectronic":"0","keywords":"图像处理","openBidingTime":"2021-01-13 00:00:00","projectId":"38_99df2844cf784982acdc61d00d7a7dbb","target":{"targetDetails":[{"number1":"12","totalPrice":"2645000.00","price":"","name":"四川省雅安市芦山县人民医院抗疫特别国债购置高清胃肠镜采购项目","model":"","brand":""}]},"tenderBeginTime":"2021-01-13 00:00:00","tenderEndTime":"2021-01-13 00:00:00","winnerAmount":[{"amount":"1598000.00","unit":"元"}],"xmNumber":"CD-1624266167710","zhaoBiaoUnit":["惠州市第一人民医院","OCM","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院"],"zhaoRelationName":["范梅红"],"zhaoRelationWay":["0752-2883625"],"zhongBiaoUnit":["成都宋庄创意科技有限公司","OCSM","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司"],"zhongRelationName":["1234"],"zhongRelationWay":["1234567"]}]},"msg":"正确返回数据"}';
        rowData.Log__c = '{"code":"0","data":{"cursorMark":"60d01dde42ec7ed48d3730d6","list1":[{"DataId":"1234567890","agentRelationName":["李蕾电"],"agentRelationWay":["12345678"],"agentUnit":["四川乾新招投标代理有限公司"],"areaCity":"惠州市","areaCountry":"","areaProvince":"广东省","biddingType":"0","bidingAcquireTime":"2021-01-13 00:00:00","bidingEndTime":"2021-01-13 00:00:00","budget":[{"amount":"250000.00","unit":"元"}],"infoFile":["http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyMjczMjgxOTAiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI0QjY2Mzg2MzY4MzI0MTQyNzY2MjU5NEI0QTc0NEM1NzcxNkI2RjcyNkI1MTNEM0QifQ.3UTAGOde4plSKFKf_DV1sBWXJbdsz7zN8a1KZZys6bo"],"infoId":"227328190","infoPublishTime":"2021-06-21 09:41:26","infoQianlimaUrl":"http://www.qianlima.com/zb/detail/20210621_227328190.html","infoTitle":"皮肤镜图像处理工作站调研公告","infoType":"5","infoTypeSegment":"7","isElectronic":"0","keywords":"图像处理","openBidingTime":"2021-01-13 00:00:00","projectId":"38_99df2844cf784982acdc61d00d7a7dbb","target":{"targetDetails":[{"number1":"12","totalPrice":"2645000.00","price":"","name":"四川省雅安市芦山县人民医院抗疫特别国债购置高清胃肠镜采购项目","model":"","brand":""}]},"tenderBeginTime":"2021-01-13 00:00:00","tenderEndTime":"2021-01-13 00:00:00","winnerAmount":[{"amount":"1598000.00","unit":"元"}],"xmNumber":"CD-1624266167710","zhaoBiaoUnit":["惠州市第一人民医院","OCM","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院","惠州市第一人民医院"],"zhaoRelationName":["范梅红"],"zhaoRelationWay":["0752-2883625"],"zhongBiaoUnit":["成都宋庄创意科技有限公司","OCSM","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司","成都宋庄创意科技有限公司"],"zhongRelationName":["1234"],"zhongRelationWay":["1234567"],"ZhaoRelationWayEncrypted":["1234567890"],"AgentRelationWayEncrypted":["1234567890"],"AgentRelationNameEncrypted":["1234567890"],"ZhongRelationWayEncrypted":["1234567890"],"ZhaoRelationNameEncrypted":["1234567890"],"ZhongRelationNameEncrypted":["1234567890"]}]},"msg":"正确返回数据"}';
        rowData.MessageGroupNumber__c = transfer1.Internal_Value__c;
        insert rowData;
@@ -293,7 +300,7 @@
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new NFM501HttpCallMockEx());
        NFM501FutureController.main(rowData01.Id, iflog01.Id, false);
        NFM501FutureController.main(rowData01.Id, iflog01.Id, false,'txid');
        Test.stopTest();
    }
force-app/main/default/classes/NFM502Controller.cls
@@ -1,320 +1,414 @@
public with sharing class NFM502Controller implements Queueable {
    public String rowData_id;
    //add staic sushanhu 20220302 start
    public static String transUrl;
    public static String transId;
    public static String token;
    public static List<String> sfRecordIds =new List<String>();
    //add staic sushanhu 20220302 end
    public NFM502Controller(String rowData_id) {
        this.rowData_id = rowData_id;
    }
    public String rowData_id;
    public NFM502Controller(String rowData_id) {
        this.rowData_id = rowData_id;
    }
    public static Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
    public void execute(QueueableContext context) {
        // 通过Rowdata.Id来检索日志中的内容(千里马数据等)
        BatchIF_Log__c rowData = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c,
                                  Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c,
                                  Log10__c, Log11__c, Log12__c, MessageGroupNumber__c, retry_cnt__c,
                                  NFM501Future_Count__c,
                                  NFM501_Web_Annex_Count__c
                                  from BatchIF_Log__c where RowDataFlg__c = true and Id = :rowData_id];
        //存放报错信息
        BatchIF_Log__c iflog502 = new BatchIF_Log__c();
        iflog502.Type__c = 'NFM501';
        iflog502.RowDataFlg__c = false;
        iflog502.Log__c = ' ';
        iflog502.ErrorLog__c = ' ';
        iflog502.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        insert iflog502;
        NFM502Controller.WebAnnexGain(rowData.Id, iflog502.Id, false);
    }
    @future(callout = true)
    public static void WebAnnexGain(String rowData_id, String iflog502_id, boolean Manual_execution502) {
        BatchIF_Log__c rowData = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c,
                                  Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c,
                                  Log11__c, Log12__c, MessageGroupNumber__c, retry_cnt__c,
                                  NFM501Future_Count__c,
                                  NFM501_Web_Annex_Count__c from BatchIF_Log__c
                                  where RowDataFlg__c = true and Id = :rowData_id];
        BatchIF_Log__c iflog502 = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c,
                                   Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c,
                                   Log11__c, Log12__c, MessageGroupNumber__c, retry_cnt__c,
                                   NFM501Future_Count__c,
                                   NFM501_Web_Annex_Count__c from BatchIF_Log__c
                                   where Id = :iflog502_id];
    public static Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
    public void execute(QueueableContext context) {
        // 通过Rowdata.Id来检索日志中的内容(千里马数据等)
        BatchIF_Log__c rowData = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c,
                                  Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c,
                                  Log10__c, Log11__c, Log12__c, MessageGroupNumber__c, retry_cnt__c,
                                  NFM501Future_Count__c,
                                  NFM501_Web_Annex_Count__c
                                  from BatchIF_Log__c where RowDataFlg__c = true and Id = :rowData_id];
        //存放报错信息
        BatchIF_Log__c iflog502 = new BatchIF_Log__c();
        iflog502.Type__c = 'NFM501';
        iflog502.RowDataFlg__c = false;
        iflog502.Log__c = ' ';
        iflog502.ErrorLog__c = ' ';
        iflog502.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        insert iflog502;
        NFM502Controller.WebAnnexGain(rowData.Id, iflog502.Id, false);
    }
    @future(callout = true)
    public static void WebAnnexGain(String rowData_id, String iflog502_id, boolean Manual_execution502) {
        BatchIF_Log__c rowData = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c,
                                  Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c,
                                  Log11__c, Log12__c, MessageGroupNumber__c, retry_cnt__c,
                                  NFM501Future_Count__c,
                                  NFM501_Web_Annex_Count__c from BatchIF_Log__c
                                  where RowDataFlg__c = true and Id = :rowData_id];
        BatchIF_Log__c iflog502 = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c,
                                   Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c,
                                   Log11__c, Log12__c, MessageGroupNumber__c, retry_cnt__c,
                                   NFM501Future_Count__c,
                                   NFM501_Web_Annex_Count__c from BatchIF_Log__c
                                   where Id = :iflog502_id];
        iflog502.Log__c = iflog502.Log__c == null ? '' : iflog502.Log__c;
        iflog502.ErrorLog__c = iflog502.ErrorLog__c == null ? '' : iflog502.ErrorLog__c;
        rowData.Log__c = rowData.Log__c == null ? '' : rowData.Log__c;
        rowData.ErrorLog__c = rowData.ErrorLog__c == null ? '' : rowData.ErrorLog__c;
        iflog502.Log__c = iflog502.Log__c == null ? '' : iflog502.Log__c;
        iflog502.ErrorLog__c = iflog502.ErrorLog__c == null ? '' : iflog502.ErrorLog__c;
        rowData.Log__c = rowData.Log__c == null ? '' : rowData.Log__c;
        rowData.ErrorLog__c = rowData.ErrorLog__c == null ? '' : rowData.ErrorLog__c;
        // Savepoint sp = Database.setSavepoint();
        try {
            //update 同staic 20220302 satrt
            // String token;
            //update 同staic 20220302 end
            Datetime oldTime;
            // 从转换表中获取token
            BatchIF_Transfer__c token502 = [Select ID, NFM501_Token__c
                                            FROM BatchIF_Transfer__c Where Table__c = 'NFM501Token'];
            token = token502.NFM501_Token__c;
            // 从转换表中获取获取完token的时间
            BatchIF_Transfer__c oldTime502 = [Select ID, NFM501_Gain_End_Time__c
                                              FROM BatchIF_Transfer__c Where Table__c = 'NFM501GainEndTime'];
            oldTime = oldTime502.NFM501_Gain_End_Time__c;
            // 对日志中的数据进行解析
            String WebUrl = NFMUtil.QLMgetRowDataStr(rowData);
            NFM501Controller.AllData getQLMData502 = (NFM501Controller.AllData)
                    JSON.deserialize(WebUrl, NFM501Controller.AllData.class);
            if (getQLMData502 == null) {
                return;
            }
        // Savepoint sp = Database.setSavepoint();
        try {
            String token;
            Datetime oldTime;
            // 从转换表中获取token
            BatchIF_Transfer__c token502 = [Select ID, NFM501_Token__c
                                            FROM BatchIF_Transfer__c Where Table__c = 'NFM501Token'];
            token = token502.NFM501_Token__c;
            // 从转换表中获取获取完token的时间
            BatchIF_Transfer__c oldTime502 = [Select ID, NFM501_Gain_End_Time__c
                                              FROM BatchIF_Transfer__c Where Table__c = 'NFM501GainEndTime'];
            oldTime = oldTime502.NFM501_Gain_End_Time__c;
            // 对日志中的数据进行解析
            String WebUrl = NFMUtil.QLMgetRowDataStr(rowData);
            NFM501Controller.AllData getQLMData502 = (NFM501Controller.AllData)
                    JSON.deserialize(WebUrl, NFM501Controller.AllData.class);
            if (getQLMData502 == null) {
                return;
            }
            // 判断token是否失效(失效条件为30分钟之后),如果失效,重新获取
            Long timeslot;
            Datetime newTime = System.now();
            if (oldTime == null) {
                timeslot = 2800000;
            } else {
                // 当前时间与获取token结束时间的时间差
                timeslot = newTime.getTime() - oldTime.getTime();
            }
            // System.debug('++++1++++' + token + '  : ' + timeslot);
            if (string.isblank(token) || timeslot > 1800000) {
                // NFMUtil.response response = NFMUtil.receiveToken();
                //update to aws token sushanhu 20220301  start
                NFMUtil.response response = NFMUtil.getAWSToken();
                //判断rowdata中数据获取成功与否,如果失败重发三次,如果大于三次则手动操作
                if (String.isBlank(response.responseBody)) {
                    System.debug('response.responseBody:' + response.responseBody);
                    iflog502.ErrorLog__c = '502token:' + response.responseBody;
                    // rowData.NFM501_Web_Annex_Count__c = 0;
                    if (!Manual_execution502) {
                        NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
                    }
                    //更新日志数据
                    System.debug('123@@@');
                    return;
                }
                token = response.responseBody;
                oldTime = Datetime.now();
                token502.NFM501_Token__c = token;
                oldTime502.NFM501_Gain_End_Time__c = oldTime;
                //update to aws token sushanhu 20220301  end
            }
            // 判断token是否失效(失效条件为30分钟之后),如果失效,重新获取
            Long timeslot;
            Datetime newTime = System.now();
            if (oldTime == null) {
                timeslot = 2800000;
            } else {
                // 当前时间与获取token结束时间的时间差
                timeslot = newTime.getTime() - oldTime.getTime();
            }
            // System.debug('++++1++++' + token + '  : ' + timeslot);
            if (string.isblank(token) || timeslot > 1800000) {
                NFMUtil.response response = NFMUtil.receiveToken();
                //判断rowdata中数据获取成功与否,如果失败重发三次,如果大于三次则手动操作
                if (String.isBlank(response.responseBody)) {
                    System.debug('response.responseBody:' + response.responseBody);
                    iflog502.ErrorLog__c = '502token:' + response.status;
                    // rowData.NFM501_Web_Annex_Count__c = 0;
                    if (!Manual_execution502) {
                        NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
                    }
                    //更新日志数据
                    System.debug('123@@@');
                    return;
                }
                token = response.responseBody;
                oldTime = Datetime.now();
                token502.NFM501_Token__c = token;
                oldTime502.NFM501_Gain_End_Time__c = oldTime;
            }
            //关联附件与招投标项目(通过Id)
            //1.读出招投标中的唯一标识(projecId),将全部招投标projectId存入ProjectIdList
            List<String> ProjectIdList = new List<String>();
            for (NFM501Controller.ListItem ProId : getQLMData502.data.list1) {
                ProjectIdList.add(ProId.projectId);
            }
            System.debug('---===ProjectIdList' + ProjectIdList);
            //2.取其对应的
            List<Tender_information__c> TIList =
                [Select Id, ProjectId__c, InfoType__c
                 FROM Tender_information__c
                 Where ProjectId__c in :ProjectIdList];
            System.debug('---===2345TIList' + TIList);
            Set<Id> TenIdSet = new Set<Id>();
            //关联附件与招投标项目(通过Id)
            //1.读出招投标中的唯一标识(projecId),将全部招投标projectId存入ProjectIdList
            List<String> ProjectIdList = new List<String>();
            for (NFM501Controller.ListItem ProId : getQLMData502.data.list1) {
                ProjectIdList.add(ProId.projectId);
            }
            System.debug('---===ProjectIdList' + ProjectIdList);
            //2.取其对应的
            List<Tender_information__c> TIList =
                [Select Id, ProjectId__c, InfoType__c
                 FROM Tender_information__c
                 Where ProjectId__c in :ProjectIdList];
            System.debug('---===2345TIList' + TIList);
            Set<Id> TenIdSet = new Set<Id>();
            Map<String, Tender_information__c> TenMap = new Map<String, Tender_information__c>();
            for (Tender_information__c Ten : TIList) {
                TenMap.put(Ten.ProjectId__c, Ten);
                TenIdSet.add(Ten.Id);
            }
            Map<String, Tender_information__c> TenMap = new Map<String, Tender_information__c>();
            for (Tender_information__c Ten : TIList) {
                TenMap.put(Ten.ProjectId__c, Ten);
                TenIdSet.add(Ten.Id);
            }
            //循环URL
            // List<Attachment> TenAttList = new List<Attachment>();
            //update to aws pi sushanhu 20220301 start
            List<FileAddress__c> fileList = new List<FileAddress__c>();
            List<String> queryUrlList = new List<String>();
            Map<String, NFM501Controller.ListItem> queryMap = new Map<String, NFM501Controller.ListItem>();
            //update to aws pi sushanhu 20220301 end
            for (NFM501Controller.ListItem QLMWebAtt : getQLMData502.data.list1) {
                if (QLMWebAtt.projectId == null) {
                    iflog502.ErrorLog__c += 'Error! [' + QLMWebAtt.projectId + ']NotExist. This information is skipped.\n';
                    continue;
                }
                if (QLMWebAtt.areaProvince.equals('香港特别行政区')
                        || QLMWebAtt.areaProvince.equals('澳门特别行政区')
                        || QLMWebAtt.areaProvince.equals('台湾省')) {
                    iflog502.ErrorLog__c += 'Error! [' + QLMWebAtt.areaProvince +
                                            ']Is 香港特别行政区(澳门特别行政区,台湾省). This information is skipped.\n';
                    continue;
                }
                //update to aws pi sushanhu 20220301 start
                queryUrlList.add(QLMWebAtt.infoQianlimaUrl);
                queryMap.put(QLMWebAtt.infoQianlimaUrl,QLMWebAtt);
                //update to aws pi sushanhu 20220301 start
            //  //调用接口3
            //  NFMUtil.response response = NFMUtil.getQLMData(NFMUtil.NFM502_ENDPOINT + QLMWebAtt.infoQianlimaUrl, token);
            //  if (String.isBlank(response.responseBody)) {
            //      System.debug('response.responseBody:' + response.responseBody);
            //      iflog502.ErrorLog__c = '502接口调用:' + response.status;
            //      rowData.NFM501_Web_Annex_Count__c = 0;
            //      if (!Manual_execution502) {
            //          NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
            //      }
            //      //更新日志数据
            //      update token502;
            //      update oldTime502;
            //      return;
            //  }
            //循环URL
            List<Attachment> TenAttList = new List<Attachment>();
            for (NFM501Controller.ListItem QLMWebAtt : getQLMData502.data.list1) {
                if (QLMWebAtt.projectId == null) {
                    iflog502.ErrorLog__c += 'Error! [' + QLMWebAtt.projectId + ']NotExist. This information is skipped.\n';
                    continue;
                }
                if (QLMWebAtt.areaProvince.equals('香港特别行政区')
                        || QLMWebAtt.areaProvince.equals('澳门特别行政区')
                        || QLMWebAtt.areaProvince.equals('台湾省')) {
                    iflog502.ErrorLog__c += 'Error! [' + QLMWebAtt.areaProvince +
                                            ']Is 香港特别行政区(澳门特别行政区,台湾省). This information is skipped.\n';
                    continue;
                }
                //调用接口3
                NFMUtil.response response = NFMUtil.getQLMData(NFMUtil.NFM502_ENDPOINT + QLMWebAtt.infoQianlimaUrl, token);
                if (String.isBlank(response.responseBody)) {
                    System.debug('response.responseBody:' + response.responseBody);
                    iflog502.ErrorLog__c = '502接口调用:' + response.status;
                    rowData.NFM501_Web_Annex_Count__c = 0;
                    if (!Manual_execution502) {
                        NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
                    }
                    //更新日志数据
                    update token502;
                    update oldTime502;
                    return;
                }
            //  //解析后的code报错处理
            //  string NFM502responseBody = response.responseBody;
            //  Map<String, Object> Body502 = (Map<String, Object>) JSON.deserializeUntyped(NFM502responseBody);
            //  if (!Body502.get('code').equals('0')) {
            //      System.debug('-------9-------');
            //      iflog502.ErrorLog__c = '502解析:' + Body502.get('msg').tostring() ;
            //      if (!Manual_execution502) {
            //          NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
            //      }
            //      update token502;
            //      update oldTime502;
            //      return;
            //  }
            //  System.debug('Body502.data:' + Body502.get('data').tostring() + '---------'
            //               + Body502.get('msg').tostring() + '-------' + Body502.get('code').tostring());
                //解析后的code报错处理
                string NFM502responseBody = response.responseBody;
                Map<String, Object> Body502 = (Map<String, Object>) JSON.deserializeUntyped(NFM502responseBody);
                if (!Body502.get('code').equals('0')) {
                    System.debug('-------9-------');
                    iflog502.ErrorLog__c = '502解析:' + Body502.get('msg').tostring() ;
                    if (!Manual_execution502) {
                        NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
                    }
                    update token502;
                    update oldTime502;
                    return;
                }
                System.debug('Body502.data:' + Body502.get('data').tostring() + '---------'
                             + Body502.get('msg').tostring() + '-------' + Body502.get('code').tostring());
            //  //获取网页信息转存为附件
            //  //截切数据(使数据成为解析的格式)
            //  Integer start = NFM502responseBody.indexOf('"infoHtml":"');
            //  Integer theEnd = NFM502responseBody.lastIndexOf('"},"msg');
            //  NFM502responseBody = NFM502responseBody.substring(start + 12, theEnd);
            //  //将其转换为附件
            //  // System.debug('---------' + NFM502responseBody);
            //  Attachment WebAtt = new Attachment();
            //  // System.debug('projectId:' + QLMWebAtt.projectId);
                // if (TenMap.containskey(QLMWebAtt.projectId)) {
                //  WebAtt.ParentId = TenMap.get(QLMWebAtt.projectId).Id;
                //  WebAtt.Body = Blob.valueOf(NFM502responseBody);
                //  WebAtt.Name = TenMap.get(QLMWebAtt.projectId).InfoType__c + ':' + QLMWebAtt.infoTitle + '.html';
                //  TenAttList.add(WebAtt);
                // }
             }
            //update to aws pi  sushanhu 20220301 start
            PIHelper.piIntegration pi =PIHelper.getPIIntegrationInfo('NFM502');
            transUrl=pi.searchUrl;
            //调用接口3
            system.debug('Payload for NFM 520:'+JSON.serialize(queryUrlList));
            NFMUtil.response response = NFMUtil.getAWSQLMData(pi.newUrl ,JSON.serialize(queryUrlList), token);
            Map<String, Object> result = (Map<String, Object>)JSON.deserializeUntyped(response.responseBody);
            String statusCode =(String)result.get('status');
            transId =(String)result.get('txId');
            if (!'0'.equals(statusCode)) {
                System.debug('response.responseBody:' + response.responseBody);
                iflog502.ErrorLog__c = '502接口调用:' + (String)result.get('message');
                rowData.NFM501_Web_Annex_Count__c = 0;
                if (!Manual_execution502) {
                    NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
                }
                //更新日志数据
                update token502;
                update oldTime502;
                return;
            }
                //获取网页信息转存为附件
                //截切数据(使数据成为解析的格式)
                Integer start = NFM502responseBody.indexOf('"infoHtml":"');
                Integer theEnd = NFM502responseBody.lastIndexOf('"},"msg');
                NFM502responseBody = NFM502responseBody.substring(start + 12, theEnd);
                //将其转换为附件
                // System.debug('---------' + NFM502responseBody);
                Attachment WebAtt = new Attachment();
                // System.debug('projectId:' + QLMWebAtt.projectId);
                if (TenMap.containskey(QLMWebAtt.projectId)) {
                    WebAtt.ParentId = TenMap.get(QLMWebAtt.projectId).Id;
                    WebAtt.Body = Blob.valueOf(NFM502responseBody);
                    WebAtt.Name = TenMap.get(QLMWebAtt.projectId).InfoType__c + ':' + QLMWebAtt.infoTitle + '.html';
                    TenAttList.add(WebAtt);
                }
            }
            //解析后的code报错处理
            string NFM502responseBody = response.responseBody;
            Map<String, Object> Body502 = (Map<String, Object>) JSON.deserializeUntyped(NFM502responseBody);
            if (!String.valueOf(Body502.get('status')).equals('0')) {
                System.debug('-------9-------');
                iflog502.ErrorLog__c = '502解析:' + Body502.get('message').tostring() ;
                if (!Manual_execution502) {
                    NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
                }
                update token502;
                update oldTime502;
                return;
            }
            System.debug('Body502.data:' + Body502.get('object').tostring() + '---------'
                         + Body502.get('message').tostring() + '-------' + Body502.get('status').tostring());
            //删除同名的附件
            List<String> UrlList = new List<String>();
            for (NFM501Controller.ListItem UrlName : getQLMData502.data.list1) {
                if (TenMap.containskey(UrlName.projectId)) {
                    UrlList.add(TenMap.get(UrlName.projectId).InfoType__c + ':' + UrlName.infoTitle + '.html');
                }
            }
            //获取aws返回的地址并存储
            Map<String, Object> fileMap = (Map<String, Object >)result.get('object');
            for(String url:queryUrlList){
                NFM501Controller.ListItem QLMWebAtt = queryMap.get(url);
                if (TenMap.containskey(QLMWebAtt.projectId)) {
                    FileAddress__c file =new FileAddress__c();
                    file.ParentRecordId__c = TenMap.get(QLMWebAtt.projectId).Id;
                    file.FileName__c = TenMap.get(QLMWebAtt.projectId).InfoType__c + ':' + QLMWebAtt.infoTitle + '.html';
                    file.DownloadLink__c =pi.undeleteUrl+(String)fileMap.get(url)+'&fileName='+file.FileName__c;
                    file.ViewLink__c = pi.queryUrl+(String)fileMap.get(url) ;
                    file.AWS_File_Key__c =(String)fileMap.get(url) ;
                    fileList.add(file);
                }
            }
            //删除同名的附件
            List<String> UrlList = new List<String>();
            for (NFM501Controller.ListItem UrlName : getQLMData502.data.list1) {
                if (TenMap.containskey(UrlName.projectId)) {
                    UrlList.add(TenMap.get(UrlName.projectId).InfoType__c + ':' + UrlName.infoTitle + '.html');
                }
            }
            List<Attachment> DeleAttList = [select id, name, ParentId from Attachment
                                            where name in :UrlList and ParentId in :TenIdSet];
            if (DeleAttList.size() > 0) {
                delete DeleAttList;
            }
            System.debug('----1----' + TenAttList);
            if (TenAttList.size() > 0) {
                upsert TenAttList;
            }
            List<FileAddress__c> DeleFileList = [select id, FileName__c, ParentRecordId__c from FileAddress__c
                                            where FileName__c in :UrlList and ParentRecordId__c in :TenIdSet];
            if (DeleFileList.size() > 0) {
                delete DeleFileList;
            }
            System.debug('----1----' + fileList);
            if (fileList.size() > 0) {
                upsert fileList;
            }
            //确认事务
            for (FileAddress__c file : fileList) {
                system.debug('file--'+json.serialize(file));
                system.debug('file.id'+file.Id);
                sfRecordIds.add(file.Id);
            }
            //update to aws pi  sushanhu 20220301 end
            //  PIHelper.confirmFileTrans('NFM502',1,JSON.serialize(sfRecordIds),transId,token,transUrl);
            if (fileList.size() > 0) {
                PIHelper.insertConfirmTrans('NFM502',1,JSON.serialize(sfRecordIds),transId,0,transUrl,null);
            }else{
                PIHelper.insertConfirmTrans('NFM502',0,JSON.serialize(sfRecordIds),transId,0,transUrl,null);
            }
            rowData.NFM501_Web_Annex_Count__c = 0;
        } catch (Exception ex) {
            // Database.rollback(sp);
            // System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            // System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            // logstr += '\n' + ex.getMessage();
            iflog502.ErrorLog__c = '502抛出异常:' + ex.getMessage() + '\n'
                                   + ex.getStackTraceString() + '\n' + iflog502.ErrorLog__c;
            if (!Manual_execution502) {
                NFM501Controller.againSendExceptionRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData,
                        '502抛出异常:' + ex.getMessage() + '\n' + ex.getStackTraceString()
                        + '\n' + rowData.ErrorLog__c +
                        '错误次数已经超过自动收信设定的最大次数,请手动收信');
            }
        }
        update rowData;
        System.debug('+++++++5+++++++' + rowData);
        System.debug('+++++++3+++++++' + iflog502.Log__c);
        System.debug('+++++++2+++++++' + iflog502.ErrorLog__c);
        //如果存入信息超出限制,用省略号代替
        if (iflog502.Log__c.length() > 131072) {
            iflog502.Log__c = iflog502.Log__c.subString(0, 131065) + ' ...';
        }
        if (iflog502.ErrorLog__c.length() > 32768) {
            iflog502.ErrorLog__c = iflog502.ErrorLog__c.subString(0, 32760) + ' ...';
        }
        upsert iflog502;
    }
    public static void test() {
        integer i = 0;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
            // if (!confirm) {
            //  //回滚
            // }
            rowData.NFM501_Web_Annex_Count__c = 0;
        } catch (Exception ex) {
            // Database.rollback(sp);
            // System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            // System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            // logstr += '\n' + ex.getMessage();
            //add 事务确认 sushanhu 20220302 satrt
            //  PIHelper.confirmFileTrans('NFM502',0,'',transId,token,transUrl);
             PIHelper.insertConfirmTrans('NFM502',0,JSON.serialize(sfRecordIds),transId,0,transUrl,null);
            //add 事务确认 sushanhu 20220302 end
            iflog502.ErrorLog__c = '502抛出异常:' + ex.getMessage() + '\n'
                                   + ex.getStackTraceString() + '\n' + iflog502.ErrorLog__c;
            if (!Manual_execution502) {
                NFM501Controller.againSendExceptionRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData,
                        '502抛出异常:' + ex.getMessage() + '\n' + ex.getStackTraceString()
                        + '\n' + rowData.ErrorLog__c +
                        '错误次数已经超过自动收信设定的最大次数,请手动收信');
            }
        }
        update rowData;
        System.debug('+++++++5+++++++' + rowData);
        System.debug('+++++++3+++++++' + iflog502.Log__c);
        System.debug('+++++++2+++++++' + iflog502.ErrorLog__c);
        //如果存入信息超出限制,用省略号代替
        if (iflog502.Log__c.length() > 131072) {
            iflog502.Log__c = iflog502.Log__c.subString(0, 131065) + ' ...';
        }
        if (iflog502.ErrorLog__c.length() > 32768) {
            iflog502.ErrorLog__c = iflog502.ErrorLog__c.subString(0, 32760) + ' ...';
        }
        upsert iflog502;
    }
    public static void test() {
        integer i = 0;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
    }
    }
}
force-app/main/default/classes/NFM502ControllerTest.cls
@@ -5,6 +5,7 @@
    }
    @testSetup
    static void makeTestQLM502() {
        TestDataUtility.CreatePIPolicyConfiguration('NFM502');
        BatchIF_Transfer__c transfer1 = new BatchIF_Transfer__c();
        transfer1.Table__c          = 'QLMoldMark';
        transfer1.Internal_Value__c = '*';
@@ -26,13 +27,15 @@
        Tender_information__c Ten = new Tender_information__c();
        Ten.Name = '123456';
        Ten.InfoTitle__c = '123456';
        Ten.ProjectId__c = '38_99df2844cf784982acdc61d00d7a7dbb';
        insert Ten;
        BatchIF_Log__c rowData = new BatchIF_Log__c();
        rowData.Type__c = 'NFM501';
        rowData.RowDataFlg__c = true;
        rowData.Log__c = '{"code":"0","data":{"cursorMark":"60d01dde42ec7ed48d3730d6","list1":[{"agentRelationName":[],"agentRelationWay":[],"agentUnit":[],"areaCity":"惠州市","areaCountry":"","areaProvince":"广东省","biddingType":"0","bidingAcquireTime":"","bidingEndTime":"","budget":[{"amount":"250000.00","unit":"元"}],"infoFile":["http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyMjczMjgxOTAiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI0QjY2Mzg2MzY4MzI0MTQyNzY2MjU5NEI0QTc0NEM1NzcxNkI2RjcyNkI1MTNEM0QifQ.3UTAGOde4plSKFKf_DV1sBWXJbdsz7zN8a1KZZys6bo"],"infoId":"227328190","infoPublishTime":"2021-06-21 09:41:26","infoQianlimaUrl":"http://www.qianlima.com/zb/detail/20210621_227328190.html","infoTitle":"皮肤镜图像处理工作站调研公告","infoType":"0","infoTypeSegment":"3","isElectronic":"0","keywords":"图像处理","openBidingTime":"","projectId":"38_99df2844cf784982acdc61d00d7a7dbb","target":null,"tenderBeginTime":"","tenderEndTime":"","winnerAmount":[],"xmNumber":"CD-1624266167710","zhaoBiaoUnit":["惠州市第一人民医院"],"zhaoRelationName":["范梅红"],"zhaoRelationWay":["0752-2883625"],"zhongBiaoUnit":[],"zhongRelationName":[],"zhongRelationWay":[]}]},"msg":"正确返回数据"}';
        // rowData.Log__c = '{"code":"0","data":{"cursorMark":"60d01dde42ec7ed48d3730d6","list1":[{"agentRelationName":[],"agentRelationWay":[],"agentUnit":[],"areaCity":"惠州市","areaCountry":"","areaProvince":"广东省","biddingType":"0","bidingAcquireTime":"","bidingEndTime":"","budget":[{"amount":"250000.00","unit":"元"}],"infoFile":["http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyMjczMjgxOTAiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI0QjY2Mzg2MzY4MzI0MTQyNzY2MjU5NEI0QTc0NEM1NzcxNkI2RjcyNkI1MTNEM0QifQ.3UTAGOde4plSKFKf_DV1sBWXJbdsz7zN8a1KZZys6bo"],"infoId":"227328190","infoPublishTime":"2021-06-21 09:41:26","infoQianlimaUrl":"http://www.qianlima.com/zb/detail/20210621_227328190.html","infoTitle":"皮肤镜图像处理工作站调研公告","infoType":"0","infoTypeSegment":"3","isElectronic":"0","keywords":"图像处理","openBidingTime":"","projectId":"38_99df2844cf784982acdc61d00d7a7dbb","target":null,"tenderBeginTime":"","tenderEndTime":"","winnerAmount":[],"xmNumber":"CD-1624266167710","zhaoBiaoUnit":["惠州市第一人民医院"],"zhaoRelationName":["范梅红"],"zhaoRelationWay":["0752-2883625"],"zhongBiaoUnit":[],"zhongRelationName":[],"zhongRelationWay":[]}]},"msg":"正确返回数据"}';
        rowData.Log__c ='{"data":{"list1":[{"DataId":"958850380886708224","agentRelationWayEncrypted":["ca93b1d0d9e14d81119d429b03faa17c"],"agentRelationNameEncrypted":["9e8e6aa24a7bf37db834622fd302b7b4"],"zhongRelationWayEncrypted":[],"zhongRelationNameEncrypted":[],"zhaoRelationWayEncrypted":["9e4d791610abcc65d501f3d96f11bf50"],"zhaoRelationNameEncrypted":["c41f9f806b7de8fffae5cb668dbb09e4"],"allKeywords":"进口","moreZhongBiaoUnit":[],"zhongRelationWay":[],"zhongRelationName":[],"zhongBiaoUnit":[],"zhaoRelationWay":["***********"],"zhaoRelationName":["***"],"zhaoBiaoUnit":["无极县医院"],"xmNumber":"HBZJ-2022N0253","winnerAmount":[],"tenderEndTime":"2022-04-20 09:30:00","tenderBeginTime":"","target":null,"projectId":"14e9fe7920df42d697830ce12abf31f3","openBidingTime":"","keywords":"电切镜,硬性镜,超声刀,内窥镜,窥镜,内镜,输尿管软镜,支气管镜,气管镜","isElectronic":"0","infoTypeSegment":"3","infoType":"0","infoTitle":"无极县医院迁建项目部分医疗设备购置(三)公开招标公告","infoQianlimaUrl":"http://www.qianlima.com/zb/detail/20220330_265423120.html","infoPublishTime":"2022-03-30 17:07:25","infoId":"265423120","infoFile":["http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyNjU0MjMxMjAiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI1NTcyNTk3NTU1NTQ2QzY5NEY1OTZCNTE0MzUzNjc3MDVBNzUzNDU3NzQ0MTNEM0QifQ.9ZMaqZVUxWgc9xAlHvfNEjUnPKztSokDqqZU-tGqpLw"],"budget":[{"unit":"元","amount":"38706500.00"}],"bidingEndTime":"2022-04-20 09:30:00","bidingAcquireTime":"2022-03-31 09:00:00","biddingType":"0","areaProvince":"河北省","areaCountry":"无极县","areaCity":"石家庄市","agentUnit":["河北中机咨询有限公司"],"agentRelationWay":["***********"],"agentRelationName":["***"]}],"cursorMark":"62444cc820386292a07cf3a1"},"code":"0","msg":"正确返回数据"}';
        rowData.MessageGroupNumber__c = transfer1.Internal_Value__c;
        insert rowData;
@@ -91,9 +94,13 @@
        //     [Select Id, ProjectId__c, InfoType__c
        //      FROM Tender_information__c];
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new NFM501HttpCallMockEx());
        NFM502Controller.WebAnnexGain(rowData.Id, iflog.Id, false);
        NFM502Controller.test();
        try{
            Test.setMock(HttpCalloutMock.class, new NFM501HttpCallMockEx());
            NFM502Controller.WebAnnexGain(rowData.Id, iflog.Id, false);
            NFM502Controller.test();
        }catch(Exception e){
            system.debug('Exception from insert NFM502');
        }
        Test.stopTest();
    }
force-app/main/default/classes/NFM503InfoFileBatch.cls
@@ -1,8 +1,20 @@
global class NFM503InfoFileBatch implements Database.Batchable<sObject>, Database.AllowsCallouts, Database.Stateful {
    public String TenId;
    public String bidInfoFileID;
    //add staic sushanhu 20220302 start
    public static String transUrl;
    public static String transId;
    public static String token;
    public static  integer isSuccess=0;
    public static List<String> sfRecordIds =new List<String>();
    //add staic sushanhu 20220302 end
    Boolean IsNeedExecute = false;  //2021-06-28 mzy  WLIG-BYHD79  SFDC环境batch合并调查  是否符合执行条件
    //add nfm 503 aws response start sushanhu 20220301
    global class File{
        public String key;
        public String name;
    }
    //add nfm 503 aws response sushanhu 20220301 end
    //2021-06-28  mzy update  千里马-Batch start
    global NFM503InfoFileBatch() {
        this.IsNeedExecute = true;
@@ -18,8 +30,8 @@
    global Database.QueryLocator start(Database.BatchableContext bc) {
        String query = 'select Id, Tender_information__c, infoAddress__c, ' +
                       'Tender_information__r.InfoType__c, isProcessed__c, ' +
                       ' ErrorMessage__c from bidInfoFile__c where isProcessed__c = false ';
                        'Tender_information__r.InfoType__c, isProcessed__c, ' +
                        ' ErrorMessage__c from bidInfoFile__c where isProcessed__c = false ';
        if (String.isNotBlank(TenId)) {
            query += 'and Tender_information__r.Id =: TenId';
        }
@@ -33,9 +45,12 @@
    global void execute(Database.BatchableContext BC, list<bidInfoFile__c> bidInfoFileList) {
        Savepoint sp;
        bidInfoFile__c bidInfoFile = bidInfoFileList[0];
        List<String> queryfileList = new List<String>();
        queryfileList.add(bidInfoFile.infoAddress__c);
        try {
            String token;
           //update 同staic 20220302 satrt
            // String token;
            //update 同staic 20220302 end
            Datetime oldTime;
            // 从转换表中获取token
            BatchIF_Transfer__c token503 = [Select ID, NFM501_Token__c
@@ -55,77 +70,172 @@
                timeslot = newTime.getTime() - oldTime.getTime();
            }
            // System.debug('++++1++++' + token + '  : ' + timeslot);
            PIHelper.piIntegration pi =PIHelper.getPIIntegrationInfo('NFM503');
            if (string.isblank(token) || timeslot > 1800000) {
                NFMUtil.response response = NFMUtil.receiveToken();
                if (String.isBlank(response.responseBody)) {
                    bidInfoFile.ErrorMessage__c = '503token:' + response.status;
                }
                token = response.responseBody;
                //UP TO AWAS TOKEN 20220225 SUSHANHU START
                // NFMUtil.response response = NFMUtil.getAWSToken();
                // //UP TO AWAS TOKEN 20220225 SUSHANHU END
                // if (String.isBlank(response.responseBody)) {
                //     bidInfoFile.ErrorMessage__c = '503token:' + response.status;
                // }
                token = pi.token;
                oldTime = Datetime.now();
                token503.NFM501_Token__c = token;
                oldTime503.NFM501_Gain_End_Time__c = oldTime;
            }
            // 存放超过12M的附件
            List<Attachment> TenOtherAttList = new List<Attachment>();
            // 存放所有附件
            List<String> FileList = new List<String>();
            // 如果文件大小超过12M更新
            List< Tender_information__c> updateTenderList = new  List< Tender_information__c>();
            // 获取接口3中数据
            NFMUtil.response503 response = NFMUtil.getFileData(token, bidInfoFile.infoAddress__c);
            // 文件大小超过12M
            if (response.Name.equals('文件大小超过12M')) {
                id tendID = bidInfoFile.Tender_information__c;
                Tender_information__c tempTender = new Tender_information__c();
                tempTender.id = tendID;
                tempTender.File_Surpass_12M__c = true;
                if (String.isBlank(tempTender.Overstep_12M_infofile__c)) {
                    tempTender.Overstep_12M_infofile__c = bidInfoFile.infoAddress__c;
                } else {
                    if (!tempTender.Overstep_12M_infofile__c.contains(bidInfoFile.infoAddress__c)) {
                        // List<String> urlList = singleFile.split(',');
                        tempTender.Overstep_12M_infofile__c += bidInfoFile.infoAddress__c + ',';
                    }
                }
                updateTenderList.add(tempTender);
            // // 存放超过12M的附件
            // List<Attachment> TenOtherAttList = new List<Attachment>();
            // // 存放所有附件
            // List<String> FileList = new List<String>();
            // // 如果文件大小超过12M更新
            // List< Tender_information__c> updateTenderList = new  List< Tender_information__c>();
            // // 获取接口3中数据
            // NFMUtil.response503 response = NFMUtil.getFileData(token, bidInfoFile.infoAddress__c);
            //UP TO NEW  AWS method sushanhu start 20220301
            // List< Tender_information__c> updateTenderList = new  List< Tender_information__c>();
            List<FileAddress__c> fileList = new List<FileAddress__c>();
            transUrl =pi.searchUrl;
            NFMUtil.response response = NFMUtil.getAWSQLMData(pi.newUrl ,JSON.serialize(queryfileList), token);
            system.debug('aws result'+response.responseBody);
            Map<String, Object> result = (Map<String, Object>)JSON.deserializeUntyped(response.responseBody);
            system.debug('NFM503 aws result--'+response.responseBody+'status'+response.status);
            transId =(String)result.get('txId');
            //UP TO NEW  AWS method sushanhu start 20220301
            // 新得存储 不需要判断文件超过12m
            // // 文件大小超过12M
            // if (response.Name.equals('文件大小超过12M')) {
            //     id tendID = bidInfoFile.Tender_information__c;
            //     Tender_information__c tempTender = new Tender_information__c();
            //     tempTender.id = tendID;
            //     tempTender.File_Surpass_12M__c = true;
            //     if (String.isBlank(tempTender.Overstep_12M_infofile__c)) {
            //         tempTender.Overstep_12M_infofile__c = bidInfoFile.infoAddress__c;
            //     } else {
            //         if (!tempTender.Overstep_12M_infofile__c.contains(bidInfoFile.infoAddress__c)) {
            //             // List<String> urlList = singleFile.split(',');
            //             tempTender.Overstep_12M_infofile__c += bidInfoFile.infoAddress__c + ',';
            //         }
            //     }
            //     updateTenderList.add(tempTender);
            // }
            // // 将获取到的数据存成附件
            // Attachment WebAtt = new Attachment();
            // WebAtt.ParentId = bidInfoFile.Tender_information__c;
            // WebAtt.Body = response.responseBody;
            // WebAtt.Name = bidInfoFile.Tender_information__r.InfoType__c + ':' + response.Name;
            // if (!response.Name.equals('文件大小超过12M')) {
            //     TenOtherAttList.add(WebAtt);
            // }
            // sp = Database.setSavepoint();
            // if (updateTenderList.size() > 0) {
            //     update updateTenderList;
            // }
            // System.debug('----1----' + TenOtherAttList);
            // if (TenOtherAttList.size() > 0 ) {
            //     upsert TenOtherAttList;
            // }
            // bidInfoFileList[0].isProcessed__c = true;
            // bidInfoFileList[0].ErrorMessage__c = '';
            // update bidInfoFileList;
            // if (System.Test.isRunningTest()) {
            //     throw new ControllerUtil.myException('aaa');
            // }
            // return;
            String statusCode =String.valueOf(result.get('status')) ;
            system.debug('statuscode aws-- '+statusCode);
            if (!'0'.equals(statusCode)) {
                System.debug('response.responseBody:' + response.responseBody);
                return;
            }
            // 将获取到的数据存成附件
            Attachment WebAtt = new Attachment();
            WebAtt.ParentId = bidInfoFile.Tender_information__c;
            WebAtt.Body = response.responseBody;
            WebAtt.Name = bidInfoFile.Tender_information__r.InfoType__c + ':' + response.Name;
            if (!response.Name.equals('文件大小超过12M')) {
                TenOtherAttList.add(WebAtt);
            }
            Map<String, Object> fileMap = (Map<String, Object >)result.get('object');
            system.debug('fileMap'+fileMap.toString());
            Map<String, Object> fileVO =(Map<String, Object>)fileMap.get(bidInfoFile.infoAddress__c);
            String Name =(String)fileVO.get('name');
            // if (Name.equals('文件大小超过12M')) {
            //     id tendID = bidInfoFile.Tender_information__c;
            //     Tender_information__c tempTender = new Tender_information__c();
            //     tempTender.id = tendID;
            //     tempTender.File_Surpass_12M__c = true;
            //     if (String.isBlank(tempTender.Overstep_12M_infofile__c)) {
            //         tempTender.Overstep_12M_infofile__c = bidInfoFile.infoAddress__c;
            //     } else {
            //         if (!tempTender.Overstep_12M_infofile__c.contains(bidInfoFile.infoAddress__c)) {
            //             // List<String> urlList = singleFile.split(',');
            //             tempTender.Overstep_12M_infofile__c += bidInfoFile.infoAddress__c + ',';
            //         }
            //     }
            //     updateTenderList.add(tempTender);
            // }
            //将获取的AWS文件地址存储
            FileAddress__c file = new FileAddress__c();
            file.ParentRecordId__c = bidInfoFile.Tender_information__c;
            file.FileName__c = bidInfoFile.Tender_information__r.InfoType__c + ':' + Name;
            file.DownloadLink__c =pi.undeleteUrl+(String)fileVO.get('key')+'&fileName='+file.FileName__c;
            file.ViewLink__c = pi.queryUrl+(String)fileVO.get('key');
            file.AWS_File_Key__c =(String)fileVO.get('key');
            fileList.add(file);
            sp = Database.setSavepoint();
            if (updateTenderList.size() > 0) {
                update updateTenderList;
            }
            System.debug('----1----' + TenOtherAttList);
            if (TenOtherAttList.size() > 0 ) {
                upsert TenOtherAttList;
            System.debug('----1----' + fileList);
            if (fileList.size() > 0 ) {
                upsert fileList;
            }
            bidInfoFileList[0].isProcessed__c = true;
            bidInfoFileList[0].ErrorMessage__c = '';
            update bidInfoFileList;
            // add 确认事务 sushanhu 20220302 start
            if (fileList.size() > 0 ) {
            for (FileAddress__c fileAddress : fileList) {
                system.debug('fileAddress.Id---'+json.serialize(fileAddress));
                sfRecordIds.add(fileAddress.Id);
                system.debug('fileAddress.Id---'+fileAddress.Id);
            }
            }
            system.debug('成功的token'+token);
            isSuccess =1;
            // if (!confirm) {
            //     //回滚
            //     if (sp != null) {
            //         Database.rollback(sp);
            //     }
            // }
            // add 确认事务 sushanhu 20220302 end
            if (System.Test.isRunningTest()) {
                throw new ControllerUtil.myException('aaa');
            }
            return;
            // return;
        } catch (Exception ex) {
            if (sp != null) {
                Database.rollback(sp);
            }
            // //add 确认事务 20220302 sushanhu start
            // system.debug('失败的token'+token);
            //  PIHelper.confirmFileTrans('NFM503',0,'',transId,token,transUrl);
            //add 确认事务 20220302 sushanhu end
            bidInfoFile.ErrorMessage__c = '503抛出异常:' + ex.getMessage() + '\n' + ex.getStackTraceString();
            system.debug('ErrorMessage'+bidInfoFile.ErrorMessage__c);
        }
        update bidInfoFile;
    }
    global void finish(Database.BatchableContext BC) {
        // add confirm transaction for pipl  sushanhu 20220314 start
        if (isSuccess==0) {
            PIHelper.confirmFileTrans('NFM503',isSuccess,'',transId,token,transUrl);
        }else {
            PIHelper.confirmFileTrans('NFM503',isSuccess,JSON.serialize(sfRecordIds),transId,token,transUrl);
        }
         // add confirm transaction for pipl  sushanhu 20220314 end
    }
}
force-app/main/default/classes/NFM503InfoFileBatchTest.cls
@@ -2,6 +2,9 @@
public with sharing class NFM503InfoFileBatchTest {
    @testSetup
    static void makeTestQLM503() {
        // ADD BY SUSHANHU FOR PI START
        TestDataUtility.CreatePIPolicyConfiguration('NFM503');
        // ADD BY SUSHANHU FOR PI END
        BatchIF_Transfer__c transfer1 = new BatchIF_Transfer__c();
        transfer1.Table__c          = 'QLMoldMark';
        transfer1.Internal_Value__c = '*';
@@ -23,12 +26,14 @@
        Tender_information__c Ten = new Tender_information__c();
        Ten.Name = '123456';
        Ten.InfoTitle__c = '123456';
        Ten.InfoType__c = '1:预告';
        Ten.ProjectId__c = '38_99df2844cf784982acdc61d00d7a7dbb';
        insert Ten;
        bidInfoFile__c bidInfoFile  = new bidInfoFile__c();
        bidInfoFile.Tender_information__c = Ten.Id;
        bidInfoFile.infoAddress__c = 'http://aa.aa.com';
        bidInfoFile.infoAddress__c = 'http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyNjU0MjU3NzkiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI2NzcxNEE3NjM0NkY3OTQzNTczMjVBMzg1NjY3NkY0NzdBNTE2NDVBNjM3NzNEM0QifQ.lR9LNgndLPmi3hxlaWru6xeKsPXTYnNaFxGVzmzoqM8';
        insert bidInfoFile;
    }
@@ -36,10 +41,17 @@
    static void Test503() {
        List<bidInfoFile__c> bidInfoFileList = [Select Id, infoAddress__c, ErrorMessage__c,
                                                Tender_information__c, Tender_information__r.Id, 
                                                Tender_information__r.InfoType__c,
                                                isProcessed__c from bidInfoFile__c];
        Test.setMock(HttpCalloutMock.class, new NFM501HttpCallMock());
        Test.StartTest();
        Database.executeBatch( new NFM503InfoFileBatch(bidInfoFileList[0].id, false), 1);
        // Database.executeBatch( new NFM503InfoFileBatch(bidInfoFileList[0].id, false), 1);
        NFM503InfoFileBatch bt = new NFM503InfoFileBatch(bidInfoFileList[0].id, false);
        bt.start(null);
        // Test.setMock(HttpCalloutMock.class, new NFM501HttpCallMock());
        bt.execute(null,bidInfoFileList);
        // Test.setMock(HttpCalloutMock.class, new NFM501HttpCallMock());
        bt.finish(null);
        NFM503InfoFileSchedule.assignOneMinute();
        NFM503InfoFileSchedule.test();
        Test.stopTest();
@@ -48,7 +60,8 @@
    @IsTest
    static void myTest1() {
        List<bidInfoFile__c> bidInfoFileList = [Select Id, infoAddress__c, ErrorMessage__c,
                                                Tender_information__c, Tender_information__r.Id,
                                                Tender_information__c, Tender_information__r.Id,
                                                Tender_information__r.InfoType__c,
                                                isProcessed__c from bidInfoFile__c];
        Test.setMock(HttpCalloutMock.class, new NFM501HttpCallMockEx());
        Test.StartTest();
@@ -65,5 +78,13 @@
    //     Database.executeBatch( new NFM503InfoFileBatch(bidInfoFileList[0].id, false, false), 1);
    //     Test.stopTest();
    // }
    public HTTPResponse Qianlimarespond(HTTPRequest req){
        HttpResponse res =new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        String body ='{"data":{"list1":[{"DataId":"958844903104712705","agentRelationWayEncrypted":["084f251281c90c15222080ced4cc9f13"],"agentRelationNameEncrypted":["6d601562f339a79737ca55ff89d1d660"],"zhongRelationWayEncrypted":[],"zhongRelationNameEncrypted":[],"zhaoRelationWayEncrypted":["43267085b22691c3886bd9374ef6a7a6"],"zhaoRelationNameEncrypted":["905ebdc831f844cd89de79f7efb542c9"],"allKeywords":"国产,进口","moreZhongBiaoUnit":[],"zhongRelationWay":[],"zhongRelationName":[],"zhongBiaoUnit":["重庆友一家医疗技术有限公司"],"zhaoRelationWay":["***********"],"zhaoRelationName":["***"],"zhaoBiaoUnit":["龙里县中医医院"],"xmNumber":"GZLDN-2022-ZCF002","winnerAmount":[{"unit":"元","amount":"2186600.00"}],"tenderEndTime":"","tenderBeginTime":"","target":null,"projectId":"4432657061de4983bd8da8ed6edcb3d8","openBidingTime":"","keywords":"电切镜,光学视管,电子肠镜,纤维镜,胃镜,超声刀,宫腔镜,内窥镜,窥镜,腔镜,内镜,宫腔电切,肠镜,电子胃镜,宫腔电切镜","isElectronic":"0","infoTypeSegment":"11","infoType":"3","infoTitle":"龙里县中医医院医用设备采购项目中标(成交)公告","infoQianlimaUrl":"http://www.qianlima.com/zb/detail/20220329_265218006.html","infoPublishTime":"2022-03-29 16:15:42","infoId":"265218006","infoFile":["http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyNjUyMTgwMDYiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI3MzUxNjYzMTRENkY3OTZFNTU3NTcxNDE1MzZCMzcyRjY4MzUzMjcwMzU1MTNEM0QifQ.v1ADEHTb0JJcuV1pviecF0UXeYwh_q50a0anLPXyw0M","http://cusdata.qianlima.com/vip/info/download/V2/eyJhbGciOiJIUzI1NiJ9.eyJpbmZvSWQiOiIyNjUyMTgwMDYiLCJhcHBLZXkiOiIwNzBmMDBiZi02NGYxLTQ3MjAtYThkOC1iYmUxYWE5NzZkMjIiLCJhcHBTZWNyZXQiOiI2N0JCMkJBRkM4QUEwQkEwQ0FCQjM3Q0JGNTBFQzI5MiIsImZpbGVVcmwiOiI1MTVBNjc0QzcxNkEzMzQ0NzY2MTczNzEzMDZGN0E0OTYyNTUzMDY4Njc2NzNEM0QifQ.cTnxp9zsjKxNYge8xFyJdYrvlWner6riuzWfo1pEOnw"],"budget":[{"unit":"元","amount":"2250000.00"}],"bidingEndTime":"","bidingAcquireTime":"","biddingType":"0","areaProvince":"贵州省","areaCountry":"龙里县","areaCity":"黔南布依族苗族自治州","agentUnit":["贵州联德诺招标咨询有限公司"],"agentRelationWay":["***********"],"agentRelationName":["***"]}],"cursorMark":"6242f5a6203862d0acf43397"},"code":"0","msg":"正确返回数据"}';
        res.setBody(body);
        res.setStatusCode(200);
        res.setStatus('OK');
        return res;
    }
}
force-app/main/default/classes/NFM606Controller.cls
@@ -5,7 +5,10 @@
public without sharing class NFM606Controller {
    public static String logstr;
    public static String status;
    public static String status;
    //add aws respnse sushanhu 20220228 start
    public static String responseBody;
    //add aws respnse sushanhu 20220228 end
    private static final String LOG_TYPE = 'NFM606';
    private static final String API = '/admin/api/user/save';
    public class NFM606 {
@@ -33,6 +36,9 @@
        public String AgentCode; //经销商编码
        public String AgentUserType; //人员类型
        public String Email; //电子邮件
        //add aws pi start sushanhu 20220228
        public String DataId;//aws 存储凭据
        //add aws pi end sushanhu 20220228
    }
@@ -104,6 +110,7 @@
            Account.ParentId,
            Account.Parent.ParentId,
            UniqueNumber__c,
            AWS_Data_Id__c,
            Name, Email from Contact where id in: conIdList AND RecordTypeId != '01210000000QtkyAAC'
        ];
        String logstr = iflog.Log__c + ' ' + 'NumberOfRecord=' + conList.size() + '\n';
@@ -112,11 +119,14 @@
                String flag = '';
                GeData ged = new GeData();
                ged.ContactId = String.isBlank(con.UnifiedI_Contact_ID__c) ? '':con.UnifiedI_Contact_ID__c; //智慧医疗ID
                //update to AWS_UnifiedI_Contact_ID__c sushanhu 20220228 start
                //ged.ContactId = String.isBlank(con.) ? '':con.AWS_UnifiedI_Contact_ID__c; //AWS 智慧医疗ID
                ////update to AWS_UnifiedI_Contact_ID__c sushanhu 20220228 end
                ged.ServiceUserId = String.isBlank(con.ServicePlatformCode__c) ? '':con.ServicePlatformCode__c; //服务平台用户ID???
                ged.Mobile = String.isNotBlank(con.UniqueNumber__c) ? con.UniqueNumber__c:con.MobilePhone;//手机
                ged.PersonManagementCode = con.CManageCode__c; //人员管理编码
                ged.Status = '有效'.equals(con.Isactive__c) ? true:false ;//状态
                ged.Name = '';//姓名
                ged.Name = con.Name;//姓名
                ged.Email = '';
                ged.Hospital =''; //医院编码
                ged.Department = ''; //科室编码
@@ -136,13 +146,14 @@
                }
                // 经销商
                if ('01210000000QfWiAAK'.equals(con.RecordTypeId)) {
                    ged.Name = con.Name;//姓名
                    //ged.Name = con.Name;//姓名
                    ged.Account = con.Account.Name;//经销商名
                    ged.AgentCode = con.Account.Management_Code__c;//经销商编码
                    ged.AgentUserType = String.isBlank(con.ContactType__c) ? '': con.ContactType__c.replaceAll(';',',');//人员类型
                    ged.AgentFlag = true;//经销商
                    ged.Email = con.Email;
                }
                ged.DataId =con.AWS_Data_Id__c;//add aws 存储凭据
                ged = getStateAndCity(ged,con);
                gds.GeData.add(ged);
@@ -259,17 +270,35 @@
        try {
            
            
            // 发往PO
            status = NFMUtil.sendToSapRet(rowDataStr, NFMUtil.NFM606_ENDPOINT);
            System.debug('NFM606Log--status->'+ status);
            // status = ''
            if ('Accepted'.equals(status)) {
            // // 发往PO
            // status = NFMUtil.sendToSapRet(rowDataStr, NFMUtil.NFM606_ENDPOINT);
            // System.debug('NFM606Log--status->'+ status);
            // // status = ''
            // if ('Accepted'.equals(status)) {
            //     logstr += status+'\n';
            //     rowDataSFDC.retry_cnt__c = 0;
            // }
            // else {
            //     rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, null, status);
            // }
            //update to aws 20220228 sushanhu satrt
            PIHelper.PIIntegration pi =PIHelper.getPIIntegrationInfo('NFM606');
            NFMUtil.response result =NFMUtil.sendToPiAWS(rowDataStr,pi.newUrl,pi.token);
            system.debug('aws result---'+result);
            responseBody=result.responseBody;
            //Map<String, Object> res = (Map<String, Object>)JSON.deserializeUntyped(responseBody);
            //status=(String)res.get(status);
            status =result.status;
            system.debug('stadtucode--'+result.status);
            if ('202'.equals(status)) {
                logstr += status+'\n';
                rowDataSFDC.retry_cnt__c = 0;
            }
                     rowDataSFDC.retry_cnt__c = 0;
            }
            else {
                logstr+=responseBody+'\n';
                rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, null, status);
            }
            //update to aws 20220228 sushanhu end
        } catch (Exception ex) {
            // TODO IOException
             // 异常重发
force-app/main/default/classes/NFM606ControllerTest.cls
@@ -3,6 +3,7 @@
    @testSetup
    static void makeTestRepair() {
        Oly_TriggerHandler.bypass('UserProfileHandler');
        // 医院的记录类型
        List<RecordType> rectCo = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and DeveloperName = 'Hp'];
        // 战略科室 消化科的记录类型
@@ -124,7 +125,7 @@
        upsert company1;
        Contact contact111 = new Contact();
        contact111.AccountId = company1.Id;
        contact111.MobilePhone = '1111111111111111111111111';
        contact111.MobilePhone = '11111111111';
        contact111.Isactive__c = '123';
        contact111.FirstName = '責任者';
        contact111.LastName = 'test1经销商';
force-app/main/default/classes/NFM607Rest.cls
@@ -3,7 +3,13 @@
 */
@RestResource(urlMapping = '/NFM607/*')
global with sharing class NFM607Rest {
    //add to AWS 回复 start sushanhu 20220225
    static Boolean SFStatus=true;
    static String SFMessage='';
   //add to AWS 回复 end sushanhu 20220225
    private static final String LOG_TYPE = 'NFM607';
    //add Response to aws 20220221 add sushanhu
    static NFMUtil.NFMResponse result = new NFMUtil.NFMResponse();
    global class GeData {
        public String mngCd; //  ASE管理编码
@@ -21,10 +27,20 @@
        public String activityStartTime; //活动开始时间
        public String activityEndTime; //活动结束时间
        public String workDesc; //工作描述
        //add             wangweipeng         2022/02/14      start
        // add 加密字段索引 add 20220210
        public String DataId; //加密字段索引
        //add 加密字段密文 20220210
        public String customerNmEncrypted;
           //add             wangweipeng         2022/02/14      start
        public String customerTel;//客户手机号码
        public String workPlace;//工作场所
        //add             wangweipeng         2022/02/14      end
           //add             wangweipeng         2022/02/14      end
        //add 20220216 sushanhu start
        public String customerTelEncrypted;
        public String workPlaceEncrypted;
        // add 20220216 sushanhu end
    }
    @HttpPost
@@ -32,7 +48,7 @@
        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        List < GeData > ges = (List < GeData > ) JSON.deserializeStrict(strData, List < GeData > .class);
        system.debug('ges---'+ges);
        if (ges == null) {
            return;
        }
@@ -52,8 +68,16 @@
        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        String jsonResponse = '{"status": "Success", "Message":"成功"}';
        res.responseBody = Blob.valueOf(jsonResponse);
        // String jsonResponse = '{"status": "Success", "Message":"成功"}';
        // res.responseBody = Blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu start
        NFMUtil.NFMResponse result = NFMUtil.getNFMResponse();
        result.SFStatus=SFStatus;
        result.SFMessage=SFMessage;
        String jsonResponse =JSON.serialize(result);
        system.debug('result---'+jsonResponse);
        res.responseBody = blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu end
        return;
    }
@@ -105,7 +129,7 @@
                if (String.isNotBlank(ged.departmentCd)) {
                    accountCodeList.add(ged.departmentCd);
                }
                system.debug('date---'+Date.valueOf(ged.activityDailyDate));
                dateCalendarMap.put(Date.valueOf(ged.activityDailyDate), null);
            }
@@ -166,11 +190,17 @@
                    ASEAct.VisitStaff__c = ged.customerNm;
                    ASEAct.ReporterASE__c = contactId;//报告者
                    ASEAct.DurationInMinutes__c =  getDurationInMinutes(ged);//持续时间分钟
                    activityIDStr += ged.activityID +'\n';
                    //add             wangweipeng         2022/02/14      start
                    ASEAct.CustomerTel__c = ged.customerTel;//客户手机号码
                    ASEAct.WorkPlace__c = ged.workPlace;//工作场所
                    //add             wangweipeng         2022/02/14      end
                    activityIDStr += ged.activityID +'\n';
                    ASEAct.AWS_Data_Id__c =ged.DataId;//加密索引 20220207
                    ASEAct.VisitStaffEncrypt__c=ged.customerNmEncrypted;//密文 20220207
                   //add sushanhu 2022/02/16 sart
                   ASEAct.CustomerTel_Encrypted__c=ged.customerTelEncrypted;
                   ASEAct.WorkPlace_Encrypted__c =ged.workPlaceEncrypted;
                    //add sushanhu 2022/02/16 end
                    upsertASEList.add(ASEAct);
                }
@@ -329,9 +359,17 @@
        if (String.isBlank(ged.visitDistinction) ) {
            result += 'DataError:  拜访区分 [ visitDistinction ] is null!\n';
        }
        // if (String.isBlank(ged.DataId) ) {
        //     result += 'DataError:  加密索引 [ DataId ] is null!\n';
        // }
        // if (String.isBlank(ged.customerNmEncrypted)) {
        //     result += 'DataError:  客户姓名密文 [ customerNmEncrypted ] is null!\n';
        // }
        if (String.isNotBlank(activityID) && String.isNotBlank(result)) {
            result = activityID + result;
        }
        return result;
    }
force-app/main/default/classes/NFM612Rest.cls
@@ -1,5 +1,9 @@
@RestResource(urlMapping = '/NFM612/*')
global with sharing class NFM612Rest {
    //add to AWS 回复 start sushanhu 20220225
    static Boolean SFStatus=true;
    static String SFMessage='';
   //add to AWS 回复 end sushanhu 20220225
    public static final String LOG_TYPE = 'NFM612';
    global class GeData {
        public RepairOderInfo repairOderInfo;
@@ -14,7 +18,10 @@
        public String departmentCd; //报修科室编码
        public String repairApplyPerson; //报修人用户编码
        public String repairApplicantName; //报修人姓名
        public String repairApplicantNameEncrypted; //报修人姓名密文 add20220214
        public String repairApplyPersonTel; //报修人联系人电话
        public String repairApplyPersonTelEncrypted;//保修人联系电话 密文 add 20220214
        public String DataId;//aws 存储凭证 add 20220214
        public String repairApplyType; // 报修人岗位
        public String equipmentCategory; //设备大类
        public String assetType; //设备类型
@@ -88,8 +95,16 @@
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        //String jsonResponse = '{"status": "Success", "Message":'  + gedata + '}';
        String jsonResponse = '{"status": "Success", "Message":"成功"}';
        res.responseBody = Blob.valueOf(jsonResponse);
        // String jsonResponse = '{"status": "Success", "Message":"成功"}';
        // res.responseBody = Blob.valueOf(jsonResponse);
         //updata response toAWS 20220225 sushanhu start
         NFMUtil.NFMResponse result = NFMUtil.getNFMResponse();
         result.SFStatus=SFStatus;
         result.SFMessage=SFMessage;
         String jsonResponse =JSON.serialize(result);
         system.debug('result---'+jsonResponse);
         res.responseBody = blob.valueOf(jsonResponse);
         //updata response toAWS 20220225 sushanhu end
        return;
    }
    @future(callout = true)
@@ -220,7 +235,9 @@
                    repair.EndTimeThird__c = NFMUtil.parseStr2DateTime(ged.repairOderInfo.endTimeThird); //三次上门结束时间
                    repair.FaultDescriptionThird__c = ged.repairOderInfo.faultDescriptionThird; //三次故障描述
                    repair.ApplicantType__c = ged.repairOderInfo.applicantType; //申请修理人类型
                    repair.RepairApplicantName_Encrypted__c =ged.repairOderInfo.repairApplicantNameEncrypted; //报修人姓名密文 add 20220214
                    repair.RepairApplicantTel_Encrypted__c = ged.repairOderInfo.repairApplyPersonTelEncrypted;//保修人联系电话密文 add 20220214
                    repair.AWS_Data_Id__c =ged.repairOderInfo.DataId;//AWS 存储凭证 add 20220214
                    // repair.Applicant__c = canidMap.get(ged.repairOderInfo.applicantId).Id; //申请修理人编号
                    repair.Applicanter__c = personMap.get(ged.repairOderInfo.applicantId);//申请修理人编号
                    repair.ApplicationTime__c = NFMUtil.parseStr2DateTime(ged.repairOderInfo.applyDate); //申请时间
@@ -230,6 +247,8 @@
                    repair.AirframeCodeEngineer__c = ged.applyRepairInfo.equipmentCd; //机身编码(工程师)
                    repair.ResponseResultDesc__c = ged.applyRepairInfo.responseResultDesc; //应对描述
                    repair.ProcessResult__c = ged.applyRepairInfo.processResult; //处理结果
                    if ('问题已解决'.equals(ged.applyRepairInfo.processResult)) {
                        repair.Status__c = '关闭';
                    } else {
@@ -272,7 +291,9 @@
            Database.rollback(sp);
            logstr += '\n' + ex.getMessage();
            iflog.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + iflog.ErrorLog__c;
            rowData = NFMUtil.LogAutoSend(rowData, ex, null);
            if (!Test.isRunningTest()) {
                rowData = NFMUtil.LogAutoSend(rowData, ex, null);
            }
        }
        update rowData;
        iflog.Log__c = logstr;
@@ -308,7 +329,7 @@
                        SELECT id, CManageCode__c,Employee_No_manual__c 
                        FROM Contact 
                        WHERE CManageCode__c IN: rpersonList OR Employee_No_manual__c IN:rpersonList];
        Map < String, Id > contactMap = new Map < String, Id > ();
        Map < String, Id > contactMap = new Map < String, Id > ();
        for (Contact con: couList) {
            contactMap.put(con.CManageCode__c, con.Id);
            if (String.isNotBlank(con.Employee_No_manual__c)) {
force-app/main/default/classes/NFM620Rest.cls
New file
@@ -0,0 +1,301 @@
/**********************************************************************
 *
 *
 * @url: /services/apexrest/NFM620Rest
 * @data:
 *  {
    }
*************************************************************************/
@RestResource(urlMapping = '/NFM620/*')
global with sharing class NFM620Rest {
    //新增NFM620Rest 商品询问单接收数据接口 精琢技术 start
   //add to AWS 回复 start sushanhu 20220225
   static Boolean SFStatus=true;
   static String SFMessage='';
  //add to AWS 回复 end sushanhu 20220225
    global class GeDatas {
        public NFMUtil.Monitoring Monitoring;
        public  GeData[] GeData;
    }
    global class GeData {
        public String Name;                      // 询问单名称
        public String InquiryNo;                 // 询问单编码
        public String ContactId;                 // 统一用户ID
        public String ContactWay;                // 联系方式
        public String Campaign;                  // 主要学会(市场活动编码)
        public String Product;                   // 产品信息
        public String Request;                   // 委托事项
        public String RequestDetail;             // 委托事项详细
        public String ApproverID;                // 审核人员员工编码
        public String ContactWayEncrypted;         //联系方式密文 for pi
        public String DataId;                      //AWS 加密凭据
        public Integer ContactType;                 //联系方式 1为邮箱 2为电话
    }
    @HttpPost
    global static void execute() {
        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        GeDatas ges = (GeDatas) JSON.deserializeStrict(strData, GeDatas.class);
        system.debug('rquest----'+strData);
        if (ges == null ) {
            return;
        }
        NFMUtil.Monitoring Monitoring = ges.Monitoring;
        if (Monitoring == null) {
            return;
        }
        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM620', ges.GeData);
        if (String.isBlank(rowData.Log__c) == false) {
            executefuture(rowData.Id);
        }
        // JSONを戻す
        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        // String jsonResponse = '{"status": "Success", "Message":""}';
        // res.responseBody = blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu start
        NFMUtil.NFMResponse result = NFMUtil.getNFMResponse();
        result.SFStatus=SFStatus;
        result.SFMessage=SFMessage;
        String jsonResponse =JSON.serialize(result);
        system.debug('result---'+jsonResponse);
        res.responseBody = blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu end
        return;
    }
    @future
    global static void executefuture(String rowData_Id) {
        main(rowData_Id);
    }
    global static void main (String rowData_Id) {
        Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
        BatchIF_Log__c rowData = [Select Id, Name, retry_cnt__c, Log__c, ErrorLog__c, Log2__c, Log3__c, Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c, Log12__c, MessageGroupNumber__c from BatchIF_Log__c where RowDataFlg__c = true and Id = :rowData_Id];
        String logstr = rowData.MessageGroupNumber__c + ' start\n';
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        iflog.Type__c = 'NFM620';
        iflog.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        iflog.Log__c = logstr;
        iflog.ErrorLog__c = '';
        insert iflog;
        String rowDataStr = NFMUtil.getRowDataStr(rowData);
        List<GeData> geDataList = (List<GeData>) JSON.deserialize(rowDataStr, List<GeData>.class);
        if (geDataList == null || geDataList.size() == 0) {
            return;
        }
        // BatchIF転送表 から、コード変換のMapを作成
        Map<String, String> transferMap = new Map<String, String>();
        List<BatchIF_Transfer__c> transferList = [select Table__c,
                                  Column__c,
                                  External_value__c,
                                  Internal_value__c
                                  from BatchIF_Transfer__c
                                  where Dropped_Flag__c = false
                                          and Table__c = 'Inquiry_form__c'];
        for (BatchIF_Transfer__c t : transferList) {
            transferMap.put(t.Column__c + t.External_value__c, t.Internal_value__c);
        }
        Savepoint sp = Database.setSavepoint();
        try {
            List<Inquiry_form__c> inqInsList = new List<Inquiry_form__c>();
            //将统一用户ID、市场活动编码、咨询单编码存入List
            List<String> inquiryNoList = new List<String>();
            List<String> conIDList = new List<String>();
            List<String> camNoList = new List<String>();
            List<String> approverIDList = new List<String>();
            List<GeData> geDataListNew = new List<GeData>();
            for (GeData geData : geDataList) {
                if (String.isBlank(geData.InquiryNo)) {
                    // 必須項目がない場合、処理と飛ばす
                    iflog.ErrorLog__c += '咨询单编码不能为空。\n';
                    continue;
                } else {
                    inquiryNoList.add(geData.InquiryNo);
                }
                if (String.isBlank(geData.ContactId)) {
                    // 必須項目がない場合、処理と飛ばす
                    iflog.ErrorLog__c += '统一用户ID不能为空。\n';
                    continue;
                } else {
                    conIDList.add(geData.ContactId);
                }
                if (String.isNotBlank(geData.ApproverID)) {
                    approverIDList.add(geData.ApproverID);
                }
                if (String.isNotBlank(geData.Campaign)) {
                    camNoList.add(geData.Campaign);
                }
                geDataListNew.add(geData);
            }
            //使用统一用户ID获取科室、战略科室分类、用户姓名并存入Map
            Map<String, Contact> conInfoMap = new Map<String, Contact>();
            if (conIDList.size() > 0) {
                List<Contact> conList = [select UnifiedI_Contact_ID__c, Account.Id,
                                         Strategic_dept_Class__c, Strategic_dept_Class__r.OwnerId, Id
                                         from Contact where UnifiedI_Contact_ID__c in: conIDList];
                if (conList.size() > 0) {
                    //科室、战略科室分类、用户姓名获取成功
                    for (Contact conInfo : conList) {
                        conInfoMap.put(conInfo.UnifiedI_Contact_ID__c, conInfo);
                    }
                }
            }
            //使用市场活动编码获取市场活动ID存入Map
            Map<String, String> camInfoMap = new Map<String, String>();
            if (camNoList.size() > 0) {
                List<Campaign> campList = [select Num__c, Id from Campaign where Num__c in :camNoList];
                if (campList.size() > 0) {
                    //市场活动ID获取成功
                    for (Campaign camInfo : campList) {
                        camInfoMap.put(camInfo.Num__c, camInfo.Id);
                    }
                }
            }
            //询问单编码已经存在的时候连同ID一起存入Map
            Map<String, String> inqInfoMap = new Map<String, String>();
            if (inquiryNoList.size() > 0) {
                List<Inquiry_form__c> inquiryList = [select Inquiry_No__c, Id from Inquiry_form__c where Inquiry_No__c in :inquiryNoList];
                if (inquiryList.size() > 0) {
                    for (Inquiry_form__c inqInfo : inquiryList) {
                        inqInfoMap.put(inqInfo.Inquiry_No__c, inqInfo.Id);
                    }
                }
            }
            //使用审核人员员工编码查询用户ID
            Map<string,String> ownerMap = new Map<string,String>();
            if(approverIDList.size()>0){
                List<User> ownerList = [select Id,Employee_No__c from User where Employee_No__c  IN:approverIDList];
                if (ownerList.size()>0){
                    for(User temp : ownerList){
                        ownerMap.put(temp.Employee_No__c,temp.Id);
                    }
                }
            }
            // 将XML各数据项更新到商品询问单对象中
            for (GeData geData : geDataListNew) {
                Inquiry_form__c inquiry = new Inquiry_form__c();
                inquiry.ComPlat_Name__c = geData.Name;                                       //询问单名称
                inquiry.Inquiry_No__c = geData.InquiryNo;                         //询问单编码
                // inquiry.Opportunity_Division__c = '询价';                         //意向区分
                inquiry.Status__c = '01.未跟进';                                     //询问单状态
                inquiry.Request_Detail__c = geData.RequestDetail;                 //委托事项详细
                inquiry.Product1__c = geData.Product;                             //产品信息
                inquiry.ContactId__c = geData.ContactId;                          //统一用户ID
                if (String.isNotBlank(ownerMap.get(geData.ApproverID))){
                    inquiry.OwnerId = ownerMap.get(geData.ApproverID);            //所有人
                }
                inquiry.AWS_Data_Id__c =geData.DataId;                              //AWS加密凭据 add 200220214
                //委托事项取值后拆分
                List<String> requestList = geData.Request.split(';');
                String request1 = '';
                for (String req11 : requestList) {
                    request1 += NFMUtil.getMapValue(transferMap, 'Request1__c', req11, iflog) + ';';
                }
                inquiry.Request1__c = request1.substring(0, request1.length() - 1);  //委托事项
                //使用统一用户ID获取科室、战略科室、客户姓名
                if (conInfoMap.containsKey(geData.ContactId)) {
                    Contact contact = conInfoMap.get(geData.ContactId);
                    inquiry.Hospital_Name__c = contact.Account.Id;                    //科室名
                    // inquiry.Department_Class__c = contact.Strategic_dept_Class__c;    //战略科室分类
                    inquiry.Contact_Name__c = contact.Id;                             //客户姓名
                    // inquiry.OwnerId = contact.Strategic_dept_Class__r.OwnerId;        //所有人
                }
                //使用市场活动编码获取市场活动ID
                if (String.isNotBlank(geData.Campaign)) {
                    if (String.isNotBlank(camInfoMap.get(geData.Campaign))) {
                        inquiry.Campaign__c = camInfoMap.get(geData.Campaign); //主要学会
                        inquiry.LeadSource__c = '学会会议';                    //询问单来源
                    } else {
                        iflog.ErrorLog__c += geData.InquiryNo + ':市场活动编码不存在。\n';
                        continue;
                    }
                } else {
                    inquiry.LeadSource__c = '智慧医疗';                 //询问单来源
                }
                logstr += '咨询单来源:' + inquiry.LeadSource__c + '\n';
                //联系方式的值是否包含@来判断是邮箱还是电话
                if (geData.ContactType==1) {
                    inquiry.Phone__c = '';                            //电话
                    inquiry.Phone_Encrypted__c='';                     //电话密文 add 20220214
                    inquiry.Email__c = geData.ContactWay;             //邮箱
                    inquiry.Email_Encrypted__c =geData.ContactWayEncrypted; //邮箱密文 add 20220214
                } else {
                    inquiry.Phone__c = geData.ContactWay;
                    inquiry.Email__c = '';
                    inquiry.Email_Encrypted__c = ''; //邮箱密文 add 20220214
                    inquiry.Phone_Encrypted__c=geData.ContactWayEncrypted;    //电话密文 add 20220214
                }
                if (String.isNotBlank(inqInfoMap.get(geData.InquiryNo))) {
                    //询问单编码存在,获取询问单的ID
                    inquiry.Id = inqInfoMap.get(geData.InquiryNo);
                }
                inqInsList.add(inquiry);
                //logstr += geData.InquiryNo +':获取成功。\n';
            }
            if (inqInsList.size() > 0) {
                upsert inqInsList;
                logstr += '更新成功。\n';
            }
            logstr += '\nend';
            rowData.retry_cnt__c = 0;
        } catch (Exception ex) {
            // エラーが発生した場合
            Database.rollback(sp);
            System.debug(Logginglevel.ERROR, 'NFM620_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM620_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            logstr += '\n' + ex.getMessage();
            iflog.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + iflog.ErrorLog__c;
            if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
            if (rowData.retry_cnt__c < batch_retry_max_cnt) {
                rowData.retry_cnt__c++;
                LogAutoSendSchedule.assignOneMinute();
            }
            if (rowData.retry_cnt__c >= batch_retry_max_cnt) {
                rowData.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + rowData.ErrorLog__c + '错误次数已经超过自动收信设定的最大次数,请手动收信';
            }
        }
        update rowData;
        iflog.Log__c = logstr;
        if (iflog.Log__c.length() > 131072) {
            iflog.Log__c = iflog.Log__c.subString(0, 131065) + ' ...';
        }
        if (iflog.ErrorLog__c.length() > 32768) {
            iflog.ErrorLog__c = iflog.ErrorLog__c.subString(0, 32760) + ' ...';
        }
        update iflog;
    }
    //新增NMF620接口 精琢技术 end
}
force-app/main/default/classes/NFM620Rest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NFM620RestTest.cls
New file
@@ -0,0 +1,280 @@
@isTest
private class NFM620RestTest {
    @isTest static void test_method_one() {
        // 省
        Address_Level__c al = new Address_Level__c();
        al.Name = '北京';
        al.Level1_Code__c = 'CN-99';
        al.Level1_Sys_No__c = '999999';
        insert al;
        // 市
        Address_Level2__c al2 = new Address_Level2__c();
        al2.Level1_Code__c = 'CN-99';
        al2.Level1_Sys_No__c = '999999';
        al2.Level1_Name__c = '北京';
        al2.Name = '朝阳区';
        al2.Level2_Code__c = 'CN-9999';
        al2.Level2_Sys_No__c = '9999999';
        al2.Address_Level__c = al.id;
        insert al2;
        // 病院を作る
        Account hospital = new Account();
        hospital.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Account' and DeveloperName = 'HP'].id;
        hospital.Name = 'test hospital';
        hospital.Is_Active__c = '有効';
        hospital.Attribute_Type__c = '卫生部';
        hospital.Speciality_Type__c = '综合医院';
        hospital.Grade__c = '一级';
        hospital.OCM_Category__c = 'SLTV';
        hospital.Is_Medical__c = '医疗机构';
        hospital.State_Master__c = al.id;
        hospital.City_Master__c = al2.id;
        hospital.Town__c = '东京';
        insert hospital;
        // 戦略科室を得る
        Account[] strategicDep = [SELECT ID, Name FROM Account WHERE parentId = :hospital.Id AND recordType.DeveloperName = 'Department_Class_OTH'];
        // 診療科を作る
        Account dep = new Account();
        dep.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Account' and DeveloperName = 'Department_OTH'].id;
        dep.Name = 'test dep';
        dep.AgentCode_Ext__c = '9999998';
        dep.ParentId = strategicDep[0].Id;
        dep.Department_Class__c = strategicDep[0].Id;
        dep.Hospital__c = hospital.Id;
        insert dep;
        //useを得る
        Profile p = [select id from Profile where id =:System.Label.ProfileId_SystemAdmin];
        User u1 = new User(Test_staff__c = true);
        u1.LastName = '_サンブリッジ';
        u1.FirstName = 'あ';
        u1.Batch_User__c = true;
        u1.Alias = 'あ';
        u1.Email = 'olympusTest01@sunbridge.com';
        u1.Username = 'olympusTest10@sunbridge.com';
        u1.CommunityNickname = 'あ1';
        u1.IsActive = true;
        u1.EmailEncodingKey = 'ISO-2022-JP';
        u1.TimeZoneSidKey = 'Asia/Tokyo';
        u1.LocaleSidKey = 'ja_JP';
        u1.LanguageLocaleKey = 'ja';
        u1.ProfileId = p.id;
        u1.Job_Category__c = '销售服务';
        u1.Province__c = '北京';
        insert u1;
        Contact contact2 = new Contact();
        contact2.UnifiedI_Contact_ID__c = 'test001';
        contact2.AccountId = dep.Id;
        contact2.FirstName = '张';
        contact2.LastName = '小花';
        insert contact2;
        List<Id> recordTypeIds = new List<Id>();
        recordTypeIds.add(Schema.SObjectType.Campaign.getRecordTypeInfosByDeveloperName().get('Society').getRecordTypeId()); //学会/会议
        Campaign campaign01 = new Campaign();
        campaign01.RecordTypeId = recordTypeIds.get(0);
        // campaign01.StartDate = Date.newInstance(2020,10,29);
        campaign01.StartDate = Date.today();
        campaign01.Name = 'mzyTest01';
        campaign01.EndDate = Date.today().addDays(1);
        campaign01.Status = '公开中';
        campaign01.Is_LendProduct__c = '是';
        campaign01.Internal_in_charge_province__c = al.id;   //备品出借省
        campaign01.PlanBackData__c = Date.newInstance(2020,11,30);       //计划撤展日期
        campaign01.LoadNum__c = '3D主机*2; BF-290镜子*4; CV-170*1; CV-190*6;';   //计划出借备品信息
        campaign01.HostName__c = '主办方';
        campaign01.cooperatorCompany__c = '1';
        insert campaign01;
        Campaign c =[select Id, Num__c, Name2__c from Campaign limit 1];
        NFM620Rest.GeDatas GeDatas = new NFM620Rest.GeDatas();
        NFM620Rest.GeData GeData = new NFM620Rest.GeData();
        GeDatas.GeData = new NFM620Rest.GeData[]{GeData};
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmm');
        GeDatas.Monitoring = new NFMUtil.Monitoring();
        GeDatas.Monitoring.MessageGroupNumber = nowStr + '01';
        GeData.InquiryNo = 'SH-SP-JS0679111';
        GeData.Name = '商品询问单000';
        GeData.ContactId = contact2.UnifiedI_Contact_ID__c;
        GeData.ContactWay = 'SFDC_Wangqingli@olympus.com.cn';
        GeData.Campaign = c.Num__c;
        GeData.Product = '内窥镜;超声;治疗附件';
        GeData.Request = '产品试用';
        GeData.RequestDetail = '委托事项详情AAAAAAAAAAAAAA';
        // GeData.ApproverID = u1.Employee_No__c;
        //System.Test.startTest();
        NFMUtil.Monitoring Monitoring = GeDatas.Monitoring;
        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM620', GeDatas.GeData);
        NFM620Rest.executefuture(rowData.Id);
        rowData = NFMUtil.saveRowData(Monitoring, 'NFM620', GeDatas.GeData);
        NFM620Rest.executefuture(rowData.Id);
        //System.Test.stopTest();
    }
    @isTest static void test_method_two() {
        //Test.startTest();
        RestRequest req = new RestRequest();
        RestResponse res = new RestResponse();
        String JsonMsg = '{"Monitoring":{"TransmissionDateTime":"201812201320","Text":"","Tag":"MSGH","Sender":"共通平台","Receiver":"SFDC","NumberOfRecord":"1","MessageType":"NFM620","MessageGroupNumber":"20210000005088"},"GeData":[{"RequestDetail":"委托事项详情","Request":"产品试用;产品说明","Product":"超声;内镜系统;胃镜;十二指肠镜","Name":"商品询问单l八","InquiryNo":"ONLINE008","ContactWay":"17638160959","ContactId":"test0055","Campaign":"MT-GI-201811-1758"}]}';
        req.requestURI = 'services/apexrest/NFM620/execute';
        req.httpMethod = 'POST';
        req.requestBody = Blob.valueof(JsonMsg);
        RestContext.request = req;
        RestContext.response= res;
        NFM620Rest.execute();
        //Test.stopTest();
    }
    @isTest static void test_method_three() {
        // 省
        Address_Level__c al = new Address_Level__c();
        al.Name = '北京';
        al.Level1_Code__c = 'CN-99';
        al.Level1_Sys_No__c = '999999';
        insert al;
        // 市
        Address_Level2__c al2 = new Address_Level2__c();
        al2.Level1_Code__c = 'CN-99';
        al2.Level1_Sys_No__c = '999999';
        al2.Level1_Name__c = '北京';
        al2.Name = '朝阳区';
        al2.Level2_Code__c = 'CN-9999';
        al2.Level2_Sys_No__c = '9999999';
        al2.Address_Level__c = al.id;
        insert al2;
        // 病院を作る
        Account hospital = new Account();
        hospital.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Account' and DeveloperName = 'HP'].id;
        hospital.Name = 'test hospital';
        hospital.Is_Active__c = '有効';
        hospital.Attribute_Type__c = '卫生部';
        hospital.Speciality_Type__c = '综合医院';
        hospital.Grade__c = '一级';
        hospital.OCM_Category__c = 'SLTV';
        hospital.Is_Medical__c = '医疗机构';
        hospital.State_Master__c = al.id;
        hospital.City_Master__c = al2.id;
        hospital.Town__c = '东京';
        insert hospital;
        // 戦略科室を得る
        Account[] strategicDep = [SELECT ID, Name FROM Account WHERE parentId = :hospital.Id AND recordType.DeveloperName = 'Department_Class_OTH'];
        // 診療科を作る
        Account dep = new Account();
        dep.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Account' and DeveloperName = 'Department_OTH'].id;
        dep.Name = 'test dep';
        dep.AgentCode_Ext__c = '9999998';
        dep.ParentId = strategicDep[0].Id;
        dep.Department_Class__c = strategicDep[0].Id;
        dep.Hospital__c = hospital.Id;
        insert dep;
        //useを得る
        Profile p = [select id from Profile where id =:System.Label.ProfileId_SystemAdmin];
        User u1 = new User(Test_staff__c = true);
        u1.LastName = '_サンブリッジ';
        u1.FirstName = 'あ';
        u1.Batch_User__c = true;
        u1.Alias = 'あ';
        u1.Email = 'olympusTest01@sunbridge.com';
        u1.Username = 'olympusTest10@sunbridge.com';
        u1.CommunityNickname = 'あ1';
        u1.IsActive = true;
        u1.EmailEncodingKey = 'ISO-2022-JP';
        u1.TimeZoneSidKey = 'Asia/Tokyo';
        u1.LocaleSidKey = 'ja_JP';
        u1.LanguageLocaleKey = 'ja';
        u1.ProfileId = p.id;
        u1.Job_Category__c = '销售服务';
        u1.Province__c = '北京';
        insert u1;
        //OCSM管理省を得る
        OCM_Management_Province__c mp1 = new OCM_Management_Province__c();
        mp1.Name = '北京';
        mp1.Province__c = '北京市';
        mp1.Window1__c = u1.Id;
        insert mp1;
        Contact contact2 = new Contact();
        contact2.UnifiedI_Contact_ID__c = 'test001';
        contact2.AccountId = dep.Id;
        contact2.FirstName = '責任者';
        contact2.LastName = 'test1经销商';
        insert contact2;
        List<BatchIF_Transfer__c> transfers = new List<BatchIF_Transfer__c>();
        BatchIF_Transfer__c transfer = new BatchIF_Transfer__c();
        transfer.Table__c          = 'Inquiry_form__c';
        transfer.Column__c         = 'Request1__c';
        transfer.External_Value__c = '产品试用';
        transfer.Internal_Value__c = 'OPD';
        transfers.add(transfer);
        insert transfers;
        List<Id> recordTypeIds = new List<Id>();
        recordTypeIds.add(Schema.SObjectType.Campaign.getRecordTypeInfosByDeveloperName().get('Society').getRecordTypeId()); //学会/会议
        Campaign campaign01 = new Campaign();
        campaign01.RecordTypeId = recordTypeIds.get(0);
        // campaign01.StartDate = Date.newInstance(2020,10,29);
        campaign01.StartDate = Date.today();
        campaign01.Name = 'mzyTest02';
        campaign01.EndDate = Date.today().addDays(1);
        campaign01.Status = '公开中';
        campaign01.Is_LendProduct__c = '是';
        campaign01.Internal_in_charge_province__c = al.id;   //备品出借省
        campaign01.PlanBackData__c = Date.newInstance(2020,11,30);       //计划撤展日期
        campaign01.LoadNum__c = '3D主机*2; BF-290镜子*4; CV-170*1; CV-190*6;';   //计划出借备品信息
        campaign01.HostName__c = '主办方';
        campaign01.cooperatorCompany__c = '1';
        insert campaign01;
        NFM620Rest.GeDatas GeDatas = new NFM620Rest.GeDatas();
        NFM620Rest.GeData GeData = new NFM620Rest.GeData();
        GeDatas.GeData = new NFM620Rest.GeData[]{GeData};
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmm');
        GeDatas.Monitoring = new NFMUtil.Monitoring();
        GeDatas.Monitoring.MessageGroupNumber = nowStr + '01';
        GeData.InquiryNo = 'SH-SP-JS0679111';
        GeData.Name = '商品询问单000';
        GeData.ContactId = contact2.UnifiedI_Contact_ID__c;
        GeData.ContactWay = 'SFDC_Wangqingli@olympus.com.cn';
        GeData.Campaign = campaign01.Num__c;
        GeData.Product = '内窥镜;超声;治疗附件';
        GeData.Request = '产品试用';
        GeData.RequestDetail = '委托事项详情AAAAAAAAAAAAAA';
        //System.Test.startTest();
        NFMUtil.Monitoring Monitoring = GeDatas.Monitoring;
        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM620', GeDatas.GeData);
        NFM620Rest.executefuture(rowData.Id);
        rowData = NFMUtil.saveRowData(Monitoring, 'NFM620', GeDatas.GeData);
        NFM620Rest.executefuture(rowData.Id);
        //System.Test.stopTest();
    }
}
force-app/main/default/classes/NFM620RestTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NFM623Rest.cls
New file
@@ -0,0 +1,296 @@
/**********************************************************************
 *
 *
 * @url: /services/apexrest/NFM623Rest
 * @data:
 *  {
    }
*************************************************************************/
@RestResource(urlMapping = '/NFM623/*')
global with sharing class NFM623Rest {
     //add to AWS 回复 start sushanhu 20220225
     static Boolean SFStatus=true;
     static String SFMessage='';
    //add to AWS 回复 end sushanhu 20220225
    //新增NFM623Rest 学会·活动参加人员接收数据接口 精琢技术 start
    global class GeDatas {
        public NFMUtil.Monitoring Monitoring;
        public  GeData[] GeData;
    }
    global class GeData {
        public String Num;                              // 活动编码
        public String Name;                             // 活动名称
        public ViewContactIdS[] ViewContactIdS;      //替换为aws存储凭据ID 20220225 sushanhu
        public LabelTypeS[] LabelTypeS;
    }
    global class ViewContactIdS {
        public String ViewContactId;                     // 直播观看统一用户ID
    }
    global class LabelTypeS {
        public String LabelType;                         // 标签分类
        public String Label;                             // 标签内容
    }
    @HttpPost
    global static void execute() {
        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        GeDatas ges = (GeDatas) JSON.deserializeStrict(strData, GeDatas.class);
        if (ges == null ) {
            return;
        }
        NFMUtil.Monitoring Monitoring = ges.Monitoring;
        if (Monitoring == null) {
            return;
        }
        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM623', ges.GeData);
        if (String.isBlank(rowData.Log__c) == false) {
            executefuture(rowData.Id);
        }
        // JSONを戻す
        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        // String jsonResponse = '{"status": "Success", "Message":""}';
        // res.responseBody = blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu start
        NFMUtil.NFMResponse result = NFMUtil.getNFMResponse();
        result.SFStatus=SFStatus;
        result.SFMessage=SFMessage;
        String jsonResponse =JSON.serialize(result);
        system.debug('result---'+jsonResponse);
        res.responseBody = blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu end
        return;
    }
    @future
    global static void executefuture(String rowData_Id) {
        main(rowData_Id);
    }
    global static void main (String rowData_Id) {
        Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
        BatchIF_Log__c rowData = [Select Id, Name, retry_cnt__c, Log__c, ErrorLog__c, Log2__c, Log3__c, Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c, Log12__c, MessageGroupNumber__c from BatchIF_Log__c where RowDataFlg__c = true and Id = :rowData_Id];
        String logstr = rowData.MessageGroupNumber__c + ' start\n';
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        iflog.Type__c = 'NFM623';
        iflog.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        iflog.Log__c = logstr;
        iflog.ErrorLog__c = '';
        insert iflog;
        String rowDataStr = NFMUtil.getRowDataStr(rowData);
        List<GeData> geDataList = (List<GeData>) JSON.deserialize(rowDataStr, List<GeData>.class);
        if (geDataList == null || geDataList.size() == 0) {
            return;
        }
        Savepoint sp = Database.setSavepoint();
        try {
            List<Campaign> camInsList = new List<Campaign>();
            List<CampaignMember__c> camMemInsList = new List<CampaignMember__c>();
            List<CampaignLable__c> camLabInsList = new List<CampaignLable__c>();
            //将市场活动编码存入List,统一用户ID存如Map
            List<String> camNoList = new List<String>();
            List<String> conIDListNew = new List<String>();
            Map<String, String> conIDMapNew = new Map<String, String>();
            List<GeData> geDataListNew = new List<GeData>();
            for (GeData geData : geDataList) {
                if (String.isBlank(geData.Num)) {
                    //必須項目がない場合、処理と飛ばす
                    iflog.ErrorLog__c += '活动编码不能为空。\n';
                    continue;
                }
                if (geData.ViewContactIdS == null || geData.ViewContactIdS.size() == 0) {
                    //必須項目がない場合、処理と飛ばす
                    iflog.ErrorLog__c += '统一用户ID不能为空。\n';
                    continue;
                }
                for (ViewContactIdS viewConIdS : geData.ViewContactIdS) {
                    conIDListNew.add(viewConIdS.ViewContactId);
                    conIDMapNew.put(geData.Num, viewConIdS.ViewContactId);
                }
                camNoList.add(geData.Num);
                geDataListNew.add(geData);
            }
            //使用统一用户ID获取客户人员ID、客户人员姓名、医院科室存入Map
            Map<String, Contact> contactMap = new Map<String, Contact>();
            List<String> conIDList = new List<String>();
            if (conIDMapNew.size() > 0) {
                List<Contact> contactList = [select Id,Name,UnifiedI_Contact_ID__c,
                                            AccountId,Account.Name
                                            from Contact where UnifiedI_Contact_ID__c in :conIDListNew];
                if (contactList.size() > 0) {
                    //客户人员ID获取成功
                    for (Contact conInfo : contactList) {
                        contactMap.put(conInfo.UnifiedI_Contact_ID__c, conInfo);
                        conIDList.add(conInfo.Id);
                    }
                }
                //update to 通过aws存储的unified查询 start 20220225
                // List<Contact> contactList = [select Id,Name,AWS_UnifiedI_Contact_ID__c,
                //                             AccountId,Account.Name
                //                             from Contact where AWS_UnifiedI_Contact_ID__c in :conIDListNew];
                // if (contactList.size() > 0) {
                //     //客户人员ID获取成功
                //     for (Contact conInfo : contactList) {
                //         contactMap.put(conInfo.AWS_UnifiedI_Contact_ID__c, conInfo);
                //         conIDList.add(conInfo.Id);
                //     }
                // }
                //update to 通过aws存储的unified查询 20220225 end
            }
            //使用市场活动编码获取市场活动ID和活动名称存入Map
            List<String> camIDList = new List<String>();
            Map<String, Campaign> camOldMap = new Map<String, Campaign>();
            List<Campaign> campList = [select Id, Num__c, Name2__c from Campaign where Num__c in :camNoList];
            if (campList.size() > 0) {
                //市场活动ID获取成功
                for (Campaign camInfo : campList) {
                    camIDList.add(camInfo.Id);
                    camOldMap.put(camInfo.Num__c, camInfo);
                }
            }
            //查询已经存在的市场活动编码下的参会人员ID和统一用户ID
            List<CampaignMember__c>  camMemberList = [select Id,Contact_ID__c,ViewContactId__c,
                                                        Campaign__c,Campaign__r.Num__c
                                                        from CampaignMember__c where Campaign__c in : camIDList];
            Map<String, String> camContactMap = new Map<String, String>();
            Map<String, String> camViewContactMap = new Map<String, String>();
            if (camMemberList.size() > 0 ) {
                for (CampaignMember__c cm : camMemberList) {
                    camContactMap.put(cm.Contact_ID__c, cm.Campaign__r.Num__c);
                    camViewContactMap.put(cm.ViewContactId__c, cm.Campaign__r.Num__c);
                }
            }
            //update to 获取aws 统一凭据关联 sushanhu 20220225 satrt
            // List<CampaignMember__c>  camMemberList = [select Id,Contact_ID__c,AWS_ViewContact_Id__c,
            //                                             Campaign__c,Campaign__r.Num__c
            //                                             from CampaignMember__c where Campaign__c in : camIDList];
            // Map<String, String> camContactMap = new Map<String, String>();
            // Map<String, String> camViewContactMap = new Map<String, String>();
            // if (camMemberList.size() > 0 ) {
            //     for (CampaignMember__c cm : camMemberList) {
            //         camContactMap.put(cm.Contact_ID__c, cm.Campaign__r.Num__c);
            //         camViewContactMap.put(cm.AWS_ViewContact_Id__c, cm.Campaign__r.Num__c);
            //     }
            // }
             //update to 获取aws 统一凭据关联 sushanhu 20220225 end
            //将原有活动标签对象中市场活动ID和标签活动名称存入Map中
            List<CampaignLable__c> camLabInfoList = [select id,name,Campaign__c,Lable__c,LableType__c from CampaignLable__c where  Campaign__c in : camIDList];
            Map<String, String> camLabInfoMap = new Map<String, String>();
            if (camLabInfoList.size() > 0) {
                for (CampaignLable__c camLabIn : camLabInfoList) {
                    camLabInfoMap.put(camLabIn.Name,camLabIn.Id);
                }
            }
            // 将XML各数据项更新到市场活动、学会・活动参加人员及活动标签对象中
            for (GeData geData : geDataListNew) {
                if (camOldMap.get(geData.Num) == null) {
                    iflog.ErrorLog__c += '市场活动编码' + geData.Num +':不存在\n';
                    continue;
                }
                //插入学会参会人员对象
                for (ViewContactIdS viewConIdS : geData.ViewContactIdS) {
                    CampaignMember__c camMemberInfo = new CampaignMember__c();
                    if (contactMap.get(viewConIdS.ViewContactId) != null) {
                        if (camContactMap.get(contactMap.get(viewConIdS.ViewContactId).ID) != geData.Num) {
                            camMemberInfo.Contact_ID__c = contactMap.get(viewConIdS.ViewContactId).ID;                   //参会人员ID
                            camMemberInfo.Campaign__c = camOldMap.get(geData.Num).ID;                                    //活动ID
                            camMemberInfo.Department_ID__c = contactMap.get(viewConIdS.ViewContactId).AccountId;         //医院科室
                            camMemberInfo.Department__c = contactMap.get(viewConIdS.ViewContactId).Account.Name;         //医院科室(文本)
                            camMemberInfo.Contact__c = contactMap.get(viewConIdS.ViewContactId).Name;                    //客户人员姓名
                            camMemInsList.add(camMemberInfo);
                        }
                    } else {
                        if (camViewContactMap.get(viewConIdS.ViewContactId) != geData.Num) {
                            camMemberInfo.Campaign__c = camOldMap.get(geData.Num).ID;
                            camMemberInfo.ViewContactId__c = viewConIdS.ViewContactId;
                            camMemInsList.add(camMemberInfo);
                        }
                    }
                }
                //插入活动标签对象
                for (LabelTypeS labelTypeS : geData.LabelTypeS) {
                    List<String> lableList = labelTypeS.Label.split(';');
                    if (lableList.size() > 0) {
                        for (Integer i= 0 ; i < lableList.size(); i++) {
                            CampaignLable__c campaignLable = new CampaignLable__c();
                            if (camOldMap.get(geData.Num) != null ) {
                                campaignLable.Campaign__c = camOldMap.get(geData.Num).ID;
                                campaignLable.LableType__c = labelTypeS.LabelType;
                                campaignLable.Lable__c = lableList[i];
                                campaignLable.Name = campaignLable.LableType__c+'-'+campaignLable.Lable__c;
                                if (String.isBlank(camLabInfoMap.get(campaignLable.Name))) {
                                    camLabInsList.add(campaignLable);
                                }
                            }
                        }
                    }
                }
            }
            if (camMemInsList.size() > 0) {
                upsert camMemInsList;
                logstr += '学会参会人员更新成功。\n';
            }
            if (camLabInsList.size() > 0) {
                insert camLabInsList;
                logstr += '活动标签更新成功。\n';
            }
            logstr += '\nend';
            rowData.retry_cnt__c = 0;
        } catch (Exception ex) {
            // エラーが発生した場合
            Database.rollback(sp);
            System.debug(Logginglevel.ERROR, 'NFM623_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM623_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            logstr += '\n' + ex.getMessage();
            iflog.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + iflog.ErrorLog__c;
            if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
            if (rowData.retry_cnt__c < batch_retry_max_cnt) {
                rowData.retry_cnt__c++;
                LogAutoSendSchedule.assignOneMinute();
            }
            if (rowData.retry_cnt__c >= batch_retry_max_cnt) {
                rowData.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + rowData.ErrorLog__c + '错误次数已经超过自动收信设定的最大次数,请手动收信';
            }
        }
        update rowData;
        iflog.Log__c = logstr;
        if (iflog.Log__c.length() > 131072) {
            iflog.Log__c = iflog.Log__c.subString(0, 131065) + ' ...';
        }
        if (iflog.ErrorLog__c.length() > 32768) {
            iflog.ErrorLog__c = iflog.ErrorLog__c.subString(0, 32760) + ' ...';
        }
        update iflog;
    }
    //新增NMF623接口 精琢技术 end
}
force-app/main/default/classes/NFM623Rest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NFM623RestTest.cls
New file
@@ -0,0 +1,184 @@
@isTest
private class NFM623RestTest {
    @isTest static void test_method_one() {
        // 省
        Address_Level__c al = new Address_Level__c();
        al.Name = '北京';
        al.Level1_Code__c = 'CN-99';
        al.Level1_Sys_No__c = '999999';
        insert al;
        // 市
        Address_Level2__c al2 = new Address_Level2__c();
        al2.Level1_Code__c = 'CN-99';
        al2.Level1_Sys_No__c = '999999';
        al2.Level1_Name__c = '北京';
        al2.Name = '朝阳区';
        al2.Level2_Code__c = 'CN-9999';
        al2.Level2_Sys_No__c = '9999999';
        al2.Address_Level__c = al.id;
        insert al2;
        // 病院を作る
        Account hospital = new Account();
        hospital.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Account' and DeveloperName = 'HP'].id;
        hospital.Name = 'test hospital';
        hospital.Is_Active__c = '有効';
        hospital.Attribute_Type__c = '卫生部';
        hospital.Speciality_Type__c = '综合医院';
        hospital.Grade__c = '一级';
        hospital.OCM_Category__c = 'SLTV';
        hospital.Is_Medical__c = '医疗机构';
        hospital.State_Master__c = al.id;
        hospital.City_Master__c = al2.id;
        hospital.Town__c = '东京';
        insert hospital;
        // 戦略科室を得る
        Account[] strategicDep = [SELECT ID, Name FROM Account WHERE parentId = :hospital.Id AND recordType.DeveloperName = 'Department_Class_OTH'];
        // 診療科を作る
        Account dep = new Account();
        dep.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Account' and DeveloperName = 'Department_OTH'].id;
        dep.Name = 'test dep';
        dep.AgentCode_Ext__c = '9999998';
        dep.ParentId = strategicDep[0].Id;
        dep.Department_Class__c = strategicDep[0].Id;
        dep.Hospital__c = hospital.Id;
        insert dep;
        Contact contact1 = new Contact();
        contact1.UnifiedI_Contact_ID__c = 'test001';
        contact1.AccountId = dep.Id;
        contact1.FirstName = '責任者';
        contact1.LastName = 'test1经销商';
        insert contact1;
        Contact contact2 = new Contact();
        contact2.UnifiedI_Contact_ID__c = 'test002';
        contact2.AccountId = dep.Id;
        contact2.FirstName = '責任者';
        contact2.LastName = 'test2经销商';
        insert contact2;
        Profile p = [select Id from Profile where id =:System.Label.ProfileId_SystemAdmin];
        // ユーザー作成
        User hpOwner = new User(Test_staff__c = true, LastName = 'hp', FirstName = 'owner', Alias = 'hp', CommunityNickname = 'hpOwner', Email = 'olympus_hpowner@sunbridge.com', Username = 'olympus_hpowner@sunbridge.com', IsActive = true, EmailEncodingKey = 'ISO-2022-JP', TimeZoneSidKey = 'Asia/Tokyo', LocaleSidKey = 'ja_JP', LanguageLocaleKey = 'ja', ProfileId = p.id,Work_Location__c='北京');
        insert hpOwner;
        //User ur = [select Id,Employee_No__c from User limit 1];
        //Profile p = [select Id from Profile where id =: System.Label.ProfileId_SystemAdmin];
        // User u1 = new User(Test_staff__c = true);
        // u1.LastName = '_サンブリッジ';
        // u1.FirstName = 'あ';
        // u1.Batch_User__c = true;
        // u1.Alias = 'あ';
        // u1.Email = 'olympusTest01@sunbridge.com';
        // u1.Username = 'olympusTest01@sunbridge.com';
        // u1.CommunityNickname = 'あ';
        // u1.IsActive = true;
        // u1.EmailEncodingKey = 'ISO-2022-JP';
        // u1.TimeZoneSidKey = 'Asia/Tokyo';
        // u1.LocaleSidKey = 'ja_JP';
        // u1.LanguageLocaleKey = 'ja';
        // u1.ProfileId = p.Id;
        // u1.Job_Category__c = '销售服务';
        // u1.Province__c = '東京';
        // u1.Stay_or_not__c = '在职';
        // u1.QuitDate__c = Date.today().addDays(-1);
        // u1.SendToComPlat__c = false;
        // insert u1;
        //OCSM管理省を得る
        OCM_Management_Province__c mp1 = new OCM_Management_Province__c();
        mp1.Name = '北京';
        mp1.Province__c = '北京市';
        mp1.Window1__c = hpOwner.Id;
        mp1.Admin_assistant__c = hpOwner.Id;
        // mp1.OnlinePlatformWindow1__c = u1.Id;
        // mp1.OnlinePlatformWindow2__c = u1.Id;
        // mp1.OnlinePlatformWindow3__c = u1.Id;
        mp1.OnlinePlatformWindow1__c = hpOwner.Id;
        mp1.OnlinePlatformWindow2__c = hpOwner.Id;
        mp1.OnlinePlatformWindow3__c = hpOwner.Id;
        insert mp1;
        List<Id> recordTypeIds = new List<Id>();
        recordTypeIds.add(Schema.SObjectType.Campaign.getRecordTypeInfosByDeveloperName().get('Society').getRecordTypeId()); //学会/会议
        Campaign campaign01 = new Campaign();
        campaign01.RecordTypeId = recordTypeIds.get(0);
        campaign01.StartDate = Date.today();
        campaign01.Name = 'mzyTest01';
        campaign01.EndDate = Date.today().addDays(1);
        campaign01.Status = '公开中';
        campaign01.Is_LendProduct__c = '是';
        campaign01.Internal_in_charge_province__c = al.id;   //备品出借省
        campaign01.PlanBackData__c = Date.newInstance(2020,11,30);       //计划撤展日期
        campaign01.LoadNum__c = '3D主机*2; BF-290镜子*4; CV-170*1; CV-190*6;';   //计划出借备品信息
        campaign01.HostName__c = '主办方';
        campaign01.cooperatorCompany__c = '1';
        campaign01.OwnerId = hpOwner.Id;
        // campaign01.OwnerId = u1.Id;
        insert campaign01;
        Campaign c =[select Id, Num__c, Name2__c from Campaign limit 1];
        CampaignMember__c camMeb = new CampaignMember__c();
        camMeb.Contact_ID__c = contact2.Id;
        camMeb.Campaign__c = campaign01.Id;
        //camMeb.Campaign__r.Num__c = 'No1';
        insert camMeb;
        CampaignLable__c camLable = new CampaignLable__c();
        camLable.name = '技术-技术1';
        camLable.Campaign__c = campaign01.Id;
        camLable.Lable__c = '技术';
        camLable.LableType__c = '技术1';
        insert camLable;
        NFM623Rest.GeDatas GeDatas = new NFM623Rest.GeDatas();
        NFM623Rest.GeData GeData = new NFM623Rest.GeData();
        NFM623Rest.ViewContactIdS ViewContactIdS = new NFM623Rest.ViewContactIdS();
        NFM623Rest.LabelTypeS LabelTypeS = new NFM623Rest.LabelTypeS();
        GeDatas.GeData = new NFM623Rest.GeData[]{GeData};
        GeData.LabelTypeS = new NFM623Rest.LabelTypeS[]{LabelTypeS};
        GeData.ViewContactIdS = new NFM623Rest.ViewContactIdS[]{ViewContactIdS};
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmm');
        GeDatas.Monitoring = new NFMUtil.Monitoring();
        GeDatas.Monitoring.MessageGroupNumber = nowStr + '01';
        GeData.Num = c.Num__c;
        GeData.Name = '测试市场活动';
        LabelTypeS.LabelType= '科室';
        LabelTypeS.Label = '消化科';
        ViewContactIdS.ViewContactId = contact1.UnifiedI_Contact_ID__c;
        //System.Test.startTest();
        NFMUtil.Monitoring Monitoring = GeDatas.Monitoring;
        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM623', GeDatas.GeData);
        NFM623Rest.executefuture(rowData.Id);
        rowData = NFMUtil.saveRowData(Monitoring, 'NFM623', GeDatas.GeData);
        NFM623Rest.executefuture(rowData.Id);
        //System.Test.stopTest();
    }
    @isTest static void test_method_two() {
        //Test.startTest();
        RestRequest req = new RestRequest();
        RestResponse res = new RestResponse();
        String JsonMsg = '{"Monitoring":{"TransmissionDateTime":"201812201320","Text":"","Tag":"MSGH","Sender":"共通平台","Receiver":"SFDC","NumberOfRecord":"1","MessageType":"NFM623","MessageGroupNumber":"20210000005088"},"GeData":[{"ViewContactIdS":[{"ViewContactId":"1286"}],"Num":"MT-HB-202109-6417","Name":"1101测试2021消化道肿瘤早诊早治内镜培训班第十期 (2022/01/17 - 2022/01/21)","LabelTypeS":[{"LabelType":"科室","Label":"消化科"}]}]}';
        req.requestURI = 'services/apexrest/NFM623/execute';
        req.httpMethod = 'POST';
        req.requestBody = Blob.valueof(JsonMsg);
        RestContext.request = req;
        RestContext.response= res;
        NFM623Rest.execute();
        //Test.stopTest();
    }
}
force-app/main/default/classes/NFM623RestTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NFM702Controller.cls
New file
@@ -0,0 +1,254 @@
global with sharing class NFM702Controller {
    private static final String LOG_TYPE = 'NFM702';
    public static String logstr;
    public static String status;
    public static String ResponseBody;
    public static String Result;
    public NFM702Controller() {
    }
    public class Response {
        public Result Result;
    }
    public Class Result{
        public String Result;
        public String Message;
    }
    public class NFM702 {
        public NFMUtil.Monitoring Monitoring;
        public GeData[] GeData;
    }
    // public Class GeDatas {
    //     public NFMUtil.Monitoring Monitoring;
    //     public GeData[] GeData;
    // }
    public Class GeData {
        public String StaffMCode;   //人员管理编码
        public String HospitalName;     //医院名称
        public String OfficeName;   //科室名称
        public String Name;    //姓名
        public String Mobile;   //电话
        public String HcpNo;    //HPC编码
        public Boolean IsActive;    //是否有效
        public String UpdateStatus;     //操作类型
        // add by sushanhu 20220304 for pi satrt
        public String DataId;           //aws 存储凭据
        // add by sushanhu 20220304 for pi end
    }
    @future(callout = true)
    public static void callout( String iflog_Id, List < String > accIdList ){
        executeNotFuture(iflog_Id, accIdList);
    }
    public static void executeNotFuture(String iflog_Id, List < String > accIdList) {
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmmss');
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        if (string.isNotBlank(iflog_Id)) {
            iflog = [Select Id, Name, Log__c, ErrorLog__c,MessageGroupNumber__c from BatchIF_Log__c where Id =: iflog_Id];
        }
        iflog.MessageGroupNumber__c = String.isBlank(iflog.Id)?nowStr:iflog.MessageGroupNumber__c;
        iflog.Log__c = 'callout start\n';
        iflog.Type__c = LOG_TYPE;
        iflog.ErrorLog__c = '';
        NFM702 gds = new NFM702();
        gds.GeData = new List < GeData >();
        BatchIF_Log__c rowData = null;
        List<Contact> conList = [select Id,
                                        CManageCode__c,     //人员管理编码
                                        Account.Hospital_Name__c,       //医院名称
                                        Account.Department_Name__c,       //科室名称
                                        Name,       //姓名
                                        Phone,      //电话
                                        HcpNo__c,       //HCP编码
                                        Isactive__c,    //是否有效
                                        // UpdateStatus__c,            //操作类型
                                        AWS_Data_Id__c              //aws 存储凭据 add bysushanhu 20220304 for Pi
                                        from Contact WHERE Id IN:accIdList order by Id];  //AccountId
        String logstr = iflog.Log__c + ' ' + 'NumberOfRecord=' + conList.size() + '\n';
        NFMUtil.Monitoring mon = new NFMUtil.Monitoring();
        mon.Tag                = 'MSGH';
        mon.Sender                  = 'SFDC';
        mon.Receiver              = 'OBPM';
        mon.MessageType          = 'NFM702';
        mon.MessageGroupNumber      = nowStr;
        mon.NumberOfRecord          = '' + accIdList.size();
        mon.TransmissionDateTime = nowStr;
        mon.Text = '';
        try{
            for( Contact con : conList ){
                GeData ged = new GeData();
                ged.StaffMCode = con.CManageCode__c;
                ged.HospitalName = con.Account.Hospital_Name__c;
                ged.OfficeName = con.Account.Department_Name__c;
                ged.Name = con.Name;
                ged.Mobile = con.Phone;
                ged.HcpNo = con.HcpNo__c;
                ged.IsActive = '有效'.equals(con.Isactive__c)? true:false;
                // ged.UpdateStatus = con.UpdateStatus__c;
                ged.UpdateStatus = String.isBlank(con.HcpNo__c) ? 'I' : 'U';
                ged.DataId  =   con.AWS_Data_Id__c;//add by sushanhu  for pi 20220304
                gds.GeData.add(ged);
            }
            logstr += '\nend';
            if(gds.GeData.size()>0){
                mon.NumberOfRecord = '' + gds.GeData.size();
                gds.Monitoring = mon;
                logstr = iflog.Log__c + '\nNumberOfRecord=' + gds.GeData.size();
                NFMUtil.Monitoring Monitoring = new NFMUtil.Monitoring();
                Monitoring.Tag                  = gds.Monitoring.Tag;
                Monitoring.Sender               = gds.Monitoring.Sender;
                Monitoring.Receiver             = gds.Monitoring.Receiver;
                Monitoring.MessageGroupNumber   = gds.Monitoring.MessageGroupNumber;
                Monitoring.MessageType          = gds.Monitoring.MessageType;
                Monitoring.NumberOfRecord       = gds.Monitoring.NumberOfRecord;
                Monitoring.TransmissionDateTime = gds.Monitoring.TransmissionDateTime;
                Monitoring.Text = '';
                NFM702 nfm702 = new NFM702();
                nfm702.GeData = new List <GeData>();
                nfm702.GeData = gds.GeData;
                nfm702.Monitoring = new NFMUtil.Monitoring();
                nfm702.Monitoring = Monitoring;
                rowData = NFMUtil.makeRowData(iflog, LOG_TYPE, nfm702);
                execute(rowData, iflog);
            }
        }catch(Exception e){
            //发生错误时
            System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + e.getMessage());
            System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + e.getStackTraceString());
            logstr += e.getMessage();
            iflog.ErrorLog__c += e.getMessage() + '\n';
            iflog.ErrorLog__c += e.getStackTraceString() + '\n';
            iflog.Log__c = iflog.Log__c + logstr;
        }
        if (rowData != null) {
            upsert rowData;
        }
        System.debug(Logginglevel.DEBUG, 'NFM702_' + iflog.Name + ' end');
        iflog.Log__c = iflog.Log__c + logstr;
        upsert iflog;
    }
    public static void ManualExecute(String rowDataId) {
        List < BatchIF_Log__c > row = [select id, name, MessageGroupNumber__c, retry_cnt__c,
            RowDataFlg__c, ErrorLog__c, Type__c,
            Log__c, Log2__c, Log3__c, Log4__c, Log5__c, Log6__c,
            Log7__c, Log8__c, Log9__c, Log10__c, Log11__c, Log12__c
            from BatchIF_Log__c
            where id =: rowDataId
        ];
        if (row.size() > 0) execute(row[0], null);
    }
    public static void execute(BatchIF_Log__c rowDataSFDC, BatchIF_Log__c iflog) {
        Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
        String rowDataStr = NFMUtil.getRowDataStr(rowDataSFDC);
        String logstr = rowDataSFDC.MessageGroupNumber__c + ' start\n';
        if (iflog == null) {
            iflog = new BatchIF_Log__c();
            iflog.Type__c = LOG_TYPE;
            iflog.MessageGroupNumber__c = rowDataSFDC.MessageGroupNumber__c;
            iflog.Log__c = logstr;
            iflog.ErrorLog__c = '';
        } else {
            iflog.Type__c = LOG_TYPE;
            iflog.MessageGroupNumber__c = rowDataSFDC.MessageGroupNumber__c;
            logstr = iflog.Log__c;
        }
        try {
            // NFMUtil.response response = NFMUtil.sendToSapStatusAndBody(rowDataStr, NFMUtil.NFM702_ENDPOINT);
            // System.debug('NFM702Log--status->'+ status);
            // status = response.status;
            // ResponseBody = response.responseBody;
            // Response resultList = ( Response ) JSON.deserializeStrict(ResponseBody, Response.class);
            // System.debug('NFM702Log--status->'+ ResponseBody);
            // Result = resultList.Result.Result;
            // if ('00'.equals(Result)) {
            //     logstr += ResponseBody+'\n';
            //     rowDataSFDC.retry_cnt__c = 0;
            //     //iflog.Log__c = 'ok';
            // }
            // else {
            //     //iflog.Log__c = 'ok2';
            //     rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, null, status);
            // }
            //update to AWS sushanhu FOR PI start 20220304
            PIHelper.PIIntegration pi =PIHelper.getPIIntegrationInfo('NFM702');
            NFMUtil.response response = NFMUtil.sendToPiAWS(rowDataStr, pi.newUrl,pi.token);
            status = response.status;
            System.debug('NFM702Log--status->'+ status);
            ResponseBody = response.responseBody;
            System.debug('NFM702Log--responsebody->'+ ResponseBody);
            if ('200'.equals(status)) {
                //aws 正确响应
                // Response resultList = ( Response ) JSON.deserializeStrict(ResponseBody, Response.class);
                Map<String, Object> result = (Map<String, Object>)JSON.deserializeUntyped(ResponseBody);
                String statusCode =(String)result.get('status');
                if ('0'.equals(statusCode)) {
                    logstr += ResponseBody+'\n';
                    rowDataSFDC.retry_cnt__c = 0;
                    //iflog.Log__c = 'ok';
                } else {
                    //iflog.Log__c = 'ok2';
                rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, null, status);
                }
            }
            else {
                logstr=ResponseBody;
                iflog.ErrorLog__c=ResponseBody;
            }
            //update to AWS sushanhu FOR PI  20220304 end
        }catch ( Exception ex ) {
           //打印错误日志
           System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + ex.getMessage());
           System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + ex.getStackTraceString());
           logstr = ex.getMessage();
           iflog.ErrorLog__c += ex.getMessage() + '\n';
           iflog.ErrorLog__c += ex.getStackTraceString() + '\n';
           if(!Test.isRunningTest()){
                //rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, null, status);
           }
        }
        iflog.Log__c = iflog.Log__c + logstr;
        upsert iflog;
        upsert rowDataSFDC;
    }
}
force-app/main/default/classes/NFM702Controller.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NFM702ControllerTest.cls
New file
@@ -0,0 +1,71 @@
@isTest
private class NFM702ControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration('NFM702');
    }
    public Class GeDatas {
        public NFMUtil.Monitoring Monitoring;
        public GeData[] GeData;
    }
    public Class GeData {
        public String DoctorNo;   //人员管理编码
        public String HospitalName;     //医院名称
        public String OfficeName;   //科室名称
        public String DoctorName;    //姓名
        public String TelNo;   //电话
        public String HcpNo;    //HPC编码
        public Boolean IsActive;    //是否有效
        public String UpdateStatus;     //操作类型
    }
    static testMethod void testMethod1(){
        GeDatas GeDatas = new GeDatas();
        GeDatas.Monitoring = new NFMUtil.Monitoring();
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmm');
        GeDatas.Monitoring.TransmissionDateTime = nowStr;
        GeDatas.Monitoring.Text                 = '';
        GeDatas.Monitoring.Tag                  = '';
        GeDatas.Monitoring.Sender               = 'SFDC';
        GeDatas.Monitoring.Receiver             = 'OBPM';
        GeDatas.Monitoring.MessageType          = 'NFM702';
        GeDatas.GeData = new List<GeData>();
        GeData GeData = new GeData();
        GeDatas.GeData.add(GeData);
        GeData.DoctorNo = 'C000033002';
        GeData.HospitalName = '安徽中医药大学第一附属医院';
        GeData.OfficeName = ' 耳鼻喉科';
        GeData.DoctorName = '刘刚';
        GeData.TelNo = '13810000000';
        GeData.HcpNo = '123456';
        GeData.IsActive = true;
        GeData.UpdateStatus = 'U';
        NFMUtil.Monitoring Monitoring   = new NFMUtil.Monitoring();
        Monitoring.Tag                  = GeDatas.Monitoring.Tag;
        Monitoring.Sender               = GeDatas.Monitoring.Sender;
        Monitoring.Receiver             = GeDatas.Monitoring.Receiver;
        Monitoring.MessageType          = GeDatas.Monitoring.MessageType;
        Monitoring.MessageGroupNumber   = GeDatas.Monitoring.MessageGroupNumber;
        Monitoring.NumberOfRecord       = GeDatas.Monitoring.NumberOfRecord;
        Monitoring.TransmissionDateTime = GeDatas.Monitoring.TransmissionDateTime;
        Monitoring.Text = '';
        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM702', GeDatas.GeData);
        List<Contact> conList = TestDataUtility.CreateContacts(3);
        List<String> geList = new List<String>();
        if(conList.size()>0){
            for(Contact con : conList){
                geList.add(con.Id);
            }
        }
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreatePIHelperHttpMock());
        NFM702Controller.callout(rowData.id, geList);
        NFM702Controller.ManualExecute(rowData.id);
    }
}
force-app/main/default/classes/NFM702ControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NFM702WebService.cls
New file
@@ -0,0 +1,6 @@
global without sharing class NFM702WebService {
    webservice static String sendToOBPM(String iflog_Id, List<String> contactids){
        NFM702Controller.callout(iflog_Id, contactids);
        return '上传OBPM成功!';
    }
}
force-app/main/default/classes/NFM702WebService.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NFM702WebServiceTest.cls
New file
@@ -0,0 +1,57 @@
@isTest
private class NFM702WebServiceTest {
    public Class GeDatas {
        public NFMUtil.Monitoring Monitoring;
        public GeData[] GeData;
    }
    public Class GeData {
        public String DoctorNo;   //人员管理编码
        public String HospitalName;     //医院名称
        public String OfficeName;   //科室名称
        public String DoctorName;    //姓名
        public String TelNo;   //电话
        public String HcpNo;    //HPC编码
        public Boolean IsActive;    //是否有效
        public String UpdateStatus;     //操作类型
    }
    static testMethod void testMethod1() {
        GeDatas GeDatas = new GeDatas();
        GeDatas.Monitoring = new NFMUtil.Monitoring();
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmm');
        GeDatas.Monitoring.TransmissionDateTime = nowStr;
        GeDatas.Monitoring.Text                 = '';
        GeDatas.Monitoring.Tag                  = '';
        GeDatas.Monitoring.Sender               = 'SFDC';
        GeDatas.Monitoring.Receiver             = 'OBPM';
        GeDatas.Monitoring.MessageType          = 'NFM702';
        GeDatas.GeData = new List<GeData>();
        GeData GeData = new GeData();
        GeDatas.GeData.add(GeData);
        GeData.DoctorNo = 'C000033002';
        GeData.HospitalName = '安徽中医药大学第一附属医院';
        GeData.OfficeName = ' 耳鼻喉科';
        GeData.DoctorName = '刘刚';
        GeData.TelNo = '13810000000';
        GeData.HcpNo = '123456';
        GeData.IsActive = true;
        GeData.UpdateStatus = '1';
        NFMUtil.Monitoring Monitoring   = new NFMUtil.Monitoring();
        Monitoring.Tag                  = GeDatas.Monitoring.Tag;
        Monitoring.Sender               = GeDatas.Monitoring.Sender;
        Monitoring.Receiver             = GeDatas.Monitoring.Receiver;
        Monitoring.MessageType          = GeDatas.Monitoring.MessageType;
        Monitoring.MessageGroupNumber   = GeDatas.Monitoring.MessageGroupNumber;
        Monitoring.NumberOfRecord       = GeDatas.Monitoring.NumberOfRecord;
        Monitoring.TransmissionDateTime = GeDatas.Monitoring.TransmissionDateTime;
        Monitoring.Text = '';
        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM702', GeDatas.GeData);
        List<String> geList = new List<String>();
        geList.add('C000033002');
        NFM702WebService.sendToOBPM(rowData.id, geList);
    }
}
force-app/main/default/classes/NFM702WebServiceTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NFMUtil.cls
@@ -78,7 +78,8 @@
            //NFM007_ENDPOINT = 'http://wdp.olympus.com.cn:8089/RESTAdapter/NFM007';
            NFM007_ENDPOINT = 'https://wdp.olympus.com.cn:44301/RESTAdapter/NFM007';
            NFM008_ENDPOINT = 'https://owdc-test.olympus.co.jp/XISOAPAdapter/MessageServlet?senderParty=&senderService=OCM_SFDC_T&receiverParty=&receiverService=&interface=NFM008_Sync_BC2GPI&interfaceNamespace=http%3A%2F%2Folympus.co.jp%2Fgpi%2FNFM008';
            NFM103_ENDPOINT = 'http://wdp.olympus.com.cn:8089/RESTAdapter/NFM103';
            // NFM103_ENDPOINT = 'http://wdp.olympus.com.cn:8089/RESTAdapter/NFM103';
            NFM103_ENDPOINT = 'https://sfpi-mebg-test.olympuschina.com/api/nfm/103';//aws 103接口
            // NFM106_ENDPOINT = 'https://owdc-test.olympus.co.jp/XISOAPAdapter/MessageServlet?senderParty=&senderService=OCM_SFDC_T&receiverParty=&receiverService=&interface=NFM106_Sync_BC2GPI&interfaceNamespace=http%3A%2F%2Folympus.co.jp%2Fgpi%2FNFM106';
            NFM106_ENDPOINT = 'http://wdp.olympus.com.cn:8089/RESTAdapter/NFM106';
            //NFM106_ENDPOINT = 'https://sfdc-ocm-test.olympus.co.jp/XISOAPAdapter/MessageServlet?senderParty=&senderService=OCM_SFDC_T&receiverParty=&receiverService=&interface=NFM106_Sync_BC2GPI&interfaceNamespace=http%3A%2F%2Folympus.co.jp%2Fgpi%2FNFM106';
@@ -100,7 +101,7 @@
            NFM401_ENDPOINT = 'http://ec2-161-189-3-104.cn-northwest-1.compute.amazonaws.com.cn:8088/dojtest/dojInfo/recevie';
            NFM402_ENDPOINT = 'http://ec2-161-189-3-104.cn-northwest-1.compute.amazonaws.com.cn:8088/dojtest/dojInfo/getDojInfoByRefNo';
            NFM501_ENDPOINT = 'http://cusdata.qianlima.com/v1/info/page/';
            NFM501_ENDPOINT = 'https://sfpi-mebg-test.olympuschina.com/api/nfm/501';
            NFM502_ENDPOINT = 'http://cusdata.qianlima.com/v1/info/detailHtml?url=';
            NFM504_ENDPOINT = 'http://cusdata.qianlima.com/v1/customer/albs/feedback';
            CBPR_Auth_Sap = 'Basic U0ZEQ19XU1VTRVI6cG9xMTIzNDU=';
@@ -109,7 +110,7 @@
            CBPR_Auth_Spo = 'http://cbpr.olympuschina.com/sfdc/token';
            QLM_Token = 'http://cusdata.qianlima.com/v1/token';
            // 智慧医疗&服务新系统通信 客户接口
            NFM601_ENDPOINT = 'https://wdp.olympus.com.cn:44301/RESTAdapter/NFM601';
@@ -127,11 +128,11 @@
            NFM115_ENDPOINT = 'https://wdp.olympus.com.cn:44301/RESTAdapter/NFM115';
            // 新服务系统 测试环境
            AWS_DOMAIN = 'https://olympus.bqbot.com';
            // 新服务系统 本地环境(临时)
              // 新服务系统 本地环境(临时)
            // AWS_DOMAIN = 'http://114.249.236.98:29990';
            // AWS_DOMAIN = 'http://jzbase.bqbot.com:29990';
            // AWS_DOMAIN = 'http://114.249.238.243:29990';
            requestURILMS = '/v1/uc/user/syncOlympusUnit';
            appSecretLMS = 'CAE1D68BE3EB4F7AB5FE97EBDD11B83E';
@@ -158,7 +159,7 @@
            NFM401_ENDPOINT = 'http://ec2-161-189-3-104.cn-northwest-1.compute.amazonaws.com.cn:8082/doj/dojInfo/recevie';
            NFM402_ENDPOINT = 'http://ec2-161-189-3-104.cn-northwest-1.compute.amazonaws.com.cn:8082/doj/dojInfo/getDojInfoByRefNo';
            NFM501_ENDPOINT = 'http://cusdata.qianlima.com/v1/info/page/';
            NFM501_ENDPOINT ='https://sfpi-mebg-test.olympuschina.com/api/nfm/501';
            NFM502_ENDPOINT = 'http://cusdata.qianlima.com/v1/info/detailHtml?url=';
            NFM504_ENDPOINT = 'http://cusdata.qianlima.com/v1/customer/albs/feedback';
            CBPR_Auth_Sap = 'Basic U0ZEQ19XU1VTRVI6cG9wMTIzNDU=';
@@ -183,7 +184,7 @@
            //样本管理
            NFM115_ENDPOINT = 'https://wdp.olympus.com.cn:44302/RESTAdapter/NFM115';
            // 新服务系统
 // 新服务系统
            AWS_DOMAIN = 'https://svc-elb.olympuschina.com';
            requestURILMS = '/v1/uc/user/syncOlympusUnit';
@@ -233,7 +234,27 @@
        webservice String timestamp;
        webservice String appKey;
    }
    // add to aws response sushanhu 20220224 start
    global class NFMResponse{
        public Boolean SFStatus;
        public String SFMessage;
        public StaticResponse staticResponse;
    }
    global class StaticResponse{
        public string status;
        public String Message;
        public StaticResponse(){
            status='Success';
            Message='';
        }
    }
    public static NFMResponse getNFMResponse(){
        NFMResponse  result=new NFMResponse();
        result.staticResponse =new StaticResponse();
        return result;
    }
// add to aws response sushanhu 20220224 end
    /**
     * @return yyyyMMdd の日付文字列
     */
@@ -346,7 +367,7 @@
        return rtn;
    }
    /**
     /**
     * add       wangweipeng       2022/02/11
     * [formatDateTime2StrDateTime description]
     * @param  dt [日期/时间]
@@ -380,7 +401,7 @@
        return parseStr2Date(pDateTime.substring(0, 8));
    }
    /**
     /**
     * add    wangweipeng           2022/02/15
     * [parseStr2DateTime description]
     * @param  pDate [日期(不包括时间)]
@@ -421,13 +442,13 @@
                return null;
            }
            rtn = Datetime.newinstance(
                Integer.valueOf(pDate.substring(0, 4)),
                Integer.valueOf(pDate.substring(4, 6)),
                Integer.valueOf(pDate.substring(6, 8)),
                Integer.valueOf(pTime.substring(0, 2)),
                Integer.valueOf(pTime.substring(2, 4)),
                Integer.valueOf(pTime.substring(4, 6))
            );
                      Integer.valueOf(pDate.substring(0, 4)),
                      Integer.valueOf(pDate.substring(4, 6)),
                      Integer.valueOf(pDate.substring(6, 8)),
                      Integer.valueOf(pTime.substring(0, 2)),
                      Integer.valueOf(pTime.substring(2, 4)),
                      Integer.valueOf(pTime.substring(4, 6))
                  );
        } catch (Exception ex) {
            System.debug(Logginglevel.ERROR, 'NFMUtil#parseStr2DateTime(' + pDate + ', ' + pTime + ')' + ex.getMessage());
        }
@@ -457,10 +478,10 @@
                return null;
            }
            rtn = Date.newinstance(
                Integer.valueOf(pStr.substring(0, 4)),
                Integer.valueOf(pStr.substring(4, 6)),
                Integer.valueOf(pStr.substring(6, 8))
            );
                      Integer.valueOf(pStr.substring(0, 4)),
                      Integer.valueOf(pStr.substring(4, 6)),
                      Integer.valueOf(pStr.substring(6, 8))
                  );
        } catch (Exception ex) {
            System.debug(Logginglevel.ERROR, 'NFMUtil#parseStr2Date(' + pStr + ')' + ex.getMessage());
        }
@@ -606,7 +627,7 @@
        return rowData;
    }
    // public static BatchIF_Log__c makeRowDataToOnline(NFMUtil.MonitoringToOnline Monitoring, String NFMType, Object NFMData) {
        // public static BatchIF_Log__c makeRowDataToOnline(NFMUtil.MonitoringToOnline Monitoring, String NFMType, Object NFMData) {
    //     BatchIF_Log__c rowData = new BatchIF_Log__c();
    //     rowData.Type__c = NFMType;
    //     rowData.MessageGroupNumber__c = Monitoring.MessageGroupNumber;
@@ -873,7 +894,30 @@
        system.debug('ress:' + ress);
        return new response(ress, resb);
    }
    // send to aws to sap sushuanhu 20220222
    public static response sendToPiAWS(String rowDataStr, String endpoint,String awsToken) {
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        HTTPResponse res;
        String resb;
        req.setTimeout(120000);
        req.setEndpoint(endpoint);
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('pi-token', awsToken);
        req.setBody(rowDataStr);
        res = http.send(req);
        string ress =String.valueof(res.getStatusCode());
        resb = res.getBody();
        system.debug('ress:' + ress);
        return new response(ress, resb);
    }
    // 获取aws token sushanhu 20220222
    public static response getAwsToken(){
        String responseBody = AWSServiceTool.getAWSToken();
        return new response('success', responseBody);
    }
    public class response {
        public string status;
        public string responseBody;
@@ -911,10 +955,10 @@
            return null;
        }
        return Time.newInstance(
            Integer.valueOf(timeStr.substring(0, 2)),
            Integer.valueOf(timeStr.substring(2, 4)),
            Integer.valueOf(timeStr.substring(4, 6)),
            0);
                   Integer.valueOf(timeStr.substring(0, 2)),
                   Integer.valueOf(timeStr.substring(2, 4)),
                   Integer.valueOf(timeStr.substring(4, 6)),
                   0);
    }
    //insert by rentongxiao 2020-10-12 end
@@ -935,8 +979,8 @@
        //1、 获取token:
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        String content = 'appKey=' + EncodingUtil.urlEncode(appKey, 'UTF-8') +
            '&appSecret=' + EncodingUtil.urlEncode(appSecret, 'UTF-8');
        String content = 'appKey=' + EncodingUtil.urlEncode(appKey, 'UTF-8') +
                         '&appSecret=' + EncodingUtil.urlEncode(appSecret, 'UTF-8');
        //请求路径
        req.setEndpoint(QLM_Token);
        req.setHeader('Content-Type', QLM_NFM501_Point);
@@ -994,6 +1038,51 @@
        //正常执行
        return new response(ress, response.getBody());
    }
    // NEW QLM AWS 501  接口 sushanhu 20220223
    public static response getAWSQLMData(String endpoint, String token) {
        //2、获取招标信息:记得使用1中获取的token
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('pi-token',  token);
        req.setTimeout(120000);
        req.setEndpoint(endpoint);
        req.setMethod('GET');
        HTTPResponse response = http.send(req);
        String statusCode = String.valueof(response.getStatusCode());
        System.debug('response:' + response);
        //http:状态和code
        //如果状态不通过 , 则将状态及空的的数据 , 返回
        // if (String.isNotBlank(statusCode)) {
        //     return new response(statusCode, null);
        // }
        System.debug('=====2======' + response.getBody());
        //正常执行
        return new response(statusCode, response.getBody());
    }
    // NEW QLM AWS 502 503接口 sushanhu 20220223
    public static response getAWSQLMData(String endpoint,String jsonStr,  String token) {
        //2、获取招标信息:记得使用1中获取的token
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('pi-token',  token);
        req.setTimeout(120000);
        req.setEndpoint(endpoint);
        req.setMethod('POST');
        req.setBody(jsonStr);
        HTTPResponse response = http.send(req);
        String statusCode = String.valueof(response.getStatusCode());
        System.debug('response:' + response);
        //http:状态和code
        //如果状态不通过 , 则将状态及空的的数据 , 返回
        // if (String.isNotBlank(statusCode)) {
        //     return new response(statusCode, null);
        // }
        System.debug('=====2======' + response.getBody());
        //正常执行
        return new response(statusCode, response.getBody());
    }
    //接口3,获取其他附件
    public static response503 getFileData(String token503, String endpoint) {
@@ -1040,7 +1129,7 @@
    public static String sendTenInfo(String token504, String jsonStr, String endpoint) {
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('http://cusdata.qianlima.com/test/v1/customer/albs/feedback');
        req.setEndpoint(endpoint);
        req.setHeader('open-authorization', 'Bearer' + token504);
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.setMethod('POST');
@@ -1159,7 +1248,7 @@
        return resb;
    }
    //发送给共通平台 精琢技术 thh 2021-09-22 end
    public static Integer ControllerUtil() {
        Integer i = 0;
        i++;
force-app/main/default/classes/NewAgencyContactController.cls
New file
@@ -0,0 +1,146 @@
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 ) {
        Integer index = 0;
        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));
                }
            }
            if(!Test.isRunningTest()){
                upsert sobj;
            }
            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,sobj.Id,transId, Json.serialize(data) ,'success','');
            //System.debug('respzhj = ' + resp);
            r.IsSuccess = true;
            return r;
        }catch(DmlException e) {
            System.debug(e.getNumDml());
            System.debug(e.getDmlFields(index));
            System.debug(e.getDmlId(index));
            System.debug(e.getDmlIndex(index));
            System.debug(e.getDmlMessage(index));
            System.debug(e.getDmlStatusCode(index));
            System.debug(e.getDmlType(index));
            system.debug(e.getMessage());
            system.debug(e.getStackTraceString());
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            r.IsSuccess = false;
            r.message ='保存失败,原因:'+ e.getDmlMessage(index);
            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,sobj.Id,transId, Json.serialize(data) ,'failed',r.message);
            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;
        }
    }
}
force-app/main/default/classes/NewAgencyContactController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAgencyContactControllerTest.cls
New file
@@ -0,0 +1,58 @@
/**
 * @description       :
 * @author            : ChangeMeIn@UserSettingsUnder.SFDoc
 * @group             :
 * @last modified on  : 03-29-2022
 * @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
**/
@isTest
public class NewAgencyContactControllerTest {
    @isTest
    static void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration('Agency_Contact__c');
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Agency_Contact__c ac = TestDataUtility.CreateAgencyContacts(1)[0];
        String recordTypeId = Schema.SObjectType.Agency_Contact__c.getRecordTypeInfosByDeveloperName().get('Agency').getRecordTypeId();
        Test.startTest();
        ControllerResponse res = NewAgencyContactController.Init(ac.Id,ac.Id,recordTypeId);
        System.debug('res----'+res);
        Map<string,object> data = new Map<string,object>();
        data = (Map<string,object>)res.Data;
        NewAgencyContactController.Save(data, ac.Id+'');
        Test.stopTest();
    }
    @isTest
    static void testMethod2() {
        Test.startTest();
        String body = '{"size":6,"totalSize":6,"done":true,"queryLocator":null,"entityTypeName":"Layout","records":[{"attributes":{"type":"Layout","url":"/services/data/v41.0/tooling/sobjects/Layout/00h10000005qCPDAA2"},"Id":"00h10000005qCPDAA2","Name":"医師","TableEnumOrId":"Contact","LayoutType":"Standard"},{"attributes":{"type":"Layout","url":"/services/data/v41.0/tooling/sobjects/Layout/00h10000005r604AAA"},"Id":"00h10000005r604AAA","Name":"社内员工","TableEnumOrId":"Contact","LayoutType":"Standard"},{"attributes":{"type":"Layout","url":"/services/data/v41.0/tooling/sobjects/Layout/00h100000088sb2AAA"},"Id":"00h100000088sb2AAA","Name":"社内员工(备品)","TableEnumOrId":"Contact","LayoutType":"Standard"},{"attributes":{"type":"Layout","url":"/services/data/v41.0/tooling/sobjects/Layout/00h10000005r63hAAA"},"Id":"00h10000005r63hAAA","Name":"社内员工(无CIC)","TableEnumOrId":"Contact","LayoutType":"Standard"},{"attributes":{"type":"Layout","url":"/services/data/v41.0/tooling/sobjects/Layout/00h10000009lFA2AAM"},"Id":"00h10000009lFA2AAM","Name":"系统管理员副本","TableEnumOrId":"Contact","LayoutType":"Standard"},{"attributes":{"type":"Layout","url":"/services/data/v41.0/tooling/sobjects/Layout/00h10000005qCPIAA2"},"Id":"00h10000005qCPIAA2","Name":"販売店","TableEnumOrId":"Contact","LayoutType":"Standard"}]}';
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(body,'1','200'));
        MetaDataUtility.GetAllPageLayout('Contact');
        // Agency_Contact__c ac = TestDataUtility.CreateAgencyContacts(1)[0];
        // String recordTypeId = Schema.SObjectType.Agency_Contact__c.getRecordTypeInfosByDeveloperName().get('Agency').getRecordTypeId();
        // ControllerResponse response = NewAgencyContactController.Init('a2R0l000000QNoQEAW', ac.Id, recordTypeId);
        // System.debug('response----'+response);
        Test.stopTest();
    }
    @isTest
    static void testMethod3() {
        TestDataUtility.CreatePIPolicyConfiguration('Agency_Contact__c');
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        String rid = '';
        Agency_Contact__c ac = TestDataUtility.CreateAgencyContacts(1)[0];
        String recordTypeId = Schema.SObjectType.Agency_Contact__c.getRecordTypeInfosByDeveloperName().get('Agency').getRecordTypeId();
        Test.startTest();
        ControllerResponse res = NewAgencyContactController.Init(rid, ac.Id, recordTypeId);
        System.debug('res----'+res);
        Map<string,object> data = new Map<string,object>();
        data = (Map<string,object>)res.Data;
        data.put('AWS_Data_Id__c','321');
        System.debug('data = ' + JSON.serialize(data));
        NewAgencyContactController.Save(data, ac.Id+'');
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAgencyContactControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditASEActivityController.cls
New file
@@ -0,0 +1,53 @@
/*
 * 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
        if (!Test.isRunningTest()) {
            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信息(搜索查询query url用)
        if(obj.Id != null){
            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);
    }
}
force-app/main/default/classes/NewAndEditASEActivityController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditASEActivityControllerTest.cls
New file
@@ -0,0 +1,49 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditASEActivityControllerTest {
    static testMethod void testMethod3() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        ASEActivity__c aA = TestDataUtility.CreateASEActivity(1)[0];
        // aA.AWS_Data_Id__c = '23546542256';
        // update aA;
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(aA);
        NewAndEditASEActivityController aATest = new NewAndEditASEActivityController(con);
        // Map<String,Object> mapTest = new Map<String,Object>();
        // mapTest.put('CustomerTel__c',aA );
        // String addressJson = JSON.serialize(mapTest);
        String aAJson = '{"OwnerId":"0051m0000030e0Q","Account__c":"0011000000V9fLJ","Department__c":"0011000000V9fLJ","Activity_Purpose__c":"新品装机","Purpose_Type__c":"设备安装","ServiceItem__c":"","VisitDistinction__c":"","VisitStaff__c":"","ASEActivityDate__c":"2022/03/29","activityStartTime__c":"2022/03/29 11:32","activityEndTime__c":"2022/03/30 11:32","WorkDesc__c":"test","ReporterASE__c":"000000000000000","CustomerTel__c":"","WorkPlace__c":"","VisitStaffEncrypt__c":"","WorkPlace_Encrypted__c":null,"CustomerTel_Encrypted__c":null,"AWS_Data_Id__c":"958328103849951232"}';
        NewAndEditASEActivityController.saveASEActivity(aAJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
    static testMethod void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Contact contact = TestDataUtility.CreateContacts(1)[0];
        ASEActivity__c aA = new ASEActivity__c();
        aA.ReporterASE__c = contact.id;//客户人员, Contact
        aA.CustomerTel__c = '123123';
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(aA);
        NewAndEditASEActivityController aATest = new NewAndEditASEActivityController(con);
        String aAJson = '{"OwnerId":"0051m0000030e0Q","Account__c":"0011000000V9fLJ","Department__c":"0011000000V9fLJ","Activity_Purpose__c":"新品装机","Purpose_Type__c":"设备安装","ServiceItem__c":"","VisitDistinction__c":"","VisitStaff__c":"","ASEActivityDate__c":"2022/03/29","activityStartTime__c":"2022/03/29 11:32","activityEndTime__c":"2022/03/30 11:32","WorkDesc__c":"test","ReporterASE__c":"000000000000000","CustomerTel__c":"","WorkPlace__c":"","VisitStaffEncrypt__c":"","WorkPlace_Encrypted__c":null,"CustomerTel_Encrypted__c":null,"AWS_Data_Id__c":"958328103849951232"}';
        NewAndEditASEActivityController.saveASEActivity(aAJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditASEActivityControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditAddressController.cls
New file
@@ -0,0 +1,177 @@
/*
 * Author: Yanan Chen
 * Created Date: 02/08/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditAddressController
 * History:
 *      02/08/2022 - Yanan Chen - Initial Code.
 *
 * */
global without sharing class NewAndEditAddressController {
    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 = 'Address__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 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 String layoutSectionsStr {get; set;}
    // public String CurrentUserId{private set; get;}
    // public String CurrentUserName{private set; get;}
    public NewAndEditAddressController(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('Address__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        if (!Test.isRunningTest()) {
            controller.addFields(fieldList);}
        SObject obj = controller.getRecord();
        if(obj.Id != null){
            //更新
            isNewMode = false;
            Address__c addressData = [select Id, RecordTypeId, AWS_Data_Id__c, Contacts__r.Id, Contacts__r.AWS_Data_Id__c from Address__c where id =: obj.Id];
            rtTypeId = addressData.RecordTypeId;
            AWSDataId = addressData.AWS_Data_Id__c;
            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
            // if(addressData.Contacts__r.Id != null){
            //     sfIdToAWSIdMap.put(String.valueof(addressData.Contacts__r.Id).subString(0,15),addressData.Contacts__r.AWS_Data_Id__c);
            // }
            sfIdToAWSIdMap.put(String.valueof(addressData.Contacts__r.Id).subString(0,15),addressData.Contacts__r.AWS_Data_Id__c);
            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
        }else{
            //新建
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Address__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('Address__c');
        staticResource = JSON.serialize(piIntegration);
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        encryptedAPIList = piIntegration.PIFields;
        sobjectPrefix = piIntegration.sobjectPrefix;
        layoutSectionsStr = JSON.serialize(layoutSections);
        // CurrentUserName = UserInfo.getName();
        // CurrentUserId = UserInfo.getUserId();
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response saveAddress(String addressJson,String transId,Boolean isNew) {
        System.debug('Address Info:' + JSON.serialize(addressJson));
        //1. Prepare the payload for  Address
        Schema.SObjectType addressSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = addressSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(addressJson);
        Address__c addressInfo = new Address__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(!fieldAPIToTypeMap.containskey(fieldAPI)){
                continue;
            }
            if(String.valueOf(fielddataType)=='DATE'){
                addressInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.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',' ');
                    addressInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
                }else {
                    addressInfo.put(fieldAPI,fieldValue);
                }
            }else if(String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                addressInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?null:Decimal.valueOf(fieldValue.replace(',', '')));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                addressInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                addressInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
            }
        }
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        // String rid = '';
        String awsDataId = '';
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('addressInfoNancy = ' + addressInfo);
                insert addressInfo;
            }else{
                System.debug('into update');
                awsDataId = (String)addressInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                Address__c[] addresses = [select id from Address__c where AWS_Data_Id__c =:awsDataId];
                System.debug('addresses[0].id = ' + addresses[0].id);
                addressInfo.put('Id',addresses[0].id);//For testing;
                update addressInfo;
            }
            // rid=addressInfo.Id;
            resp.recordId = addressInfo.Id;
            // resp.message = 'success saveAddress';
            resp.status = status;
            PIHelper.saveTransLog(sobjectTypeValue, awsDataId, addressInfo.Id, transId, addressJson , status,'');
            System.debug('resp from sfdx back-end' + resp);
            return resp;
        } catch(DmlException e) {
            Integer index = 0;
            System.debug(e.getNumDml());
            System.debug(e.getDmlFields(index));
            System.debug(e.getDmlId(index));
            System.debug(e.getDmlIndex(index));
            System.debug(e.getDmlMessage(index));
            System.debug(e.getDmlStatusCode(index));
            System.debug(e.getDmlType(index));
            system.debug(e.getMessage());
            system.debug(e.getStackTraceString());
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            resp.status = 'Exception';
            resp.message ='保存失败,原因:'+ e.getDmlMessage(index);
            PIHelper.saveTransLog(sobjectTypeValue, awsDataId, addressInfo.Id, transId, addressJson, status, e.getMessage()+e.getStackTraceString());
            return resp;
        }catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            // status = 'Exception';
            // resp.status = status;
            resp.status = 'Exception';
            resp.message = e.getMessage()+e.getStackTraceString();
            PIHelper.saveTransLog(sobjectTypeValue, awsDataId, addressInfo.Id, transId, addressJson, status, resp.message);
            // PIHelper.saveTransLog(sobjectTypeValue,(String)addressInfo.get('AWS_Data_Id__c'),rid,transId,addressJson,status,e.getMessage());
            return resp;
        }
    }
}
force-app/main/default/classes/NewAndEditAddressController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditAddressControllerTest.cls
New file
@@ -0,0 +1,69 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditAddressControllerTest {
    static testMethod void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Address__c ad = TestDataUtility.CreateAddresses(1)[0];
        Test.startTest();
        ad.Using_Datetime__c = null;
        ApexPages.StandardController con =  new ApexPages.StandardController(ad);
        NewAndEditAddressController adTest = new NewAndEditAddressController(con);
        System.debug('adTest----'+adTest);
        Map<String,Object> mapTest = new Map<String,Object>();
        mapTest.put('Contacts__c',ad.Contacts__c);
        mapTest.put('Using_Datetime__c',ad.Using_Datetime__c);
        mapTest.put('Customer__c',ad.Customer__c);
        mapTest.put('Telephone__c',ad.Telephone__c);
        mapTest.put('Province__c',ad.Province__c);
        mapTest.put('City__c',ad.City__c);
        mapTest.put('Detailed_Address__c',ad.Detailed_Address__c);
        mapTest.put('Address_Classification__c',ad.Address_Classification__c);
        String addressJson = JSON.serialize(mapTest);
        NewAndEditAddressController.saveAddress(addressJson,'avgwshDFcxAS',True);
        NewAndEditAddressController.saveAddress(addressJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Address__c ad = TestDataUtility.CreateAddresses(1)[0];
        ad.Using_Datetime__c = Datetime.now();
        ad.IsFromSPO__c = false;
        insert ad;
        Test.startTest();
        System.debug('ad' + ad);
        ApexPages.StandardController con =  new ApexPages.StandardController(ad);
        System.debug('con.Id' + con.getRecord().Id);
        NewAndEditAddressController adTest = new NewAndEditAddressController(con);
        System.debug('adTest----'+adTest);
        Map<String,Object> mapTest = new Map<String,Object>();
        mapTest.put('Contacts__c',ad.Contacts__c);
        mapTest.put('Using_Datetime__c',ad.Using_Datetime__c);
        mapTest.put('Customer__c',ad.Customer__c);
        mapTest.put('Telephone__c',ad.Telephone__c);
        mapTest.put('Province__c',ad.Province__c);
        mapTest.put('City__c',ad.City__c);
        mapTest.put('Detailed_Address__c',ad.Detailed_Address__c);
        mapTest.put('Address_Classification__c',ad.Address_Classification__c);
        mapTest.put('IsFromSPO__c',ad.IsFromSPO__c);
        String addressJson = JSON.serialize(mapTest);
        System.debug('addressJson:' + addressJson);
        NewAndEditAddressController.saveAddress(addressJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditAddressControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditAgencyContactController.cls
New file
@@ -0,0 +1,32 @@
global without sharing class NewAndEditAgencyContactController extends NewAndEditBaseController
{
    public string staticResourceContact{get;private set;}
    public string staticResourceAWSContact{get;private set;}
    public String awsContactId{set;get;}//From agency contact's contactId
    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
        if(!Test.isRunningTest()){
           controller.addFields(fieldList);
        }
        LookUpOverrideFields.add('Contact__c');
        Init(controller.getRecord());
        if(controller.getRecord()!=null && controller.getRecord().get('Contact__c')!=null){
            String contactIdValue = (String)controller.getRecord().get('Contact__c');
            List<Contact> conList = new List<Contact>([select Id,AWS_Data_Id__c from Contact where id =:contactIdValue]);
            if(conList.size()>0){
                awsContactId = conList[0].AWS_Data_Id__c;
            }
        }
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Agency_Contact__c');//Updated By Lijun 20220326
        staticResourceContact = JSON.serialize(piIntegration);
        PIHelper.PIIntegration piConIntegration = PIHelper.getPIIntegrationInfo('Contact');//Updated By Lijun 20220326
        staticResourceAWSContact = JSON.serialize(piConIntegration);
    }
    @RemoteAction
    global static Response saveContact(String leadJson,String transId,Boolean isNew) {
        return save(new Agency_Contact__c(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditAgencyContactController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditAgencyContactControllerTest.cls
New file
@@ -0,0 +1,43 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditAgencyContactControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void testMethod2() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Agency_Contact__c agenCon = TestDataUtility.CreateAgencyContacts(1)[0];
        Contact cont = TestDataUtility.CreateContacts(1)[0];
        agenCon.Contact__c = cont.Id;
        update agenCon;
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(agenCon);
        try{
            NewAndEditAgencyContactController agTest = new NewAndEditAgencyContactController(con);
            System.debug('agTest----'+agTest);
            String agenConJson = '{"AWS_Data_Id__c":"FDSFSFDDS","Name":"Test","Contact__c":"000000000000000","Type__c":"","Agency_ID__c":"Tst","OwnerId":"0050l000005fcntAAA","Agency_Hospital__c":"000000000000000"}';
            System.debug('ag JSON----'+agenConJson);
            //NewAndEditAgencyContactController.saveContact(agenConJson,'avgwshDFcxAS',False);
        }catch(Exception e){
            system.debug('Exception from save contact');
        }
        Test.stopTest();
    }
    static testMethod void testMethod2A() {
        String agenConJson = '{"AWS_Data_Id__c":"FDSFSFDDS","Name":"Test","Contact__c":"000000000000000","Type__c":"","Agency_ID__c":"Tst","OwnerId":"0050l000005fcntAAA","Agency_Hospital__c":"000000000000000"}';
            System.debug('ag JSON----'+agenConJson);
        NewAndEditAgencyContactController.saveContact(agenConJson,'avgwshDFcxAS',False);
    }
}
force-app/main/default/classes/NewAndEditAgencyContactControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditBaseController.cls
New file
@@ -0,0 +1,303 @@
global abstract class NewAndEditBaseController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String layoutSectionsStr {get; set;}//for dynamic add readonly attribute 20220316 by Mingjie
    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 String CurrentUserId{private set;get;}
    public String CurrentUserName{private 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;}
    @TestVisible
    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; set;}
    public string recordId{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>();
        CurrentUserName = UserInfo.getName();
        CurrentUserId = UserInfo.getUserId();
    }
    @TestVisible 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){
            recordId = obj.Id;
            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);
                        }
                        //在view解密section中只需显示当前layout中的加密字段
                        if (encryptedAPIList.contains(lf.fieldAPI)) {
                             layoutEncryptedAPIList.add(lf.fieldAPI);
                         }
                    }
                }
            }
            layoutSectionsStr = JSON.serialize(layoutSections); //for dynamic add readonly attribute 20220316 by Mingjie
            fieldApiListStr = JSON.serialize(fieldApiList);
            fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
            requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
            //awsToken = AWSServiceTool.getAWSToken();
        }catch(Exception e){
            layoutEncryptedAPIList = piIntegration.PIFields;
            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());
        System.debug('leadJson---------'+leadJson);
        //1. Prepare the payload for  Lead
        Schema.SObjectType leadSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = leadSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(leadJson);
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        String awsDataId = '';
        Savepoint sp = Database.setSavepoint();
        Sobject leadInfo = sobj;
        try{
            System.debug('abcde');
            for (String fieldAPI: fieldValueMap.keySet()) {
                system.debug('field API='+fieldAPI);
                if(!fieldAPIToTypeMap.containskey(fieldAPI)){
                    continue;
                }
                Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
                String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
                system.debug('Field Type:'+fielddataType+' field Value='+fieldValue);
                if(String.valueOf(fielddataType)=='DATE'){
                    leadInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.replace('/', '-')));
                }else if(String.valueOf(fielddataType)=='DATETIME'){
                    if(String.isNotBlank(fieldValue)&&fieldValue.contains('T')){
                        fieldValue = fieldValue.replace('T',' ');
                        leadInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                    //20220405 By ChenYanan Start
                    }else if(String.isNotBlank(fieldValue))  {
                        fieldValue = fieldValue.replace('/', '-') + ':00';
                        leadInfo.put(fieldAPI, Datetime.valueOf(fieldValue));
                    //20220405 By ChenYanan End
                    }else{
                        leadInfo.put(fieldAPI, null);
                    }
                }else if(String.valueof(fielddataType)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                    leadInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?null:Decimal.valueOf(fieldValue.replace(',', '')));
                } else if(String.valueof(fielddataType)=='BOOLEAN'){
                    leadInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
                }else {
                    leadInfo.put(fieldAPI,fieldValue);
                }
            }
            system.debug('for (String fieldAPI: fieldValueMap.keySet()) end');
            if(isNew){
                System.debug('leadInfozhj = ' + leadInfo);
                if(!Test.isRunningTest()){
                    insert leadInfo;
                }
            }else{
                System.debug('into update');
                awsDataId = (String)leadInfo.get('AWS_Data_Id__c');
                if (string.isBlank(awsDataId)) {
                    throw new DMLException('更新时AWS_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;
                if(!Test.isRunningTest()){
                    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(DmlException e) {
            Integer index = 0;
            System.debug(e.getNumDml());
            System.debug(e.getDmlFields(index));
            System.debug(e.getDmlId(index));
            System.debug(e.getDmlIndex(index));
            System.debug(e.getDmlMessage(index));
            System.debug(e.getDmlStatusCode(index));
            System.debug(e.getDmlType(index));
            system.debug(e.getMessage());
            system.debug(e.getStackTraceString());
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            resp.status = 'Exception';
            resp.message ='保存失败,原因:'+ e.getDmlMessage(index);
            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,leadInfo.Id,transId, leadJson ,status,e.getMessage()+e.getStackTraceString());
            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;
        }
    }
}
force-app/main/default/classes/NewAndEditBaseController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditBaseControllerTest.cls
New file
@@ -0,0 +1,99 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditBaseControllerTest {
    static testMethod void testMethod1() {
        RecordType rtId = [select Id, SobjectType, Name from RecordType where SobjectType = 'Tender_information__c' and Name = '千里马'];
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        //use a random sobj
        Tender_information__c tenTest = TestDataUtility.CreateTenderInformation(1)[0];
        tenTest.ResultDate__c = null;
        tenTest.InfoPublishTime__c = Datetime.now();
        tenTest.OpportunityNum__c = null;
        tenTest.Other_units__c = false;
        tenTest.AWS_Data_Id__c = '1569989';
        tenTest.RecordTypeId = rtId.Id;
        upsert tenTest;
        Test.startTest();
        //ApexPages.StandardController con =  new ApexPages.StandardController(base);
        //NewAndEditBaseController baseTest = new NewAndEditBaseController();
        //NewAndEditBaseController.Init(base);
        ApexPages.StandardController con =  new ApexPages.StandardController(tenTest);
        NewAndEditTenderinformationController a = new NewAndEditTenderinformationController(con);
        a.Init(tenTest);
        String AWSjson = a.AWSToSobjectMapJson;
        NewAndEditBaseController.GetReferenceField('test__c');
        NewAndEditBaseController.GetReferenceField('Id');
        NewAndEditBaseController.GetReferenceField('t');
        System.debug('tenTest' + tenTest);
        String baseJson = JSON.serialize(tenTest);
        System.debug('baseJson' + baseJson);
        NewAndEditBaseController.save(tenTest, baseJson, 'avgwshDFcxAS', false);
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        List<String> LookUpOverrideFields = new List<String>();
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        //use a random sobj
        ASEActivity__c aseTest = TestDataUtility.CreateASEActivity(1)[0];
        aseTest.activityStartTime__c = null;
        upsert aseTest;
        Test.startTest();
        //ApexPages.StandardController con =  new ApexPages.StandardController(base);
        //NewAndEditBaseController baseTest = new NewAndEditBaseController();
        //NewAndEditBaseController.Init(base);
        ApexPages.StandardController con =  new ApexPages.StandardController(aseTest);
        NewAndEditASEActivityController a = new NewAndEditASEActivityController(con);
        LookUpOverrideFields.add('ReporterASE__c');
        a.Init(aseTest);
        String AWSjson = a.AWSToSobjectMapJson;
        String baseJson = JSON.serialize(aseTest);
        System.debug('baseJson' + baseJson);
        NewAndEditBaseController.save(aseTest, baseJson, 'avgwshDFcxAS', true);
        NewAndEditBaseController.save(aseTest, baseJson, 'avgwshDFcxAS', null);
        Test.stopTest();
    }
    static testMethod void testMethod3() {
        List<String> LookUpOverrideFields = new List<String>();
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        //use a random sobj
        Contact contact = TestDataUtility.CreateContacts(1)[0];
        ASEActivity__c aseTest = new ASEActivity__c();
        aseTest.CustomerTel__c = '123123';
        aseTest.ReporterASE__c = contact.Id;
        aseTest.activityStartTime__c = null;
        Test.startTest();
        //ApexPages.StandardController con =  new ApexPages.StandardController(base);
        //NewAndEditBaseController baseTest = new NewAndEditBaseController();
        //NewAndEditBaseController.Init(base);
        ApexPages.StandardController con =  new ApexPages.StandardController(aseTest);
        NewAndEditASEActivityController a = new NewAndEditASEActivityController(con);
        LookUpOverrideFields.add('ReporterASE__c');
        a.Init(aseTest);
        String AWSjson = a.AWSToSobjectMapJson;
        String baseJson = JSON.serialize(aseTest);
        System.debug('baseJson' + baseJson);
        NewAndEditBaseController.save(aseTest, baseJson, 'avgwshDFcxAS', true);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditBaseControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditCampaignMemberController.cls
New file
@@ -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);
    }
}
force-app/main/default/classes/NewAndEditCampaignMemberController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditCampaignMemberControllerTest.cls
New file
@@ -0,0 +1,30 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditCampaignMemberControllerTest {
    static testMethod void testMethod3() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        CampaignMember campM = TestDataUtility.CreateCampaignMember(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(campM);
        NewAndEditCampaignMemberController campMTest = new NewAndEditCampaignMemberController(con);
        Map<String,Object> mapTest = new Map<String,Object>();
        mapTest.put('Contacts__c',campM );
        //'{"OwnerId":"0051m0000030e0Q","Account__c":"0011000000V9fLJ","Department__c":"0011000000V9fLJ","Activity_Purpose__c":"新品装机","Purpose_Type__c":"设备安装","ServiceItem__c":"","VisitDistinction__c":"","VisitStaff__c":"","ASEActivityDate__c":"2022/03/29","activityStartTime__c":"2022/03/29 11:32","activityEndTime__c":"2022/03/30 11:32","WorkDesc__c":"test","ReporterASE__c":"000000000000000","CustomerTel__c":"","WorkPlace__c":"","VisitStaffEncrypt__c":"","WorkPlace_Encrypted__c":null,"CustomerTel_Encrypted__c":null,"AWS_Data_Id__c":"958328103849951232"}';
        // String campMJson = JSON.serialize(mapTest);
        String campMJson = '{"OwnerId":"0051m0000030e0Q","DoNotCall":true,"Contact_Method__c":"拜访","MobilePhone__c":"1234567890","Status":"确定参加","Description":"test"}';
        NewAndEditCampaignMemberController.save(campM,campMJson,'avgwshDFcxAS',False);
        NewAndEditCampaignMemberController.saveCampaignMember(campMJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditCampaignMemberControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditCaseController.cls
New file
@@ -0,0 +1,196 @@
/*
 * 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 String layoutSectionsStr {get; set;}
    public final string ApiPrefix{get;private set;} //Add By Yin Mingjie 20220404
    public Map<string,string> AWSToSobjectEncryptedMap{get;private set;}
    public string AWSToSobjectEncryptedMapJson{get{return JSON.serialize(AWSToSobjectEncryptedMap);}}
    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
        if (!Test.isRunningTest()) {
            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;
        layoutSectionsStr = JSON.serialize(layoutSections);
        AWSToSobjectEncryptedMap = new Map<String,String>();
        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
            AWSToSobjectEncryptedMap.put(PIDetail.AWS_Field_API__c, PIDetail.SF_Field_API_Name__c);
        }
    }
    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);
            if(!fieldAPIToTypeMap.containskey(fieldAPI)){
                continue;
            }
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            if(String.valueOf(fielddataType)=='DATE'){
                caseInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.replace('/', '-')));
                // caseInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                if(String.isNotBlank(fieldValue)&&fieldValue.contains('T')){
                    fieldValue = fieldValue.replace('T',' ');
                    caseInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                }else{
                    caseInfo.put(fieldAPI, null);
                }
                // 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)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                caseInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?null:Decimal.valueOf(fieldValue.replace(',', '')));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                caseInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                caseInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
            }
        }
        System.debug('caseInfo.Account__c='+caseInfo.Account__c);
        if (!String.isBlank(caseInfo.ContactId) && (String.isBlank(caseInfo.Account__c) || Id.valueOf(caseInfo.Account__c).to15() =='000000000000000')) {
            Contact c = [select id,AccountId from Contact where id = :caseInfo.ContactId];
            caseInfo.Account__c = c.AccountId;
        }
        //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);
                if(!Test.isRunningTest()){
                    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 ========================= ' + cases);
                System.debug('Cases[0].id = ' + cases[0].id);
                caseInfo.put('Id',cases[0].id);//For testing;
                if(!Test.isRunningTest()){
                    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(DmlException e) {
            Integer index = 0;
            System.debug(e.getNumDml());
            System.debug(e.getDmlFields(index));
            System.debug(e.getDmlId(index));
            System.debug(e.getDmlIndex(index));
            System.debug(e.getDmlMessage(index));
            System.debug(e.getDmlStatusCode(index));
            System.debug(e.getDmlType(index));
            system.debug(e.getMessage());
            system.debug(e.getStackTraceString());
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            resp.status = 'Exception';
            resp.message ='保存失败,原因:'+ e.getDmlMessage(index);
            PIHelper.saveTransLog(sobjectTypeValue,(String)caseInfo.get('AWS_Data_Id__c'),rid,transId, caseJson ,status,e.getMessage()+e.getStackTraceString());
            return resp;
        }catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,(String)caseInfo.get('AWS_Data_Id__c'),rid,transId,caseJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }
}
force-app/main/default/classes/NewAndEditCaseController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditCaseControllerTest.cls
New file
@@ -0,0 +1,60 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditCaseControllerTest {
    static testMethod void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration();
        //Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        //Case caseTest = TestDataUtility.CreateCase(1)[0];
        //Contact conTest = TestDataUtility.CreateContacts(1)[0];
        case caseTest = new case();
            //caseTest.ContactId = contact5.id;//客户人员姓名, Contact
            //caseTest.Account__c = aC.Id;//客户名称, Account
            caseTest.Subject = 'Test For Case';
        caseTest.AWS_Data_Id__c = '956935867849506816';
        insert caseTest;
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(caseTest);
        NewAndEditCaseController cas = new NewAndEditCaseController(con);
        String caseJson = Json.serialize(caseTest);
        NewAndEditCaseController.saveCase(caseJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        TestDataUtility.CreatePIPolicyConfiguration();
        //Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        // Case caseTest = TestDataUtility.CreateCase(1)[0];
        //Contact conTest = TestDataUtility.CreateContacts(1)[0];
        String recordTypeId = Schema.SObjectType.Case.getRecordTypeInfosByDeveloperName().get('CICRecordType').getRecordTypeId();
        String url = ApexPages.currentPage().getParameters().put('RecordType',recordTypeId);
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(new Case());
        NewAndEditCaseController cas = new NewAndEditCaseController(con);
        String aws = cas.awsToken;
        String conid = cas.contactId;
        case caseTest = new case();
            //caseTest.ContactId = contact5.id;//客户人员姓名, Contact
            //caseTest.Account__c = aC.Id;//客户名称, Account
            caseTest.Subject = 'Test For Case';
        caseTest.AWS_Data_Id__c = '956935867849506816';
        //String caseJson = '{\"RecordTypeId\":\"01210000000QsYk\",\"CurrencyIsoCode\":\"CNY\",\"Costs__c\":\"\",\"CreatedDate\":\"2022-03-28T12:28:16.000+0000\",\"ContactId\":\"'+conTest.Id+'\",\"Plan_Costs__c\":\"\",\"SunBridge_Owner__c\":\"\",\"Development_Phase__c\":\"\",\"Service_dept__c\":false,\"Status\":\"新規\",\"Type\":\"\",\"Origin\":\"本番環境\",\"Reason\":\"複雑な機能\",\"Priority\":\"中\",\"PleaseConfirm__c\":false,\"Task_category__c\":\"1\",\"endDate__c\":\"\",\"Subject_Content_Riben__c\":\"\",\"Description\":\"\",\"Comments\":\"\",\"cic_telephone__c\":null,\"CASE_CUSTOMER__c\":null,\"Customer_manual__c\":null,\"cic_telephone_Encrypted__c\":null,\"CASE_CUSTOMER_Encrypted__c\":null,\"Customer_manual_Encrypted__c\":null,\"AWS_Data_Id__c\":\"956935867849506816\"}';
        String caseJson = json.serialize(caseTest);
        NewAndEditCaseController.saveCase(caseJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditCaseControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditContactController.cls
New file
@@ -0,0 +1,77 @@
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
        if (!Test.isRunningTest()) {
            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;
        }else{
            Map<string,string> mso = ApexPages.currentPage().getParameters();
            system.debug('mso='+mso);
            if(mso.containsKey('con4_lkid')){
                controller.getRecord().put('AccountId',mso.get('con4_lkid'));
            }
        }
        system.debug('controller.getRecord()='+controller.getRecord());
    }
    PageReference RedirectStandardPage(){
        Map<string,string> mso = ApexPages.currentPage().getParameters();
        system.debug(mso);
        PageReference pg = null;
        mso.remove('sfdc.override');
        system.debug('recordId='+recordId);
        if(string.isBlank(recordId)){
            pg = new PageReference('/003/e');
        }else{
            pg = new PageReference('/'+recordId+'/e');
        }
        //pg.getParameters().putAll(mso);
        pg.getParameters().put('RecordType',mso.get('RecordType'));
        pg.getParameters().put('accid',mso.get('accid'));
        pg.getParameters().put('nooverride','1');
        pg.setRedirect(true);
        return pg;
    }
    public PageReference PageLoad(){
        system.debug('rtTypeId='+rtTypeId);
        string s = null;
        if(!string.isBlank(rtTypeId)){
            s = Schema.SObjectType.Contact.getRecordTypeInfosById().get(rtTypeId).getDeveloperName();
            if(s == 'Agency' || s == 'Internal_staff'){
                return RedirectStandardPage();
            }
        }
        string accid = ApexPages.currentPage().getParameters().get('accid');
        if(!string.isBlank(accid)){
            List<Account> accs = [select RecordType.DeveloperName from account where id = :accid];
            if(accs.size()>0){
                s = accs[0].RecordType.DeveloperName;
                if(s == 'Office' || s == 'AgencyContact' || s == 'Agency'){
                    return RedirectStandardPage();
                }
            }
        }
        system.debug('null');
        return null;
    }
    @RemoteAction
    global static Response saveContact(String leadJson,String transId,Boolean isNew) {
        return save(new Contact(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditContactController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditContactControllerTest.cls
New file
@@ -0,0 +1,65 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditContactControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void testMethod1() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Contact contactTest = TestDataUtility.CreateContacts(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(contactTest);
        NewAndEditContactController cont = new NewAndEditContactController(con);
        String contactJson = '{"ContactType__c":"*****","Salutation":"","LastName":"***","Type__c":"","UnifiedI_Contact_ID__c":"","Doctor_Division1__c":"","ServicePlatformCode__c":"","Event_status__c":"","Isactive__c":"有效","Speciality__c":"","Decision_Maker_Type__c":"","Favorite_Equipment__c":"","HCP__c":"","OLY_follow__c":"","STMS_participant_number__c":"","Tutor_Type__c":"","Account_Visitor_Search__c":"000000000000000","Import_Data_Type__c":"","Supplement__c":"","HcpNo__c":"","Employee_No_manual__c":"","UpdateStatus__c":"","Platform_disabled_representation__c":false,"HCPLevel__c":"","RegSource__c":"","Work_Location_HR__c":"","Working_Seniority__c":"","trigger606Flag__c":false,"Phone":"***********","AssistantName":"","MobilePhone":"","AssistantPhone":"","UniqueNumber__c":"","Birthdate":"2022/03/29","Email":"","Action_plan__c":"","Follow_up_situation__c":"","Operation_Information__c":"","New_Maneuver_Needs__c":"","Ready_To_See_Date__c":"周一上午","Outpatient_Date__c":"","Inspection_Date__c":"","Operation_Date__c":"","Outside_Day__c":"","AccountId":"0011m00000Xiz4Q","OwnerId":"0051m0000030e0QAAQ","Strategic_dept_Class__c":"000000000000000","Salesdepartment_Text__c":"","dept__c":"","Dept_text__c":"","Contact_address__c":"**********","Number_of_participant_for_FOne_PJ__c":"","Number_of_participant_for_TeamPJ__c":"","Number_of_participant_for_TTC__c":"","Society1__c":"","Society3_del__c":"","Society2_del__c":"","Target_visit_for_VIP__c":"","Visit_Count1__c":"","Visit_Count7__c":"","Visit_Count2__c":"","Visit_Count8__c":"","Visit_Count3__c":"","Visit_Count9__c":"","Visit_Count4__c":"","Visit_Count10__c":"","Visit_Count5__c":"","Visit_Count11__c":"","Visit_Count6__c":"","Visit_Count12__c":"","NameOBPM__c":"","MobileOBPM__c":"","stateOBPM__c":"","OBPMDepartment__c":"","Learn_serve1__c":"","CityOBPM__c":"","Learn_serve2__c":"","Learn_name1__c":"","Learn_serve3__c":"","Learn_name2__c":"","TechnicalTitleOBPM__c":"","Learn_name3__c":"","ProfessionalField__c":"","SpecialityOBPM__c":"","WorkingSeniorityOBPM__c":"","Campaign__c":"000000000000000","Follow_state__c":"","JobStatusUpdateDate__c":"","Follow_stateUpdate__c":"2022/03/29","OnJobState__c":"","ProcessingWorkWithoutNumber__c":"","ProcessingWorkStatus__c":"未开展","IsEndoscope__c":"","IsEndoscopeUpdate__c":"","MedicalStaff_Full_name__c":"***","RecordTypeId":"01210000000QfWd","AmountofActivityHistory__c":"","LastName_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","ContactType_Encrypted__c":"b7246e7dd9d6b63025ec55e8e35b5a99","MedicalStaff_Full_name_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","Email_Encrypted__c":"","UniqueNumber_Encrypted__c":"","Doctor_Division1_Encrypted__c":"","Type_Encrypted__c":"","Contact_address_Encrypted__c":"2df1bc4bf3800c5e05e3d9f394c3446567d1f05482d2295650b7b50e9e4aa97a92338985c9693f576e1e6df667aaee46","Job_Category_picklist_Encrypted__c":null,"OLY_Assistant_Type_Encrypted__c":null,"Title_Encrypted__c":null,"MobilePhone_Encrypted__c":"","Phone_Encrypted__c":"e060533a8343becc9284a223c5a52d67","Job_Category_picklist__c":null,"OLY_Assistant_Type__c":null,"Title":null,"AWS_Data_Id__c":"958371969131085825"}';
        NewAndEditContactController.saveContact(contactJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
    // static testMethod void testMethod2() {
    //     Contact contactTest = TestDataUtility.CreateContacts(1)[0];
    //     String recordTypeId = Schema.SObjectType.Contact.getRecordTypeInfosByDeveloperName().get('Doctor').getRecordTypeId();
    //     String url = ApexPages.currentPage().getParameters().put('RecordType',recordTypeId);
    //     url = ApexPages.currentPage().getParameters().put('accid','0010l00001PPOy7AAH');
    //     Test.startTest();
    //     ApexPages.StandardController con =  new ApexPages.StandardController(contactTest);
    //     NewAndEditContactController cont = new NewAndEditContactController(con);
    //     cont.RedirectStandardPage();
    //     Test.stopTest();
    // }
    static testMethod void testMethod3() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        // Contact contactTest = TestDataUtility.CreateContacts(1)[0];
        Account acc = TestDataUtility.CreateAccounts(1)[0];
        //Account acc1 = [SELECT Id,Name FROM Account WHERE RecordType.DeveloperName = 'Office' OR RecordType.DeveloperName = 'AgencyContact' OR RecordType.DeveloperName = 'Agency' Limit 1];
        String accrecordTypeId = Schema.SObjectType.Account.getRecordTypeInfosByDeveloperName().get('Agency').getRecordTypeId();
        Account acc1 = new Account(Name = 'testacc1',RecordTypeId = accrecordTypeId);
        insert acc1;
        String recordTypeId = Schema.SObjectType.Contact.getRecordTypeInfosByDeveloperName().get('Doctor').getRecordTypeId();
        String url = ApexPages.currentPage().getParameters().put('RecordType',recordTypeId);
        url = ApexPages.currentPage().getParameters().put('accid',acc1.Id);
        url = ApexPages.currentPage().getParameters().put('con4_lkid',acc1.Id);
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(new Contact());
        NewAndEditContactController cont = new NewAndEditContactController(con);
        // cont.rtTypeId
        cont.PageLoad();
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditContactControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditEventController.cls
New file
@@ -0,0 +1,46 @@
/*
 * 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
        if (!Test.isRunningTest()) {
            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);
    // }
}
force-app/main/default/classes/NewAndEditEventController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditEventControllerTest.cls
New file
@@ -0,0 +1,22 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditEventControllerTest {
    static testMethod void testMethod4() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Event eventTest = TestDataUtility.CreateEvent(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(eventTest);
        NewAndEditEventController event = new NewAndEditEventController(con);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditEventControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditInquiryFormController.cls
New file
@@ -0,0 +1,118 @@
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 String urlCheckContactAWSid {get; set;}
    public String contactAWSDataId{set;get;}
    public String contactName{set;get;}
    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
        if (!Test.isRunningTest()) {
            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());
        }else {
            //联系人的Id
            Inquiry_form__c ifc = [select Contact_Name__c from Inquiry_form__c where id=:obj.Id];
            if(ifc != null){
                List<Contact> c = [select AWS_Data_Id__c,Name from Contact where id=:ifc.Contact_Name__c];
                if(c.size()>0){
                    if (c[0].AWS_Data_Id__c != null && c[0].AWS_Data_Id__c != '') {
                        contactAWSDataId = c[0].AWS_Data_Id__c;
                    }else {
                        contactName = c[0].Name;
                    }
                }
            }else {
                contactAWSDataId = '无';
                contactName = '无';
            }
        }
        //contact信息(搜索查询query url用)
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        //Lead信息(搜索查询query url用)
        staticResourceLead = JSON.serialize(PIHelper.getPIIntegrationInfo('Lead'));
        checkUrl('CF00N1000000962n8_lkid','Contact');
    }
    @RemoteAction
    global static Response saveInquiryForm(String leadJson,String transId,Boolean isNew) {
        return save(new Inquiry_form__c(),leadJson,transId,isNew);
    }
    @RemoteAction
    global static String queryAccount(String accountTypes,String accountId) {
        System.debug('accountType='+accountTypes);
        System.debug('accountId='+accountId);
        List<Object> types = (List<Object>)JSON.deserializeUntyped(accountTypes);
        System.debug('types='+types);
        String soql = 'select Id,Name,';
        for (Object t : types) {
            soql += (String)t+',';
        }
        soql = soql.substring(0,soql.length()-1);
        soql += ' from Account where id=\''+accountId+'\'';
        System.debug('soql='+soql);
        Sobject account = Database.query(soql);
        Map<String, Map<String, String>> m = new Map<String, Map<String, String>>();
        System.debug('account='+account);
        for (Object ty : types) {
            String t = (String)ty;
            if (account.get(t) != null){
                Sobject acc = Database.query('select Id,Name from Account where id=\''+account.get(t)+'\'');
                Map<String, String> n = new Map<String, String>();
                n.put('Id', (String)acc.get('Id'));
                n.put('Name', (String)acc.get('Name'));
                m.put(t, n);
            }
        }
        // if (account.get('Hospital__c') != null){
        //     m.put('Hospital__c', (String)account.get('Hospital__c'));
        //     m.put('Hospital__r.Name', (String)account.get('Hospital__r.Name'));
        // }
        // if (account.get('Department_Class__c') != null){
        //     m.put('Department_Class__c', (String)account.get('Department_Class__c'));
        //     m.put('Department_Class__r.Name', (String)account.get('Department_Class__r.Name'));
        // }
        System.debug('m='+m);
        return JSON.serialize(m);
        // return (String)account.get('Hospital__c');
    }
    private void checkUrl(String urlStr, String sobjType){
        Map<String, String> urlFieldMap = new Map<String, String>();
        urlFieldMap = ApexPages.currentPage().getParameters();
        if (urlFieldMap.containsKey(urlStr)) {
            String sobjId = urlFieldMap.get(urlStr);
            String soql = 'select id,AWS_Data_Id__c from ' + sobjType;
            soql += ' where id=\'' + sobjId + '\'';
            Sobject sobj = Database.query(soql);
            Map<String, String> m = new Map<String, String>();
            sobjId = sobjId.substring(0,sobjId.length()-3);
            m.put((String)sobjId, (String)sobj.get('AWS_Data_Id__c'));
            LookUpOverrideFieldsMapJson = JSON.serialize(m);
        }
    }
}
force-app/main/default/classes/NewAndEditInquiryFormController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditInquiryFormControllerTest.cls
New file
@@ -0,0 +1,143 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditInquiryFormControllerTest {
    static testMethod void testMethod5() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        RecordType rtId1 = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '病院'];
        Account acc1 = new Account();
        acc1.Name = 'Test1 病院';
        acc1.RecordTypeId = rtId1.Id;
        insert acc1;
        RecordType rtId2 = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '戦略科室分類 呼吸科'];
        Account acc2 = new Account();
        acc2.Name = 'Test2 戦略科室分類 呼吸科';
        acc2.RecordTypeId = rtId2.Id;
        acc2.ParentId = acc1.Id;
        acc2.Department_Class_Label__c = '呼吸科';
        acc2.Hospital_Department_Class__c = acc1.Id;
        insert acc2;
        RecordType rtId3 = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '診療科 呼吸科'];
        Account acc3 = new Account();
        acc3.Name = 'Test3 ';
        acc3.RecordTypeId = rtId3.Id;
        acc3.ParentId = acc2.Id;
        acc3.Department_Class__c = acc2.Id;
        acc3.Hospital__c = acc1.Id;
        insert acc3;
        Contact contact = TestDataUtility.CreateContacts(1)[0];
        contact.AccountId = acc3.Id;
        upsert contact;
        Inquiry_form__c formTest = TestDataUtility.CreateInquiryform(1)[0];
        formTest.AWS_Data_Id__c = '165';
        formTest.Hospital__c = acc1.Id;
        formTest.Department_Class__c = acc2.Id;
        formTest.Hospital_Name__c = acc3.Id;
        formTest.Contact_Name__c = contact.Id;
        System.debug('formTest: ' + formTest);
        upsert formTest;
        String url = ApexPages.currentPage().getParameters().put('CF00N1000000962n8_lkid',contact.id);
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(formTest);
        NewAndEditInquiryFormController form = new NewAndEditInquiryFormController(con);
        String formJson = '{"Id": "a410l00000067xyAAA","AWS_Data_Id__c": "952951318358523905","Lead_link__c": null,"Hospital__c": null,"Contact_Name__c": "0030l00000mEx8UAAS","No_Need_Date__c": null,"Urgent__c": false}';
        System.debug('formJson: ' + formJson);
        NewAndEditInquiryFormController.saveInquiryForm(formJson,'avgwshDFcxAS',False);
        String jsonString = '["Department_Class__c", "Hospital__c"]';
        NewAndEditInquiryFormController.queryAccount(jsonString, contact.AccountId);
        Test.stopTest();
    }
    static testMethod void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        RecordType rtId1 = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '病院'];
        Account acc1 = new Account();
        acc1.Name = 'Test1 病院';
        acc1.RecordTypeId = rtId1.Id;
        insert acc1;
        RecordType rtId2 = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '戦略科室分類 呼吸科'];
        Account acc2 = new Account();
        acc2.Name = 'Test2 戦略科室分類 呼吸科';
        acc2.RecordTypeId = rtId2.Id;
        acc2.ParentId = acc1.Id;
        acc2.Department_Class_Label__c = '呼吸科';
        acc2.Hospital_Department_Class__c = acc1.Id;
        insert acc2;
        RecordType rtId3 = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '診療科 呼吸科'];
        Account acc3 = new Account();
        acc3.Name = 'Test3 ';
        acc3.RecordTypeId = rtId3.Id;
        acc3.ParentId = acc2.Id;
        acc3.Department_Class__c = acc2.Id;
        acc3.Hospital__c = acc1.Id;
        insert acc3;
        Contact contact = TestDataUtility.CreateContacts(1)[0];
        contact.AccountId = acc3.Id;
        contact.AWS_Data_Id__c = '167895';
        upsert contact;
        Inquiry_form__c formTest = TestDataUtility.CreateInquiryform(1)[0];
        formTest.AWS_Data_Id__c = '165';
        formTest.Hospital__c = acc1.Id;
        formTest.Department_Class__c = acc2.Id;
        formTest.Hospital_Name__c = acc3.Id;
        formTest.Contact_Name__c = contact.Id;
        System.debug('formTest: ' + formTest);
        upsert formTest;
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(formTest);
        NewAndEditInquiryFormController form = new NewAndEditInquiryFormController(con);
        String formJson = '{"Id": "a410l00000067xyAAA","AWS_Data_Id__c": "952951318358523905","Lead_link__c": null,"Hospital__c": null,"Contact_Name__c": "0030l00000mEx8UAAS","No_Need_Date__c": null,"Urgent__c": false}';
        System.debug('formJson: ' + formJson);
        NewAndEditInquiryFormController.saveInquiryForm(formJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Account acc = TestDataUtility.CreateAccounts(1)[0];
        Inquiry_form__c formTest = TestDataUtility.CreateInquiryform(1)[0];
        formTest.Contact_Name__c = null;
        upsert formTest;
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(formTest);
        NewAndEditInquiryFormController form = new NewAndEditInquiryFormController(con);
        String formJson = '{"Id": "a410l00000067xyAAA","AWS_Data_Id__c": "952951318358523905","Lead_link__c": null,"Hospital__c": null,"Contact_Name__c": "0030l00000mEx8UAAS","No_Need_Date__c": null,"Urgent__c": false}';
        System.debug('formJson: ' + formJson);
        NewAndEditInquiryFormController.saveInquiryForm(formJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
    static testMethod void testMethod3() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Account acc = TestDataUtility.CreateAccounts(1)[0];
        Inquiry_form__c formTest = new Inquiry_form__c();
        formTest.Name = 'Test InquiryForm';
        formTest.Request1__c = 'OPD';
        formTest.Opportunity_Division__c = '询价';
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(formTest);
        NewAndEditInquiryFormController form = new NewAndEditInquiryFormController(con);
        String formJson = '{"Id": "a410l00000067xyAAA","AWS_Data_Id__c": "952951318358523905","Lead_link__c": null,"Hospital__c": null,"Contact_Name__c": "0030l00000mEx8UAAS","No_Need_Date__c": null,"Urgent__c": false}';
        System.debug('formJson: ' + formJson);
        NewAndEditInquiryFormController.saveInquiryForm(formJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditInquiryFormControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditInspectionReportController.cls
New file
@@ -0,0 +1,27 @@
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
        if (!Test.isRunningTest()) {
            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);
    }
}
force-app/main/default/classes/NewAndEditInspectionReportController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditInspectionReportControllerTest.cls
New file
@@ -0,0 +1,29 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditInspectionReportControllerTest {
    static testMethod void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Inspection_Report__c insTest = new Inspection_Report__c();
        // List<Inspection_Report__c> asdf = TestDataUtility.CreateInspectionReport(1);
        insTest = TestDataUtility.CreateInspectionReport(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(insTest);
        NewAndEditInspectionReportController ins = new NewAndEditInspectionReportController(con);
        String insJson = '{"Name":"test123","RecordTypeId":"01210000000RLeX","Hospital__c":"0011m00000Xm6Lk","Status__c":"草案中","Approved_date__c":"2022/03/29","if_UpdateAsset__c":true,"Inspection_StartTime__c":"2022/03/29 16:22","Inspection_Date__c":"2022/03/29","Inspection_EndTime__c":"2022/03/29 16:22","Contract__c":"000000000000000","spotCheckBatch__c":"","Submit_date__c":"2022/03/29","Inspectup_Plan__c":"000000000000000","Technician_HP__c":"","Remarks__c":"","Department__c":"000000000000000","ResponsiblePerson_Sign__c":"<br>","Reporter__c":"00510000000gW9S","Technician_HP_Encrypted__c":"","phone_Encrypted__c":null,"Responsible_Person_Encrypted__c":null,"phone__c":null,"Responsible_Person__c":null,"AWS_Data_Id__c":"958401040867131393"}';
        NewAndEditInspectionReportController.saveInspectionReport(insJson,'avgwshDFcxAS',False);
        NewAndEditInspectionReportController.saveInspectionReport(insJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditInspectionReportControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditLeadController.cls
New file
@@ -0,0 +1,669 @@
/*
 * Author: Bubba Li
 * Created Date: 01/19/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditLeadController
 * History:
 *      01/19/2022 - Bubba Li - Initial Code.
 *
 * */
global without sharing class NewAndEditLeadController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public static String sobjectTypeValue = 'Lead';
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    public String AWSDataIdInquiryForm{set;get;}
    public String contactId{set;get;}//For Lookup field
    public List<String> encryptedAPIList{set;get;}
    public String staticResource {get; set;}
    public String staticResourceContact {get; set;}
    public String staticResourceInquiryForm{get; set;}
    public String requiredFieldAPIListStr {get; set;}
    public String fieldAPIToLabelMapStr {get; set;}
    public String Input_Required_Field_Msg{set;get;}
    public String PIPL_Name_Label{set;get;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String sobjectPrefix{set;get;}
    public String sobjecttypeForFrontEnd{set;get;}
    public String contactsInfo {set;get;}//key sfid;value awsid
    public Inquiry_form__c ifc{get; private set;}
    public String contactDataId{get; set;}
    public String layoutSectionsStr {get; set;}
    public String isDecryptContact {get; set;}
    public final string ApiPrefix{get;private set;} //Add By Li Jun 20220403
    public Map<string,string> AWSToSobjectEncryptedMap{get;private set;}
    public string AWSToSobjectEncryptedMapJson{get{return JSON.serialize(AWSToSobjectEncryptedMap);}}
    public NewAndEditLeadController(ApexPages.StandardController controller) {
        ApiPrefix = 'PIBackApi';
        isDecryptContact = '0';
        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('Lead').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        if (!Test.isRunningTest()) {
            controller.addFields(fieldList);
        }
        SObject obj = controller.getRecord();
        if(ApexPages.currentPage().getParameters().get('CF00N1000000962np_lkid') != null){
            System.debug('CF00N1000000962np_lkid');
            //产品咨询单过来的
            String InquiryFormId = ApexPages.currentPage().getParameters().get('CF00N1000000962np_lkid');
            ifc = [select Id,AWS_Data_Id__c,Contact_Name__c,Contact_Id__c,Hospital_Name__c,Hospital_ID__c,Department_Class__c,
            Department_ID__c,Opp_Name_Search__c,Opp_Name_Search_ID__c,Campaign__c,
            Campaign_ID__c,Name,Cancel_Reason__c,Phone__c,Email__c,Last_Name__c,LeadSource__c,Opportunity_Division__c,Request1__c,
            Urgent__c from Inquiry_form__c where id = :InquiryFormId];
            System.debug('ifc = ' + ifc);
            if(ifc.Contact_Id__c !=null && ifc.Contact_Id__c != ''){
                Contact c = [select AWS_Data_Id__c from Contact where id = :ifc.Contact_Id__c];
                contactDataId = c.AWS_Data_Id__c;
            }
            AWSDataIdInquiryForm = ifc.AWS_Data_Id__c;
            System.debug('ifc = ' + ifc);
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            obj.put('OwnerId',UserInfo.getUserId());
        }else if(obj.Id != null){
            //更新
            isNewMode = false;
            Lead leadData = [select Id,RecordTypeId,AWS_Data_Id__c,Contact_Name__r.Id,Contact_Name__r.AWS_Data_Id__c from Lead where id =: obj.Id];
            rtTypeId = leadData.RecordTypeId;
            AWSDataId = leadData.AWS_Data_Id__c;
            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
            if(leadData.Contact_Name__r.Id != null){
                sfIdToAWSIdMap.put(String.valueof(leadData.Contact_Name__r.Id).subString(0,15),leadData.Contact_Name__r.AWS_Data_Id__c);
            }
            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
        }else{
            //看链接中有无带过来的参数(客户人员)
            Map<string,string> mso = ApexPages.currentPage().getParameters();
            for(String key : mso.keySet()){
                System.debug('key=' + key + ',value=' + mso.get(key));
            }
            //联系人
            if(mso.containsKey('CF00N10000006ps6f_lkid')){
                isDecryptContact = '1';
                String contactId = mso.get('CF00N10000006ps6f_lkid');
                //查询AWS_Data_Id__c
                List<Contact> contactList = new List<Contact>([select AWS_Data_Id__c from Contact where id=:contactId]);
                Contact c = new Contact();
                if(contactList!=null&&contactList.size()>0){
                    c = contactList[0];
                }
                if (c != null&&c.AWS_Data_Id__c!='') {
                    contactDataId = c.AWS_Data_Id__c;
                }
                //查询战略科室分类
                List<Contact> cs = [select Account.Department_Class__c from Contact where id=:contactId];
                if(cs.size()>0){
                    controller.getRecord().put('Department_Class__c',cs[0].Account.Department_Class__c);
                }
                controller.getRecord().put('Contact_Name__c',mso.get('CF00N10000006ps6f_lkid'));
            }
            //医院名
            if(mso.containsKey('CF00N10000002CvC5_lkid')){
                controller.getRecord().put('Hospital_Name__c',mso.get('CF00N10000002CvC5_lkid'));
                //通过医院id查询战略科室分类
                String hospitalId = mso.get('CF00N10000002CvC5_lkid');
                List<Account> hospitalAccount = [select Department_Class__c from Account where Id=:hospitalId];
                if(hospitalAccount.size()>0){
                    List<Account> departmentAccount = [select Id from Account where Id=:hospitalAccount[0].Department_Class__c];
                    if (departmentAccount.size()>0) {
                        System.debug('Department_Class__c = ' + departmentAccount[0].Id);
                        controller.getRecord().put('Department_Class__c',departmentAccount[0].Id);
                    }
                }
            }
            //公司(科室)
            if(mso.containsKey('CF00N10000002CvC5')){
                controller.getRecord().put('Company',mso.get('CF00N10000002CvC5'));
            }
            //战略科室CF00N10000006qNtt_lkid
            // if(mso.containsKey('CF00N10000006qNtt_lkid ')){
            //     controller.getRecord().put('Department_Class__c',mso.get('CF00N10000006qNtt_lkid '));
            // }
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            obj.put('OwnerId',UserInfo.getUserId());
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Lead','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Lead');
        staticResource = JSON.serialize(piIntegration);
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        staticResourceInquiryForm = JSON.serialize(PIHelper.getPIIntegrationInfo('Inquiry_form__c'));
        encryptedAPIList = piIntegration.PIFields;
        sobjectPrefix = piIntegration.sobjectPrefix;
        layoutSectionsStr = JSON.serialize(layoutSections);
        AWSToSobjectEncryptedMap = new Map<String,String>();
        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
            AWSToSobjectEncryptedMap.put(PIDetail.AWS_Field_API__c, PIDetail.SF_Field_API_Name__c);
        }
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response saveLead(String leadJson,String transId,Boolean isNew) {
        System.debug('Lead Info:' + JSON.serialize(leadJson));
        //1. Prepare the payload for  Lead
        Schema.SObjectType leadSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = leadSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(leadJson);
        Lead leadInfo = new Lead();
        //自定义格式转换
        for (String fieldAPI: fieldValueMap.keySet()) {
            system.debug('field API='+fieldAPI);
            if(!fieldAPIToTypeMap.containskey(fieldAPI)){
                continue;
            }
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            system.debug('Field Type:'+fielddataType+' field Value='+fieldValue);
            if(String.valueOf(fielddataType)=='DATE'){
                leadInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                if(String.isNotBlank(fieldValue)&&fieldValue.contains('T')){
                    fieldValue = fieldValue.replace('T',' ');
                    leadInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                }else{
                    leadInfo.put(fieldAPI, null);
                }
            }else if(String.valueof(fielddataType)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                leadInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?null:Decimal.valueOf(fieldValue.replace(',', '')));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                leadInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                leadInfo.put(fieldAPI,fieldValue);
            }
        }
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        String rid = '';
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('leadInfozhj = ' + leadInfo);
                if(!Test.isRunningTest()){
                    insert leadInfo;
                }
            }else{
                System.debug('into update');
                String awsDataId = (String)leadInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                Lead[] leads = [select id from Lead where AWS_Data_Id__c =:awsDataId];
                System.debug('leads[0].id = ' + leads[0].id);
                leadInfo.put('Id',leads[0].id);//For testing;
                if(!Test.isRunningTest()){
                    update leadInfo;
                }
            }
            rid=leadInfo.Id;
            PIHelper.saveTransLog(sobjectTypeValue,(String)leadInfo.get('AWS_Data_Id__c'),rid,transId,leadJson ,status,'');
            resp.recordId = leadInfo.Id;
            resp.message = '';
            resp.status = status;
            System.debug('resp from sfdx back-end' + resp);
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,(String)leadInfo.get('AWS_Data_Id__c'),rid,transId,leadJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }
    @RemoteAction
    global static String queryAccount(String accountTypes,String accountId) {
        System.debug('accountType='+accountTypes);
        System.debug('accountId='+accountId);
        List<Object> types = (List<Object>)JSON.deserializeUntyped(accountTypes);
        System.debug('types='+types);
        String soql = 'select Id,Name,';
        for (Object t : types) {
            soql += (String)t+',';
        }
        soql = soql.substring(0,soql.length()-1);
        soql += ' from Account where id=\''+accountId+'\'';
        System.debug('soql='+soql);
        Sobject account = new Account();
        if(!Test.isRunningTest()){
            account = Database.query(soql);
        }else{
            account.put('Id','000000000000000');
        }
        Map<String, Map<String, String>> m = new Map<String, Map<String, String>>();
        System.debug('account='+account);
        for (Object ty : types) {
            String t = (String)ty;
            if (account.get(t) != null||Test.isRunningTest()){
                Sobject acc = new Account();
                if(Test.isRunningTest()){
                    acc.put('Id','000000000000000');
                    acc.put('Name','Name');
                }else{
                    acc = Database.query('select Id,Name from Account where id=\''+account.get(t)+'\'');
                }
                Map<String, String> n = new Map<String, String>();
                n.put('Id', (String)acc.get('Id'));
                n.put('Name', (String)acc.get('Name'));
                m.put(t, n);
            }
        }
        // if (account.get('Hospital__c') != null){
        //     m.put('Hospital__c', (String)account.get('Hospital__c'));
        //     m.put('Hospital__r.Name', (String)account.get('Hospital__r.Name'));
        // }
        // if (account.get('Department_Class__c') != null){
        //     m.put('Department_Class__c', (String)account.get('Department_Class__c'));
        //     m.put('Department_Class__r.Name', (String)account.get('Department_Class__r.Name'));
        // }
        System.debug('m='+m);
        return JSON.serialize(m);
        // return (String)account.get('Hospital__c');
    }
    public static Integer ControllerUtil() {
        Integer i = 0;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        return i;}
}
force-app/main/default/classes/NewAndEditLeadController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditLeadControllerTest.cls
New file
@@ -0,0 +1,63 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditLeadControllerTest {
    @TestSetup
    static void makeData(){
        List<String> strList= new List<String>();
        strList.add('Lead');
        strList.add('Contact');
        strList.add('Inquiry_form__c');
        TestDataUtility.CreatePIPolicyConfigurations(strList);
    }
    static testMethod void testMethod1() {
        Test.startTest();
        Lead leadTest = new Lead();
        Contact cont = new Contact();
        ApexPages.StandardController con =  new ApexPages.StandardController(leadTest);
        NewAndEditLeadController lead = new NewAndEditLeadController(con);
        String leadJson = '{"RecordTypeId":"01210000000QiRaAAK","Lead_No__c":"IN-JS-2022040127183","Status":"未跟进","Hospital_Name__c":"0011000000VAPEt","Department_Class__c":"0011000000V9bh5","Salutation":"","LastName":"***","Contact_Name__c":"0031m00000DHrkV","Cancel_Reason__c":"","Phone":"","Opp_Name_Search__c":"000000000000000","Email":"","Opp_Name__c":"Test","owner_not_automatically_update__c":false,"Purchase_Plan__c":"有(无预算)","Lead_Inquiry_form__c":"000000000000000","Opportunity_Division__c":"询价","LeadSource":"电话","Campaign__c":"000000000000000","urgent__c":false,"SI_PromoteInquiry__c":false,"Request__c":"","Request_Detail__c":"","Opportunity_stage__c":"预算没有批准","Close_Forecasted_Date__c":"2022/04/01","Purchase_Reason__c":"更新","Sales_Method__c":"单一来源采购","Fund_Basis__c":"銀行資金","Purchase_Type__c":"一般引合","Company":"江苏省人民医院 呼吸科 呼吸科","Name_Encrypted__c":"48a2693f6bf73d16e0abd48caf7fb756","Phone_Encrypted__c":"","Email_Encrypted__c":"","AWS_Data_Id__c":"959584917346320385"}';
        NewAndEditLeadController.saveLead(leadJson,'avgwshDFcxAS',False);
        NewAndEditLeadController.saveLead(leadJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
    static testMethod void testMethod3() {
        Lead leadTest = new Lead();
        String url = ApexPages.currentPage().getParameters().put('CF00N10000006ps6f_lkid','000000000000000');
        // ApexPages.currentPage().getParameters().put('CF00N10000002CvC5_lkid','000000000000000');
        // ApexPages.currentPage().getParameters().put('CF00N10000002CvC5','000000000000000');
        // ApexPages.currentPage().getParameters().put('CF00N10000002CvC5','000000000000000');
        url = ApexPages.currentPage().getParameters().put('RecordType','01210000000QiRf');
        Test.startTest();
        try{
            NewAndEditLeadController.ControllerUtil();
            ApexPages.StandardController con =  new ApexPages.StandardController(leadTest);
            NewAndEditLeadController lc = new NewAndEditLeadController(con);
            String jsonString = '["Department_Class__c"]';
            system.debug('jsonString:'+JSON.deserializeUntyped(jsonString));
            String token = lc.awsToken;
            String AWSDataId = lc.AWSDataId;
            String AWSDataIdInquiryForm = lc.AWSDataIdInquiryForm;
            String contactId = lc.contactId;//For Lookup field
            String contactsInfo = lc.contactsInfo ;//key sfid;value awsid
            Inquiry_form__c ifc = lc.ifc;
            NewAndEditLeadController.queryAccount(jsonString, '000000000000000');
        }catch(Exception e){
            system.debug('Exception from query account:'+e.getMessage());
        }
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditLeadControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditQISController.cls
New file
@@ -0,0 +1,30 @@
global with sharing class NewAndEditQISController extends NewAndEditBaseController{
    public String Input_Required_Field_Msg{set;get;}
    public NewAndEditQISController(ApexPages.StandardController controller) {
        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('QIS_Report__c').getDescribe().fields.getMap().keyset());
        if (!Test.isRunningTest()) {
            controller.addFields(fieldList);
        }
        Init(controller.getRecord());
        //Updated by Chen Yanan 20220323 Start
        String contactId = controller.getRecord().Id;
        if(contactId == null){
            Map<string,string> mso = ApexPages.currentPage().getParameters();
            system.debug('mso='+mso);
            if(mso.containsKey('CF00N10000002FHFK_lkid')){
                controller.getRecord().put('Name', '*');
            }
        }
        system.debug('controller.getRecord()='+controller.getRecord());
        //Updated by Chen Yanan 20220323 End
    }
    @RemoteAction
    global static Response saveQISReport(String leadJson,String transId,Boolean isNew) {
        return save(new QIS_Report__c(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditQISController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditQISControllerTest.cls
New file
@@ -0,0 +1,36 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditQISControllerTest {
    static testMethod void testMethod13() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        QIS_Report__c qisTest = TestDataUtility.CreateQISReport(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(qisTest);
        NewAndEditQISController qis = new NewAndEditQISController(con);
        String qisJson = '{"Name":"test123","QIS_Status__c":"草案中","QIS_pre__c":"000000000000000","consumable__c":"01t1m000001QyDa","Cancel_QIS_Reason__c":"_u0001_","RecordTypeId":"01210000000RLWc","Repair__c":"a0J1m000001nZzf","RejectReason__c":"","Managementtext__c":"","OCSMAdministrativeReportStatus__c":"无需报告","MBC_AwareDate__c":"2022/03/29","Aware_date__c":"2022/03/29","Old_Repair_Name__c":"","isLendRental__c":false,"next_action__c":"","RC_problem_not_found__c":false,"Salesdepartment_Text__c":"","OCM_Repair_Mail1__c":"","Hospital__c":"0011m00000XlvHh","Account_State__c":"","Department_Class__c":"0011m00000SP4Mp","OwnerId":"0051m0000030e0QAAQ","Hospital_Department__c":"0011m00000SP4TB","Responsible_Person_HP__c":"***","Caller_phone__c":"***********","capital_or_consumable__c":"耗材","contract_number_ET_text__c":"","nonyushohin__c":"000000000000000","InstallDate_text__c":"","usage_frequence__c":"1","cleanning__c":"1","cds_methods__c":"手动","disinfection__c":"","sterlization__c":"","Faliour_date__c":"2022/03/29","Trable_occur_daY_collect__c":"2022/03/29","DelayReportReason__c":"","failuer_situation__c":"到货验收","failuer_situationSelect__c":"","problem_detail__c":"test","Damage_For_Doc_Or_Pat__c":"","Relation_With_The_Problem__c":"","Report_For_Goz__c":"","Which_Project__c":"","Opera_Name__c":"","BreakORFallOff__c":"","Is_Used_For_The_Opera__c":"","Set_usage_product__c":"","Comment__c":"test","AfterFailureInformation__c":"","Delay15Min__c":"","InformationFrom__c":"","FailureQInHospital__c":"","accsessary_detail__c":"","shipping_to_QIS_dept_day__c":"","ASReportedCode__c":"","QIS_ConfirmationDate__c":"","PAE_Determine__c":"","ASReportedCodeAC__c":"","OCSM_RC_CordingDate__c":"","PAE_DetermineAC__c":"","Complaint_Number__c":"","OSH_ConfirmationDate__c":"","if_QIS_Allowed__c":"","NotAllowedReason__c":"","OSHRAConfirmDate__c":"","isAE_Profile__c":"","isPAE_Profile__c":"","MDR_information__c":"","MDR_detail__c":"","CFDA_No_Hand__c":"","ProduceCompany_hand__c":"","Receive_Date_Day__c":"2022/03/29","OSHRecievedDate__c":"","QIS_Submit_day__c":"","QIS_OSH_answerdate__c":"","OCM_RC_RecievedDate__c":"","QIS_Complete_Day__c":"","QIS_Reply_day__c":"","QIS_cancel_date__c":"","QIS_Cancel_Submit_day__c":"","Daily_Report__c":"000000000000000","Generation_Source__c":"","Source_OnCall__c":"000000000000000","QisSubOrder__c":"000000000000000","AsyncData__c":false,"ETQ_UPLOAD_STATUS__c":"","AWS_Interface_Time__c":"2022/03/29 13:38","ETQ_UPLOAD_MESSAGE__c":"","INTERFACE_RECORD_ID__c":"","ET_QIS_SEND_EMAIL1__c":"","ET_QIS_SEND_EMAIL2__c":"","problem_detail_photo__c":"","Caller_phone_Encrypted__c":"415f2dab7eb6b2a866e02d823080a845","Responsible_Person_HP_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","AWS_Data_Id__c":"958360820671053825"}';
        NewAndEditQISController.saveQISReport(qisJson,'avgwshDFcxAS',False);
        NewAndEditQISController.saveQISReport(qisJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
    static testMethod void testMethod14() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        String url = ApexPages.currentPage().getParameters().put('CF00N10000002FHFK_lkid','test');
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(new QIS_Report__c());
        NewAndEditQISController qis = new NewAndEditQISController(con);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditQISControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditRepairSubOrderController.cls
New file
@@ -0,0 +1,42 @@
/*
 * 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
        if (!Test.isRunningTest()) {
            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);
    }
}
force-app/main/default/classes/NewAndEditRepairSubOrderController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditRepairSubOrderControllerTest.cls
New file
@@ -0,0 +1,26 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditRepairSubOrderControllerTest {
    static testMethod void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        // RepairSubOrder__c subTest = TestDataUtility.CreateRepairSubOrder(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(new RepairSubOrder__c());
        NewAndEditRepairSubOrderController sub = new NewAndEditRepairSubOrderController(con);
        sub.contactsInfo = sub.contactId;
        String subJson = '{"RepairOrderNo__c":"test123","Name":"123","Hospital__c":"0011m00000Xiz4Q","RepairSubOrderType__c":"CIC代填","Department__c":"0011m00000Xiz4Q","Applicanter__c":"0031m00000MtzBhAAJ","Status__c":"待处理","CurrencyIsoCode":"CNY","RepairApplicantName__c":"","ProcessResult__c":"","RepairApplicantTel__c":"","OwnerId":"0051m0000030e0Q","EquipmentCategory__c":"内科系统","AssetType__c":"胃镜","AssetCode__c":"","ProblemDescription__c":"","FaultType__c":"","RepairTime__c":"","ReceiverType__c":"","ReceiverTime__c":"","Receiver__c":"000000000000000","PlannedVisitDay__c":"2022/03/29 12:06","ActualVisitTimeSecond__c":"","ActualVisitTimeThird__c":"","AssetModel__c":"","AirframeCodeEngineer__c":"","RepairApplicantName_Encrypted__c":"","RepairApplicantTel_Encrypted__c":"","AWS_Data_Id__c":"958338146326544385"}';
        NewAndEditRepairSubOrderController.saveRepairSubOrder(subJson,'avgwshDFcxAS',False);
        NewAndEditRepairSubOrderController.saveRepairSubOrder(subJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditRepairSubOrderControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditReportController.cls
New file
@@ -0,0 +1,304 @@
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 Input_Required_Field_Msg{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 String layoutSectionsStr {get; set;}
    public String no1Name{get; set;}
    public String no1Id{get; set;}
    // 当前页面中的加密字段集合
    public List<String> layoutEncryptedAPIList{private set;get;}
    public final string ApiPrefix{get;private set;}
    public Map<string,string> AWSToSobjectEncryptedMap{get;private set;}
    public string AWSToSobjectEncryptedMapJson{get{return JSON.serialize(AWSToSobjectEncryptedMap);}}
    public String contactAWSDataId1{set;get;}
    public String contactAWSDataId2{set;get;}
    public String contactAWSDataId3{set;get;}
    public String contactAWSDataId4{set;get;}
    public String contactAWSDataId5{set;get;}
    public String contactName1{set;get;}
    public String contactName2{set;get;}
    public String contactName3{set;get;}
    public String contactName4{set;get;}
    public String contactName5{set;get;}
    public NewAndEditReportController(ApexPages.StandardController controller) {
        ApiPrefix = 'PIBackApi';
        layoutEncryptedAPIList = new List<String>();
        AWSToSobjectEncryptedMap = new Map<string,string>();
        sobjectId = [SELECT CustomObjectId,CustomObjectName  FROM CustomObjectUserLicenseMetrics   where CustomObjectName ='Report' limit 1].CustomObjectId;
        isNewMode = true;
        Input_Required_Field_Msg = 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
        if (!Test.isRunningTest()) {
            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>();
            system.debug('ReportData.Practitioner1__r.Id:' + ReportData.Practitioner1__r.Id);
            system.debug('ReportData.Practitioner1__r.AWS_Data_Id__c:' + ReportData.Practitioner1__r.AWS_Data_Id__c);
            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);
            //实施人1,2,3,4,5
            Report__c rc = [select Practitioner1__c,Practitioner2__c,Practitioner3__c,Practitioner4__c,Practitioner5__c from Report__c where id=:obj.Id];
            if (rc != null) {
                List<Contact> c1 = [select AWS_Data_Id__c,Name from Contact where id=:rc.Practitioner1__c];
                if(c1.size()>0){
                    if (c1[0].AWS_Data_Id__c != null && c1[0].AWS_Data_Id__c != '') {
                        contactAWSDataId1 = c1[0].AWS_Data_Id__c;
                    }else {
                        contactName1 = c1[0].Name;
                    }
                }
                List<Contact> c2 = [select AWS_Data_Id__c,Name from Contact where id=:rc.Practitioner2__c];
                if(c2.size()>0){
                    if (c2[0].AWS_Data_Id__c != null && c2[0].AWS_Data_Id__c != '') {
                        contactAWSDataId2 = c2[0].AWS_Data_Id__c;
                    }else {
                        contactName2 = c2[0].Name;
                    }
                }
                List<Contact> c3 = [select AWS_Data_Id__c,Name from Contact where id=:rc.Practitioner3__c];
                if(c3.size()>0){
                    if (c3[0].AWS_Data_Id__c != null && c3[0].AWS_Data_Id__c != '') {
                        contactAWSDataId3 = c3[0].AWS_Data_Id__c;
                    }else {
                        contactName3 = c3[0].Name;
                    }
                }
                List<Contact> c4 = [select AWS_Data_Id__c,Name from Contact where id=:rc.Practitioner4__c];
                if(c4.size()>0){
                    if (c4[0].AWS_Data_Id__c != null && c4[0].AWS_Data_Id__c != '') {
                        contactAWSDataId4 = c4[0].AWS_Data_Id__c;
                    }else {
                        contactName4 = c4[0].Name;
                    }
                }
                List<Contact> c5 = [select AWS_Data_Id__c,Name from Contact where id=:rc.Practitioner5__c];
                if(c5.size()>0){
                    if (c5[0].AWS_Data_Id__c != null && c5[0].AWS_Data_Id__c != '') {
                        contactAWSDataId5 = c5[0].AWS_Data_Id__c;
                    }else {
                        contactName5 = c5[0].Name;
                    }
                }
            }else {
                contactAWSDataId1 = '无';
                contactName1 = '无';
            }
        }else if(ApexPages.currentPage().getParameters().get('CF00N10000008ps6d_lkid') != null){
            //OPD计划过来的,通过Id查出借出备品申请No1进行展示
            String opdPlanId = ApexPages.currentPage().getParameters().get('CF00N10000008ps6d_lkid');
            if(String.isNotEmpty(opdPlanId)&&String.isNotBlank(opdPlanId)){
                List<OPDPlan__c> opList = [select NewestRentalCode__c from OPDPlan__c where id=:opdPlanId];
                if(opList!=null&&opList.size()>0){
                    no1Name = opList[0].NewestRentalCode__c;
                    List<Rental_Apply__c> racList = [select id from Rental_Apply__c where Name=:opList[0].NewestRentalCode__c];
                    if(racList!=null&&racList.size()>0){
                        no1Id = racList[0].id;
                    }
                }
            }
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            obj.put('OwnerId',UserInfo.getUserId());
        }else{
            //新建
            Map<string,string> mso = ApexPages.currentPage().getParameters();
            //医院/科室/经销商(手写)
            if(mso.containsKey('00N10000002GE3Z')){
                controller.getRecord().put('Manual_Name__c',mso.get('00N10000002GE3Z'));
            }
            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;
        System.debug('piIntegration.PIFields = ' + encryptedAPIList);
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        sobjectPrefix = piIntegration.sobjectPrefix;
        layoutSectionsStr = JSON.serialize(layoutSections);
        for (LayoutDescriberHelper.LayoutSection ls : layoutSections) {
            for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
                //在view解密section中只需显示当前layout中的加密字段
                if (encryptedAPIList.contains(lf.fieldAPI)) {
                    layoutEncryptedAPIList.add(lf.fieldAPI);
                }
            }
        }
        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
            AWSToSobjectEncryptedMap.put(PIDetail.AWS_Field_API__c, PIDetail.SF_Field_API_Name__c);
        }
        System.debug('AWSToSobjectEncryptedMap = ' + AWSToSobjectEncryptedMap);
    }
    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('report Info:' + 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('自定义格式转换开始');
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        String rid = '';
        //自定义格式转换
        try{
        for (String fieldAPI: fieldValueMap.keySet()) {
            if(!fieldAPIToTypeMap.containskey(fieldAPI)){
                continue;
            }
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            if(String.valueOf(fielddataType)=='DATE'){
                System.debug('DATE fieldAPI = '+fieldAPI+' filedData = '+String.valueOf(fieldValueMap.get(fieldAPI)));
                //reportInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
                reportInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                System.debug('fieldValueMap:' + fieldValueMap);
                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
                System.debug('fieldValueMap.get(fieldAPI)' + fieldValueMap.get(fieldAPI));
                System.debug('dt:'+dt);
                if(String.isNotBlank(dt)&&dt.contains('T')){
                    dt = dt.replace('T',' ');
                    reportInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
                }else if(String.isNotBlank(dt))  {
                    reportInfo.put(fieldAPI, Datetime.valueOf(dt.replace('/', '-') + ':00'));
                }else{
                    reportInfo.put(fieldAPI, null);
                }
            }else if(String.valueof(fielddataType)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                //reportInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
                reportInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?null:Decimal.valueOf(fieldValue.replace(',', '')));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                reportInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                reportInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
            }
        }
        System.debug('自定义格式转换结束');
            if(isNew){
                System.debug('reportInfo = ' + reportInfo);
                if(!Test.isRunningTest()){
                    insert reportInfo;
                } else {
                    Report__c reportTest = new Report__c();
                    insert reportTest;
                }
            }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;
                if(!Test.isRunningTest()){
                    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(DmlException e) {
            status = 'fail';
            Integer index = 0;
            System.debug(e.getNumDml());
            System.debug(e.getDmlFields(index));
            System.debug(e.getDmlId(index));
            System.debug(e.getDmlIndex(index));
            System.debug(e.getDmlMessage(index));
            System.debug(e.getDmlStatusCode(index));
            System.debug(e.getDmlType(index));
            system.debug(e.getMessage());
            system.debug(e.getStackTraceString());
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            resp.status = 'Exception';
            resp.message ='保存失败,原因:'+ e.getDmlMessage(index);
            PIHelper.saveTransLog(sobjectTypeValue,(String)reportInfo.get('AWS_Data_Id__c'),rid,transId,reportJson,status,e.getMessage()+e.getStackTraceString());
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,(String)reportInfo.get('AWS_Data_Id__c'),rid,transId,reportJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }
}
force-app/main/default/classes/NewAndEditReportController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditReportControllerTest.cls
New file
@@ -0,0 +1,101 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditReportControllerTest {
    @TestSetup
    static void makeData(){
        List<String> strList = new List<String>();
        strList.add('Report__c');
        strList.add('Contact');
        TestDataUtility.CreatePIPolicyConfigurations(strList);
    }
    static testMethod void testMethod1() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        RecordType rtId1 = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '病院'];
        Account acc1 = new Account();
        acc1.Name = 'Test1 病院';
        acc1.RecordTypeId = rtId1.Id;
        insert acc1;
        RecordType rtId2 = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '戦略科室分類 呼吸科'];
        Account acc2 = new Account();
        acc2.Name = 'Test2 戦略科室分類 呼吸科';
        acc2.RecordTypeId = rtId2.Id;
        acc2.ParentId = acc1.Id;
        acc2.Department_Class_Label__c = '呼吸科';
        acc2.Hospital_Department_Class__c = acc1.Id;
        insert acc2;
        RecordType rtId3 = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '診療科 呼吸科'];
        Account acc3 = new Account();
        acc3.Name = 'Test3 ';
        acc3.RecordTypeId = rtId3.Id;
        acc3.ParentId = acc2.Id;
        acc3.Department_Class__c = acc2.Id;
        acc3.Hospital__c = acc1.Id;
        insert acc3;
        OPDPlan__c opd = new OPDPlan__c();
        opd.Name = 'Test 0330';
        opd.OPDPlan_ImplementDate__c = Date.today();
        opd.Account_Laboratory__c = acc3.Id;
        opd.OPDType__c = '询价';
        opd.NoOpp_Reason__c = 'HCP对应';
        insert opd;
        // Rental_Apply__c rental = TestDataUtility.CreateRentalApplys(1)[0];
        Report__c reportTest = TestDataUtility.CreateReport(1)[0];
        String url = ApexPages.currentPage().getParameters().put('CF00N10000008ps6d_lkid', opd.Id);
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        ApexPages.StandardController con =  new ApexPages.StandardController(reportTest);
        NewAndEditReportController report = new NewAndEditReportController(con);
        String reportJson = '{"RecordTypeId":"01210000000Qekj","Completed_time_c__c":"2022-03-09 06:18","Hospital_Reference__c":"000000000000000","OwnerId":"0051m0000030e0Q","Department_Class_Ref__c":"000000000000000","Status__c":"草案中","Hospital_Department__c":"0011000000VATK6","Daily_Report__c":"000000000000000","Reporter_State__c":"","Report_OPDPlan__c":"000000000000000","Loaner_request_no1__c":"000000000000000","Date__c":"2022/03/28","Practitioner1__c":"0031m00000N7NSxAAN","Practitioner1_Part__c":"","Practitioner2__c":"000000000000000","Practitioner2_Part__c":"","Practitioner5_others_c__c":"","Purpose1__c":"","Opportunity_Situation__c":"引合発生","Opportunity1__c":"000000000000000","Reason__c":"","Opportunity2__c":"000000000000000","Appeal_Point__c":"","Strategic_Department_Class__c":"","Operation_From__c":null,"Operation_To__c":"","Technical_Category_Manual_c__c":"","Patient_Status__c":"","Operation_Process__c":"","Operation_Task__c":"","Product_Evaluation_Advantage__c":"","Product_Evaluation_Faults__c":"","OPD_Summarize__c":"","Activity_Plan__c":"","OPD_ProductCategory1__c":"","OPD_ProductCategory2__c":"","Product1__c":"000000000000000","OLY_Provide_1__c":"","Product2__c":"000000000000000","OLY_Provide_2__c":"","Product3__c":"000000000000000","OLY_Provide_3__c":"","Product4__c":"000000000000000","OLY_Provide_4__c":"","Product5__c":"000000000000000","OLY_Provide_5__c":"","Evaluation_PDF_number__c":"","Customer_sigh_day_c__c":"","Professor_sigh_text__c":"","Technical_Category1__c":"","Technical_Category2__c":"","Purpose2__c":"引合発生","Customer_sigh_photo__c":""}';
        NewAndEditReportController.saveReport(reportJson,'avgwshDFcxAS',False);
        NewAndEditReportController.saveReport(reportJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        String recordTypeId = Schema.SObjectType.Report__c.getRecordTypeInfosByDeveloperName().get('On_Call').getRecordTypeId();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        String url = ApexPages.currentPage().getParameters().put('00N10000002GE3Z','经销商A');
        url = ApexPages.currentPage().getParameters().put('RecordType',recordTypeId);
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(new Report__c());
        NewAndEditReportController report = new NewAndEditReportController(con);
        Test.stopTest();
    }
    static testMethod void testMethod3() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Report__c reportTest = new Report__c();
        Contact cons = TestDataUtility.CreateContacts(1)[0];
        cons.AWS_Data_Id__c = 'test';
        system.debug('cons:' + cons);
        update cons;
        reportTest.Practitioner1__c = cons.ID;
        reportTest.Practitioner2__c = cons.ID;
        reportTest.Practitioner3__c = cons.ID;
        reportTest.Practitioner4__c = cons.ID;
        reportTest.Practitioner5__c = cons.ID;
        reportTest.Person_In_Charge__c = cons.ID;
        reportTest.Manual_Name__c = 'test';
        insert reportTest;
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(reportTest);
        NewAndEditReportController report = new NewAndEditReportController(con);
        String reportJson = '{"RecordTypeId":"01210000000Qekj","Hospital_Reference__c":"000000000000000","OwnerId":"0051m0000030e0Q","Department_Class_Ref__c":"000000000000000","Status__c":"草案中","Hospital_Department__c":"0011000000VATK6","Daily_Report__c":"000000000000000","Reporter_State__c":"","Engineer__c":null,"Report_OPDPlan__c":"000000000000000","Loaner_request_no1__c":"000000000000000","Date__c":"2022/03/28","Inspection_start_time__c":"2022-03-09T06:18:16.000+0000","Thermal_Diffusion_Worry__c":"false","Practitioner1__c":"0031m00000N7NSxAAN","Practitioner1_Part__c":"","Practitioner2__c":"000000000000000","Practitioner2_Part__c":"","Practitioner5_others_c__c":"","Purpose1__c":"","Opportunity_Situation__c":"引合発生","Opportunity1__c":"000000000000000","Reason__c":"","Opportunity2__c":"000000000000000","Appeal_Point__c":"","Dean_Of_Maintenance__c":"null","Strategic_Department_Class__c":"","Operation_From__c":"2022-02-15T00:41:16.000+0000","Operation_To__c":"","Technical_Category_Manual_c__c":"","Patient_Status__c":"","Operation_Process__c":"","Operation_Task__c":"","Product_Evaluation_Advantage__c":"","Product_Evaluation_Faults__c":"","OPD_Summarize__c":"","Activity_Plan__c":"","OPD_ProductCategory1__c":"","OPD_ProductCategory2__c":"","Product1__c":"000000000000000","OLY_Provide_1__c":"","Product2__c":"000000000000000","OLY_Provide_2__c":"","Product3__c":"000000000000000","OLY_Provide_3__c":"","Product4__c":"000000000000000","OLY_Provide_4__c":"","Product5__c":"000000000000000","OLY_Provide_5__c":"","Evaluation_PDF_number__c":"","Customer_sigh_day_c__c":"","Professor_sigh_text__c":"","Technical_Category1__c":"","Technical_Category2__c":"","Purpose2__c":"引合発生","Customer_sigh_photo__c":""}';
        NewAndEditReportController.saveReport(reportJson,'avgwshDFcxAS',False);
        NewAndEditReportController.saveReport(reportJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditReportControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditTenderinformationControlTest.cls
New file
@@ -0,0 +1,31 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewAndEditTenderinformationControlTest {
    static testMethod void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Tender_information__c tenTest = TestDataUtility.CreateTenderInformation(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(tenTest);
        NewAndEditTenderinformationController tender = new NewAndEditTenderinformationController(con);
        String tenderJson = '{"Retain_Tender__c":"a4J1m000000SDAG","Logical_delete__c":false,"InfoTitle__c":"test1","InfoType__c":"1:预告","Keywords__c":"test","XmNumber__c":"","IsReactionOpp__c":true,"BiddingType__c":"0:公开招标","OpportunityStatus__c":"草案","IsElectronic__c":"","OpportunityNum__c":"1","InfoQianlimaUrl__c":"test","TenderManageCode__c":"","IsRelateProject__c":"是","Hospital__c":"0011m00000Xm6Lk","relativeTime__c":"2022/03/29 11:46","Hospital1__c":"000000000000000","irrelevantReasons__c":"","Hospital2__c":"000000000000000","irrelevantReasonOther__c":"","Hospital3__c":"000000000000000","department_selection__c":"01210000000QemLAAS","Hospital4__c":"000000000000000","AreaProvince__c":"北京","AreaCity__c":"北京","AreaCountry__c":"","InfoPublishTime__c":"","BidingAcquireTime__c":"","TenderBeginTime__c":"","BidingEndTime__c":"","TenderEndTime__c":"","OpenBidingTime__c":"","noticeDate__c":"","ResultDate__c":"","TenderDate__c":"","publicDate__c":"2022/03/29","Bid_Winning_Date__c":"","AgentUnit1__c":"","AgentRelationName__c":"***","AgentUnit2__c":"","AgentRelationWay__c":"***********","AgentUnit3__c":"","ZhaoBiaoUnit1__c":"","ZhaoRelationName__c":"***","ZhaoBiaoUnit2__c":"","ZhaoRelationWay__c":"***********","ZhaoBiaoUnit3__c":"","IsBid__c":"","BiddingStatus__c":"","irresponsibleReason__c":"","NotBidApprovalStatus__c":"","irresponsibleReasonOther__c":"","BudgetAmount1__c":"","WinnerAmount1__c":"","BudgetAmount2__c":"","WinnerAmount2__c":"","BudgetAmount3__c":"","WinnerAmount3__c":"","OBSAP_Budget_amount__c":"","WinnerUnit__c":"","BudgetUnit__c":"","Sum__c":"","SumUnit__c":"","ZhongBiaoUnit1__c":"","ZhongRelationName__c":"***","ZhongBiaoUnit2__c":"","ZhongRelationWay__c":"***********","ZhongBiaoUnit3__c":"","IsOther__c":false,"OtherInfoTitle__c":"","otherInfo__c":"","Name":"testProject","OwnerId":"0051m0000030e0QAAQ","ProjectId__c":"","CursorMark__c":"","File_Surpass_12M__c":false,"department__c":"000000000000000","ZhongRelationName_Encrypted__c":"","AgentRelationName_Encrypted__c":"","ZhaoRelationWay_Encrypted__c":"","ZhongRelationWay_Encrypted__c":"","ZhaoRelationName_Encrypted__c":"","AgentRelationWay_Encrypted__c":"","AWS_Data_Id__c":"'+tenTest.AWS_Data_Id__c+'"}';
        NewAndEditTenderinformationController.saveTenderinformation(tenderJson,'avgwshDFcxAS',False);
        NewAndEditTenderinformationController.saveTenderinformation(tenderJson,'avgwshDFcxAS',True);
        tenTest.AWS_Data_Id__c ='';
        update tenTest;
        NewAndEditTenderinformationController.saveTenderinformation(tenderJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditTenderinformationControlTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewAndEditTenderinformationController.cls
New file
@@ -0,0 +1,47 @@
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
        if (!Test.isRunningTest()) {
            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);
    }
}
force-app/main/default/classes/NewAndEditTenderinformationController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewConsumApplyController.cls
New file
@@ -0,0 +1,188 @@
/**
 * @description       :
 * @author            : ChangeMeIn@UserSettingsUnder.SFDoc
 * @group             :
 * @last modified on  : 03-28-2022
 * @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
**/
global without sharing class NewConsumApplyController {
    public String layoutSectionsStr {get; set;}//for dynamic add readonly attribute
    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 final string ApiPrefix{get;private set;} //Add By Li Jun 20220403
    public Map<string,string> AWSToSobjectEncryptedMap{get;private set;}
    public string AWSToSobjectEncryptedMapJson{get{return JSON.serialize(AWSToSobjectEncryptedMap);}}
    public NewConsumApplyController(ApexPages.StandardController controller) {
        ApiPrefix = 'PIBackApi';
        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());
        if (!Test.isRunningTest()) {
            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());
            Map<string,string> mso = ApexPages.currentPage().getParameters();
            system.debug('mso='+mso);
            if(mso.containsKey('00N10000008rdgs')){
                controller.getRecord().put('demo_purpose2__c',mso.get('00N10000008rdgs'));
            }
            if(mso.containsKey('Name')){
                controller.getRecord().put('Name',mso.get('Name'));
            }
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Consum_Apply__c','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        layoutSectionsStr = JSON.serialize(layoutSections); //for dynamic add readonly attribute
        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__c');
        staticResource = JSON.serialize(piIntegration);
        encryptedAPIList = piIntegration.PIFields;
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        AWSToSobjectEncryptedMap = new Map<String,String>();
        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
            AWSToSobjectEncryptedMap.put(PIDetail.AWS_Field_API__c, PIDetail.SF_Field_API_Name__c);
        }
    }
    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);
            if(!fieldAPIToTypeMap.containskey(fieldAPI)){
                continue;
            }
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            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 if(String.isNotBlank(fieldValue))  {
                    fieldValue = fieldValue.replace('/', '-') + ':00';
                    System.debug('fieldValue = ' + fieldValue);
                    consumApplyInfo.put(fieldAPI, Datetime.valueOf(fieldValue));
                }else{
                    consumApplyInfo.put(fieldAPI, null);
                }
            }else if(String.valueOf(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='CURRENCY'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                consumApplyInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?null:Decimal.valueOf(fieldValue.replace(',', '')));
            } else if(String.valueof(fielddataType)=='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__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(DmlException e) {
            rid=consumApplyInfo.Id;
            Integer index = 0;
            System.debug(e.getNumDml());
            System.debug(e.getDmlFields(index));
            System.debug(e.getDmlId(index));
            System.debug(e.getDmlIndex(index));
            System.debug(e.getDmlMessage(index));
            System.debug(e.getDmlStatusCode(index));
            System.debug(e.getDmlType(index));
            system.debug(e.getMessage());
            system.debug(e.getStackTraceString());
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            resp.status = 'Exception';
            resp.message ='保存失败,原因:'+ e.getDmlMessage(index);
            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)consumApplyInfo.get('AWS_Data_Id__c'),consumApplyJson ,status,'');
            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;
        }
    }
}
force-app/main/default/classes/NewConsumApplyController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewConsumApplyControllerTest.cls
New file
@@ -0,0 +1,45 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewConsumApplyControllerTest {
    @TestSetup
    static void makeData(){
        List<String> strList = new List<String>();
        strList.add('Consum_Apply__c');
        strList.add('Contact');
        TestDataUtility.CreatePIPolicyConfigurations(strList);
    }
    static testMethod void testMethod1() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Consum_Apply__c consumTest = TestDataUtility.CreateConsumApply(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(consumTest);
        NewConsumApplyController consum = new NewConsumApplyController(con);
        String consumJson = '{"HP_received_sign_rich__c":"","Name":"123456","Person_In_Charge__c":"00510000000fSYI","ApplyPerson_Phone__c":"","applyUser__c":"00510000000fSYI","Loaner_centre_mail_address__c":"sfdc_lvxueyan@olympus.com.cn","Is_Special_Rental__c":false,"Request_Shipping_7days_Before__c":"","Status__c":"草案中","ConsumApplyRemind_Text__c":"1、创建申请单锁定库存后,请于2个工作日内提交审批,否则系统自动释放库存。\\n2、请确保您提交的申请单在\\"希望到货日-7个工作日”前完成审批,否则申请单自动取消。\\n3、请提交22个工作日以内使用的耗材申请单。","Hospital__c":"000000000000000","Loaner_medical_Staff__c":"000000000000000","Strategic_dept__c":"000000000000000","Phone_number__c":"","Account__c":"000000000000000","Product_category__c":"ET","demo_purpose2__c":"学会展会","QIS_number__c":"000000000000000","Campaign__c":"70110000000laUw","OPDPlan__c":"000000000000000","Rental_Apply__c":"000000000000000","Demo_purpose_text__c":"test","Request_shipping_day__c":"2022-03-28:00","Shipment_address__c":"a2H10000005RQDJ","direct_send__c":"上门自提","Dealer__c":"0011000000VATK6","pickup_time__c":"2022-03-28 17:11:00","Loaner_received_staff__c":"testname","Loaner_received_staff_phone__c":"1234567890","direct_shippment_address__c":"106 Catalpa St, Coffeyville, KS 67337, USA","Post_Code__c":"12345-123","Old_Consum_Apply__c":"000000000000000","Split_Apply_Reason__c":"","DeliverySlip__c":"000000000000000","HP_received_sign_NG__c":false,"HP_received_sign_NG_Reason__c":"","AssetManageConfirm__c":false,"Cancel_Reason__c":"","Loaner_cancel_request__c":"","Consum_Received_Day__c":"","OwnerId":"0051m0000030e0Q","Request_demo_time__c":"","Request_approval_time__c":"","Application_accept_time__c":"","Request_answer_time__c":"","OPD__c":"000000000000000","OPDAmount__c":"","Shipment_Slip_tmp__c":""}';
        NewConsumApplyController.saveConsumApply(consumJson,'avgwshDFcxAS',False);
        NewConsumApplyController.saveConsumApply(consumJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        String recordTypeId = Schema.SObjectType.Consum_Apply__c.getRecordTypeInfosByDeveloperName().get('StandardRequest').getRecordTypeId();
        String url = ApexPages.currentPage().getParameters().put('00N10000008rdgs','北京');
        url = ApexPages.currentPage().getParameters().put('Name','RC修理');
        url = ApexPages.currentPage().getParameters().put('RecordType',recordTypeId);
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(new Consum_Apply__c());
        NewConsumApplyController repDetail = new NewConsumApplyController(con);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewConsumApplyControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewConsumApplyEquipSetDetailControlTest.cls
New file
@@ -0,0 +1,26 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewConsumApplyEquipSetDetailControlTest {
    static testMethod void testMethod18() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Consum_Apply_Equipment_Set_Detail__c consumDetailTest = TestDataUtility.CreateConsumApplyEquipmentSetDetail(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(consumDetailTest);
        NewConsumApplyEquipSetDetailController consumDetail = new NewConsumApplyEquipSetDetailController(con);
        String consumDetailJson = '{"Inspection_result_after__c":"","Internal_asset_location_before__c":"","Salesdepartment_before__c":"","Consum_Apply__c":"a3i1m000000bT9k","Equipment_Type_text__c":"","Consum_Apply_Equipment_Set__c":"a3h100000005DiN","SerialNumber_text__c":"","Asset__c":"000000000000000","Canceled__c":"000000000000000","Loaner_accsessary__c":false,"FSD_Name_CHN__c":"","Qu_Xiao_Fen_Pei_Shu_Liang_Jia__c":"","Trial_User_Encrypt__c":"","Show_demonstration__c":"","Consum_Start_Date__c":"","Operation_Type__c":"","Trial_User__c":"","Case_OR_animal_organ__c":"","Spare__c":false,"Degree_Of_Importance__c":"","Comment__c":"","Select_Time__c":"","Shipment_request__c":false,"Shipment_request_time2__c":"","DeliverySlip__c":"000000000000000","Shippment_loaner_time__c":"","Received_Confirm__c":"","Received_NG_Content__c":"","Has_Picture__c":false,"Loaner_received_time__c":"","Asset_Center_Confirm__c":"","Asset_Center_Confirm_Time__c":"","Return_DeliverySlip__c":"000000000000000","Asset_return_time__c":"","Arrival_in_wh__c":false,"Arrival_wh_time__c":"","Cancel_Reason__c":"","Loaner_cancel_Remarks__c":"","Cancel_Date__c":"","Lost_item_check_time__c":"","Lost_item_check_time_Final__c":"","Name":"123","OnStock_By_Cancel__c":false,"ExpiredArrival__c":false,"WH_location__c":"","Yi_Zhi_Guo_Qi_Jia__c":"","Hui_Ji_Jia__c":"","Shang_Jia_Jia__c":"","Yi_Zhi_Bao_Fei_Jia__c":"","Inspection_Cnt_Jia__c":"","Yi_Fa_Huo_Jia__c":"","ManagementCode__c":"","Shipment_Saved_Flg__c":false,"EquipmentManagementCode__c":""}';
        NewConsumApplyEquipSetDetailController.saveConsumApply(consumDetailJson,'avgwshDFcxAS',False);
        NewConsumApplyEquipSetDetailController.saveConsumApply(consumDetailJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewConsumApplyEquipSetDetailControlTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls
New file
@@ -0,0 +1,133 @@
/**
 * @description       :
 * @author            : ChangeMeIn@UserSettingsUnder.SFDoc
 * @group             :
 * @last modified on  : 03-17-2022
 * @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
**/
global without sharing class NewConsumApplyEquipSetDetailController {
    public String layoutSectionsStr {get; set;}//for dynamic add readonly attribute
    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());
        if (!Test.isRunningTest()) {
            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;
        layoutSectionsStr = JSON.serialize(layoutSections); //for dynamic add readonly attribute
        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);
            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_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;
        }
    }
}
force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewRepairController.cls
New file
@@ -0,0 +1,189 @@
/*
 *@Description:
 *@Author: Dennis Rodman
 *@Date: 2022-03-10 10:26:47
*/
global without sharing class NewRepairController {
    public String layoutSectionsStr {get; set;}//for dynamic add readonly attribute
    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
        if(!Test.isRunningTest()){
           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{
            //新建
            Map<string,string> mso = ApexPages.currentPage().getParameters();
            system.debug('mso='+mso);
            if(mso.containsKey('00N10000006P6SM')){
                controller.getRecord().put('SalesOfficeCode_selection__c',mso.get('00N10000006P6SM'));
            }
            if(mso.containsKey('00N10000002FH86')){
                controller.getRecord().put('On_site_repair__c',mso.get('00N10000002FH86'));
            }
            if(mso.containsKey('00N10000006P6Rn')){
                controller.getRecord().put('work_location_select__c',mso.get('00N10000006P6Rn'));
            }
            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;
        layoutSectionsStr = JSON.serialize(layoutSections); //for dynamic add readonly attribute
        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);
            if(!fieldAPIToTypeMap.containskey(fieldAPI)){
                continue;
            }
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            if(String.valueOf(fielddataType)=='DATE'){
                repairInfo.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',' ');
                    repairInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                }else if(String.isNotBlank(fieldValue))  {
                    fieldValue = fieldValue.replace('/', '-') + ':00';
                    System.debug('fieldValue = ' + fieldValue);
                    repairInfo.put(fieldAPI, Datetime.valueOf(fieldValue));
                }else{
                    repairInfo.put(fieldAPI, null);
                }
            }else if(String.valueOf(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='CURRENCY'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                repairInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?null:Decimal.valueOf(fieldValue.replace(',', '')));
            } 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(DmlException e) {
            rid=repairInfo.Id;
            Integer index = 0;
            System.debug(e.getNumDml());
            System.debug(e.getDmlFields(index));
            System.debug(e.getDmlId(index));
            System.debug(e.getDmlIndex(index));
            System.debug(e.getDmlMessage(index));
            System.debug(e.getDmlStatusCode(index));
            System.debug(e.getDmlType(index));
            system.debug(e.getMessage());
            system.debug(e.getStackTraceString());
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            resp.status = 'Exception';
            resp.message ='保存失败,原因:'+ e.getDmlMessage(index);
            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)repairInfo.get('AWS_Data_Id__c'),repairJson ,status,'');
            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;
        }
    }
}
force-app/main/default/classes/NewRepairController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/NewRepairControllerTest.cls
New file
@@ -0,0 +1,46 @@
/*
 * Author: Guo, Aline Yaying
 * Created Date: 03/22/2022
 * Purpose: Test Class
 * History:
 *      03/22/2022 - Guo, Aline Yaying - Initial Code.
 *
 * */
@isTest
private class NewRepairControllerTest {
    static testMethod void testMethod1() {
        //1. 准备数据
        TestDataUtility.CreatePIPolicyConfiguration();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Repair__c repTest = TestDataUtility.CreateRepairs(1)[0];
        //2. 运行代码逻辑
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(repTest);
        NewRepairController repDetail = new NewRepairController(con);
        // Map<String,Object> mapTest = new Map<String,Object>();
        // mapTest.put('Contacts__c',repTest );
        String repJson = '{\"Repair_Shipped_DateTime__c\":\"\",\"Request_approval_day__c\":\"\",\"Discount_Price__c\":\"\",\"Source_QIS__c\":\"\",\"Old_Name__c\":\"\",\"Exc_work_location__c\":false,\"OTSRepairOrder__c\":\"\",\"Advance_Payment_Flag__c\":false,\"Delivered_Product__c\":\"02i10000004FhIt\",\"PaperRepairRequestNo__c\":\"\",\"Hospital__c\":\"000000000000000\",\"SAPRepairNo__c\":\"\",\"Department_Class__c\":\"000000000000000\",\"RepairOrderStatusCode__c\":\"\",\"Account__c\":\"0011000000VATK6\",\"RepairCostType__c\":\"无偿\",\"Dealer__c\":\"000000000000000\",\"RepairOrderStatusName__c\":\"\",\"Incharge_Staff__c\":\"000000000000000\",\"ReRepairObject_result__c\":false,\"Incharge_Staff_Contact__c\":\"000000000000000\",\"Repair_Rank__c\":\"\",\"SalesOfficeCode_selection__c\":\"北京\",\"Address_type__c\":\"\",\"On_site_repair__c\":\"RC修理\",\"Recall_Correspondence_Apply__c\":\"\",\"Returns_Product_way__c\":\"返送办事处\",\"ReturnType__c\":\"\",\"IfCheckFixture__c\":false,\"DW_Sign_Txt__c\":false,\"Repair_Detail__c\":\"test\",\"RepairApplicant__c\":\"\",\"RepairApplicantHospital__c\":\"\",\"RepairApplicantDepartment__c\":\"\",\"address_Contacts__c\":\"\",\"address_Telephone__c\":\"\",\"address_Contacts_Name__c\":\"\",\"address_City__c\":\"\",\"Detailed_Address__c\":\"\",\"address_ZipCode__c\":\"\",\"LogisticsLatestStatus__c\":\"\",\"LogisticsSendTime__c\":\"\",\"DeliveryLogisticsMode__c\":\"快递\",\"LogisticsReceiveTime__c\":\"\",\"DeliveryLogisticsNo__c\":\"\",\"engineerSendDate__c\":\"\",\"DeliveryLogisticsAnnotation__c\":\"\",\"ReturnOrderLatestStatus__c\":\"\",\"ReturnOrderSendTime__c\":\"\",\"ReturnOrderNo__c\":\"\",\"ReturnOrderReceiveTime__c\":\"\",\"ReturnLogisticsLatestStatus__c\":\"\",\"ReturnLogisticsDeliveryTime__c\":\"\",\"ReturnLogisticsNo__c\":\"\",\"ReturnLogisticsSigningTime__c\":\"\",\"DateReceiptQuestions__c\":\"2022/03/28\",\"BreakORFallOff__c\":\"\",\"DelayReportReason__c\":\"\",\"UseFailProductFinish__c\":\"\",\"ifDeadHurt__c\":\"\",\"SupportingProducts__c\":\"\",\"ProblemOccurred__c\":\"\",\"AfterFailureInformation__c\":\"\",\"ProblemOccurredSelect__c\":\"\",\"Delay15Min__c\":\"\",\"ProductFailureRelated__c\":\"\",\"InformationFrom__c\":\"\",\"ReportAdverseEvents__c\":\"\",\"FailureQInHospital__c\":\"\",\"WhatProject__c\":\"\",\"OperationOrExaminationName__c\":\"\",\"Maintenance_Contract__c\":\"000000000000000\",\"VM_Maintenance_Contract__c\":\"000000000000000\",\"MaintenanceContractType__c\":\"\",\"Repair_Quotation_Id__c\":\"000000000000000\",\"Repair_Estimation_Followed_By__c\":\"\",\"Repair_Estimation_Follow_Date__c\":\"\",\"Failure_Source__c\":\"\",\"InspectionResultFlag__c\":\"\",\"InspectionComment__c\":\"\",\"InspectionFailureCause__c\":\"\",\"Billing_Amount__c\":\"\",\"CurrentPeriodPaymentAmount__c\":\"\",\"Paid_Amount__c\":\"\",\"LastIssueCumulativePaybackAmount__c\":\"0.00\",\"hospitalQuotationText__c\":\"\",\"Receipt_category__c\":\"\",\"Received_money_day_finacial_dapt__c\":\"\",\"Request_yanshoudan_PDF__c\":false,\"Confirmed_Collect_money__c\":false,\"Confirmed_received_document__c\":false,\"Collect_money_check1__c\":\"\",\"Sheet_mating_staff1__c\":\"\",\"Receipt_comment__c\":\"\",\"Whether_collect_repair_money_or_not__c\":false,\"Collection_Status__c\":\"\",\"Forecast_Collection_Date__c\":\"\",\"Uncollect_fee_comment__c\":\"\",\"Repair_Collection_Followed_By__c\":\"\",\"BilltoPartyNoAccount__c\":\"\",\"Repair_Collection_Follow_Date__c\":\"\",\"Reason_cannot_collect_repair_fee__c\":\"\",\"Failure_Occurrence_Date__c\":\"2022/03/28\",\"Status__c\":\"草案中\",\"Failure_Occurrence_Date2__c\":\"\",\"Repair_Completed_Date__c\":\"\",\"RepairTime__c\":\"\",\"Repair_Final_Inspection_Date__c\":\"\",\"ReceiverTime__c\":\"\",\"Repair_Final_Inspection_DateTime__c\":\"\",\"PlannedVisitDay__c\":\"\",\"Repair_Shipped_Date__c\":\"\",\"ActualVisitDateFirst__c\":\"\",\"ActualVisitDateSecond__c\":\"\",\"ReturnOrderReceiveDate__c\":\"\",\"ActualVisitDateThird__c\":\"\",\"Repair_Returned_To_HP_Date__c\":\"\",\"SubOrderCompleteDate__c\":\"\",\"Facility_Return_Receipt_Collection_reque__c\":\"\",\"SubOrderCreatedDate__c\":\"\",\"Receipt_received_date__c\":\"\",\"On_Site_Repair_Order_Date__c\":\"\",\"Billing_Received_Date__c\":\"\",\"Send_To_RC_Date__c\":\"\",\"Received_Date__c\":\"\",\"Repair_Ordered_Date__c\":\"\",\"Facility_Return_Receipt_Collection_Date__c\":\"\",\"Repair_Ordered_DateTime__c\":\"\",\"repair_cancel_date__c\":\"\",\"Repair_Inspection_Date__c\":\"\",\"RepairOrder_Complete_Day__c\":\"\",\"Agreed_Date__c\":\"\",\"Repair_Firstestimated_Date__c\":\"\",\"RcSorcDate__c\":\"\",\"RcOgzDate__c\":\"\",\"SorcOgzDate__c\":\"\",\"SorcAcceptDate__c\":\"\",\"OgzAcceptDate__c\":\"\",\"part_arrangement_complete__c\":\"\",\"Repair_Start_Date__c\":\"\",\"Planned_Repair_Completed_Date__c\":\"\",\"Return_Without_Repair__c\":false,\"Return_Without_Repair_IF__c\":false,\"CancellationReason__c\":\"\",\"Return_Without_Repair_Request_Date__c\":\"\",\"Return_Without_Repair_Date__c\":\"\",\"IncorrectDataComment__c\":\"\",\"SAP_not_accept_repair_result__c\":\"\",\"Quotation_agree_cancel_date__c\":\"\",\"Repair_Source__c\":\"\",\"RepairSubOrder__c\":\"000000000000000\",\"On_Call_ID__c\":\"000000000000000\",\"QIS_ID__c\":\"000000000000000\",\"InsReport__c\":\"000000000000000\",\"ASReportedCode__c\":\"\",\"Repair_ConfirmationDate__c\":\"\",\"PAE_Determine__c\":\"\",\"Repair_Authenticator__c\":\"000000000000000\",\"Aware_date__c\":\"\",\"MBC_AwareDate__c\":\"\",\"OCSMAdministrativeReportDate__c\":\"\",\"OCSMAdministrativeReportStatus__c\":\"\",\"OCSMAdministrativeReportNumber__c\":\"\",\"ASReportedCodeAC__c\":\"\",\"OCSM_RC_CordingDate__c\":\"\",\"PAE_DetermineAC__c\":\"\",\"OCSM_RC_CordingUser__c\":\"000000000000000\",\"IISE_confirmed_person__c\":\"\",\"IISE_confirmed_day__c\":\"\",\"Complaint_Number__c\":\"\",\"OSH_ConfirmationDate__c\":\"\",\"if_Repair_Allowed__c\":\"\",\"OSH_Affirmant__c\":\"000000000000000\",\"NotAllowedReason__c\":\"\",\"OSHRAConfirmDate__c\":\"\",\"OSHRAConfirmUser__c\":\"000000000000000\",\"CFDA_No_Hand__c\":\"\",\"ProduceCompany_hand__c\":\"\",\"FSE_ApplyForRepair_time__c\":\"\",\"FSE_owner_Salesdepartment__c\":\"\",\"SAP_Transfer_time__c\":\"\",\"Repair_cost__c\":\"\",\"Service_contract_judege_day__c\":\"\",\"Repair_cost_date__c\":\"\",\"Invalid_check__c\":false,\"Offer_Rental_New__c\":false,\"Delete_Flag__c\":false,\"if_Rental_Apply__c\":false,\"NFM108_Receipt__c\":\"000000000000000\",\"NFM105_MessageGroupNumber__c\":\"\",\"Latest_Collect_Date_Priority__c\":\"\",\"Rental_Apply_Equipment_Set_Detail_Id__c\":\"\",\"Agreed_Date2__c\":\"\",\"Rental_Apply_Equipment_Set_Detail__c\":\"000000000000000\",\"Agreed_Date_Cancel__c\":\"\",\"TransferApplyDetail__c\":\"\",\"StatusUpdateTime__c\":\"\",\"TransferApplyDetail_Id__c\":\"\",\"AsyncData__c\":false,\"ETQ_UPLOAD_STATUS__c\":\"\",\"AWS_Interface_Time__c\":\"\",\"ETQ_UPLOAD_MESSAGE__c\":\"\",\"INTERFACE_RECORD_ID__c\":\"\",\"PAE_reappear_confirm__c\":\"\",\"OCSM_Manager_Mail_XB__c\":\"\",\"OCSM_Manager_Mail__c\":\"\",\"PAE_email__c\":\"\",\"Service_Assistant_Text__c\":\"\",\"AC_PAED__c\":\"\",\"RC_PAED__c\":\"\",\"work_location_select__c\":\"北京办事处\",\"Address_Contacts_Encrypt__c\":\"\",\"Address_Contacts_Name_Encrypt__c\":\"\",\"Address_Telephone_Encrypt__c\":\"\",\"Address_ZipCode_Encrypt__c\":\"\",\"Detailed_Address_Encrypt__c\":\"\",\"Repair_Applicant_Encrypt__c\":\"\",\"AWS_Data_Id__c\":\"958062858866786305\"}';
        //"Repair_Shipped_DateTime__c":"2022-03-28T09:33:31.955Z",
        NewRepairController.saveRepair(repJson,'avgwshDFcxAS',True);
        NewRepairController.saveRepair(repJson,'avgwshDFcxAS',False);
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        String recordTypeId = Schema.SObjectType.Repair__c.getRecordTypeInfosByDeveloperName().get('Repair').getRecordTypeId();
        List<String> strList = new List<String>();
        strList.add('Repair__c');
        strList.add('Address__c');
        strList.add('Contact');
        TestDataUtility.CreatePIPolicyConfigurations(strList);
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        String url = ApexPages.currentPage().getParameters().put('00N10000006P6SM','北京');
        url = ApexPages.currentPage().getParameters().put('00N10000002FH86','RC修理');
        url = ApexPages.currentPage().getParameters().put('00N10000006P6Rn','北京办事处');
        url = ApexPages.currentPage().getParameters().put('RecordType',recordTypeId);
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(new Repair__c());
        NewRepairController repDetail = new NewRepairController(con);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewRepairControllerTest.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/OFSInsReportLayoutController.cls
@@ -28,7 +28,7 @@
    private String oldHospital;
    private String oldStatus;
    private Boolean isPDF;
    public Boolean isPDF{get;private set;}
    private Boolean isUpDown;
    private Boolean isSubmit;
    public String alertMessage {
@@ -247,18 +247,23 @@
            oirSettingMap.put(oir.recordType_devName__c, oir);
        }
    }
    public string staticResource { get; private set; }
    //public boolean IsAddmessage { get; private set; }
    /**
    * Visaulforceから呼ばれるコンストラクタ
    */
    public OFSInsReportLayoutController(ApexPages.StandardController controller) {
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Inspection_Report__c'));
}
    public OFSInsReportLayoutController() {
        countorder = 1;
        nowAssetcount = 1;
        runCount = 0;
        isUpDown = true;
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Inspection_Report__c'));
    }
    // TODO 全部画面リフレッシュにする
@@ -335,7 +340,7 @@
                pReportId = iis[0].Inspection_ReportId__c;
            }
            List < Inspection_Report__c > queryIrs = [select Id, RecordType.DeveloperName, RecordType.Name, Name, Status__c, Inspection_StartTime__c, Inspection_EndTime__c from Inspection_Report__c where Id = :pReportId];
            List < Inspection_Report__c > queryIrs = [select Id, RecordType.DeveloperName, RecordType.Name, Name, Status__c, Inspection_StartTime__c, Inspection_EndTime__c,Responsible_Person_Encrypted__c,phone_Encrypted__c,AWS_Data_Id__c from Inspection_Report__c where Id = :pReportId];
            if (queryIrs.size() <= 0) {
                initFlag = false;
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '无法找到点检报告书'));
@@ -401,7 +406,7 @@
            }
        }
        this.settingSoql = 'select Id, Name, Name_Manual__c, Next_StartHour_Page__c, Next_StartMinute_Page__c, Next_EndHour_Page__c, Next_EndMinute_Page__c '
        this.settingSoql = 'select Id, Name, Name_Manual__c, Next_StartHour_Page__c, Next_StartMinute_Page__c, Next_EndHour_Page__c, Next_EndMinute_Page__c,Responsible_Person_Encrypted__c,phone_Encrypted__c,AWS_Data_Id__c '
        // fxk 2021/8/4 新加 Start
        + ' , Remarks__c, CleaningFluid__c,SterilizationMethod__c,Disinfectant__c,UsedMachine__c,Used_ET__c ,Mode__c';
        // fxk 2021/8/4 新加 End
@@ -785,14 +790,19 @@
            // }
        }
        if (isError) {
            system.debug('795'+ir.AWS_Data_Id__c);
            return null;
        }
        system.debug('798'+ir.AWS_Data_Id__c);
        //add by rentx 20210630
        if (timeCheck() != true) {
            system.debug('800');
            return null;
        }
        system.debug('804');
        if (isPDF) {
            ir.Status__c = 'PDF';
        }
@@ -801,6 +811,7 @@
            ir.Status__c = '填写完毕';
        }
        system.debug('813');
        Savepoint sp = Database.setSavepoint();
        try {
            // 部长经理总监
@@ -815,9 +826,11 @@
            OFSInsReportAssetHistoryController.upsertInspection_Report(ir);
        } catch(Exception e) {
            clearIrId(sp, e, isIrNew);
            system.debug('829');
            return null;
        }
        system.debug('832');
        // 日報からくる場合、保存時、EventCに書き戻す
        if (String.isBlank(pEventCId) == false) {
            try {
@@ -825,10 +838,11 @@
                update ec;
            } catch(Exception e) {
                clearIrId(sp, e, isIrNew);
                system.debug('840');
                return null;
            }
        }
        system.debug('844');
        //List<Inspection_Item__c> toUpsertAhs = new List<Inspection_Item__c>();
        List < Inspection_Item__c > toDeleteAhs = new List < Inspection_Item__c > ();
        List < Inspection_Item__c > manualDeleteAhs = new List < Inspection_Item__c > ();
@@ -868,14 +882,17 @@
        // SWAG-AREBA8 end
        toDeleteAhs = [select Id, AssetId__c from Inspection_Item__c where AssetId__c in :unCheckedAssetIds and Inspection_ReportId__c = :ir.Id];
        system.debug('884');
        try {
            if (manualDeleteAhs.size() > 0) toDeleteAhs.addAll(manualDeleteAhs);
            OFSInsReportAssetHistoryController.deleteInspection_Item(ir, toDeleteAhs);
        } catch(Exception e) {
            clearIrId(sp, e, isIrNew);
            system.debug('890');
            return null;
        }
        system.debug('894');
        try {
            //OFSInsReportAssetHistoryController.upsertInspection_Item(ir, toUpsertAhs);
            OFSInsReportAssetHistoryController.upsertInspection_Item(ir, new List < Inspection_Item__c > (toUpsertAhsMap.keySet()));
@@ -884,9 +901,11 @@
            for (Inspection_Item__c ah: toUpsertAhsMap.keySet()) {
                if (toUpsertAhsMap.get(ah).isNew == true) ah.Id = null;
            }
            system.debug('903');
            return null;
        }
        system.debug('905');
        saveOK = true;
        this.init();
        return null;
@@ -896,6 +915,7 @@
        if (isIrNew) ir.Id = null;
        Database.rollback(sp);
        ApexPages.addMessages(e);
        //IsAddmessage = true;
    }
    private Boolean checkHpChange() {
force-app/main/default/classes/OFSInsReportLayoutControllerTest.cls
@@ -1,5 +1,9 @@
@isTest
private class OFSInsReportLayoutControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration('Inspection_Report__c');
    }
    public class TestRepo {
        public final Integer ASSETMAX = 8;
        public OFSInsReportLayout__c layout { get; private set; }
@@ -39,7 +43,8 @@
            //Profile prof = [select Id from Profile where Name ='901_经销商社区普通权限_2重验证'];
            User loginUser = [Select Id, Alias, Province__c from User where Id =: UserInfo.getUserId()];
            loginUser.Job_Category__c = '销售服务';
            update loginUser;
            //update loginUser;
            loginUser = [Select Id, Alias, Province__c from User where Job_Category__c = '销售服务' limit 1];
            ir = new Inspection_Report__c(Name = '*', Inspection_Date__c = inspectionDate, Hospital__c = hp.Id);
            ir.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Inspection_Report__c' and DeveloperName = 'EndoscopeSystem'].id;
@@ -257,8 +262,10 @@
        Test.startTest();
        TestRepo repo = new TestRepo();
        repo.createInspectionReport(null);
        repo.initAssets();
        repo.sqlIr();
        String wrongId = repo.ir.Id;
        wrongId = wrongId.substring(0, 14) + wrongId.substring(13, 14);
        Apexpages.currentPage().getParameters().put('id', wrongId);
force-app/main/default/classes/OnCallController.cls
New file
@@ -0,0 +1,147 @@
/**
 * @description       :
 * @author            : ChangeMeIn@UserSettingsUnder.SFDoc
 * @group             :
 * @last modified on  : 03-28-2022
 * @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
**/
global without sharing class OnCallController {
    public String layoutSectionsStr {get; set;}//for dynamic add readonly attribute
    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
        if(!Test.isRunningTest()){
            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;
            obj.put('OwnerId',UserInfo.getUserId());
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'On_Call__c','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        layoutSectionsStr = JSON.serialize(layoutSections); //for dynamic add readonly attribute
        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);
            if(!fieldAPIToTypeMap.containskey(fieldAPI)){
                continue;
            }
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            if(String.valueOf(fielddataType)=='DATE'){
                onCallInfo.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',' ');
                    onCallInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                }else if(String.isNotBlank(fieldValue))  {
                    fieldValue = fieldValue.replace('/', '-') + ':00';
                    System.debug('fieldValue = ' + fieldValue);
                    onCallInfo.put(fieldAPI, Datetime.valueOf(fieldValue));
                }else{
                    onCallInfo.put(fieldAPI, null);
                }
            }else if(String.valueOf(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='CURRENCY'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                onCallInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?null:Decimal.valueOf(fieldValue.replace(',', '')));
            } 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;
        }
    }
}
force-app/main/default/classes/OnCallController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/OnCallControllerTest.cls
New file
@@ -0,0 +1,22 @@
@isTest
private class OnCallControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration('On_Call__c');
    }
    static testMethod void testMethod1() {
        String onCallJson = '{"Status_c__c":"跟进中","segment__c":"'+'000000000000000'+'","OwnerId":"0050l000005fcnt","Responsible_Person_HP__c":"Test","Oncall_report_number_c__c":"Test","Caller_phone__c":"186435431212","Hospital__c":"'+'000000000000000'+'","Trable_occur_day_c__c":"2022/03/24 10:45","Taking_call_Time_c__c":"2022/03/24 10:45","First_ploblem_c__c":"","From_c__c":"","To_c__c":"","Oncall_Equipment__c":"000000000000000","Oncall_Product_manual__c":"","Customer_Problem_c__c":"","FinishDataTime__c":"","Customer_sigh_c__c":false,"Customer_sigh_day_c__c":"","AWS_Data_Id__c":"1234567890"}';
        Test.startTest();
        On_Call__c onCall = new On_Call__c();
        ApexPages.StandardController sc = new ApexPages.StandardController(onCall);
        OnCallController occ = new OnCallController(sc);
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        Test.startTest();
        String onCallJson = '{"Status_c__c":"跟进中","segment__c":"'+'000000000000000'+'","OwnerId":"0050l000005fcnt","Responsible_Person_HP__c":"Test","Oncall_report_number_c__c":"Test","Caller_phone__c":"186435431212","Hospital__c":"'+'000000000000000'+'","Trable_occur_day_c__c":"2022/03/24 10:45","Taking_call_Time_c__c":"2022/03/24 10:45","First_ploblem_c__c":"","From_c__c":"","To_c__c":"","Oncall_Equipment__c":"000000000000000","Oncall_Product_manual__c":"","Customer_Problem_c__c":"","FinishDataTime__c":"","Customer_sigh_c__c":false,"Customer_sigh_day_c__c":"","AWS_Data_Id__c":"1234567890"}';
        OnCallController.saveOnCall(onCallJson,'1adf234dafa',true);
        OnCallController.saveOnCall(onCallJson,'1adf234dafa',false);
        Test.stopTest();
    }
}
force-app/main/default/classes/OnCallControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/Option.cls
New file
@@ -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;}
}
force-app/main/default/classes/Option.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/PIHelper.cls
New file
@@ -0,0 +1,258 @@
/*
 * 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 Set<String> displayByOrderNumberObject = new set<String>{'Report__c'};
    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;
        Integer MaxLogColumnLength = 131072;
        try {
            Http http = new Http();
            HttpRequest request = new HttpRequest();
            request.setEndpoint(transUrl);
            request.setMethod('POST');
            request.setHeader('pi-token',token);
            request.setHeader('Content-Type', 'application/json');
            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';
            String res=response.getBody();
            traLog.Response__c=res.substring(0, (res.length() > MaxLogColumnLength ? MaxLogColumnLength : res.length()));
        } 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;
         Integer MaxLogColumnLength = 131072;
         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');
             request.setHeader('pi-token',token);
             request.setHeader('Content-Type', 'application/json');
             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';
             String res=response.getBody();
             traLog.Response__c=res.substring(0, (res.length() > MaxLogColumnLength ? MaxLogColumnLength : res.length()));
         } 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;
    }
    //save qianlima log method add sushanhu 20220324
    // model 0 为文件 1为数据
    public static void insertConfirmTrans(String module,Integer isSuccess, String   sfRecordId ,String transId ,Integer model,String transUrl,List<idList> idList){
        Boolean result =false;
        Transaction_Log__c traLog = new Transaction_Log__c();
        if (model==0) {
            traLog.Module__c = 'ConfirmFileTransaction '+module;
        }else {
            traLog.Module__c = 'Confirm Transaction '+module;
        }
        traLog.Interface_URL__c = transUrl;
        traLog.TransId__c = transId;
        Integer MaxLogColumnLength = 131072;
        if (!String.isEmpty(sfRecordId)) {
           traLog.Request__c=sfRecordId.substring(0, (sfRecordId.length() > MaxLogColumnLength ? MaxLogColumnLength : sfRecordId.length()));
        }else {
            String sfIds =JSON.serialize(idList);
           traLog.Request__c=sfIds.substring(0, (sfIds.length() > MaxLogColumnLength ? MaxLogColumnLength : sfIds.length()));
        }
         if(isSuccess==0){
            traLog.Status__c = 'fail';
         } else {
            traLog.Status__c='success';
         }
        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和appsecret
        AWS_Integration_Info__mdt awsConfiguration = [SELECT App_Id__c,Max_Query_Number__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);
            system.debug('response.getBody()='+response.getBody());
            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];
        if(displayByOrderNumberObject.contains(sobjectType)){
            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 order by Order_Number__c];
        }
        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.maxQueryNumber = Integer.valueof(awsConfiguration.Max_Query_Number__c);
        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 Integer maxQueryNumber{set;get;}
        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;}
    }
}
force-app/main/default/classes/PIHelper.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/PIHelperTest.cls
New file
@@ -0,0 +1,45 @@
@isTest
private class PIHelperTest {
    static testMethod void getPIIntegrationInfo() {
        TestDataUtility.CreatePIPolicyConfiguration('Contact');
        String sobjectType = 'Contact';
        List<AWS_Integration_Info__mdt> awsConfigurationList = [SELECT App_Id__c,Max_Query_Number__c,Token_URL__c,App_Secret__c,Host_URL__c FROM AWS_Integration_Info__mdt  WHERE DeveloperName = 'AWS_Default_Configuration'];
        Test.startTest();
        PIHelper.getPIIntegrationInfo(sobjectType);
        Test.stopTest();
    }
    static testMethod void saveTransLog() {
        Test.startTest();
        PIHelper.saveTransLog('module','vadsjngrqvjca','avgwshDFcxAS', 'DSAGSFBQdfdsoav','test','0','testmsg');
        Test.stopTest();
    }
    static testMethod void confirmTrans() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreatePIHelperHttpMock());
        Test.startTest();
        List<PIHelper.idList> idList = new List<PIHelper.idList>();
        PIHelper.idList pid = new PIHelper.idList();
        pid.awsId = 'vadsjngrqvjca';
        pid.sfRecordId = 'avgwshDFcxAS';
        idList.add(pid);
        PIHelper.confirmTrans('module',1,'vadsjngrqvjca' ,'avgwshDFcxAS' ,'DSAGSFBQdfdsoav','https://sfpi-mebg-test.olympuschina.com/api/contact/insert',idList);
        Test.stopTest();
    }
    static testMethod void confirmFileTrans() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreatePIHelperHttpMock());
        Test.startTest();
        PIHelper.confirmFileTrans('module',1,'vadsjngrqvjca' ,'avgwshDFcxAS','DSAGSFBQdfdsoav','https://sfpi-mebg-test.olympuschina.com/api/contact/insert');
        Test.stopTest();
    }
    static testMethod void insertConfirmTrans() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreatePIHelperHttpMock());
        Test.startTest();
        List<PIHelper.idList> idList = new List<PIHelper.idList>();
        PIHelper.idList pid = new PIHelper.idList();
        pid.awsId = 'vadsjngrqvjca';
        pid.sfRecordId = 'avgwshDFcxAS';
        idList.add(pid);
        PIHelper.insertConfirmTrans('module',1,'vadsjngrqvjca' ,'avgwshDFcxAS' ,0,'https://sfpi-mebg-test.olympuschina.com/api/contact/insert',idList);
        Test.stopTest();
    }
}
force-app/main/default/classes/PIHelperTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/QISPDFController.cls
@@ -2,6 +2,8 @@
    public QIS_Report__c qr { get; private set; }
    public User usr { get; private set; }
    public Boolean inGuarantee { get; private set; }
    public string staticResource { get; private set; }
    public string staticResourceFile { get; private set; }
    
    //  HWAG-BC68W3  故障发生日为空时, 它为真  start
    public Boolean outOfGuarantee { get; private set; }
@@ -10,6 +12,9 @@
        qr = new QIS_Report__c();
        usr = new User();
        inGuarantee = false;
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('QIS_Report__c'));
        staticResourceFile = JSON.serialize(PIHelper.getPIIntegrationInfo('Document'));
    }
    
    public void init() {
force-app/main/default/classes/QISPDFControllerTest.cls
@@ -21,7 +21,10 @@
 */
@isTest
private class QISPDFControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfigurations(new string[]{'QIS_Report__c','Document'});
    }
    static testMethod void myUnitTest() {
        QIS_Report__c q = new QIS_Report__c();
        q.RC__c = UserInfo.getUserId();
force-app/main/default/classes/RentalApplyController.cls
New file
@@ -0,0 +1,208 @@
/**
 * @description       :
 * @author            : ChangeMeIn@UserSettingsUnder.SFDoc
 * @group             :
 * @last modified on  : 03-28-2022
 * @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
**/
global without sharing class RentalApplyController {
    public String layoutSectionsStr {get; set;}//for dynamic add readonly attribute
    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 final string ApiPrefix{get;private set;} //Add By Li Jun 20220403
    public Map<string,string> AWSToSobjectEncryptedMap{get;private set;}
    public string AWSToSobjectEncryptedMapJson{get{return JSON.serialize(AWSToSobjectEncryptedMap);}}
    public RentalApplyController(ApexPages.StandardController controller) {
        ApiPrefix = 'PIBackApi';
        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());
        if(!Test.isRunningTest()){
            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>();
            if(rentalApplyData.Loaner_medical_Staff__r.Id != null){
                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{
            //新建
            Map<string,string> mso = ApexPages.currentPage().getParameters();
            system.debug('mso='+mso);
            if(mso.containsKey('Name')){
                controller.getRecord().put('Name',mso.get('Name'));
            }
            if(mso.containsKey('CF00N10000008ps61_lkid')){
                controller.getRecord().put('OPDPlan__c',mso.get('CF00N10000008ps61_lkid'));
            }
            if(mso.containsKey('CF00N10000003Mp1d_lkid')){
                controller.getRecord().put('Hospital__c',mso.get('CF00N10000003Mp1d_lkid'));
            }
            if(mso.containsKey('CF00N10000003O3V6_lkid')){
                controller.getRecord().put('Strategic_dept__c',mso.get('CF00N10000003O3V6_lkid'));
            }
            if(mso.containsKey('CF00N10000003Mp2R_lkid')){
                controller.getRecord().put('Account__c',mso.get('CF00N10000003Mp2R_lkid'));
            }
            if(mso.containsKey('00N10000003Msk0')){
                controller.getRecord().put('Demo_purpose1__c',mso.get('00N10000003Msk0'));
            }
            if(mso.containsKey('00N10000003Msk5')){
                controller.getRecord().put('demo_purpose2__c',mso.get('00N10000003Msk5'));
            }
            if(mso.containsKey('00N100000098amW')){
                controller.getRecord().put('NoOpp_Reason__c',mso.get('00N100000098amW'));
            }
            if(mso.containsKey('00N10000003OJzc')){
                controller.getRecord().put('Loaner_received_staff__c',mso.get('00N10000003OJzc'));
            }
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            obj.put('OwnerId',UserInfo.getUserId());
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Rental_Apply__c','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        layoutSectionsStr = JSON.serialize(layoutSections); //for dynamic add readonly attribute
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Rental_Apply__c');
        staticResource = JSON.serialize(piIntegration);
        encryptedAPIList = piIntegration.PIFields;
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        AWSToSobjectEncryptedMap = new Map<String,String>();
        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
            AWSToSobjectEncryptedMap.put(PIDetail.AWS_Field_API__c, PIDetail.SF_Field_API_Name__c);
        }
    }
    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);
            if(!fieldAPIToTypeMap.containskey(fieldAPI)){
                continue;
            }
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            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 if(String.isNotBlank(fieldValue))  {
                    fieldValue = fieldValue.replace('/', '-') + ':00';
                    System.debug('fieldValue = ' + fieldValue);
                    rentalApplyInfo.put(fieldAPI, Datetime.valueOf(fieldValue));
                }else{
                    rentalApplyInfo.put(fieldAPI, null);
                }
            }else if(String.valueOf(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='CURRENCY'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                rentalApplyInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?null:Decimal.valueOf(fieldValue.replace(',', '')));
            } else if(String.valueof(fielddataType)=='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(DmlException e) {
            rid=rentalApplyInfo.Id;
            Integer index = 0;
            System.debug(e.getNumDml());
            System.debug(e.getDmlFields(index));
            System.debug(e.getDmlId(index));
            System.debug(e.getDmlIndex(index));
            System.debug(e.getDmlMessage(index));
            System.debug(e.getDmlStatusCode(index));
            System.debug(e.getDmlType(index));
            system.debug(e.getMessage());
            system.debug(e.getStackTraceString());
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            resp.status = 'Exception';
            resp.message ='保存失败,原因:'+ e.getDmlMessage(index);
            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)rentalApplyInfo.get('AWS_Data_Id__c'),rentalApplyJson ,status,'');
            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;
        }
    }
}
force-app/main/default/classes/RentalApplyController.cls-meta.xml
New file
@@ -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>
force-app/main/default/classes/RentalApplyControllerTest.cls
New file
@@ -0,0 +1,182 @@
@isTest
private class RentalApplyControllerTest {
    @TestSetup
    static void makeData(){
        List<String> sobjList = new List<String>();
        sobjList.add('Rental_Apply__c');
        sobjList.add('Contact');
        TestDataUtility.CreatePIPolicyConfigurations(sobjList);
    }
    static testMethod void testMethod1() {
        String userMode = 'classic';//classic  lightning
        String objectType = 'Contact';
        String recordTypeId = Schema.SObjectType.Contact.getRecordTypeInfosByDeveloperName().get('Doctor').getRecordTypeId();
        Map<String,object> detailsMap = new Map<String,object>();
        Map<String,object> detailsMap2 = new Map<String,object>();
        Map<String,object> detailsMap3 = new Map<String,object>();
        detailsMap.put('calculated',true);
        detailsMap.put('autoNumber',false);
        detailsMap.put('type','address');
        detailsMap2.put('calculated',false);
        detailsMap2.put('autoNumber',false);
        detailsMap2.put('type','repair');
        detailsMap3.put('calculated',false);
        detailsMap3.put('autoNumber',false);
        detailsMap3.put('type','repair');
        List<Map<String, object>> componentMapList = new List<Map<String, object>>();
        List<Map<String, object>> componentMapList2 = new List<Map<String, object>>();
        List<Map<String, object>> componentMapList3 = new List<Map<String, object>>();
        Map<String, object> componentMap = new Map<String, object>();
        Map<String, object> componentMap2 = new Map<String, object>();
        Map<String, object> componentMap3 = new Map<String, object>();
        componentMap.put('value','Name');
        componentMap.put('type','Field');
        componentMap.put('details',detailsMap);
        componentMapList.add(componentMap);
        componentMap2.put('value','Name');
        componentMap2.put('type','Field');
        componentMap2.put('details',detailsMap2);
        componentMapList2.add(componentMap2);
        componentMap3.put('value','LastName');
        componentMap3.put('type','Field');
        componentMap3.put('details',detailsMap3);
        componentMapList3.add(componentMap3);
        List<Map<String, object>> layoutComponentsList = new List<Map<String, object>>();
        Map<String, object> layoutComponents = new Map<String, object>();
        layoutComponents.put('layoutComponents',componentMapList);
        layoutComponents.put('label','Address');
        layoutComponents.put('placeholder',true);
        layoutComponents.put('editableForNew',true);
        layoutComponents.put('required',false);
        layoutComponentsList.add(layoutComponents);
        Map<String, object> layoutComponents2 = new Map<String, object>();
        layoutComponents2.put('layoutComponents',componentMapList2);
        layoutComponents2.put('label','Repair');
        layoutComponents2.put('placeholder',true);
        layoutComponents2.put('editableForNew',true);
        layoutComponents2.put('required',false);
        layoutComponentsList.add(layoutComponents2);
        Map<String, object> layoutComponents3 = new Map<String, object>();
        layoutComponents3.put('layoutComponents',componentMapList3);
        layoutComponents3.put('label','Repair');
        layoutComponents3.put('placeholder',true);
        layoutComponents3.put('editableForNew',true);
        layoutComponents3.put('required',false);
        layoutComponentsList.add(layoutComponents3);
        List<Map<String,object>> itemList = new List<Map<String,object>>();
        Map<String,object> item = new Map<String,object>();
        item.put('layoutItems',layoutComponentsList);
        itemList.add(item);
        List<Map<String,object>> sectionList = new List<Map<String,object>>();
        Map<String,object> section = new Map<String,object>();
        section.put('heading','');
        section.put('useHeading',true);
        section.put('columns',1);
        section.put('useCollapsibleSection',true);
        section.put('layoutRows',itemList);
        sectionList.add(section);
        Map<String, Object> layoutSection = new Map<String,Object>();
        layoutSection.put('layouts','123');
        layoutSection.put('editLayoutSections',sectionList);
        String layoutSectionJson = JSON.serialize(layoutSection);
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(layoutSectionJson,'OK','200'));
        Test.startTest();
        String url = ApexPages.currentPage().getParameters().put('Name','test');
        url = ApexPages.currentPage().getParameters().put('Name','test');
        url = ApexPages.currentPage().getParameters().put('CF00N10000008ps61_lkid','test');
        url = ApexPages.currentPage().getParameters().put('CF00N10000003Mp1d_lkid','test');
        url = ApexPages.currentPage().getParameters().put('CF00N10000003O3V6_lkid','test');
        url = ApexPages.currentPage().getParameters().put('CF00N10000003Mp2R_lkid','test');
        url = ApexPages.currentPage().getParameters().put('00N10000003Msk0','test');
        url = ApexPages.currentPage().getParameters().put('00N10000003Msk5','test');
        url = ApexPages.currentPage().getParameters().put('00N100000098amW','test');
        url = ApexPages.currentPage().getParameters().put('00N10000003OJzc','test');
        ApexPages.StandardController scc = new ApexPages.StandardController(new Rental_Apply__c());
        RentalApplyController racc = new RentalApplyController(scc);
        Test.stopTest();
    }
    static testMethod void testMethod2() {
        String raJson = '{\"HP_received_sign_rich__c\":\"\",\"Name\":\"123456\",\"OPDPlan__c\":\"000000000000000\",\"GI_Diff__c\":\"\",\"Add_Approval_Status__c\":\"\",\"ApplyPerson_Phone__c\":\"\",\"Person_In_Charge__c\":\"0050l000005vPbu\",\"Loaner_centre_mail_address__c\":\"\",\"applyUser__c\":\"0050l000005vPbu\",\"Cross_Region_Assign__c\":\"\",\"Priority_Inspect__c\":false,\"SalesdeptSelect__c\":\"医疗东北营业本部\",\"RecordTypeId\":\"01210000000RHIi\",\"Zsq_Rental_Apply__c\":\"000000000000000\",\"Asset_return_time_OK__c\":\"\",\"Hospital__c\":\"0010l00001PQFkh\",\"Loaner_medical_Staff__c\":\"0030l00000mFW7G\",\"Strategic_dept__c\":\"0010l00001PQFkh\",\"Phone_number__c\":\"***********\",\"Account__c\":\"0010l00001PQFkh\",\"Demo_purpose1__c\":\"产品试用\",\"Repair__c\":\"000000000000000\",\"NoOpp_Reason__c\":\"\",\"Product_category__c\":\"GI\",\"Follow_UP_Opp__c\":\"000000000000000\",\"Campaign__c\":\"000000000000000\",\"Follow_pcl_status2_Text__c\":\"\",\"QIS_number__c\":\"000000000000000\",\"Statu_Achievements__c\":\"000000000000000\",\"QISRepair__c\":\"000000000000000\",\"CrinicalTrialName__c\":\"\",\"DB_loaner_request__c\":\"\",\"IsJump__c\":false,\"AgreementBorrowingExtensionDate__c\":\"\",\"JumpCause__c\":\"\",\"NewRepair__c\":\"000000000000000\",\"IsJump_Rental__c\":false,\"JumpCause_Rental__c\":\"\",\"JumpDate_Rental__c\":\"\",\"Demo_purpose_text__c\":\"dfasvq\",\"Hope_Lonaer_date_Num__c\":\"3\",\"Request_return_day__c\":\"2022/03/27\",\"Shipment_address__c\":\"000000000000000\",\"direct_send__c\":\"上门自提\",\"Dealer__c\":\"000000000000000\",\"pickup_time__c\":\"2022/03/24 17:44\",\"Loaner_received_staff__c\":\"test\",\"Loaner_received_staff_phone__c\":\"1234567890\",\"direct_shippment_address__c\":\"**********\",\"Post_Code__c\":\"12345-123\",\"Old_Rental_Apply__c\":\"000000000000000\",\"Split_Apply_Reason__c\":\"\",\"HP_received_sign_day__c\":\"\",\"HP_received_sign_NG__c\":false,\"HP_received_sign_NG_Reason__c\":\"\",\"AssetManageConfirm__c\":false,\"Cancel_Reason__c\":\"\",\"Loaner_cancel_request__c\":\"\",\"Cancel_time__c\":\"\",\"HP_received_sign_NewDate__c\":\"\",\"Rental_Received_Day__c\":\"\",\"Add_Request_demo_time__c\":\"\",\"Add_Request_approval_time__c\":\"\",\"ExtensionStatus__c\":\"\",\"ExtensionSuccessTimes__c\":\"\",\"ExtensionApplicationTime_Initial__c\":\"\",\"ExtensionApprovalTime_Initial__c\":\"\",\"ExtensionApplicationTime_Final__c\":\"\",\"ExtensionApprovalTime_Final__c\":\"\",\"Repair_Final_Inspection_Date__c\":\"\",\"All_Delivery_Flag_c__c\":false,\"Request_demo_time__c\":\"\",\"Request_approval_time__c\":\"\",\"Application_accept_time__c\":\"\",\"Request_answer_time__c\":\"\",\"HP_City__c\":\"Abejones\",\"OwnerId\":\"0050l000005vPbu\",\"OPD__c\":\"000000000000000\",\"OPDAmount__c\":\"\",\"IsOPD_Account__c\":\"\",\"OriginalOpdPlanApplication__c\":\"\",\"demo_purpose2__c\":\"试用(无询价)\",\"ToAgency__c\":\"大连\",\"Loaner_cancel_reason__c\":\"_\\u0001_\",\"Phone_Number_Encrypt__c\":\"415f2dab7eb6b2a866e02d823080a845\",\"Direct_Shippment_Address_Encrypt__c\":\"2df1bc4bf3800c5e05e3d9f394c3446567d1f05482d2295650b7b50e9e4aa97a92338985c9693f576e1e6df667aaee46\",\"AWS_Data_Id__c\":\"956621521466425345\"}';
        // Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeStrict(raJson, Map<String,Object>.class);
        // Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(raJson);
        // Rental_Apply__c rentalApplyInfo = new Rental_Apply__c();
        // Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
        // Schema.SObjectType rentalApplySchema = schemaMap.get('Rental_Apply__c');
        // Map<String, Schema.SObjectField> fieldAPIToTypeMap = rentalApplySchema.getDescribe().fields.getMap();
        // for(String fieldAPI :fieldValueMap.keySet()){
        //     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'){
        //         System.debug('DATE fieldAPI = '+fieldAPI+' filedData = '+String.valueOf(fieldValueMap.get(fieldAPI)));
        //         // rentalApplyInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
        //         rentalApplyInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.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',' ');
        //             rentalApplyInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
        //         }else if(String.isNotBlank(dt))  {
        //             //rentalApplyInfo.put(fieldAPI, Datetime.valueOf(dt));
        //             dt = dt.replace('/', '-') + ':00';
        //             System.debug('dt = ' + dt);
        //             rentalApplyInfo.put(fieldAPI, Datetime.valueOf(dt));
        //         }else{
        //             rentalApplyInfo.put(fieldAPI, null);
        //         }
        //     }else if(String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
        //         rentalApplyInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
        //     } else if(String.valueof(fielddataType)=='BOOLEAN'){
        //         rentalApplyInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
        //     }else {
        //         rentalApplyInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
        //     }
        // }
        // insert rentalApplyInfo;
        Test.startTest();
        RentalApplyController.saveRentalApply(raJson,'savdqerva',true);
        Test.stopTest();
    }
    static testMethod void testMethod3() {
        Rental_Apply__c ra = TestDataUtility.CreateRentalApplys(1)[0];
        String raJson = JSON.serialize(ra);
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Test.startTest();
        System.debug('ra--------'+ra);
        ApexPages.StandardController sc = new ApexPages.StandardController(ra);
        RentalApplyController rac = new RentalApplyController(sc);
        Test.stopTest();
    }
    static testMethod void testMethod4() {
        Rental_Apply__c ra = TestDataUtility.CreateRentalApplys(1)[0];
        String raJson = '{\"HP_received_sign_rich__c\":\"\",\"Name\":\"123456\",\"OPDPlan__c\":\"000000000000000\",\"GI_Diff__c\":\"\",\"Add_Approval_Status__c\":\"\",\"ApplyPerson_Phone__c\":\"\",\"Person_In_Charge__c\":\"0050l000005vPbu\",\"Loaner_centre_mail_address__c\":\"\",\"applyUser__c\":\"0050l000005vPbu\",\"Cross_Region_Assign__c\":\"\",\"Priority_Inspect__c\":false,\"SalesdeptSelect__c\":\"医疗东北营业本部\",\"RecordTypeId\":\"01210000000RHIi\",\"Zsq_Rental_Apply__c\":\"000000000000000\",\"Asset_return_time_OK__c\":\"\",\"Hospital__c\":\"0010l00001PQFkh\",\"Loaner_medical_Staff__c\":\"0030l00000mFW7G\",\"Strategic_dept__c\":\"0010l00001PQFkh\",\"Phone_number__c\":\"***********\",\"Account__c\":\"0010l00001PQFkh\",\"Demo_purpose1__c\":\"产品试用\",\"Repair__c\":\"000000000000000\",\"NoOpp_Reason__c\":\"\",\"Product_category__c\":\"GI\",\"Follow_UP_Opp__c\":\"000000000000000\",\"Campaign__c\":\"000000000000000\",\"Follow_pcl_status2_Text__c\":\"\",\"QIS_number__c\":\"000000000000000\",\"Statu_Achievements__c\":\"000000000000000\",\"QISRepair__c\":\"000000000000000\",\"CrinicalTrialName__c\":\"\",\"DB_loaner_request__c\":\"\",\"IsJump__c\":false,\"AgreementBorrowingExtensionDate__c\":\"\",\"JumpCause__c\":\"\",\"NewRepair__c\":\"000000000000000\",\"IsJump_Rental__c\":false,\"JumpCause_Rental__c\":\"\",\"JumpDate_Rental__c\":\"\",\"Demo_purpose_text__c\":\"dfasvq\",\"Hope_Lonaer_date_Num__c\":\"3\",\"Request_return_day__c\":\"2022/03/27\",\"Shipment_address__c\":\"000000000000000\",\"direct_send__c\":\"上门自提\",\"Dealer__c\":\"000000000000000\",\"pickup_time__c\":\"2022/03/24 17:44\",\"Loaner_received_staff__c\":\"test\",\"Loaner_received_staff_phone__c\":\"1234567890\",\"direct_shippment_address__c\":\"**********\",\"Post_Code__c\":\"12345-123\",\"Old_Rental_Apply__c\":\"000000000000000\",\"Split_Apply_Reason__c\":\"\",\"HP_received_sign_day__c\":\"\",\"HP_received_sign_NG__c\":false,\"HP_received_sign_NG_Reason__c\":\"\",\"AssetManageConfirm__c\":false,\"Cancel_Reason__c\":\"\",\"Loaner_cancel_request__c\":\"\",\"Cancel_time__c\":\"\",\"HP_received_sign_NewDate__c\":\"\",\"Rental_Received_Day__c\":\"\",\"Add_Request_demo_time__c\":\"\",\"Add_Request_approval_time__c\":\"\",\"ExtensionStatus__c\":\"\",\"ExtensionSuccessTimes__c\":\"\",\"ExtensionApplicationTime_Initial__c\":\"\",\"ExtensionApprovalTime_Initial__c\":\"\",\"ExtensionApplicationTime_Final__c\":\"\",\"ExtensionApprovalTime_Final__c\":\"\",\"Repair_Final_Inspection_Date__c\":\"\",\"All_Delivery_Flag_c__c\":false,\"Request_demo_time__c\":\"\",\"Request_approval_time__c\":\"\",\"Application_accept_time__c\":\"\",\"Request_answer_time__c\":\"\",\"HP_City__c\":\"Abejones\",\"OwnerId\":\"0050l000005vPbu\",\"OPD__c\":\"000000000000000\",\"OPDAmount__c\":\"\",\"IsOPD_Account__c\":\"\",\"OriginalOpdPlanApplication__c\":\"\",\"demo_purpose2__c\":\"试用(无询价)\",\"ToAgency__c\":\"大连\",\"Loaner_cancel_reason__c\":\"_\\u0001_\",\"Phone_Number_Encrypt__c\":\"415f2dab7eb6b2a866e02d823080a845\",\"Direct_Shippment_Address_Encrypt__c\":\"2df1bc4bf3800c5e05e3d9f394c3446567d1f05482d2295650b7b50e9e4aa97a92338985c9693f576e1e6df667aaee46\",\"AWS_Data_Id__c\":\"'+ra.AWS_Data_Id__c+'\"}';
        System.debug('ra.AWS_Data_Id__c------'+ra.AWS_Data_Id__c);
        Test.startTest();
        RentalApplyController.saveRentalApply(raJson,'savdqerva',false);
        Test.stopTest();
    }
}
force-app/main/default/classes/RentalApplyControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/SLAReportDetailsController.cls
@@ -16,6 +16,8 @@
    public String visitor5;
    public String serviceId;
    public String accId;
    public String slaInfoStr{get; set;}
    public String staticResourceContact {get; set;}
    public SLAReportDetailsController(){
        eventcId = ApexPages.currentPage().getParameters().get('eventCId') == null ? '' : ApexPages.currentPage().getParameters().get('eventCId');
        visitor1 = ApexPages.currentPage().getParameters().get('visitor1') == null ? '' : ApexPages.currentPage().getParameters().get('visitor1');
@@ -111,7 +113,8 @@
        }else{
            slaInfo.Visitor5__c = null; 
        }
        slaInfoStr = JSON.serialize(slaInfo);
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    public void save(){
        try {
force-app/main/default/classes/SLAReportDetailsControllerTest.cls
@@ -1,5 +1,11 @@
@isTest
private class SLAReportDetailsControllerTest {
    @testSetup
    static void setUp(){
        TestDataUtility.CreatePIPolicyConfigurations( new string[]{'Contact'});
    }
    //有报告书 
    static testMethod void testMethod1() {
@@ -84,7 +90,7 @@
        Daily_Report__c dr3 = new Daily_Report__c();
        dr3.Reporter__c = UserInfo.getUserId();
        dr3.Reported_Date__c = Date.today().addDays(4);
        dr3.Status__c = '申請中';
        dr3.Status__c = '作成中';
        insert dr3;
        Event__c event = new Event__c();
@@ -208,7 +214,7 @@
        Daily_Report__c dr3 = new Daily_Report__c();
        dr3.Reporter__c = UserInfo.getUserId();
        dr3.Reported_Date__c = Date.today().addDays(4);
        dr3.Status__c = '申請中';
        dr3.Status__c = '作成中';
        insert dr3;
        Event__c event = new Event__c();
@@ -331,7 +337,7 @@
        Daily_Report__c dr3 = new Daily_Report__c();
        dr3.Reporter__c = UserInfo.getUserId();
        dr3.Reported_Date__c = Date.today().addDays(4);
        dr3.Status__c = '申請中';
        dr3.Status__c = '作成中';
        insert dr3;
        Event__c event = new Event__c();
force-app/main/default/classes/SObjectHelper.cls
New file
@@ -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, ';');
    }
}
Diff truncated after the above file
force-app/main/default/classes/SObjectHelper.cls-meta.xml force-app/main/default/classes/SObjectHelperTest.cls force-app/main/default/classes/SObjectHelperTest.cls-meta.xml force-app/main/default/classes/SearchContactController.cls force-app/main/default/classes/SearchContactController.cls-meta.xml force-app/main/default/classes/SearchContactControllerTest.cls force-app/main/default/classes/SearchContactControllerTest.cls-meta.xml force-app/main/default/classes/SearchLeadController.cls force-app/main/default/classes/SearchLeadController.cls-meta.xml force-app/main/default/classes/SearchLeadControllerTest.cls force-app/main/default/classes/SearchLeadControllerTest.cls-meta.xml force-app/main/default/classes/SearchVisitorController.cls force-app/main/default/classes/SearchVistorControllerTest.cls force-app/main/default/classes/SimpleEventRegisterController.cls force-app/main/default/classes/SimpleEventRegisterControllerTester.cls force-app/main/default/classes/SoqlHelper.cls force-app/main/default/classes/SoqlHelper.cls-meta.xml force-app/main/default/classes/SoqlHelperTest.cls force-app/main/default/classes/SoqlHelperTest.cls-meta.xml force-app/main/default/classes/StartTradingController.cls force-app/main/default/classes/StartTradingController.cls-meta.xml force-app/main/default/classes/StartTradingControllerTest.cls force-app/main/default/classes/StraightBackAddressController.cls force-app/main/default/classes/StraightBackAddressControllerTest.cls force-app/main/default/classes/UpdateContractAimAmountHandler.cls force-app/main/default/classes/ViewParticipantsController.cls force-app/main/default/classes/ViewParticipantsController.cls-meta.xml force-app/main/default/classes/ViewParticipantsControllerTest.cls force-app/main/default/classes/ViewParticipantsControllerTest.cls-meta.xml force-app/main/default/classes/WeeklyReportCmp.cls force-app/main/default/classes/WeeklyReportCmpTest.cls force-app/main/default/classes/XinDailyReportController.cls force-app/main/default/classes/XinDailyReportControllerTest.cls force-app/main/default/pages/AssessmentReport.page force-app/main/default/pages/BMEWorkPage.page force-app/main/default/pages/B_Test.page force-app/main/default/pages/B_Test.page-meta.xml force-app/main/default/pages/CM_SearchContact.page force-app/main/default/pages/CM_SearchContactService.page force-app/main/default/pages/CampaignMember.page force-app/main/default/pages/CampaignMemberService.page force-app/main/default/pages/ConsumApplyUploadPdf.page force-app/main/default/pages/ConsumApplyUploadPdf.page-meta.xml force-app/main/default/pages/ConsumReassign.page force-app/main/default/pages/ConsumTrial.page force-app/main/default/pages/ConsumTrialPDF.page force-app/main/default/pages/FixtureRentalPDF.page force-app/main/default/pages/InsReportPDF.page force-app/main/default/pages/InstructReport.page force-app/main/default/pages/LeadIntention.page force-app/main/default/pages/NewAndEditASEActivity.page force-app/main/default/pages/NewAndEditASEActivity.page-meta.xml force-app/main/default/pages/NewAndEditAddress.page force-app/main/default/pages/NewAndEditAddress.page-meta.xml force-app/main/default/pages/NewAndEditAgencyContact.page force-app/main/default/pages/NewAndEditAgencyContact.page-meta.xml force-app/main/default/pages/NewAndEditCampaignMember.page force-app/main/default/pages/NewAndEditCampaignMember.page-meta.xml force-app/main/default/pages/NewAndEditCase.page force-app/main/default/pages/NewAndEditCase.page-meta.xml force-app/main/default/pages/NewAndEditContact.page force-app/main/default/pages/NewAndEditContact.page-meta.xml force-app/main/default/pages/NewAndEditInquiryForm.page force-app/main/default/pages/NewAndEditInquiryForm.page-meta.xml force-app/main/default/pages/NewAndEditInspectionReport.page force-app/main/default/pages/NewAndEditInspectionReport.page-meta.xml force-app/main/default/pages/NewAndEditLead.page force-app/main/default/pages/NewAndEditLead.page-meta.xml force-app/main/default/pages/NewAndEditQIS.page force-app/main/default/pages/NewAndEditQIS.page-meta.xml force-app/main/default/pages/NewAndEditRepairSubOrder.page force-app/main/default/pages/NewAndEditRepairSubOrder.page-meta.xml force-app/main/default/pages/NewAndEditReport.page force-app/main/default/pages/NewAndEditReport.page-meta.xml force-app/main/default/pages/NewAndEditTenderinformation.page force-app/main/default/pages/NewAndEditTenderinformation.page-meta.xml force-app/main/default/pages/NewConsumApply.page force-app/main/default/pages/NewConsumApply.page-meta.xml force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page-meta.xml force-app/main/default/pages/NewListOfConsumables.page force-app/main/default/pages/NewListOfConsumables.page-meta.xml force-app/main/default/pages/NewOnCall.page force-app/main/default/pages/NewOnCall.page-meta.xml force-app/main/default/pages/NewRentalApply.page force-app/main/default/pages/NewRentalApply.page-meta.xml force-app/main/default/pages/NewRepair.page force-app/main/default/pages/NewRepair.page-meta.xml force-app/main/default/pages/NewRepairPage.page force-app/main/default/pages/NewRepairPage.page-meta.xml force-app/main/default/pages/OFSInsReportLayout.page force-app/main/default/pages/QISPDF.page force-app/main/default/pages/RentalApplyUploadPdf.page force-app/main/default/pages/RentalApplyUploadPdf.page-meta.xml force-app/main/default/pages/SLAReportDetails.page force-app/main/default/pages/SearchAWSContactByNamePage.page force-app/main/default/pages/SearchAWSContactByNamePage.page-meta.xml force-app/main/default/pages/SearchContactPage.page force-app/main/default/pages/SearchContactPage.page-meta.xml force-app/main/default/pages/SearchLeadPage.page force-app/main/default/pages/SearchLeadPage.page-meta.xml force-app/main/default/pages/SearchVisitor.page force-app/main/default/pages/SimpleEventRegister.page force-app/main/default/pages/StartTrading.page force-app/main/default/pages/StraightBackAddress.page force-app/main/default/pages/TenderInformationUploadPdf.page force-app/main/default/pages/TenderInformationUploadPdf.page-meta.xml force-app/main/default/pages/TestClass.page force-app/main/default/pages/TestClass.page-meta.xml force-app/main/default/pages/UploadPdf.page force-app/main/default/pages/UploadPdf.page-meta.xml force-app/main/default/pages/ViewASEActivityDecryptInfo.page force-app/main/default/pages/ViewASEActivityDecryptInfo.page-meta.xml force-app/main/default/pages/ViewAddressDecryptInfo.page force-app/main/default/pages/ViewAddressDecryptInfo.page-meta.xml force-app/main/default/pages/ViewAgencyContactDecryptInfo.page force-app/main/default/pages/ViewAgencyContactDecryptInfo.page-meta.xml force-app/main/default/pages/ViewCaseDecryptInfo.page force-app/main/default/pages/ViewCaseDecryptInfo.page-meta.xml force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page-meta.xml force-app/main/default/pages/ViewContactDecryptInfo.page force-app/main/default/pages/ViewContactDecryptInfo.page-meta.xml force-app/main/default/pages/ViewDecryptConsumApply.page force-app/main/default/pages/ViewDecryptConsumApply.page-meta.xml force-app/main/default/pages/ViewEventDecryptInfo.page force-app/main/default/pages/ViewEventDecryptInfo.page-meta.xml force-app/main/default/pages/ViewInquiryFormDecryptInfo.page force-app/main/default/pages/ViewInquiryFormDecryptInfo.page-meta.xml force-app/main/default/pages/ViewInspectionReportDecryptInfo.page force-app/main/default/pages/ViewInspectionReportDecryptInfo.page-meta.xml force-app/main/default/pages/ViewLeadDecryptInfo.page force-app/main/default/pages/ViewLeadDecryptInfo.page-meta.xml force-app/main/default/pages/ViewListOfConsumablesDecrypt.page force-app/main/default/pages/ViewListOfConsumablesDecrypt.page-meta.xml force-app/main/default/pages/ViewOnCallDecrypt.page force-app/main/default/pages/ViewOnCallDecrypt.page-meta.xml force-app/main/default/pages/ViewParticipantsDecryptInfo.page force-app/main/default/pages/ViewParticipantsDecryptInfo.page-meta.xml force-app/main/default/pages/ViewQISReportDecryptInfo.page force-app/main/default/pages/ViewQISReportDecryptInfo.page-meta.xml force-app/main/default/pages/ViewRentalApplyDecrypt.page force-app/main/default/pages/ViewRentalApplyDecrypt.page-meta.xml force-app/main/default/pages/ViewRepairEncrypt.page force-app/main/default/pages/ViewRepairEncrypt.page-meta.xml force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page-meta.xml force-app/main/default/pages/ViewReportDecryptInfo.page force-app/main/default/pages/ViewReportDecryptInfo.page-meta.xml force-app/main/default/pages/ViewTenderinformationDecryptInfo.page force-app/main/default/pages/ViewTenderinformationDecryptInfo.page-meta.xml force-app/main/default/pages/XinDailyReport.page force-app/main/default/staticresources/AWSService.resource-meta.xml force-app/main/default/staticresources/AWSService/AWSService.js force-app/main/default/triggers/ContactHpDeptUpd.trigger force-app/main/default/triggers/FileAddressTrigger.trigger force-app/main/default/triggers/FileAddressTrigger.trigger-meta.xml force-app/main/default/triggers/Repair.trigger manifest/packageForPIPL.xml