/*
 TestClass
 RentalApplyTriggerHandlerTest
 RentalFixtureManage11Test
 RentalFixtureManage14Test
*/
public without sharing class RentalApplyTriggerHandler extends Oly_TriggerHandler {
    private Map<Id, Rental_Apply__c> newMap;
    private Map<Id, Rental_Apply__c> oldMap;
    private List<Rental_Apply__c> newList;
    private List<Rental_Apply__c> oldList;
    private static Date td = Date.today();
    private static Map<Id, Rental_Apply__c> oldRaMap = new Map<Id, Rental_Apply__c>();

    //update      wangweipeng                             2021/11/25                   start
    private static Map<String, String> approver_of_Service_DepartmentMap = new Map<String, String>();
    /*private static Map<String, String> approver_of_Service_DepartmentMap = new Map<String, String>{
        '共通办事处' => System.Label.Extension_to_Beijing_common_approver,
        '北京办事处' => System.Label.Extension_to_Beijing_common_approver,
        '沈阳办事处' => System.Label.Extension_to_Shenyang_approver,
        '上海办事处' => System.Label.Extension_to_Shanghai_approver,
        '广东办事处' => System.Label.Extension_to_Guangdong_approver
    };*/
    //update      wangweipeng                             2021/11/25                   end

    private static boolean hasInsert;
    // static initialization
    static {
        hasInsert = false;
    }
    public static Integer FIELDMAX = 200; // 202100823 ljh SFDC-C448KZ add
    private static Map<String, String> rental_Apply_App_CCEmailMap = FixtureUtil.initRental_Apply_App_CCEmailMap();

    public RentalApplyTriggerHandler() {
        Integer i = 0;
        i ++;
        this.newMap = (Map<Id, Rental_Apply__c>) Trigger.newMap;
        this.oldMap = (Map<Id, Rental_Apply__c>) Trigger.oldMap;
        this.newList = (List<Rental_Apply__c>) Trigger.new;
        this.oldList = (List<Rental_Apply__c>) Trigger.old;

        approver_of_Service_DepartmentMap = customPostponeWorkLocation();
    }

    protected override void beforeInsert() {
        setManager();
        beforeSetValue();
        setOffice_Assistant();
    }
    protected override void afterInsert() {
        // Check本部是否可以选择
        checkbenbu();
        // 共享设定
        setShare();
    }
    protected override void beforeUpdate() {
        setManager();
        beforeSetValue();
        approvalCheck();
        setOffice_Assistant();

        checkExtensionDeadline();
    }

    protected override void afterUpdate() {
        // Check本部是否可以选择
        checkbenbu();
        cancelRa();
        // before では数式項目がnullの場合があります
        formulaToTextCheck();
        //医院确认相关的字段更新的时候要更新一览
        reReceivedConfirmStatus();
        //医院确认相关的字段更新的时候要更新一览
        reApprovalStatus();
        // 取消申请单的审批
        removedProcessRequest();

        synchRentalApplyData2();
        // 延期审批后需要更新一览
        setAppExtensionRaes();
        // 共享设定
        setShare();
        // 办事处分单的装机确认
        setAgencyHPReceived();
        
        //批量审批时，需要把主单和从单的延期字段信息同步
        synchRentalApplyData();
    }

    private void setAgencyHPReceived() {
        Set<Id> raIdSet = new Set<Id>();
        for (Rental_Apply__c nObj : newList) {
            Rental_Apply__c oObj;
            if(Trigger.isUpdate) {
                oObj = oldMap.get(nObj.Id);
                if(oObj.HP_received_sign_day__c != nObj.HP_received_sign_day__c
                    || oObj.HP_received_sign_rich__c != nObj.HP_received_sign_rich__c
                    || oObj.HP_received_sign_NG__c != nObj.HP_received_sign_NG__c
                    || oObj.HP_received_sign_NG_Reason__c != nObj.HP_received_sign_NG_Reason__c
                    || oObj.AssetManageConfirm__c != nObj.AssetManageConfirm__c
                    ) {
                    raIdSet.add(nObj.Id);
                }
            }
        }
        // 20220123 ljh update start
        if(raIdSet.size() > 0){
            List<Rental_Apply__c> childRaList = [
                SELECT Id
                     , Old_Rental_Apply__c,root_Rental_Apply__c 
                  FROM Rental_Apply__c
                  // WHERE Old_Rental_Apply__c IN:raIdSet
                   WHERE root_Rental_Apply__c  IN:raIdSet //20210611 ljh update 1732
                   AND RecordType.DeveloperName = 'AgencyRequest'
                   AND Split_Apply_Reason__c = '现地管理分单'
                   AND RA_Status__c <>'取消'// 20210719 SFDC-C539AF you
            ];
            for(Rental_Apply__c childRa: childRaList) {
                // Rental_Apply__c parentRa = newMap.get(childRa.Old_Rental_Apply__c);
                Rental_Apply__c parentRa = newMap.get(childRa.root_Rental_Apply__c); //20210611 ljh update 1732
                childRa.HP_received_sign_day__c = parentRa.HP_received_sign_day__c;
                childRa.HP_received_sign_rich__c = parentRa.HP_received_sign_rich__c;
                childRa.HP_received_sign_NG__c = parentRa.HP_received_sign_NG__c;
                childRa.HP_received_sign_NG_Reason__c = parentRa.HP_received_sign_NG_Reason__c;
                childRa.AssetManageConfirm__c = parentRa.AssetManageConfirm__c;
            }
            if(!childRaList.isEmpty()) {
                update childRaList;
                
                // 主单里附件
                List<Attachment> attList = [SELECT Id, Body, Name, ParentId
                                            FROM Attachment
                                            WHERE ParentId IN: raIdSet
                                            ];
                // 从单里附件，放到一起查会报limit错
                attList.addAll([SELECT Id, Name, ParentId FROM Attachment WHERE ParentId IN:childRaList]);
                if(attList.isEmpty()) {
                    return;
                }
                Map<Id, List<Attachment>> parentFiles = new Map<Id, List<Attachment>>();
                // 待删除附件
                List<Attachment> deleteFiles = new List<Attachment>();
                for(Attachment att: attList) {
                    if(att.Name.startsWith('QRCode-')) {
                        continue;
                    }
                    if(raIdSet.contains(att.ParentId)) {
                        List<Attachment> tempList = null;
                        if(parentFiles.containsKey(att.ParentId)) {
                            tempList = parentFiles.get(att.ParentId);
                        }
                        else {
                            tempList = new List<Attachment>();
                        }
                        tempList.add(att);
                        parentFiles.put(att.ParentId, tempList);
                    }
                    else {
                        deleteFiles.add(att);
                    }
                }
                // 待插入的附件
                List<Attachment> newFiles = new List<Attachment>();
                for(Rental_Apply__c childRa: childRaList) {
                    if(parentFiles.containsKey(childRa.Old_Rental_Apply__c)) {
                        for(Attachment att : parentFiles.get(childRa.Old_Rental_Apply__c)){
                            newFiles.add(new Attachment(Body = att.Body,Name = att.Name, ParentId = childRa.Id));
                        }
                    }
                }
                if(!deleteFiles.isEmpty()) {
                    delete deleteFiles;
                }
                if(!newFiles.isEmpty()) {
                    insert newFiles;
                }
            }
        }
    }

    // 前提: before 的时候 一定要运行 setOffice_Assistant() 设定 Office_Assistant1__c 和 Office_Assistant2__c
    // 20210727 ljh SFDC-C54C33 前提: before 的时候 一定要运行 setManager() 设定新的经理 部长 总监
    // after insert, after update
    private void setShare() {
        try{
        List<Rental_Apply__Share> rasList = new List<Rental_Apply__Share>();
        List<Id> deleteOfficeAssistantShare_nObjId_List = new List<Id>();       // 共享删除用
        List<Id> deleteApplyUserShare_nObjId_List = new List<Id>();// 20210727 ljh SFDC-C54C33 共享删除用
        for (Rental_Apply__c nObj : newList) {
            Rental_Apply__c oObj = (null == this.oldMap) ? null : this.oldMap.get(nObj.Id);
            // 服务部审批人
            if (nObj.Approver_of_Service_Department__c != null
                && (Trigger.isInsert
                    || (Trigger.isUpdate
                            && oObj.Approver_of_Service_Department__c != nObj.Approver_of_Service_Department__c
                        )
                    )
            ) {
                Rental_Apply__Share ras = new Rental_Apply__Share(
                            RowCause = 'ApplyUserShare__c',
                            ParentId = nObj.Id,
                            UserOrGroupId = nObj.Approver_of_Service_Department__c,
                            AccessLevel = 'Edit'
                        );
                rasList.add(ras);
            }
            // 办事处助理
            if (Trigger.isInsert
                || (oObj.Office_Assistant1__c != nObj.Office_Assistant1__c
                    || oObj.Office_Assistant2__c != nObj.Office_Assistant2__c
                )
            ) {
                deleteOfficeAssistantShare_nObjId_List.add(nObj.Id);
                //String theId=UserInfo.getUserId();
                //User theUser=[select IsActive from user where id=:theId];
                //if(theUser.IsActive==true){
                    if (nObj.Office_Assistant1__c != null) {
                    rasList.add(new Rental_Apply__Share(
                        RowCause = 'Office_Assistant__c',
                        ParentId = nObj.Id,
                        UserOrGroupId = nObj.Office_Assistant1__c,
                        AccessLevel = 'Edit'
                    ));
                //}
                if (nObj.Office_Assistant2__c != null) {
                    rasList.add(new Rental_Apply__Share(
                        RowCause = 'Office_Assistant__c',
                        ParentId = nObj.Id,
                        UserOrGroupId = nObj.Office_Assistant2__c,
                        AccessLevel = 'Edit'
                    ));
                }
                
                }
            }
            //20210727 ljh SFDC-C54C33  add start
            //审批 共享 经理、部长、总监（若有审批要求共享参考上面  办事处助理 最终定位到人员上变化）
            if ((Trigger.isUpdate && oObj.Status__c != nObj.Status__c && nObj.Status__c == '填写完毕')
                || (Trigger.isUpdate && oObj.ExtensionStatus__c != nObj.ExtensionStatus__c && nObj.ExtensionStatus__c == '填写完毕')
                || (Trigger.isUpdate && oObj.Add_Approval_Status__c != nObj.Add_Approval_Status__c && nObj.Add_Approval_Status__c == '填写完毕')
                ) {
                deleteApplyUserShare_nObjId_List.add(nObj.Id);
                if(nObj.SalesManager__c != null){
                    Rental_Apply__Share rasSalesManager = new Rental_Apply__Share(
                            RowCause = 'ApplyUserShare__c',
                            ParentId = nObj.Id,
                            UserOrGroupId = nObj.SalesManager__c,
                            AccessLevel = 'Edit'
                        );
                    rasList.add(rasSalesManager);
                }
                if(nObj.BuchangApprovalManagerSales__c != null){
                    Rental_Apply__Share rasBz = new Rental_Apply__Share(
                            RowCause = 'ApplyUserShare__c',
                            ParentId = nObj.Id,
                            UserOrGroupId = nObj.BuchangApprovalManagerSales__c,
                            AccessLevel = 'Edit'
                        );
                    rasList.add(rasBz);
                }
                if(nObj.ZongjianApprovalManager__c != null){
                    Rental_Apply__Share rasZj = new Rental_Apply__Share(
                            RowCause = 'ApplyUserShare__c',
                            ParentId = nObj.Id,
                            UserOrGroupId = nObj.ZongjianApprovalManager__c,
                            AccessLevel = 'Edit'
                        );
                    rasList.add(rasZj);
                }  
            }                
            //20210727 ljh SFDC-C54C33  add end
        }
        // 先 Delete, 后 Insert
        //20210727 ljh SFDC-C54C33  update start
        /*List<Rental_Apply__Share> deleteShareList = [SELECT Id, UserOrGroupId, ParentId, UserOrGroup.Name
                 FROM Rental_Apply__Share
                WHERE RowCause = 'Office_Assistant__c'
                  AND ParentId =: deleteOfficeAssistantShare_nObjId_List];*/
        String soql = 'SELECT Id, UserOrGroupId, ParentId, UserOrGroup.Name FROM Rental_Apply__Share ';
        soql += ' WHERE  Id != null ';
        if(deleteOfficeAssistantShare_nObjId_List.size() > 0){
            soql += ' AND (RowCause = \'Office_Assistant__c\' AND ParentId =: deleteOfficeAssistantShare_nObjId_List) ';
            if(deleteApplyUserShare_nObjId_List.size() > 0){
                soql += ' OR (RowCause = \'ApplyUserShare__c\'AND ParentId =: deleteApplyUserShare_nObjId_List)';
            }
        }else if(deleteApplyUserShare_nObjId_List.size() > 0){
            soql += ' AND (RowCause = \'ApplyUserShare__c\'AND ParentId =: deleteApplyUserShare_nObjId_List)';
        }
        List<Rental_Apply__Share> deleteShareList = new List<Rental_Apply__Share>();
        if(deleteOfficeAssistantShare_nObjId_List.size() > 0 || deleteApplyUserShare_nObjId_List.size() > 0){
            deleteShareList = Database.query(soql);
        }
        //20210727 ljh SFDC-C54C33  update end
        if (deleteShareList.size() > 0) { delete deleteShareList; }
        if (rasList.size() > 0) { insert rasList; }
        }
         catch(Exception e){
           String msg=e.getMessage();
           if(msg!=null && msg.containsIgnoreCase('INACTIVE_OWNER_OR_USER')){
           Apexpages.addMessage(new ApexPages.Message(ApexPages.Severity.Error,'未激活的审批人账号：该服务部审批人已离职，不能分单'));
           }else{
              Apexpages.addMessage(new ApexPages.Message(ApexPages.Severity.Error,msg));
           }
     }



    }

    // 延期审批逻辑修改前需要Check批准后是否需要Check的条件
    private void setAppExtensionRaes() {
        List<Rental_Apply_Equipment_Set__c> raesList = new List<Rental_Apply_Equipment_Set__c>();
        // 批准只能一条一条的批准
        for (Rental_Apply__c nObj : newList) {
            Rental_Apply__c oObj = oldMap.get(nObj.Id);
            if (oldRaMap.containsKey(nObj.Id)) {
                oObj = oldRaMap.get(nObj.Id);
            }
            oldRaMap.put(nObj.Id, nObj);
            //update          wangweipeng                  2021/12/07                start
            //如果为批量延期，并且延期的是主单下的从单，那么会走主单的审批流，而在审批过程中，会判断当前审批的单子是否满足延期条件
            //所有我们需要判断是延期的这几个从单是否满足条件
            //如果主单的延期信息设为空，那么不需要走这里的逻辑，因为可能会出现以下情况：
            //批量延期，入口为主单，主单没延期，但是从单延期，那么走完流程以后会清空主单的延期信息
            if ((oObj.ExtensionApprovalTime_Initial__c != nObj.ExtensionApprovalTime_Initial__c 
                    && nObj.ExtensionApprovalTime_Initial__c != null && oObj.ExtensionApprovalTime_Initial__c == null) 
                || (oObj.ExtensionApprovalTime_Final__c != nObj.ExtensionApprovalTime_Final__c && nObj.demo_purpose1__c == '协议借用') // 只有第二次需要审批流的才需要做check,不需要的时候设值之前已经check了
                || (oObj.Extension_NewStep_AppTime__c != nObj.Extension_NewStep_AppTime__c && nObj.Extension_NewStep_AppTime__c != null)) 
            {
                try {
                    //存放需要 验证是否可以延期的申请单
                    //如果为批量延期，那么这个集合里面会存放 原单+原单下所有的从单
                    //如果为从单，并且目的2为询价，那么会存放 当前从单的原单+从单原单下所有的从单（包括当前从单）
                    List<Rental_Apply__c> checkRentalApply = new List<Rental_Apply__c>();
                    if(String.isNotBlank(nObj.Extension_Type__c) && nObj.Extension_Type__c == '批量延期'){
                        if(String.isNotBlank(nObj.Extension_Much_ID__c)){
                            String parentId = nObj.Id;
                            parentId = parentId.substring(0,15);
                            String likeParentId = parentId+'%';

                            checkRentalApply = [SELECT id,
                                                    Name,
                                                    RA_Status__c,
                                                    Request_return_day__c,
                                                    demo_purpose1__c,demo_purpose2__c,
                                                    ExtensionApprovalTime_Final__c,
                                                    RC_Ordered_Date__c,
                                                    Bollow_Date_Add_10_WD__c,
                                                    Loaner_received_ng_num__c,
                                                    ExtensionApprovalTime_Initial__c,
                                                    next_action__c,
                                                    NewRepair__c,
                                                    NewRepair__r.Agreed_Date__c,
                                                    NewRepair__r.Status__c,
                                                    NewRepair__r.ReRepairObject_F__c,
                                                    NewRepair__r.Repair_Shipped_Date__c,
                                                    AgreementBorrowingExtensionDate__c,
                                                    Return_dadeline_final__c,
                                                    ExtensionApplicationTime_Initial__c,
                                                    Root_Rental_Apply__c,
                                                    ExtensionStatus__c
                                                FROM Rental_Apply__c WHERE id = :parentId OR Root_Rental_Apply__c like :likeParentId 
                                            order by CreatedDate asc];
                        }
                    }else{
                        //如果延期的是从单，那么需要特殊处理
                        if(String.isNotBlank(nObj.Root_Rental_Apply__c) && (nObj.demo_purpose2__c == '试用（无询价）' || nObj.demo_purpose2__c == '试用（有询价）')){
                            String likeParentId = nObj.Root_Rental_Apply__c+'%';
                            checkRentalApply = [SELECT id,
                                                    Name,
                                                    RA_Status__c,
                                                    Request_return_day__c,
                                                    demo_purpose1__c,demo_purpose2__c,
                                                    ExtensionApprovalTime_Final__c,
                                                    RC_Ordered_Date__c,
                                                    Bollow_Date_Add_10_WD__c,
                                                    Loaner_received_ng_num__c,
                                                    ExtensionApprovalTime_Initial__c,
                                                    next_action__c,
                                                    NewRepair__c,
                                                    NewRepair__r.Agreed_Date__c,
                                                    NewRepair__r.Status__c,
                                                    NewRepair__r.ReRepairObject_F__c,
                                                    NewRepair__r.Repair_Shipped_Date__c,
                                                    AgreementBorrowingExtensionDate__c,
                                                    Return_dadeline_final__c,
                                                    ExtensionApplicationTime_Initial__c,
                                                    Root_Rental_Apply__c,
                                                    ExtensionStatus__c
                                                FROM Rental_Apply__c 
                                                WHERE id != :nObj.Id 
                                                and (Root_Rental_Apply__c like :likeParentId OR id = :nObj.Root_Rental_Apply__c)
                                            order by CreatedDate asc];

                        }
                        checkRentalApply.add(oObj);
                    }
                    for (Rental_Apply_Equipment_Set__c raes : getCan_Extend_RequestList(checkRentalApply)) {
                        //延期批准时间(最初)或延期批准时间(最终) 值都有变动，那么证明此次延期已经批准了，那么需要给申请单的一览赋值
                        if (oObj.ExtensionApprovalTime_Initial__c != nObj.ExtensionApprovalTime_Initial__c
                            || oObj.ExtensionApprovalTime_Final__c != nObj.ExtensionApprovalTime_Final__c
                        ) {
                            //如果目的2为以下，那么证明需要做特殊处理
                            if(nObj.demo_purpose2__c == '试用（无询价）' || nObj.demo_purpose2__c == '试用（有询价）'){
                                //判断是此申请单是否存在 ok并且回寄时间不为空的一览，
                                if ((raes.Received_Confirm__c == 'OK' || raes.Received_Confirm__c == '默认签收-OK') && raes.Asset_return_time__c != null) {

                                }else{
                                    //如果是批量延期，要把此次延期的所有从单的配套都赋值
                                    if(String.isNotBlank(nObj.Extension_Type__c) && nObj.Extension_Type__c == '批量延期'){
                                        String emicc = raes.Rental_Apply__c;
                                        emicc = emicc.substring(0,15);
                                        if(String.isNotBlank(nObj.Extension_Much_ID__c)){
                                            for(String emic : nObj.Extension_Much_ID__c.split(',')){
                                                if(String.isNotBlank(emic)){
                                                    emic = emic.substring(0,15);
                                                    if(emic == emicc){
                                                        raes.RcUnexpectExpiryDelay__c = raes.Rental_Apply__r.RcUnexpectExpiryDelay__c;
                                                    }
                                                }
                                            }
                                        }
                                        //查看此次是否延期原单了，如果延了，那么把主单的配套也赋值
                                        if(!nObj.Is_Delete_Extension__c){
                                            String emiccc = nObj.Id;
                                            emiccc = emiccc.substring(0,15);
                                            if(emiccc == emicc){
                                                raes.RcUnexpectExpiryDelay__c = raes.Rental_Apply__r.RcUnexpectExpiryDelay__c;
                                            }
                                        }
                                    }else{
                                        //raes.RcUnexpectExpiryDelay__c = raes.RcUnexpectExpiryDelay__c;
                                        //判断是否是从单，如果是从单，那么只给从单一览赋值
                                        if(String.isNotBlank(nObj.Root_Rental_Apply__c)){
                                            if(raes.Rental_Apply__c == nObj.Id){
                                                raes.RcUnexpectExpiryDelay__c = raes.Rental_Apply__r.RcUnexpectExpiryDelay__c;
                                            }
                                        }else{//如果不为从单，那么证明此次延期为原单，他没有分割单，所有只把他自己的配套赋值就行
                                            raes.RcUnexpectExpiryDelay__c = raes.Rental_Apply__r.RcUnexpectExpiryDelay__c;
                                        }
                                    }
                                    //update          wangweipeng                  2021/12/07                end
                                    raesList.add(raes);
                                }
                            }else{//其他延期的配套赋值
                                raes.RcUnexpectExpiryDelay__c = raes.Rental_Apply__r.RcUnexpectExpiryDelay__c;
                                raesList.add(raes);
                            }
                        }
                    }
                }
                catch (Exception e) {
                    nObj.addError(e.getMessage() + ',请操作驳回。');
                }
            }
        }
        if (0 < raesList.size()) {
            update raesList;
        }
    }

    private void checkbenbu() {
        for (Rental_Apply__c nObj : newList) {
            if (nObj.DataMigration_Flag__c == false) {
                Rental_Apply__c oObj;
                if (Trigger.isUpdate) {
                    oObj = oldMap.get(nObj.Id);
                }
                if ((Trigger.isInsert
                        || oObj.Demo_purpose2__c != nObj.Demo_purpose2__c
                        || oObj.Salesdept__c != nObj.Salesdept__c)
                        // 日报画面新建的情况，可以不填使用目的
                        && !(nObj.Demo_purpose2__c == null && nObj.Event_Id__c != null)) {
                    if (!FixtureUtil.departmentMap.containsKey(nObj.Demo_purpose2__c)) {
                        nObj.Demo_purpose2__c.addError('没有定义目的2 ' + nObj.Demo_purpose2__c + '可以选择的本部');
                    }
                    else {
                        Set<String> benbuSet = new Set<String>();
                        benbuSet.addAll(FixtureUtil.departmentMap.get(nObj.Demo_purpose2__c));
                        if (!benbuSet.contains(nObj.Salesdept__c)) {
                            nObj.Person_In_Charge__c.addError('此用户无该使用目的的申请权限');
                        }
                    }
                }
            }
        }
    }

    // 申请书部长经理等设置
    private void setManager() {
        // 申請中かどうかのチェック
        List<Id> copyUserIds = new List<Id>();                       // 件数は Trigger.New と同じ
        List<Rental_Apply__c> newList1 = new List<Rental_Apply__c>(); // 件数は Trigger.New と同じ
        for (Rental_Apply__c nObj : newList) {
            Rental_Apply__c oObj;
            if (Trigger.isUpdate) {
                oObj = oldMap.get(nObj.Id);
            }
            if (nObj.Person_In_Charge__c != null) nObj.OwnerId = nObj.Person_In_Charge__c;
            System.debug(nObj.Person_In_Charge__c);
            System.debug(nObj.OwnerId);
            if (Trigger.isInsert
                        || (Trigger.isUpdate && oObj.Status__c != nObj.Status__c && nObj.Status__c == '填写完毕')
                        || (Trigger.isUpdate && oObj.ExtensionStatus__c != nObj.ExtensionStatus__c && nObj.ExtensionStatus__c == '填写完毕')
                        || (Trigger.isUpdate && oObj.Add_Approval_Status__c != nObj.Add_Approval_Status__c && nObj.Add_Approval_Status__c == '填写完毕')//20210727 ljh SFDC-C54C33  add start
                        || (Trigger.isUpdate && oObj.OwnerId != nObj.OwnerId)
                ) {
                    newList1.add(nObj);
                    copyUserIds.add(nObj.OwnerId);
                }
        }
        System.debug(copyUserIds);
        if (copyUserIds.size() > 0) {
            Map<Id, User> copyUserMap = new Map<Id, User>([
                SELECT Id, Name, Buzhang_Equipment_Manager__c, JingliEquipmentManager__c, SalesManager__c, BuchangApprovalManagerSales__c, JingliApprovalManager__c, BuchangApprovalManager__c, ZongjianApprovalManager__c, TongkuoZongjian__c FROM User WHERE Id IN :copyUserIds
            ]);

            for (Integer i = 0; i < copyUserIds.size(); i++) {
                Rental_Apply__c nObj = newList1[i];
                User loginUser = copyUserMap.get(copyUserIds[i]);
                nObj.SalesManager__c = loginUser.JingliEquipmentManager__c;
                nObj.BuchangApprovalManagerSales__c = loginUser.Buzhang_Equipment_Manager__c;
                nObj.JingliApprovalManager__c = loginUser.JingliApprovalManager__c;
                nObj.BuchangApprovalManager__c = loginUser.BuchangApprovalManager__c;
                nObj.ZongjianApprovalManager__c = loginUser.ZongjianApprovalManager__c;
                nObj.TongkuoZongjian__c = loginUser.TongkuoZongjian__c;
                 System.debug(loginUser);
            }
        }
    }

    private void beforeSetValue() {
        List<Rental_Apply__c> ApprovalApply = new List<Rental_Apply__c>();
        List<Rental_Apply__c> addApprovalApply = new List<Rental_Apply__c>();
        Set<Id> hpIdSet = new Set<Id>();
        Map<Rental_Apply__c, Id> eramap = new Map<Rental_Apply__c, Id>();
        Map<Rental_Apply__c, Id> newRepairMap = new Map<Rental_Apply__c, Id>();
        Map<Id, Id> needRaMap = new Map<Id, Id>();
        for (Rental_Apply__c nObj : newList) {
            nObj.HP_received_Confirmed__c  = nObj.HP_received_Confirmed_F__c;
            nObj.HP_received_Confirmed__c = nObj.HP_received_Confirmed_F__c;
            if (nObj.Hospital__c != null ) hpIdSet.add(nObj.Hospital__c);
            Rental_Apply__c oObj;
            if (Trigger.isUpdate) {
                oObj = oldMap.get(nObj.Id);

                if (oObj.ExtensionApprovalTime_Final__c != nObj.ExtensionApprovalTime_Final__c
                ) {
                    Map<String, Object> bkMap = new Map<String, Object>();
                    if (String.isNotBlank(nObj.Apply_Backup__c)) {
                        bkMap = (Map<String, Object>) JSON.deserializeUntyped(nObj.Apply_Backup__c);
                    }
                    bkMap.put('ExtensionApplicationTime_Final__c', nObj.ExtensionApplicationTime_Final__c.formatGmt('yyyy-MM-dd HH:mm:ss'));
                    nObj.Apply_Backup__c = JSON.serialize(bkMap);
                }

                if (oObj.ExtensionStatus__c != nObj.ExtensionStatus__c
                    && nObj.ExtensionStatus__c == '已批准'
                    && oObj.ExtensionApprovalTime_Final__c == nObj.ExtensionApprovalTime_Final__c
                    && oObj.ExtensionApprovalTime_Initial__c == nObj.ExtensionApprovalTime_Initial__c
                    && String.isNotBlank(nObj.Apply_Backup__c)
                    ) {
                    System.debug(nObj.Apply_Backup__c);
                    Map<String, Object> bkMap = (Map<String, Object>) JSON.deserializeUntyped(nObj.Apply_Backup__c);
                    System.debug(Datetime.valueOfGmt((String)bkMap.get('ExtensionApplicationTime_Final__c')));
                    nObj.ExtensionApplicationTime_Final__c = Datetime.valueOfGmt((String)bkMap.get('ExtensionApplicationTime_Final__c'));
                }

                if (oObj.Status__c != FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Qu_Xiao.ordinal())
                    && nObj.Status__c == FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Qu_Xiao.ordinal())) {
                    nObj.Cancel_time__c = Datetime.now();
                    // nObj.Cancel_Mem__c = UserInfo.getUserId();
                }
                if (oObj.NewRepair__c != nObj.NewRepair__c
                    && String.isNotBlank(nObj.NewRepair__c)
                ) {
                    newRepairMap.put(nObj, nObj.NewRepair__c);
                }
                if (nObj.demo_purpose2__c == '索赔QIS') {
                    needRaMap.put(nObj.Id, nObj.QISRepair__c);
                }
                else {
                    needRaMap.put(nObj.Id, nObj.Repair__c);
                }
                if (oObj.Status__c != '填写完毕' && nObj.Status__c == '填写完毕') {
                    ApprovalApply.add(nObj);
                    if (rental_Apply_App_CCEmailMap.containsKey(nObj.Salesdept__c)) {
                        String ccUser = nObj.get(rental_Apply_App_CCEmailMap.get(nObj.Salesdept__c)) == null ? null : String.valueOf(nObj.get(rental_Apply_App_CCEmailMap.get(nObj.Salesdept__c)));
                        nObj.CC_EmailUser__c =  ccUser;
                    }
                }

                if (oObj.Add_Approval_Status__c != '填写完毕' && nObj.Add_Approval_Status__c == '填写完毕') {
                    addApprovalApply.add(nObj);
                }

                //批准之前就有批准时间的话需要清空
                if ((nObj.Status__c == '草案中'
                      || nObj.Status__c == '填写完毕'
                      || nObj.Status__c == '申请中')
                    && nObj.Request_approval_time__c != null) {
                    nObj.Request_approval_time__c = null;
                }

                // 提交申请的时候设置跟进询价状态（申请时）
                if (oObj.Status__c != FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Tian_Xie_Wan_Bi.ordinal())
                    && nObj.Status__c == FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Tian_Xie_Wan_Bi.ordinal())) {
                        nObj.Follow_pcl_status2_Text__c = nObj.Follow_pcl_status2__c;
                }

                Rental_Apply__c oObj1 = oObj;
                if (oldRaMap.containsKey(nObj.Id)) {
                    oObj1 = oldRaMap.get(nObj.Id);
                }
                if (oObj.ExtensionApprovalTime_Initial__c == null || nObj.demo_purpose1__c == '协议借用') {
                    if (oObj.ExtensionStatus__c != nObj.ExtensionStatus__c
                        && nObj.ExtensionStatus__c == '填写完毕'
                        && nObj.Approver_of_Service_Department__c == null
                        && String.isNotBlank(nObj.NewRepair__c)
                    ) {
                        eramap.put(nObj, nObj.NewRepair__c);
                    }
                    else if (oObj1.ExtensionApprovalTime_Initial__c != nObj.ExtensionApprovalTime_Initial__c
                        || oObj1.ExtensionApprovalTime_Final__c != nObj.ExtensionApprovalTime_Final__c
                    ) {
                        if (nObj.ExtensionSuccessTimes__c == null) {
                            nObj.ExtensionSuccessTimes__c = 0;
                        }
                        nObj.ExtensionSuccessTimes__c += 1;
                        nObj.RcUnexpectExpiryDelay__c = oObj.RcUnexpectExpiryDelay_Mail__c;
                        nObj.ExtensionContent__c = '申请延期从' + oObj.Return_dadeline_final__c + '延期到' + nObj.RcUnexpectExpiryDelay__c;
                    }
                }
            }
            if (nObj.demo_purpose2__c == '试用（无询价）'
                    || nObj.demo_purpose2__c == '试用（有询价）'
                    || nObj.demo_purpose2__c == '新产品评价'
                    || nObj.demo_purpose2__c == '其他'
                    || nObj.demo_purpose2__c == '协议借用') {
                if (trigger.isInsert
                        || (oObj.Request_shipping_day__c != nObj.Request_shipping_day__c)
                        || oObj.Hope_Lonaer_date_Num__c != nObj.Hope_Lonaer_date_Num__c) {
                    if (nObj.Hope_Lonaer_date_Num__c != null && nObj.Request_shipping_day__c != null) {
                        nObj.Request_return_day__c = (nObj.Request_shipping_day__c + Integer.valueOf(nObj.Hope_Lonaer_date_Num__c));
                    }
                    else {
                        nObj.Request_return_day__c = null;
                    }
                }
            }
            else if (nObj.demo_purpose2__c == '一般用户'
                    || nObj.demo_purpose2__c == '保修用户'
                    || nObj.demo_purpose2__c == '市场多年保修'
                    || nObj.demo_purpose2__c == '再修理'
                    || nObj.demo_purpose2__c == '索赔QIS'
                    || nObj.demo_purpose2__c == '已购待货') {
                // 不需要设置预计归还日
            }
            else if (nObj.demo_purpose2__c == '学会展会') {
                // 不需要设置预计归还日
            }
            // 必ず最後で置く
            nObj.Status_Text__c = nObj.Status__c;
            nObj.RA_Status_Text__c = nObj.RA_Status__c;
            nObj.NotWatch_RA_Status__c = nObj.NotWatch_RA_Status_F__c;
            nObj.Notice_of_Delivery_Hash__c = getHash('SHA-256', nObj.Notice_of_Delivery_Text__c);
            nObj.Assigned_Hash__c = getHash('SHA-256', nObj.Assigned_Text__c);
            // OLY_OCM-621 From WF 设定-申请者相关字段文本化
            if (String.isBlank(nObj.Work_Location_text__c)
                    || String.isBlank(nObj.Owner_province_text__c)
                    || String.isBlank(nObj.Onwer_job_category_text__c)
                    || String.isBlank(nObj.Salesdepartment_text__c)
                    || String.isBlank(nObj.Branch_text__c)
                    || String.isBlank(nObj.Salesdept_text__c)
                    || (Trigger.isUpdate
                            && (oObj.OwnerId != nObj.OwnerId || hasInsert))) {
                // 设定-借出申请人-工作地(文本)
                nObj.Work_Location_text__c = nObj.Work_Location__c;
                // 设定-借出申请人-省(文本)
                nObj.Owner_province_text__c = nObj.Owner_province__c;
                // 设定-借出申请人-职种(文本)
                nObj.Onwer_job_category_text__c = nObj.Onwer_job_category__c;
                // 设定-借出申请人-销售本部(文本)
                nObj.Salesdepartment_text__c = nObj.Salesdepartment__c;
                // 设定-借出申请人-分公司(文本)
                nObj.Branch_text__c = nObj.Branch__c;
                // 设定-申请者销售本部(文本)
                nObj.Salesdept_text__c = nObj.Salesdept__c;

                // OLY_OCM-666 第二次trigger更新正确数据， 新建数据时第二次更新OwnerId无变化， 需要强制更新
                if (Trigger.isInsert) {
                    RentalApplyTriggerHandler.hasInsert = true;
                }
            }
        }
        //拷贝医院的市字段
        Map<Id, Account> accMap = new Map<Id, Account>();
        if (hpIdSet.size() > 0) {
            accMap.putAll([SELECT Id, City_Master__r.Name, State_Text__c FROM Account WHERE Id IN: hpIdSet]);
            for (Rental_Apply__c nObj : newList) {
                if (accMap.containsKey(nObj.Hospital__c)) {
                    nObj.HP_City__c = accMap.get(nObj.Hospital__c).City_Master__r.Name;
                }
            }
        }

        if (!ApprovalApply.isEmpty()) {
            List<Rental_Apply_Equipment_Set__c> raess = [Select Id, Loaner_name_F__c, Rental_Apply__c, Loaner_code_F__c,
                    First_RAESD_Model_No_F__c
                    From Rental_Apply_Equipment_Set__c
                    Where Rental_Apply__c =: ApprovalApply
                    AND Cancel_Select__c = false
                    order by Rental_Apply__c];
            Map<Id, String> raMap = new Map<Id, String>();
            String baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
            for (Integer i = 0; i < raess.size(); i ++) {
                Rental_Apply_Equipment_Set__c raes = raess[i];
                if(!raMap.containsKey(raes.Rental_Apply__c)) {
                    raMap.put(raes.Rental_Apply__c, '');
                }
                String str = raMap.get(raes.Rental_Apply__c);
                raMap.put(raes.Rental_Apply__c,str + '备品配套'
                        + (i + 1)
                        + ':<BR>'
                        // + '<a href="'
                        // + baseUrl + '/' + raes.Id
                        // +'">'
                        + '' + raes.First_RAESD_Model_No_F__c
                        // + '  '
                        // + ' 主体明细型号:' + raes.First_RAESD__r.Fixture_Model_No_F__c
                        // + + '</a>'
                        + '<BR>');
            }
            for (Rental_Apply__c nObj : newList) {
                if (raMap.containsKey(nObj.Id)) {
                    nObj.Email_Rental_Apply_Equipment_Set__c = raMap.get(nObj.id);
                }
            }
        }

        if (!addApprovalApply.isEmpty()) {
            List<Rental_Apply_Equipment_Set_Detail__c> raesds = [SELECT Id
                        , Fixture_Model_No_F__c
                        , Rental_Apply_Equipment_Set__r.Rental_Apply__c
                     FROM Rental_Apply_Equipment_Set_Detail__c
                    WHERE Rental_Apply_Equipment_Set__r.Rental_Apply__c = :addApprovalApply
                      AND Cancel_Select__c = false
                      AND ApplyPersonAppended_F__c = true
                      AND Add_Request_approval_time__c = null
                      AND Add_Request_demo_time__c = null
                    ORDER BY Rental_Apply_Equipment_Set__r.Rental_Apply__c];
            String baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
            Map<Id, String> raMap = new Map<Id, String>();
            for (Integer i = 0; i < raesds.size(); i ++) {
                Rental_Apply_Equipment_Set_Detail__c raes = raesds[i];
                if(!raMap.containsKey(raes.Rental_Apply_Equipment_Set__r.Rental_Apply__c)) {
                    raMap.put(raes.Rental_Apply_Equipment_Set__r.Rental_Apply__c, '');
                }
                String str = raMap.get(raes.Rental_Apply_Equipment_Set__r.Rental_Apply__c);
                raMap.put(raes.Rental_Apply_Equipment_Set__r.Rental_Apply__c,str + '备品明细'
                        + (i + 1)
                        + ':<BR>'
                        // + '<a href="'
                        // + baseUrl + '/' + raes.Id
                        // +'">'
                        + '型号:' + raes.Fixture_Model_No_F__c
                        // + '</a>'
                        + '<BR>');
            }
            for (Rental_Apply__c nObj : newList) {
                if (raMap.containsKey(nObj.Id)) {
                    nObj.Email_Add_Detail__c = raMap.get(nObj.id);
                }
            }
        }

        if (eramap.isEmpty() == false) {
            Map<Id, Repair__c> rsMap = new Map<Id, Repair__c>();
            for (Repair__c re : [SELECT ID
                                        , work_location_select__c
                                        , Delivered_Product__c
                                    FROM Repair__c
                                    WHERE Id =:eramap.values()
                                       OR Id = :needRaMap.values()]) {
                if (approver_of_Service_DepartmentMap.containsKey(re.work_location_select__c)) {
                    rsMap.put(re.Id, re);
                }
            }
            for (Rental_Apply__c nObj : eramap.keySet()) {
                if (rsMap.get(needRaMap.get(nObj.Id)).Delivered_Product__c != rsMap.get(nObj.NewRepair__c).Delivered_Product__c) {
                    nObj.NewRepair__c.addError('新修理必须和原修理是同一设备');
                }
                if (rsMap.containsKey(nObj.NewRepair__c)) {
                    nObj.Approver_of_Service_Department__c = approver_of_Service_DepartmentMap.get(rsMap.get(nObj.NewRepair__c).work_location_select__c);
                }
            }
        }
        if (newRepairMap.isEmpty() == false) {
            Map<Id, Repair__c> rsMap = new Map<Id, Repair__c>();
            for (Repair__c re : [SELECT ID
                                        , work_location_select__c
                                        , Delivered_Product__c
                                    FROM Repair__c
                                    WHERE Id =:newRepairMap.values()
                                       OR Id = :needRaMap.values()
            ]) {
                rsMap.put(re.Id, re);
            }
            for (Rental_Apply__c nObj : newRepairMap.keySet()) {
                if (rsMap.get(needRaMap.get(nObj.Id)).Delivered_Product__c != rsMap.get(nObj.NewRepair__c).Delivered_Product__c) {
                    nObj.NewRepair__c.addError('新修理必须和原修理是同一设备');
                }
            }
        }

    }

    // before insert, before update
    private void setOffice_Assistant() {

        Set<String> locSet = new Set<String>();
        List<Rental_Apply__c> nObjList = new List<Rental_Apply__c>();
        for (Rental_Apply__c nObj : newList) {
            Rental_Apply__c oObj = (null == this.oldMap) ? null : this.oldMap.get(nObj.Id);
            if (Trigger.isInsert
                || oObj.ToAgency__c != nObj.ToAgency__c
            ) {
                nObj.Office_Assistant1__c = null;
                nObj.Office_Assistant2__c = null;
                if (String.isNotBlank(nObj.ToAgency__c)) {
                    locSet.add(nObj.ToAgency__c);
                    nObjList.add(nObj);
                }
            }
        }

        if (locSet.size() > 0) {
            Map<String, OCM_Management_Province__c> ocpMap = new Map<String, OCM_Management_Province__c>();
            for (OCM_Management_Province__c ocp : [SELECT Id
                                                        , Name
                                                        , Agency_assistant1__c
                                                        , Agency_assistant2__c
                                                     FROM OCM_Management_Province__c
                                                    WHERE Name = :locSet]
            ) {
                ocpMap.put(ocp.Name, ocp);
            }
            for (Rental_Apply__c nObj : nObjList) {
                if (ocpMap.containsKey(nObj.ToAgency__c)) {
                    nObj.Office_Assistant1__c = ocpMap.get(nObj.ToAgency__c).Agency_assistant1__c;
                    nObj.Office_Assistant2__c = ocpMap.get(nObj.ToAgency__c).Agency_assistant2__c;
                }
            }
        }
    }

    private void cancelRa() {
        Set<Id> raIdSet = new Set<Id>();
        List<Rental_Apply__c> raList = new List<Rental_Apply__c>(); //20210823 ljh 
        for (Rental_Apply__c nObj : newList) {
            Rental_Apply__c oObj = oldMap.get(nObj.Id);
            System.debug(FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Qu_Xiao.ordinal()));
            System.debug(oObj.Status__c);
            System.debug(nObj.Status__c);
            if (oObj.Status__c != FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Qu_Xiao.ordinal())
                && nObj.Status__c == FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Qu_Xiao.ordinal())) {
                raIdSet.add(nObj.Id);
            }
            // 20210823 ljh SFDC-C448KZ add start
            if(oObj.Cancel_Reason__c == null && nObj.Cancel_Reason__c != null 
                && oObj.Loaner_cancel_reason__c == null && nObj.Loaner_cancel_reason__c != null 
                && oObj.Loaner_cancel_request__c == null && nObj.Loaner_cancel_request__c != null){
                raList.add(nObj);
            }
            // 20210823 ljh SFDC-C448KZ add end
        }
        //20210823 ljh SFDC-C448KZ add start 
        if(raList.size() >0 ){
            Map<String,String> cancleMap = new Map<String,String>();
            List<CancelPostponePlan__c> cppList  = new List<CancelPostponePlan__c>();
            SS_Batch_Column_Mapping__c mpdMapping = SS_Batch_Column_Mapping__c.getValues('Rental_Apply_OPD_Cancle');         
            Map<String,String> opdMap = new Map<String,String>();
            for (Integer i = 101; i <= FIELDMAX; i++) {
                String lpadI = ('00' + i).right(3);
                String fromColumn = 'From_Column_' + lpadI + '__c';
                String apiStr = String.valueOf(mpdMapping.get(fromColumn));
                if (String.isBlank(apiStr) == false) {
                    String ssColumn = 'SS_Column_' + lpadI + '__c';
                    String ssApiStr = String.valueOf(mpdMapping.get(ssColumn));
                    if(apiStr.split(';').size()>=2){
                        if(apiStr.split(';')[1] != null && (apiStr.split(';')[1] == '主动取消'||apiStr.split(';')[1] == '被动取消')){
                            cancleMap.put(apiStr.split(';')[0],ssApiStr);
                        }                   
                    }          
                }
            }
            for(Rental_Apply__c ra:raList){
                if(ra.OPDPlan__c != null && !ra.if_HaveOPD_Apply__c){
                    CancelPostponePlan__c cpp = new CancelPostponePlan__c();
                    Boolean  flag = true;
                    cpp.CancelOPDPlan__c = ra.OPDPlan__c;//opdList[0].id;
                    cpp.RecordTypeId = '01210000000gQyL';
                    cpp.Status__c='取消成功';
                    if (ra.OPDType__c == '学会') {
                        flag = false;
                    }else{  
                        cpp.cancelReasonCombobox__c = cancleMap.get(ra.Loaner_cancel_reason__c);
                    }
                    cpp.if_HaveRental_Apply__c=true;//打标机是防止循环更新 opd计划
                    if (flag) {
                        cppList.add(cpp);
                    }
                }
            }
            if(cppList.size() > 0 ){
                insert cppList;
            }
        }
        //20210823 ljh SFDC-C448KZ add end
        if (raIdSet.isEmpty()) {
            return;
        }
        List<Rental_Apply_Equipment_Set__c> raess = [Select id, Rental_Apply__r.Cancel_Reason__c,
                Rental_Apply__r.Loaner_cancel_request__c,
                Rental_Apply__r.Loaner_cancel_reason__c
                FROM Rental_Apply_Equipment_Set__c
                WHERE Rental_Apply__c = :raIdSet
                  AND Cancel_Select__c = false // OLY_OCM-609 已经取消的备品借出一览不再修改取消理由等字段
                ];
        if (raess.size() > 0) {
            for (Rental_Apply_Equipment_Set__c raes : raess) {
                raes.Cancel_Select__c = true;
                raes.Cancel_Reason__c = raes.Rental_Apply__r.Cancel_Reason__c;
                raes.Loaner_cancel_Remarks__c = raes.Rental_Apply__r.Loaner_cancel_request__c;
                //20210706 SFDC-C448KZ you
                raes.Loaner_cancel_reason__c = raes.Rental_Apply__r.Loaner_cancel_reason__c;
                raes.Cancel_Mem__c = UserInfo.getUserId();
                raes.Cancel_Date__c = Date.today();
                raes.Cancel_Time__c = MainFixtureSelectController.getCurrentTime();
            }
            update raess;
        }
    }

    // From RentalApplyApprovalProcess.trigger TODO test
    // beforeUpdate
    private void approvalCheck() {
        List<Id> raIdList = new List<Id> ();
        for (Rental_Apply__c nObj : newList) {
            Rental_Apply__c oObj = null;
            if (Trigger.isUpdate) {
                oObj = oldMap.get(nObj.Id);
            }
            if (oObj.Status__c == '申请中' && nObj.Status__c == '已批准'
                    && nObj.Rental_Apply_Equipment_Set_Cnt__c != 0) {
//bp2               // 自动引当
                // 借出时间check
                String rs1 = RentalApplyWebService.approvalCheck(nObj.Id);
                if (rs1 != '1') {
                    nObj.addError(rs1);
                }
//bp2               else {
//                  // 正常终了
//                  raesNew.Status__c = '引当完了';
//              }
            }
            if (nObj.ExtensionStatus__c == '申请中' && oObj != null && nObj.Extension_NewStep_AppTime__c != null && oObj.Extension_NewStep_AppTime__c != nObj.Extension_NewStep_AppTime__c
            ) {
                raIdList.add(nObj.Id);
            }
        }
        if (raIdList.size() > 0) {
            RentalApplyTriggerHandler.doUnlockByFuture(raIdList);
        }
    }

    @future
    public static void doUnlockByFuture(List<ID> idList) {
        // Unlock操作
        List<Rental_Apply__c> raList = [SELECT Id FROM Rental_Apply__c WHERE ID IN: idList];
        Approval.UnLockResult[] results = Approval.unlock(raList, false);
        System.debug('非同期処理によるロック解除操作の対象件数 = ' + results.size()+' 日志：'+results);
    }

    //before 数式の値がnullになる可能性がありますのでここでも一回チェックします
    private void formulaToTextCheck() {
        List<Rental_Apply__c> ras = new List<Rental_Apply__c>();
        List<Id> raIds = new List<Id>();
        for (Rental_Apply__c nObj : newList) {
            if (nObj.RA_Status_Text__c != nObj.RA_Status__c
                || nObj.Status_Text__c != nObj.Status__c
                || nObj.NotWatch_RA_Status__c != nObj.NotWatch_RA_Status_F__c) {
                Rental_Apply__c ra = new Rental_Apply__c(Id = nObj.Id);
                ra.RA_Status_Text__c = nObj.RA_Status__c;
                ra.Status_Text__c = nObj.Status__c;
                ra.NotWatch_RA_Status__c = nObj.NotWatch_RA_Status_F__c;
                ras.add(ra);
                // raIds.add(ra.Id);
            }
        }
        if (!ras.isEmpty()) {
            update ras;
        }

        // if (!raIds.isEmpty()) {
        //     RentalApplyTriggerHandler.someFutureMethod(raIds);
        // }
    }

    // @future
    // public static void someFutureMethod(List<Id> recordIds) {
    //     List<Rental_Apply__c> ras = [Select Id from Rental_Apply__c Where Id IN :recordIds];
    //     update ras;
    //     // process account records to do awesome stuff
    // }

    // afterUpdate 医院确认相关的字段更新的时候要更新一览
    private void reReceivedConfirmStatus() {
        Set<Id> raIdSet = new Set<Id>();
        for (Rental_Apply__c nObj : newList) {
            Rental_Apply__c oObj = oldMap.get(nObj.Id);

            if (nObj.AssetManageConfirm__c != oObj.AssetManageConfirm__c
                    || nObj.HP_received_sign_NG__c != oObj.HP_received_sign_NG__c
                    || nObj.HP_received_sign_day__c != oObj.HP_received_sign_day__c) {
                raIdSet.add(nObj.Id);
            }
        }
         System.debug(raIdSet);
        if (raIdSet.isEmpty()) {
            return;
        }

        List<Rental_Apply_Equipment_Set__c> raess = [Select Id
                From Rental_Apply_Equipment_Set__c
                Where Rental_Apply__c = :raIdSet];
        System.debug(raess.size());
        update raess;
    }

    //
    private void reApprovalStatus() {
        Map<Id, Rental_Apply__c> raIdMap = new Map<Id, Rental_Apply__c>();
        for (Rental_Apply__c nObj : newList) {
            Rental_Apply__c oObj = oldMap.get(nObj.Id);
            if (oObj.Add_Approval_Status__c != nObj.Add_Approval_Status__c
                && nObj.Request_approval_day__c != null
                && oObj.Request_approval_day__c == nObj.Request_approval_day__c
                && nObj.Add_Approval_Status__c != '填写完毕') {
                raIdMap.put(nObj.Id, nObj);
            }
        }

        if (raIdMap.isEmpty()) {
            return;
        }

        List<Rental_Apply_Equipment_Set_Detail__c> raesds = [Select Id, Rental_Apply__c
                From Rental_Apply_Equipment_Set_Detail__c
                Where Rental_Apply__c = :raIdMap.keySet()
                AND Select_Time__c = null
                AND ApplyPersonAppended_F__c = true
                AND Add_Request_approval_time__c = null];
        for (Rental_Apply_Equipment_Set_Detail__c raesd : raesds) {
            Rental_Apply__c ra = raIdMap.get(raesd.Rental_Apply__c);
            if (ra.Add_Approval_Status__c == '申请中') {
                raesd.Add_Request_demo_time__c = ra.Add_Request_demo_time__c;
            } else if (ra.Add_Approval_Status__c == '已批准') {
                raesd.Add_Request_approval_time__c = ra.Add_Request_approval_time__c;
            } else if (ra.Add_Approval_Status__c == '草案中') {
                raesd.Add_Request_demo_time__c = null;
                raesd.Add_Request_approval_time__c = null;
            }
        }
        update raesds;
    }

    // 申请中的申请书取消时,取消审批流
    private void removedProcessRequest() {
        Set<String> cancelIdSet = new Set<String>();
        for (Rental_Apply__c nObj : newList) {
            Rental_Apply__c oObj = oldMap.get(nObj.Id);
            if (oObj.Status__c == '申请中'
                    && nObj.Status__c == '取消'
                    //SWAG-BUF6J5  20201117 you打标记为了能正确更新备品出借申请得状态  start
                    && nObj.if_HaveOPDPlanCan__c==false
                    //SWAG-BUF6J5  20201117 you打标记为了能正确更新备品出借申请得状态 end
                    ) {
                cancelIdSet.add(nObj.Id);
            }
        }

        if (cancelIdSet.size() > 0) {
            List<Approval.ProcessWorkitemRequest> requests = new List<Approval.ProcessWorkitemRequest> ();
            Map<ID,ProcessInstance> piMap = New Map<ID,ProcessInstance>([Select Id from ProcessInstance where TargetObjectId IN :cancelIdSet]);
            for(ProcessInstanceWorkItem wi : [Select Id from ProcessInstanceWorkItem where ProcessInstanceId IN :piMap.keySet()]){
                Approval.ProcessWorkitemRequest req2 = new Approval.ProcessWorkitemRequest();
                req2.setAction('Removed');
                req2.setWorkitemId(wi.Id);
                requests.add(req2);
            }
            if (requests.size() > 0) {
                Approval.ProcessResult[] processResults = null;
                processResults = Approval.process(requests, true);
            }
        }
    }

    // 字符串转Hash
    public Static String getHash(String digest, String message) {
        if (String.isBlank(message)) {
            message = '';
        }
        return EncodingUtil.convertToHex(Crypto.generateDigest(digest, Blob.valueOf(message)));
    }

    /**
     * [getCan_Extend_RequestList 验证申请单是否可以延期]
     * @param  raL [需要验证的数据]
     * @return     [description]
     *
     * 延期分两种：
     *     单独延期
     *     批量延期
     */
    public static List<Rental_Apply_Equipment_Set__c> getCan_Extend_RequestList(List<Rental_Apply__c> raL) {
        List<Rental_Apply_Equipment_Set__c> raesList = new List<Rental_Apply_Equipment_Set__c>();
        if(raL != null && raL.size() > 0){
            List<String> racIdList = new List<String>();
            for(Rental_Apply__c ra : raL){
                if (ra.demo_purpose2__c == '学会展会'
                    || ra.demo_purpose2__c == '新产品评价'
                    || ra.demo_purpose2__c == '已购待货'
                    || ra.demo_purpose2__c == '其他'
                ) {
                    throw new ControllerUtil.myException('使用目的' + ra.demo_purpose2__c + '的申请不能做延期申请');
                }
                if (ra.demo_purpose1__c == '维修代用') {
                    if (ra.ExtensionApprovalTime_Final__c != null) {
                        throw new ControllerUtil.myException('维修代用的申请不能提交两次以上延期申请');
                    }
                    if (ra.demo_purpose2__c == '故障排查'){
                        if(ra.RC_Ordered_Date__c == null){
                            throw new ControllerUtil.myException('[4.修理品RC受理日]为空，不可延期');
                        }
                        if(ra.Bollow_Date_Add_10_WD__c == null) {
                            throw new ControllerUtil.myException('此单不满足延期条件');
                        }
                        if(ra.RC_Ordered_Date__c > ra.Bollow_Date_Add_10_WD__c) {
                            throw new ControllerUtil.myException('[4.修理品RC受理日]超过出库后10个工作日，不可延期');
                        }
                    }
                    if (String.isBlank(ra.NewRepair__c)) {
                        throw new ControllerUtil.myException('提交维修代用的延期申请，必须填写新修理单号');
                    } else if (
                        ra.ExtensionApprovalTime_Initial__c != null// 第二次延期审批
                        && (
                            ra.NewRepair__r.Agreed_Date__c != null // 7.用户同意日≠空
                            && ra.NewRepair__r.Status__c != '0.取消' // 修理状态≠取消、删除
                            && ra.NewRepair__r.Status__c != '0.删除' // 修理状态≠取消、删除
                            && ra.NewRepair__r.ReRepairObject_F__c == true // 再受理对象品参考=真
                            && ra.NewRepair__r.Repair_Shipped_Date__c == null) == false// 修理品返送日=空
                    ) {
                        throw new ControllerUtil.myException('此单不满足第二次延期条件');
                    }

                }
                else if (ra.demo_purpose1__c == '产品试用') {
                    
                    //可能会出现这样的场景：有一个主单A,连个从单 A1 A2,第一次延期A A1,第二次延期入口为从单A2，那么就不需要走else判断
                    //或反过来，第一次延期一个从单，第二次准备延期主单A和A2，那么也不需要走else判断
                    if(raL.size() > 1){
                        
                    }else{
                        //批量延期时，跳过这个验证
                        if (ra.Loaner_received_ng_num__c > 0) {
                            throw new ControllerUtil.myException('未完成到货确认的操作不能做延期申请');
                            //throw new ControllerUtil.myException('存在没有做现场收到确认结果的一览不能做延期申请1111');
                        }
                        else if (ra.ExtensionApprovalTime_Initial__c != null ) {
                            throw new ControllerUtil.myException('产品试用的申请不能提交第二次延期申请');
                        }
                    }
                }else if (ra.demo_purpose1__c == '协议借用' && ra.AgreementBorrowingExtensionDate__c == null) {
                    throw new ControllerUtil.myException('协议借用的延期申请，必须填写协议借用延期日期');
                }

                if (ra.demo_purpose2__c == '索赔QIS'
                        && ra.next_action__c != '无偿维修'
                        && ra.next_action__c != '有偿维修'
                        && ra.next_action__c != '有偿维修+无偿维修'
                ) {
                    throw new ControllerUtil.myException('此单不满足延期条件');
                }

                //收集 申请单满足条件的id
                racIdList.add(ra.Id);
            }
            if(racIdList != null && racIdList.size() > 0){
                Boolean haveNotOk = false;
                for (Rental_Apply_Equipment_Set__c raes : [SELECT Id
                                                                , Rental_Apply__c
                                                                , Rental_Apply__r.Repair__r.Agreed_Date__c
                                                                , Rental_Apply__r.Repair__r.Repair_Estimated_date_formula__c
                                                                , Rental_Apply__r.NewRepair__c
                                                                , Rental_Apply__r.NewRepair__r.Agreed_Date__c
                                                                , Rental_Apply__r.NewRepair__r.Status__c
                                                                , Rental_Apply__r.NewRepair__r.ReRepairObject_F__c
                                                                , Rental_Apply__r.NewRepair__r.Repair_Shipped_Date__c
                                                                , Rental_Apply__r.QISRepair__r.Repair_Shipped_Date__c
                                                                , Rental_Apply__r.RC_return_to_office__c
                                                                , Rental_Apply__r.AgreementBorrowingExtensionDate__c
                                                                , Rental_Apply__r.ExtensionApprovalTime_Initial__c
                                                                , Rental_Apply__r.ExtensionApplicationTime_Final__c
                                                                , Rental_Apply__r.RcUnexpectExpiryDelay__c
                                                                , Final_reply_day__c
                                                                , Asset_return_time__c
                                                                , Bollow_Date__c
                                                                , demo_purpose2__c
                                                                , demo_purpose1__c
                                                                , Request_demo_time__c
                                                                , Loaner_received_time__c
                                                                , Received_Confirm__c
                                                                , Loaner_received_day2__c
                                                                , RcUnexpectExpiryDelay__c
                                                             FROM Rental_Apply_Equipment_Set__c
                                                            WHERE Rental_Apply__c in :racIdList 
                                                              AND Cancel_Reason__c = null // 取消重新分配的话需要做为NG重新分配的情况所以不能用Cancel_Select__c
                                                             ]) {
                    if (raes.demo_purpose1__c == '产品试用') {
                        if (raes.Received_Confirm__c != 'OK' && raes.Received_Confirm__c != '默认签收-OK' && raes.Received_Confirm__c != null) {
                            haveNotOk = true;
                        }
                        if ((raes.Received_Confirm__c == 'OK' || raes.Received_Confirm__c == '默认签收-OK')
                            && raes.Asset_return_time__c != null
                            && raL.size() == 1
                        ) {
                            throw new ControllerUtil.myException('此单不满足延期条件');
                        }
                        if (raes.Received_Confirm__c == 'NG'
                            && raes.Asset_return_time__c == null
                        ) {
                            throw new ControllerUtil.myException('存在NG未回寄的一览不能做延期申请');
                        }
                        if (raes.Received_Confirm__c == 'NG' && raes.Asset_return_time__c != null && raes.Loaner_received_day2__c != null
                        ) {
                            Date d2 = Date.valueOf(raes.Asset_return_time__c);
                            if (raes.Loaner_received_day2__c.daysBetween(d2) > 7) {
                                throw new ControllerUtil.myException('此单不满足延期条件');
                            }
                        }
                    }
                    if (checkCan_Extend_Request(raes, false)) {
                        raesList.add(raes);
                    }
                }
                System.debug(raesList+'---------------提示5---'+haveNotOk+'------------'+raL[0].demo_purpose1__c);
                if (raesList.size() == 0 || (haveNotOk == false && raL[0].demo_purpose1__c == '产品试用')) {
                    throw new ControllerUtil.myException('此单不满足延期条件');
                }
            }
        }
        return raesList;
    }

    // check一览是否可以做延期申请
    public static Boolean checkCan_Extend_Request(Rental_Apply_Equipment_Set__c raes, Boolean flg) {
        if (raes.demo_purpose1__c == '维修代用')  {
            // 第一次延期审批
            if (raes.Rental_Apply__r.ExtensionApprovalTime_Initial__c == null) {
                Date agreed_Date = raes.Rental_Apply__r.Repair__r.Agreed_Date__c;
                Date repair_Estimated_date_formula = raes.Rental_Apply__r.Repair__r.Repair_Estimated_date_formula__c;
                Boolean canExtend = (false == flg || raes.Rental_Apply__r.NewRepair__c != null) // 新修理单号≠空
                                    && (raes.Rental_Apply__r.RC_return_to_office__c != null || raes.Rental_Apply__r.QISRepair__r.Repair_Shipped_Date__c != null) // 旧修理.有修理品返送日≠空
                                    && raes.Final_reply_day__c >= td // 最新预定归还日 ≥ 今天
                                    && raes.Asset_return_time__c == null // 回寄时间=空
                                    && raes.Bollow_Date__c != null; // 备品中心出库≠空
                if (canExtend) {
                    if (raes.demo_purpose2__c == '一般用户') {
                        return (agreed_Date != null && agreed_Date <= raes.Request_demo_time__c) // 7.用户同意日≠空 &&7.用户同意日≤申请时间
                                || (agreed_Date != null
                                    && repair_Estimated_date_formula != null
                                    && raes.Request_demo_time__c < agreed_Date
                                    && repair_Estimated_date_formula.daysBetween(agreed_Date) <= 21);
                    }
                    else if (raes.demo_purpose2__c == '故障排查') {
                        return agreed_Date != null // 同意日!=空
                               && repair_Estimated_date_formula != null //报价日!=空
                               && repair_Estimated_date_formula.daysBetween(agreed_Date) <= 21; // 同意日-报价日<=21
                    }
                }
                return canExtend;
            }
            else {  // 第二次延期审批
                return raes.Bollow_Date__c != null // 备品中心出库≠空
                    && raes.Asset_return_time__c == null // 回寄时间=空
                    && raes.Final_reply_day__c >= td // 最新预定归还日 ≥ 今天
                    && (flg == false
                        || (raes.Rental_Apply__r.NewRepair__c != null // 新修理单号≠空
                            && raes.Rental_Apply__r.NewRepair__r.Agreed_Date__c != null // 7.用户同意日≠空
                            && raes.Rental_Apply__r.NewRepair__r.Status__c != '0.取消' // 修理状态≠取消、删除
                            && raes.Rental_Apply__r.NewRepair__r.Status__c != '0.删除' // 修理状态≠取消、删除
                            && raes.Rental_Apply__r.NewRepair__r.ReRepairObject_F__c == true // 再受理对象品参考=真
                            && raes.Rental_Apply__r.NewRepair__r.Repair_Shipped_Date__c == null // 修理品返送日=空
                        )
                    );
            }
        }
        else if (raes.demo_purpose1__c == '产品试用'
            && raes.Bollow_Date__c != null
            && raes.Asset_return_time__c == null
        ) {
            Date bollow_Date14 = raes.Bollow_Date__c.addDays(14);
            Date d1 = bollow_Date14  > raes.Final_reply_day__c ? raes.Final_reply_day__c : bollow_Date14;
            Date d2 = Date.valueOf(raes.Asset_return_time__c);
            return raes.Bollow_Date__c != null // 备品中心出库≠空
                && raes.Asset_return_time__c == null // 回寄时间=空
                //&& raes.Loaner_received_time__c != null // 申请者收到确认未完了数=0
                && d1 >= td
                && raes.Received_Confirm__c != 'NG';
        }
        else if (raes.demo_purpose1__c == '协议借用') {
            return raes.Bollow_Date__c != null // 备品中心出库≠空
                && raes.Asset_return_time__c == null // 回寄时间=空
                && raes.Final_reply_day__c >= td
                && (flg == false || raes.Rental_Apply__r.AgreementBorrowingExtensionDate__c != null)
            ;
        }
        return false;
    }

    //update      wangweipeng                             2021/11/25                   start
    //获取 自定义元数据 的数据
    public Map<String,String> customPostponeWorkLocation(){
        Map<String,String> customPostponeWorkLocationMap = new Map<String,String>();
        List<RentalApply_Postpone__mdt> usrList = [select id,MasterLabel,Approver__c from RentalApply_Postpone__mdt];
        if(usrList != null && usrList.size() > 0){
            for(RentalApply_Postpone__mdt rpm : usrList){
                if(String.isNotBlank(rpm.MasterLabel) && String.isNotBlank(rpm.Approver__c)){
                    customPostponeWorkLocationMap.put(rpm.MasterLabel,rpm.Approver__c);
                }
            }
        }
        return customPostponeWorkLocationMap;
    }

    /**add         wangweipeng                       2021/12/02                        start
     * [synchRentalApplyData 同步延期字段信息]
     * @param ra [description]
     * 批量延期时：
     *     1：主单和从单都延期了，那么需要主单和从单的延期信息同步
     *     2：如果延期了从单，但是走的是主单的审批流，那么在审批完成以后，您需要把主单的延期信息清空
     */
    public void synchRentalApplyData() {
        //获取主单延期信息有变化的id
        List<String> raIDList = new List<String>();
        for(Rental_Apply__c ra : newList){
            //是批量审批，并且延期状态发生变化，那么就需要同步延期信息
            if(ra.Extension_Type__c == '批量延期' && ra.ExtensionStatus__c != oldMap.get(ra.Id).ExtensionStatus__c){
                //只判断为主单时，并且 批量延期申请单id 字段不为空，那么就需要把延期数据同步到从单上
                if(String.isBlank(ra.Root_Rental_Apply__c) && String.isNotBlank(ra.Extension_Much_ID__c)){
                    //延期状态为 已批准、驳回或为空时，才同步
                    if('已批准'.equals(ra.ExtensionStatus__c) || '驳回'.equals(ra.ExtensionStatus__c) || String.isBlank(ra.ExtensionStatus__c)){
                        //获取此次批量延期的所有从单单子
                        for(String emic : ra.Extension_Much_ID__c.split(',')){
                            if(String.isNotBlank(emic)){
                                raIDList.add(emic);
                            }
                        }
                    }
                }
            }
        }
        if(raIDList != null && raIDList.size() > 0){
            List<Rental_Apply__c> racExtensionData = [SELECT ID
                                                            ,NAME
                                                            ,Is_Delete_Extension__c
                                                            ,ExtensionStatus__c
                                                            ,Extension_Type__c
                                                            ,Extension_Parent_Entrance__c 
                                                            ,ExtensionApplicationTime_Initial__c
                                                            ,ExtensionApprovalTime_Initial__c
                                                            ,ExtensionSuccessTimes__c
                                                            ,RcUnexpectExpiryDelay__c
                                                            ,ExtensionContent__c
                                                            ,RcUnexpectExpiryDelay_Mail__c
                                                            ,ExtensionDays__c
                                                        FROM Rental_Apply__c 
                                                        WHERE ID IN :raIDList 
                                                            AND Extension_Type__c = '批量延期'
                                                            AND ExtensionApplicationTime_Initial__c != NULL];
            if(racExtensionData != null && racExtensionData.size() > 0){
                List<Rental_Apply__c> updateRACE = new List<Rental_Apply__c>();
                for(Rental_Apply__c ra : newList){
                    //是批量审批，并且延期状态发生变化，那么就需要同步延期信息
                    if('批量延期'.equals(ra.Extension_Type__c) && ra.ExtensionStatus__c != oldMap.get(ra.Id).ExtensionStatus__c){
                        //只判断为主单时，并且 批量延期申请单id 字段不为空，那么就需要把延期数据同步到从单上
                        if(String.isBlank(ra.Root_Rental_Apply__c) 
                            && String.isNotBlank(ra.Extension_Much_ID__c)
                            && ('已批准'.equals(ra.ExtensionStatus__c) || '驳回'.equals(ra.ExtensionStatus__c) || String.isBlank(ra.ExtensionStatus__c)))
                        {
                            if('已批准'.equals(ra.ExtensionStatus__c)){
                                //updateRACE = setUpdateRACE(ra.Extension_Much_ID__c,ra,racExtensionData,'');
                                //存放当前主单数据，用于情况延期信息
                                Rental_Apply__c racc = new Rental_Apply__c();
                                racc.id = ra.id;
                                //批量延期申请单  赋值  已批量延期申请单
                                if(ra.Extension_List_RentalApply__c != null){
                                    if(ra.History_Extension_Much_ID__c != null){
                                        racc.History_Extension_List_RentalApply__c += ra.Extension_List_RentalApply__c;
                                    }else{
                                        racc.History_Extension_List_RentalApply__c = ra.Extension_List_RentalApply__c;
                                    }
                                }
                                //批量延期申请单id 赋值  已批量延期申请单id
                                if(ra.Extension_Much_ID__c != null){
                                    if(ra.History_Extension_Much_ID__c != null){
                                        racc.History_Extension_Much_ID__c += ',' +ra.Extension_Much_ID__c;
                                    }else{
                                        racc.History_Extension_Much_ID__c = ra.Extension_Much_ID__c;
                                    }
                                }
                                //如果批量延期的时候，主单没有延期，从单延期了，那么也是走主单的审批流程，但是审批完成以后，
                                //需要把主单的延期信息字段置空，不能影响主单他自己的延期
                                if(ra.Is_Delete_Extension__c){
                                    racc.ExtensionApprovalTime_Initial__c = null;//延期批准时间(最初)
                                    racc.ExtensionSuccessTimes__c = null;//延期成功次数
                                    racc.RcUnexpectExpiryDelay__c = null;//RC未定到期延时
                                    racc.RcUnexpectExpiryDelay_Mail__c = null;//RC未定到期延时(邮件用)
                                    racc.ExtensionContent__c = null;//延期内容
                                    racc.ExtensionStatus__c = null;//延期状态
                                    racc.ExtensionApplicationTime_Initial__c = null;//延期申请时间(最初)
                                    racc.Is_Delete_Extension__c = false;
                                    racc.Extension_Type__c = '';
                                    racc.Extension_Much_ID__c = null;//批量延期申请单id
                                    racc.Extension_NewStep_AppTime__c = null;
                                    racc.ExtensionDays__c = null;//延期天数
                                    //racc.Extension_List_RentalApply__c = null;//批量延期申请单
                                }
                                updateRACE.add(racc);
                            }else if('驳回'.equals(ra.ExtensionStatus__c)){
                                //updateRACE = setUpdateRACE(ra.Extension_Much_ID__c,ra,racExtensionData,'1');
                                Rental_Apply__c racc = new Rental_Apply__c();
                                racc.id = ra.id;
                                racc.Is_Delete_Extension__c = false;
                                racc.Extension_Type__c = '';
                                racc.Extension_Much_ID__c = null;//批量延期申请单id
                                racc.Extension_List_RentalApply__c = null;//批量延期申请单
                                updateRACE.add(racc);
                            }else if(String.isBlank(ra.ExtensionStatus__c)){
                                //updateRACE = setUpdateRACE(ra.Extension_Much_ID__c,ra,racExtensionData,'1');
                                Rental_Apply__c racc = new Rental_Apply__c();
                                racc.id = ra.id;
                                racc.Is_Delete_Extension__c = false;
                                racc.Extension_Type__c = '';
                                racc.Extension_Much_ID__c = null;
                                racc.Extension_List_RentalApply__c = null;
                                updateRACE.add(racc);
                            }
                        }
                    }
                }
                if(updateRACE != null && updateRACE.size() > 0){
                    update updateRACE;
                }
            }
        }
    }

    /**
     * [synchRentalApplyData2 批量延期时同步从单]
     *
     * 批量延期时，需要主单和从单的延期信息同步
     */
    public void synchRentalApplyData2() {
        //获取主单延期信息有变化的id
        List<String> raIDList = new List<String>();
        for(Rental_Apply__c ra : newList){
            //是批量审批，并且延期状态发生变化，那么就需要同步延期信息
            if(ra.Extension_Type__c == '批量延期' && ra.ExtensionStatus__c != oldMap.get(ra.Id).ExtensionStatus__c){
                //只判断为主单时，并且 批量延期申请单id 字段不为空，那么就需要把延期数据同步到从单上
                if(String.isBlank(ra.Root_Rental_Apply__c) && String.isNotBlank(ra.Extension_Much_ID__c)){
                    //延期状态为 已批准、驳回或为空时，才同步
                    if('已批准'.equals(ra.ExtensionStatus__c) || '驳回'.equals(ra.ExtensionStatus__c) || String.isBlank(ra.ExtensionStatus__c)){
                        //获取此次批量延期的所有从单单子
                        for(String emic : ra.Extension_Much_ID__c.split(',')){
                            if(String.isNotBlank(emic)){
                                raIDList.add(emic);
                            }
                        }
                    }
                }
            }
        }
        if(raIDList != null && raIDList.size() > 0){
            List<Rental_Apply__c> racExtensionData = [SELECT ID
                                                            ,NAME
                                                            ,Is_Delete_Extension__c
                                                            ,ExtensionStatus__c
                                                            ,Extension_Type__c
                                                            ,Extension_Parent_Entrance__c 
                                                            ,ExtensionApplicationTime_Initial__c
                                                            ,ExtensionApprovalTime_Initial__c
                                                            ,ExtensionSuccessTimes__c
                                                            ,RcUnexpectExpiryDelay__c
                                                            ,ExtensionContent__c
                                                            ,RcUnexpectExpiryDelay_Mail__c
                                                            ,ExtensionDays__c
                                                        FROM Rental_Apply__c 
                                                        WHERE ID IN :raIDList 
                                                            AND Extension_Type__c = '批量延期'
                                                            AND ExtensionApplicationTime_Initial__c != NULL];
            if(racExtensionData != null && racExtensionData.size() > 0){
                List<Rental_Apply__c> updateRACE = new List<Rental_Apply__c>();
                for(Rental_Apply__c ra : newList){
                    //是批量审批，并且延期状态发生变化，那么就需要同步延期信息
                    if('批量延期'.equals(ra.Extension_Type__c) && ra.ExtensionStatus__c != oldMap.get(ra.Id).ExtensionStatus__c){
                        //只判断为主单时，并且 批量延期申请单id 字段不为空，那么就需要把延期数据同步到从单上
                        if(String.isBlank(ra.Root_Rental_Apply__c) 
                            && String.isNotBlank(ra.Extension_Much_ID__c)
                            && ('已批准'.equals(ra.ExtensionStatus__c) || '驳回'.equals(ra.ExtensionStatus__c) || String.isBlank(ra.ExtensionStatus__c)))
                        {
                            if('已批准'.equals(ra.ExtensionStatus__c)){
                                updateRACE = setUpdateRACE(ra.Extension_Much_ID__c,ra,racExtensionData,'');
                            }else if('驳回'.equals(ra.ExtensionStatus__c)){
                                updateRACE = setUpdateRACE(ra.Extension_Much_ID__c,ra,racExtensionData,'1');
                            }else if(String.isBlank(ra.ExtensionStatus__c)){
                                updateRACE = setUpdateRACE(ra.Extension_Much_ID__c,ra,racExtensionData,'1');
                            }
                        }
                    }
                }
                if(updateRACE != null && updateRACE.size() > 0){
                    update updateRACE;
                }
            }
        }
    }
    /**
     * [setUpdateRACE 更新从单的延期数据]
     * @param  emicS    [主单存放的此次延期的从单id]
     * @param  ra       [主单数据]
     * @param  raIDData [所有从单数据]
     * @param  rcType   [是否为 驳回或调回]
     * @return          [description]
     *
     * 注意：驳回和调回时，需要清空延期类型，而审批完成不需要
     */
    public List<Rental_Apply__c> setUpdateRACE(String emicS,Rental_Apply__c ra,List<Rental_Apply__c> raIDData,String rcType){
        List<Rental_Apply__c> updateRACE = new List<Rental_Apply__c>();
        if(raIDData != null && raIDData.size() > 0 && String.isNotBlank(emicS)){
            for(String emic : emicS.split(',')){
                if(String.isNotBlank(emic)){
                    emic = emic.substring(0,15);
                    for(Rental_Apply__c eRac : raIDData){
                        String eRacId = eRac.Id;
                        eRacId = eRacId.substring(0,15);
                        if(emic == eRacId){
                            eRac.ExtensionApprovalTime_Initial__c = ra.ExtensionApprovalTime_Initial__c;//延期批准时间(最初)
                            //eRac.RcUnexpectExpiryDelay__c = ra.RcUnexpectExpiryDelay__c;//RC未定到期延时
                            //eRac.ExtensionContent__c = ra.ExtensionContent__c;//延期内容
                            eRac.ExtensionStatus__c = ra.ExtensionStatus__c;//延期状态
                            eRac.ExtensionApplicationTime_Initial__c = ra.ExtensionApplicationTime_Initial__c;//延期申请时间(最初)
                            //由于如果是撤回时，那么需要把延期类型设为空
                            if(String.isNotBlank(rcType) && rcType == '1'){
                                eRac.Extension_Type__c = '';
                            }else{
                                //eRac.ExtensionSuccessTimes__c = ra.ExtensionSuccessTimes__c;//延期成功次数,从单会自动判断不需要同步
                                //只有审批完成以后才会赋值给从单
                                eRac.Extension_NewStep_AppTime__c = ra.Extension_NewStep_AppTime__c;//延期最新步骤批准时间
                            }
                            updateRACE.add(eRac);
                        }
                    }
                }
            }
        }
        return updateRACE;
    }

    /**
     * [checkExtensionDeadline 延期是否还可以审批]
     *
     * 判断延期审批的时间是否超过延期截止日期
     * 如果超过了，那么就不能审批了，只能驳回会撤回
     * 如果没有超过，那么可以正常审批
     * 
     */
    public void checkExtensionDeadline() {
        for(Rental_Apply__c ra : newList){
            try{
                if(ra.demo_purpose2__c == '试用（无询价）' || ra.demo_purpose2__c == '试用（有询价）'){
                    Rental_Apply__c ora = oldMap.get(ra.Id);
                    //是批量审批，并且延期状态发生变化，那么就需要同步延期信息
                    if(ra.Extension_Type__c == '批量延期'){
                        //只判断为主单时，并且 批量延期申请单id 字段不为空，那么就需要把延期数据同步到从单上
                        if(String.isBlank(ra.Root_Rental_Apply__c)){
                            //延期状态为 已批准、驳回或为空时，才同步
                            if(('申请中'.equals(ra.ExtensionStatus__c) || ('已批准'.equals(ra.ExtensionStatus__c) && ora.ExtensionStatus__c == '申请中')) 
                                && ra.Extension_NewStep_AppTime__c != ora.Extension_NewStep_AppTime__c){
                                if(ra.Extension_Deadline__c != null){
                                    Date nDa = Date.today();
                                    if(nDa > ra.Extension_Deadline__c){
                                        throw new ControllerUtil.myException('延期截止日期小于当前时间，不能延期');
                                    }
                                }
                                //判断此次延期的申请单是否存在 ok并且回寄时间不为空的一览
                                List<String> racLi = new List<String>();
                                if(String.isNotBlank(ra.Extension_Much_ID__c)){
                                    //获取此次批量延期的所有从单单子
                                    for(String emic : ra.Extension_Much_ID__c.split(',')){
                                        if(String.isNotBlank(emic)){
                                            racLi.add(emic);
                                        }
                                    }
                                }
                                //判断批量延期的时候，主单是否延期了
                                if(!ra.Is_Delete_Extension__c){
                                    racLi.add(ra.Id);
                                }
                                if(racLi.size() > 0){
                                    getAssetReturnTime(racLi);
                                }
                            }
                        }
                    }else if(String.isNotBlank(ra.Root_Rental_Apply__c)){
                        //延期状态为 已批准、驳回或为空时，才同步
                        if(('申请中'.equals(ra.ExtensionStatus__c) || ('已批准'.equals(ra.ExtensionStatus__c) && ora.ExtensionStatus__c == '申请中')) 
                            && ra.Extension_NewStep_AppTime__c != ora.Extension_NewStep_AppTime__c){
                            if(ra.Extension_Deadline__c != null){
                                Date nDa = Date.today();
                                if(nDa > ra.Extension_Deadline__c){
                                    throw new ControllerUtil.myException('延期截止日期小于当前时间，不能延期');
                                }
                            }
                            getAssetReturnTime(new List<String>{ra.Id});
                        }
                    }
                }
            }catch (Exception e) {
                ra.addError(e.getMessage() + ',请操作驳回。');
            }
        }
    }

    /**
     * [getAssetReturnTime description]
     *
     * 判断申请单是否存在 ok并且回寄时间不为空的一览
     */
    public void getAssetReturnTime(List<String> racLi){
        if(racLi != null && racLi.size() > 0){
            List<Rental_Apply_Equipment_Set__c> raescL = [select id,name 
                                                                from Rental_Apply_Equipment_Set__c 
                                                                where Rental_Apply__c in :racLi 
                                                                and (Received_Confirm__c = 'OK' OR Received_Confirm__c = '默认签收-OK' )
                                                                and Asset_return_time__c != null];
            if(raescL != null && raescL.size() > 0){
                throw new ControllerUtil.myException('此单不满足延期条件');
            }
        }
    }
    //add         wangweipeng                       2021/12/02                        end

    @testVisible
    private void testI() {
        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++;
    }
}