public without sharing class RentalApplyEquipmentSetDetailHandler extends Oly_TriggerHandler {
  private Map<Id, Rental_Apply_Equipment_Set_Detail__c> newMap;
  private Map<Id, Rental_Apply_Equipment_Set_Detail__c> oldMap;
  private List<Rental_Apply_Equipment_Set_Detail__c> newList;
  private List<Rental_Apply_Equipment_Set_Detail__c> oldList;
  private static final Map<String, Schema.RecordTypeInfo> DEVELOPERNAMEMAP = Schema.SObjectType.Rental_Apply__c.getRecordTypeInfosByDeveloperName(); //记录类型 20201119 ljh add
  //Rental_Apply_Equipment_Set_Detail__c 更新する時にAssetも更新する可能性がありますので，ここでstaticMapを作成しsiAssetを結集します
  private static Map<Id, Asset> assMap = new Map<Id, Asset>(); // new Only
  // 上架的时候保有设备的借出分配数会-1,但是主体的话有可能会暂定分配。这时候就会有更新了两条明细,但是更新的保有设备是同一条的情况(暂定分配接触分配数量需要+1)
  // 因为暂定分配的时候借出分配书需要再原来的上架-1后的基础上+1所以上架时候保有设备的接触分配数需要保存再次使用。
  // 如果不是Static上架后就会清空assUpdMap,这时候就会使用assMap里的保有设备来做数量加减,虽然再检索一次保有设备并保存到assMap的话数据会很干净
  // 但因为SOQL101的问题发生的几率会大大增加,所以assUpdMap还是使用静态变量
  private static Map<Id, Asset> assUpdMap = new Map<Id, Asset>(); // new と old
  private static Set<Id> executeed_refreshQueueNumber = new Set<Id>(); // 已经处理过排队顺 Rental_Apply_Equipment_Set_Detail__c.Id

  private static Set<Id> shipment_requestedRaIdSet = new Set<Id>();
  private static Set<Id> shipment_requestedRaIdStaticSet = new Set<Id>();

  public RentalApplyEquipmentSetDetailHandler() {
    if (Trigger.isUpdate || Trigger.isUndelete || Trigger.isDelete) {
      this.newMap = new Map<Id, Rental_Apply_Equipment_Set_Detail__c>();
      this.newList = new List<Rental_Apply_Equipment_Set_Detail__c>();
      this.oldMap = (Map<Id, Rental_Apply_Equipment_Set_Detail__c>) Trigger.oldMap;
      this.oldList = (List<Rental_Apply_Equipment_Set_Detail__c>) Trigger.old;
      // 大前提 Fixture_Set__c ですが下記の属性が設定されています
      // 参照関係に含まれる参照レコードは削除できません。
      if (Trigger.isUpdate || Trigger.isUndelete) {
        for (SObject nSObj : Trigger.new) {
          Rental_Apply_Equipment_Set_Detail__c nObj = (Rental_Apply_Equipment_Set_Detail__c) nSObj;
          Rental_Apply_Equipment_Set_Detail__c oObj = null;
          if (Trigger.isUpdate) {
            oObj = oldMap.get(nObj.Id);
          }
          if (Trigger.isUndelete && String.isBlank(nObj.Fixture_Set_Id__c)) {
            // 旧データ、beipin2 の trigger 実行しない
            continue;
          } else if (
            Trigger.isUpdate &&
            String.isBlank(nObj.Fixture_Set_Id__c) &&
            String.isNotBlank(oObj.Fixture_Set_Id__c)
          ) {
            nObj.addError('不能清空借出备品配套 Fixture_Set__c');
          } else if (
            Trigger.isUpdate &&
            String.isNotBlank(nObj.DeliverySlip__c) &&
            String.isNotBlank(oObj.DeliverySlip__c) &&
            oObj.DeliverySlip__c != nObj.DeliverySlip__c
          ) {
            //nObj.addError('不能修改借出备品配套明细的运输单');
          } else if (
            Trigger.isUpdate &&
            String.isNotBlank(nObj.Return_DeliverySlip__c) &&
            String.isNotBlank(oObj.Return_DeliverySlip__c) &&
            oObj.Return_DeliverySlip__c != nObj.Return_DeliverySlip__c
          ) {
            nObj.addError('不能修改借出备品配套明细的回寄运输单');
          } else {
            this.newList.add(nObj);
            this.newMap.put(nObj.Id, nObj);
          }
        }
      }
    } else {
      // insert
      this.newMap = (Map<Id, Rental_Apply_Equipment_Set_Detail__c>) Trigger.newMap;
      this.oldMap = (Map<Id, Rental_Apply_Equipment_Set_Detail__c>) Trigger.oldMap;
      this.newList = (List<Rental_Apply_Equipment_Set_Detail__c>) Trigger.new;
      this.oldList = (List<Rental_Apply_Equipment_Set_Detail__c>) Trigger.old;
    }
  }
  public static Boolean disabled = false;
  // 备品优化追加 20230518 lc Start
  public static Boolean skipUpdateAgain = false;
  // 备品优化追加 20230518 lc End
  protected override void beforeInsert() {
    if (!disabled) {
      beforeSetValue();
    }
  }
  protected override void beforeUpdate() {
    if (!disabled && !FixtureUtil.isRepairRenewal) {
      beforeSetValue();

      // 设值排队的UniqueKey
      setUniqueKeyQueue();
    }
  }
  protected override void afterInsert() {
    if (!disabled && !FixtureUtil.isRepairRenewal) {
      formulaToTextCheck();
      //入力規則 新建数据不能分配がありますので，ここではLastとOut_of_wh__cの設定必要ありません

      Set<Id> raesdAssignSet = new Set<Id>();
      for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
        if (nObj.Select_Time__c != null) {
          if (String.isNotBlank(nObj.Rental_Apply__c)) {
            raesdAssignSet.add(nObj.Rental_Apply__c);
          }
        }
      }
      if (raesdAssignSet.size() > 0) {
        // 设置分配人
        setAssginPerson(raesdAssignSet);
      }
      // 办事处新建已分配明细时执行
      afterInsertAgencyAssignedDetail();
      if (!assUpdMap.isEmpty()) {
        update assUpdMap.values();
      }
    }
  }
  protected override void afterDelete() {
    // OLY_OCM-1189 追加删除Check
    deleteCheck();
    deleteReFirst();
    //排队顺有变化的时候重新设置排队顺
    // reQueueNumber();
    //added by denny
    reQueueAndSequence();
    // 办事处删除已分配明细时执行
    afterDeleteAgencyAssignedDetail();
    if (!assUpdMap.isEmpty()) {
      update assUpdMap.values();
    }
  }
  protected override void afterUpdate() {
    if (!disabled && !FixtureUtil.isRepairRenewal) {
      Set<Id> assIds = new Set<Id>();
      for (Rental_Apply_Equipment_Set_Detail__c raesd : newList) {
        if (String.isNotBlank(raesd.Asset__c)) {
          assIds.add(raesd.Asset__c);
        }
      }
      if (Trigger.isUpdate && !assIds.isEmpty()) {
        assMap = new Map<Id, Asset>(
          [
            SELECT
              Id,
              Quantity,
              Status,
              Manage_type__c,
              Out_of_wh__c,
              Rental_Count__c,
              Abandoned_Inventory__c,
              Abandoned_RealThing__c,
              Confirm_Lost_Count__c,
              CountForRepair__c
            FROM Asset
            WHERE
              Id = :assIds
              AND Asset_loaner_category__c != '耗材'
              AND RecordTypeId = '01210000000kOPR'
            FOR UPDATE
          ]
        );
      }
      // 备品数量的加减
      changeAsset();
      System.debug(
        LoggingLevel.INFO,
        '*00** assUpdMap: ' + JSON.serialize(assUpdMap)
      );
      // 排队再分配 借出分配数量的减 等, clear Last_Reserve_RAES_Detail__c, 設定First_RAESD__c
      clearLastReserveRAESD();
      System.debug(
        LoggingLevel.INFO,
        '*11** assUpdMap: ' + JSON.serialize(assUpdMap)
      );
      //Asset变更的时候 更新Asset的 Last_Reserve_RAES_Detail__c
      changeAssetLast();
      System.debug(
        LoggingLevel.INFO,
        '*22** assUpdMap: ' + JSON.serialize(assUpdMap)
      );
      // Asset.Out_of_wh__c+ -
      changeAssetCount();
      System.debug(
        LoggingLevel.INFO,
        '*33* assUpdMap: ' + JSON.serialize(assUpdMap)
      );
      // change Consumable_Guaranteen_end__c OLY_OCM-601
      changeAssetConsumable_Guaranteen_end();
      System.debug(
        LoggingLevel.INFO,
        '*44** assUpdMap: ' + JSON.serialize(assUpdMap)
      );
      // 同じblock の 排队レコード Queue_Number__c をrefresh
      // refreshQueueNumberByBlock();
      if (!assUpdMap.isEmpty()) {
        System.debug(
          LoggingLevel.INFO,
          '*----** assUpdMap: ' + JSON.serialize(assUpdMap)
        );
        update assUpdMap.values();
      }
      // 4-XX 的 一对一对应
      oneToOne4XX();
      // キャンセルコピー, 一览单位取消后的拷贝在一览的Handler里面做
      cancelCopy();
      // before では数式項目がnullの場合があります
      formulaToTextCheck();
      // 下一次借用预计出库时间  回收后-检测结果OK  2021117 ljh
      NextShippmentDate();
      NextShippmentDate_out();
      // 允许插队邮件  20211125 ljh
      setToRa_Email_Text();
      //排队顺有变化的时候重新设置排队顺
      // reQueueNumber();
      //排队新逻辑
      //added by denny
      reQueueAndSequence();
      //申请者收回NG后明细回寄时的邮件回寄单内容设置
      receivedConfirmNGSetReturnDeliverySlipText();
      Set<Id> raesdSet = new Set<Id>();
      Set<Id> raesdAssignSet = new Set<Id>();
      for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
        Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
        if (
          String.isBlank(oObj.Return_DeliverySlip__c) &&
          String.isNotBlank(nObj.Return_DeliverySlip__c)
        ) {
          raesdSet.add(nObj.Id);
        }
        if (nObj.Select_Time__c != null && oObj.Select_Time__c == null) {
          raesdAssignSet.add(nObj.Rental_Apply__c);
        }
      }
      System.debug(raesdSet);
      if (raesdSet.size() > 0) {
        // 设置回寄通知内容
        RentalApplyEquipmentSetDetailHandler.setRequestAsset_return_Text(
          raesdSet
        );
      }

      if (raesdAssignSet.size() > 0) {
        // 设置分配人
        setAssginPerson(raesdAssignSet);
      }

      // 设置耗材的备品接触申请出库指示邮件发送时间
      setConsumSend_Rental_Apply_EmailTime();

      //2021-12-20  mzy  备品任务  start
      // FinishRentalTask(); // 20220121 排队上线
      //2021-12-20  mzy  备品任务  end
    }
  }
  private Map<Id, Asset> createAssetMap() {
    Set<Id> assIds = new Set<Id>();
    String ra_RecordTypeId = DEVELOPERNAMEMAP.get('AgencyRequest')
      .getRecordTypeId();
    List<Rental_Apply_Equipment_Set_Detail__c> objList = new List<Rental_Apply_Equipment_Set_Detail__c>();
    if (Trigger.isInsert) {
      objList = newList;
    } else {
      objList = oldList;
    }
    for (Rental_Apply_Equipment_Set_Detail__c obj : objList) {
      if (
        ra_RecordTypeId != null &&
        obj.RA_RecordTypeId__c.substring(0, 15) ==
        ra_RecordTypeId.substring(0, 15) &&
        obj.Asset__c != null &&
        obj.Select_Time__c != null &&
        (Trigger.isDelete || Trigger.isInsert)
      ) {
        assIds.add(obj.Asset__c);
      }
    }
    Map<Id, Asset> m = new Map<Id, Asset>();
    if (!assIds.isEmpty()) {
      m = new Map<Id, Asset>(
        [
          SELECT
            Id,
            Quantity,
            Status,
            Manage_type__c,
            Out_of_wh__c,
            Rental_Count__c,
            Abandoned_Inventory__c,
            Abandoned_RealThing__c,
            Confirm_Lost_Count__c
          FROM Asset
          WHERE
            Id = :assIds
            AND Asset_loaner_category__c != '耗材'
            AND RecordTypeId = '01210000000kOPR'
          FOR UPDATE
        ]
      );
    }
    return m;
  }
  private void afterInsertAgencyAssignedDetail() {
    // 办事处新建已分配明细时执行
    assMap = createAssetMap();
    if (!assMap.isEmpty()) {
      for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
        if (assMap.containsKey(nObj.Asset__c)) {
          Asset ass = assMap.get(nObj.Asset__c);
          if (ass.Manage_type__c == '个体管理') {
            ass.Last_Reserve_RAES_Detail__c = nObj.Id;
          }
          if (ass.Out_of_wh__c == null) {
            ass.Out_of_wh__c = 1;
          } else {
            ass.Out_of_wh__c += 1;
          }
          assUpdMap.put(ass.Id, ass);
        }
      }
    }
  }
  private void afterDeleteAgencyAssignedDetail() {
    // 办事处删除已分配明细时执行
    assMap = createAssetMap();
    if (!assMap.isEmpty()) {
      for (Rental_Apply_Equipment_Set_Detail__c oObj : oldList) {
        if (assMap.containsKey(oObj.Asset__c)) {
          Asset ass = assMap.get(oObj.Asset__c);
          if (ass.Manage_type__c == '个体管理') {
            ass.Last_Reserve_RAES_Detail__c = null;
          }
          if (ass.Out_of_wh__c != null) {
            ass.Out_of_wh__c -= 1;
          }
          assUpdMap.put(ass.Id, ass);
        }
      }
    }
  }

  private void deleteCheck() {
    String ra_RecordTypeId = DEVELOPERNAMEMAP.get('AgencyRequest')
      .getRecordTypeId();
    for (Rental_Apply_Equipment_Set_Detail__c oObj : oldList) {
      if (
        (oObj.RA_RecordTypeId__c.substring(0, 15) !=
        ra_RecordTypeId.substring(0, 15) &&
        (oObj.Rental_Apply_Request_approval_time_F__c != null &&
        oObj.ApplyPersonAppended_F__c == false) ||
        (oObj.ApplyPersonAppended_F__c == true &&
        oObj.Add_Request_approval_time__c != null)) ||
        (oObj.RA_RecordTypeId__c.substring(0, 15) ==
        ra_RecordTypeId.substring(0, 15) &&
        (oObj.Rental_Apply_Request_approval_time_F__c != null &&
        (oObj.Rental_Apply_CreatedDate_F__c > oObj.CreatedDate ||
        oObj.StockDown__c == true) &&
        !oObj.canDelete__c)) //20210523 ljh add 1829
      ) {
        oObj.addError('已经批准的备品借出明细不能做物理删除。');
      }
    }
  }

  private void setConsumSend_Rental_Apply_EmailTime() {
    if (shipment_requestedRaIdSet.isEmpty() == false) {
      List<Consum_Apply__c> caList = [
        SELECT Id, Loaner_centre_mail_address__c
        FROM Consum_Apply__c
        WHERE Rental_Apply__c = :shipment_requestedRaIdSet
      ];
      if (caList.size() > 0) {
        Datetime dt = Datetime.now();
        for (Consum_Apply__c ca : caList) {
          ca.Send_Rental_Apply_EmailTime__c = dt;
        }
        update caList;
      }
      shipment_requestedRaIdSet = new Set<Id>();
    }
  }

  private void beforeSetValue() {
    Set<Id> raesdSet = new Set<Id>();
    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      raesdSet.add(nObj.Rental_Apply_Equipment_Set__c);
    }
    Map<Id, Rental_Apply_Equipment_Set__c> raesdMap = new Map<Id, Rental_Apply_Equipment_Set__c>(
      [
        SELECT Id, Fixture_Set__r.Name, IndexFromUniqueKey__c
        FROM Rental_Apply_Equipment_Set__c
        WHERE Id = :raesdSet
      ]
    );
    String agencyRecordTypeId = DEVELOPERNAMEMAP.get('AgencyRequest')
      .getRecordTypeId();

    // 备品性能优化改修 20230312 by lc Start
    String userid = UserInfo.getUserId();
    // 备品性能优化改修 20230312 by lc End

    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      //因为是Insert时候设值  情况1，申请新建会设值  情况2，NG拷贝出来的时候会设值
      //因为UniqueKey__c判断了DataMigration_Flag__c所以这里也需要判断  检索的时候因为要假Insert所以不需要设置
      // TODO bp3 DetailHandler里, 对FSD设值的地方 需要在Rental_Apply__c的Handler里, 变成批准時, 也要设值。
      if (Trigger.isInsert && nObj.DataMigration_Flag__c == false) {
        nObj.Is_Body__c = nObj.Is_Body_F__c;
        if (String.isNotBlank(nObj.Fixture_Set_Detail__c)) {
          nObj.FSD_Id__c = nObj.Fixture_Set_Detail__c;
        }
        // 272チケット
        // Create_State__c为空并且申请书的标准批准时间不为空的时候设置为1
        // 1 --- 追加附属品
        // 0 --- Cancel拷贝
        // null --- 普通新规
        if (
          nObj.Create_State__c == null &&
          !FixtureUtil.isRepairRenewal &&
          nObj.Rental_Apply_Request_approval_time_F__c != null &&
          nObj.Substitute_Select_Again__c == false && // OLY_OCM-404 分配代替品
          // 办事处分配时追加的明细不算追加附属品
          nObj.RA_RecordTypeId__c.substring(0, 15) !=
          agencyRecordTypeId.substring(0, 15)
        ) {
          nObj.Create_State__c = 1;
        }
        nObj.FSD_Is_Optional__c = nObj.FSD_Is_Optional_F__c;
        // 办事处在分配中强制设为true时，不从FSD拷贝
        if (
          nObj.RA_RecordTypeId__c.substring(0, 15) !=
          agencyRecordTypeId.substring(0, 15) || !nObj.FSD_Is_OneToOne__c
        ) {
          nObj.FSD_Is_OneToOne__c = nObj.FSD_Is_OneToOne_F__c;
        }
        nObj.FSD_Name_CHN__c = nObj.Fixture_Name_F__c;
        nObj.FSD_OneToOneAccessory_Cnt__c = nObj.FSD_OneToOneAccessory_Cnt_F__c;
        nObj.FSD_Fixture_Model_No__c = nObj.Fixture_Model_No_F__c;
        if (
          nObj.DataMigration_Flag__c == false &&
          (!Trigger.isUpdate || String.isNotBlank(nObj.Fixture_Set_Id__c))
        ) {
          nObj.Fixture_Model_No_text__c = nObj.Fixture_Model_No_F__c;
        }
        nObj.CreatedBy_ProfileId__c = UserInfo.getProfileId();
        //              nObj.ApplyPersonAppended__c = nObj.ApplyPersonAppended_F__c;
      }
      if (
        nObj.DeliverySlip__c != null &&
        nObj.DataMigration_Flag__c == false &&
        (!Trigger.isUpdate || String.isNotBlank(nObj.Fixture_Set_Id__c))
      ) {
        if (nObj.Shippment_loaner_time__c == null) {
          nObj.Shippment_loaner_time__c = nObj.Shippment_loaner_time2__c;
        }
      }
      nObj.DeliverySlip_Text__c = nObj.DeliverySlip__c;
      nObj.Return_DeliverySlip_Text__c = nObj.Return_DeliverySlip__c;
      nObj.Received_Confirm_Text__c = nObj.Received_Confirm_F__c;
      //备品发货报错对应 20230413 by lc Start
      nObj.Detail_Not_Finish_Text__c = !nObj.Detail_Finish__c;
      //备品发货报错对应 20230413 by lc End
      Rental_Apply_Equipment_Set_Detail__c oObj = null;
      if (Trigger.isUpdate) {
        oObj = oldMap.get(nObj.Id);
        //出库前检查NGの場合キャンセルします
        if (
          oObj.Inspection_result__c != 'NG' &&
          nObj.Inspection_result__c == 'NG'
        ) {
          nObj.Cancel_Select__c = true;
          nObj.Loaner_cancel_reason__c = '其他'; // 20210830 ljh SFDC-C448KZ add
          nObj.Cancel_Reason__c = '重新分配';
          nObj.Loaner_cancel_Remarks__c = '出库前检查NG';
        }
        // OLY_OCM-435対応 start
        // 备品性能优化改修 20230312 by lc Start
        //String userid = UserInfo.getUserId();
        // 备品性能优化改修 20230312 by lc End
        DateTime now = System.now();
        if (
          oObj.Inspection_result__c != nObj.Inspection_result__c &&
          String.isNotBlank(nObj.Inspection_result__c)
        ) {
          nObj.Pre_inspection_time__c = now;
          //20210428 ljh 1719 update start
          //nObj.Inspection_staff__c = userid;
          nObj.Inspection_staff__c = nObj.RA_RecordTypeId__c ==
            Schema.SObjectType.Rental_Apply__c.getRecordTypeInfosByDeveloperName()
              .get('AgencyRequest')
              .getRecordTypeId()
            ? null
            : userid;
          //20210428 ljh 1719 update start
        }

        if (
          oObj.Check_lost_Item_Final__c != nObj.Check_lost_Item_Final__c &&
          String.isNotBlank(nObj.Check_lost_Item_Final__c)
        ) {
          nObj.Lost_item_check_time_Final__c = now;
          nObj.Lost_item_check_staff_Final__c = userid;
        }

        if (
          oObj.Check_lost_Item__c != nObj.Check_lost_Item__c &&
          String.isNotBlank(nObj.Check_lost_Item__c)
        ) {
          nObj.Lost_item_check_time__c = now;
          nObj.Lost_item_check_staff__c = userid;
        }

        if (
          oObj.CDS_complete__c != nObj.CDS_complete__c && nObj.CDS_complete__c
        ) {
          nObj.CDS_complete_time__c = now;
          nObj.CDS_staff__c = userid;
        }

        if (
          oObj.Inspection_result_after_Final__c !=
          nObj.Inspection_result_after_Final__c &&
          String.isNotBlank(nObj.Inspection_result_after_Final__c)
        ) {
          nObj.After_Inspection_time_Final__c = now;
          nObj.Inspection_staff_After_Final__c = userid;
        }

        if (
          oObj.Inspection_result_after__c != nObj.Inspection_result_after__c &&
          String.isNotBlank(nObj.Inspection_result_after__c)
        ) {
          // 检测结果更新了但时间没有手动更新，则更新时间
          // 如果手动更新了时间，就不用再更新
          if (oObj.After_Inspection_time__c == nObj.After_Inspection_time__c) {
            nObj.After_Inspection_time__c = now;
          }
          //20210716 ljh 1719 update start
          //nObj.Inspection_staff_After__c = userid;
          nObj.Inspection_staff_After__c = nObj.RA_RecordTypeId__c ==
            Schema.SObjectType.Rental_Apply__c.getRecordTypeInfosByDeveloperName()
              .get('AgencyRequest')
              .getRecordTypeId()
            ? null
            : userid;
          //20210716 ljh 1719 update start
        }
        // OLY_OCM-435対応 end
        if (nObj.Detail_Finish__c) {
          nObj.RAESD_Status_Text__c = nObj.Id;
        } else {
          nObj.RAESD_Status_Text__c = nObj.RAESD_Status__c;
        }
      }
      Rental_Apply_Equipment_Set__c raes = raesdMap.get(
        nObj.Rental_Apply_Equipment_Set__c
      );
      //画面显示用clone出来的数据不需要设置Name
      //IndexFromUniqueKey__c.format()会报错 要判不是Null
      if (
        nObj.DataMigration_Flag__c == false &&
        raes != null &&
        String.isNotBlank(raes.Fixture_Set__r.Name) &&
        raes.IndexFromUniqueKey__c != null &&
        nObj.IndexFromUniqueKey__c != null &&
        (!Trigger.isUpdate || String.isNotBlank(nObj.Fixture_Set_Id__c))
      ) {
        String split_ApplyNum = nObj.RequestNoJoinStr2__c;
        if (nObj.Rental_Apply_r_Name__c.contains('_')) {
          // XXXX-YYYY_1 (ZZZZ_1)
          List<String> split_ApplyNumList = nObj.Rental_Apply_r_Name__c.split(
            '_'
          );
          String raName = split_ApplyNumList[split_ApplyNumList.size() - 2]; // XXXX-YYYY (ZZZZ)
          split_ApplyNum = split_ApplyNumList[split_ApplyNumList.size() - 1]; // 1
          split_ApplyNumList = raName.split('-'); // [XXXX, YYYY]  ([ZZZZ])
          if (split_ApplyNumList.size() > 1) {
            // YYYY_1
            split_ApplyNum =
              split_ApplyNumList[split_ApplyNumList.size() - 1] +
              '_' +
              split_ApplyNum;
          } else {
            // ZZZZ_1
            split_ApplyNum = nObj.Rental_Apply_r_Name__c;
          }
        }
        nObj.Name =
          split_ApplyNum +
          ':' +
          raes.Fixture_Set__r.Name +
          ':' +
          raes.IndexFromUniqueKey__c.format().leftpad(3, '0');

        // 如果是分配代替品名字加:Sub
        if (nObj.Substitute_Select_Again__c) {
          nObj.Name += ':Sub';
        }

        //一览时申请者收货NG的话名字添加NG
        if (nObj.Received_Confirm_F__c == 'NG') {
          nObj.Name += ':NG';
        }
        nObj.Name +=
          ':' +
          nObj.IndexFromUniqueKey_Text__c +
          ':' +
          nObj.IndexFromUniqueKey__c.format().leftpad(3, '0');
        //取消的时候名字加Canceled
        if (nObj.Cancel_Select__c) {
          nObj.Name += ':Canceled';
        }
      }
      nObj.Loaner_accsessary__c = nObj.Loaner_accsessary_F__c;
      nObj.Loaner_centre_mail_address__c = nObj.Loaner_centre_mail_address_F__c;
      // 20220117 ljh add start
      // 更新排队预计 公式拷文本
      if (
        Trigger.isUpdate &&
        String.isBlank(nObj.Asset__c) == false &&
        oObj.Asset__c != nObj.Asset__c
      ) {
        nObj.UQueueShippmentDateText__c = nObj.UQueueShippmentDate__c;
      }
      // 20220117 ljh add end
      // 分配时, 设值
      if (
        String.isBlank(nObj.Asset__c) == false &&
        nObj.Select_Time__c != null &&
        (Trigger.isInsert ||
        (oObj.Asset__c != nObj.Asset__c ||
        oObj.Select_Time__c != nObj.Select_Time__c))
      ) {
        // 一对一保管主体（借出时）
        // nObj.Main_OneToOne_FlagInt__c = nObj.Main_OneToOne_FlagInt__c;
        if (
          nObj.DataMigration_Flag__c == false &&
          (!Trigger.isUpdate || String.isNotBlank(nObj.Fixture_Set_Id__c))
        ) {
          // 备品配套明细型号(借出时)
          if (String.isBlank(nObj.Fixture_Model_No_F__c)) {
            nObj.addError(
              '分配的Asset:' + nObj.Asset__c + ', 没有设定 备品配套明细型号'
            );
          } else {
            nObj.Fixture_Model_No_text__c = nObj.Fixture_Model_No_F__c;
          }
        }
        // 机身编号（借出时）
        nObj.SerialNumber_text__c = nObj.SerialNumber__c;
        // 所在地区(省) 借出时 #OLY_OCM-654:因为是赋值所以不修改
        nObj.SalesProvince_before__c = nObj.SalesProvince__c;
        // 所在地区(本部) 借出时 #OLY_OCM-654:因为是赋值所以不修改
        nObj.Salesdepartment_before__c = nObj.Salesdepartment__c;
        // 产品分类(GI/SP)(借出时) #OLY_OCM-654:因为是赋值所以不修改
        nObj.Product_category_text__c = nObj.Product_category_F__c;
        // 备品分类(借出时) #OLY_OCM-654:因为是赋值所以不修改
        nObj.Equipment_Type_text__c = nObj.Equipment_Type_F__c;
        // 备品成本(借出时)
        nObj.Asset_cost_del_before__c = nObj.Asset_cost_del__c;
        // 备品存放地(借出时)
        nObj.Internal_asset_location_before__c = nObj.Internal_asset_location__c;
        //备品名称(借出时)
        nObj.Fixture_Name_text__c = nObj.Fixture_Name_F__c;
        // OLY_OCM-243 追加字段对应 备品管理编码(借出时)
        nObj.EquipmentSet_Managment_Code_text__c = nObj.EquipmentSet_Managment_Code__c;
        // OLY_OCM-452 追加字段对应 刀头(借出时)
        if (String.isNotBlank(nObj.Fixture_Set_Detail__c)) {
          nObj.Is_Special_Product_Text__c = nObj.Is_Special_Product__c;
        }
      }
      // 排队时, 要注意 设值 移动到排队btn里
      else if (
        Trigger.isUpdate &&
        String.isBlank(nObj.Asset__c) &&
        oObj.Cancel_Select__c == false &&
        // && oObj.Fixture_Model_No_text__c != nObj.Fixture_Model_No_text__c
        (oObj.Queue_Number__c == 0 ||
        oObj.Queue_Number__c == null) &&
        nObj.Queue_Number__c > 0
      ) {
        // 排队时重新赋值Fixture_Model_No_text__c 为了排的不是旧Model_No
        nObj.FSD_Fixture_Model_No__c = nObj.Fixture_Model_No_F__c;
        // 备品配套明细型号(借出时)
        // nObj.Fixture_Model_No_text__c = nObj.Fixture_Model_No_F__c;
        // 所在地区(省) 借出时
        //nObj.SalesProvince_before__c = nObj.SalesProvince__c;
        // // 所在地区(本部) 借出时
        // nObj.Salesdepartment_before__c = nObj.Salesdepartment__c;
        // // 产品分类(GI/SP)(借出时)
        // nObj.Product_category_text__c = nObj.Product_category_F__c;
        // // 备品分类(借出时)
        // nObj.Equipment_Type_text__c = nObj.Equipment_Type__c;
        // // 备品存放地(借出时)
        // nObj.Internal_asset_location_before__c = nObj.Internal_asset_location__c;
      }
      // 其他时候(申请时), null设值 和
      // 一对一已分配的附属品,主体重新排队时,一对一附属品需要重新按照申请的逻辑重新赋值
      else if (
        (Trigger.isInsert && nObj.Cancel_Select__c == false) ||
        (Trigger.isUpdate &&
        String.isBlank(nObj.Asset__c) &&
        oObj.Cancel_Select__c == false)
      ) {
        // 备品配套明细型号(借出时)
        if (
          String.isBlank(nObj.Fixture_Model_No_text__c) &&
          nObj.DataMigration_Flag__c == false &&
          (!Trigger.isUpdate || String.isNotBlank(nObj.Fixture_Set_Id__c))
        ) {
          nObj.Fixture_Model_No_text__c = nObj.Fixture_Model_No_F__c;
        }
        // 所在地区(省) 借出时 #OLY_OCM-654:因为是赋值所以不修改
        if (String.isBlank(nObj.SalesProvince_before__c)) {
          nObj.SalesProvince_before__c = nObj.SalesProvince__c;
        }
        // 所在地区(本部) 借出时 #OLY_OCM-654:因为是赋值所以不修改
        if (String.isBlank(nObj.Salesdepartment_before__c)) {
          nObj.Salesdepartment_before__c = nObj.Salesdepartment__c;
        }
        // 产品分类(GI/SP)(借出时) #OLY_OCM-654:因为是赋值所以不修改
        if (String.isBlank(nObj.Product_category_text__c)) {
          nObj.Product_category_text__c = nObj.Product_category_F__c;
        }
        // 备品分类(借出时) #OLY_OCM-654:因为是赋值所以不修改
        if (String.isBlank(nObj.Equipment_Type_text__c)) {
          nObj.Equipment_Type_text__c = nObj.Equipment_Type__c;
        }
        // 备品存放地
        if (String.isBlank(nObj.Internal_asset_location_before__c)) {
          nObj.Internal_asset_location_before__c = nObj.Internal_asset_location__c;
        }
        // 备品名称(借出时)
        if (String.isBlank(nObj.Fixture_Name_text__c)) {
          nObj.Fixture_Name_text__c = nObj.Fixture_Name_F__c;
        }
        // OLY_OCM-243 追加字段对应 备品管理编码(借出时)
        if (String.isBlank(nObj.EquipmentSet_Managment_Code_text__c)) {
          nObj.EquipmentSet_Managment_Code_text__c = nObj.EquipmentSet_Managment_Code__c;
        }
        // OLY_OCM-452 追加字段对应 刀头(借出时)
        if (String.isBlank(nObj.Is_Special_Product_Text__c)) {
          nObj.Is_Special_Product_Text__c = nObj.Is_Special_Product__c;
        }
      } else {
        // 取消的情况在下面有设值
      }
      if (
        nObj.DataMigration_Flag__c == false &&
        nObj.Cancel_Select__c == false &&
        (!Trigger.isUpdate || String.isNotBlank(nObj.Fixture_Set_Id__c))
      ) {
        if (String.isBlank(nObj.Fixture_Model_No_text__c)) {
          nObj.addError(
            nObj.Id +
              ':备品配套明细型号不能为空, 备品配套明细=' +
              nObj.Fixture_Set_Detail__c
          );
        }

        // #OLY_OCM-654 数量管理的话,所在地区(本部)&产品分类&备品分类的判断不需要 Start
        if ('数量管理' == nObj.Manage_type_F__c) {
          // || false == nObj.Loaner_accsessary__c TODO: 需确认
          if (String.isBlank(nObj.Internal_asset_location_before__c)) {
            nObj.addError('备品存放地不能为空');
          }
        } else {
          // #OLY_OCM-654 数量管理的话,所在地区(本部)&产品分类&备品分类的判断不需要 end
          if (String.isBlank(nObj.Salesdepartment_before__c)) {
            nObj.addError('所在地区(本部)不能为空');
          }
          if (String.isBlank(nObj.Internal_asset_location_before__c)) {
            nObj.addError('备品存放地不能为空');
          }
          if (
            String.isBlank(nObj.Product_category_text__c) && nObj.Is_Body__c
          ) {
            nObj.addError('产品分类(GI/SP)不能为空');
          }
          if (
            String.isBlank(nObj.Equipment_Type_text__c) &&
            nObj.Is_Body__c &&
            nObj.Demo_purpose1__c != '其他'
          ) {
            nObj.addError('备品分类不能为空');
          }
          // if (String.isBlank(nObj.SalesProvince_before__c) && nObj.Is_Body__c) {
          //     nObj.addError('所在地区(省)不能为空');
          // }
        }
      }
      if (
        nObj.DataMigration_Flag__c == false &&
        String.isNotBlank(nObj.FSD_Id__c) &&
        (!Trigger.isUpdate || String.isNotBlank(nObj.Fixture_Set_Id__c))
      ) {
        //出库指示更新明细的key
        nObj.UniqueKey__c =
          nObj.RequestNoJoinStr2__c +
          ':' +
          nObj.Rental_Apply_Equipment_Set__c +
          ':' +
          nObj.FSD_Id__c +
          ':' +
          nObj.IndexFromUniqueKey__c;
        if (nObj.Cancel_Select__c) {
          nObj.UniqueKey__c += nObj.Id;
          // 下架后的取消加;
          if (nObj.StockDown__c) {
            nObj.UniqueKey__c += ';' + nObj.Id;
          }
          // nObj.Queue_Number__c = null;
          if (
            nObj.StockDown__c &&
            nObj.Inspection_result__c != 'NG' &&
            String.isBlank(nObj.DeliverySlip__c)
          ) {
            nObj.OnStock_By_Cancel__c = true;
            //                      nObj.Inspection_result_after_Flag_Text__c = 'true';
          }
        }
      }
      System.debug(nObj.IndexFromUniqueKey__c + 'key is' + nObj.UniqueKey__c);
      // 取消分配
      //Action 18 によってキャンセルの場合
      //借出备品Set一览明细.保有设备(Link)
      //借出备品Set一览明细.分配时间
      //借出备品Set一览明细.已做出库指示
      //借出备品Set一览明细.出库指示时间
      if (Trigger.isInsert || oObj.Cancel_Select__c != nObj.Cancel_Select__c) {
        if (nObj.Cancel_Select__c) {
          nObj.Cancel_Date__c = System.today();
          nObj.Cancel_Time__c = MainFixtureSelectController.getCurrentTime();
          nObj.Cancel_Mem__c = UserInfo.getUserId();
          if (nObj.AgencyTempCancel__c) {
            if (nObj.AgencyTempCancelTime__c != null) {
              Datetime dt = nObj.AgencyTempCancelTime__c;
              nObj.Cancel_Time__c = Time.newInstance(
                dt.hour(),
                dt.minute(),
                dt.second(),
                dt.millisecond()
              );
              nObj.Cancel_Date__c = Date.newinstance(
                dt.year(),
                dt.month(),
                dt.day()
              );
            }
          }
          nObj.AgencyTempCancel__c = false; // 真取消时把临时取消标记清掉
          nObj.AgencyTempCancelTime__c = null;
          if (nObj.StockDown__c == false) {
            nObj.Asset__c = null;
            nObj.Select_Time__c = null;
            nObj.Shipment_request_time2__c = null;
            nObj.Shipment_request__c = false;
            // 根据OLY_OCM-243记载,取消也需要清除接借出时相关的字段
            if (
              nObj.DataMigration_Flag__c == false &&
              (!Trigger.isUpdate || String.isNotBlank(nObj.Fixture_Set_Id__c))
            ) {
              // 备品配套明细型号(借出时)
              nObj.Fixture_Model_No_text__c = nObj.FSD_Fixture_Model_No__c;
            }
            // 机身编号（借出时）
            nObj.SerialNumber_text__c = null;
            // 所在地区(省) 借出时 #OLY_OCM-654:因为是赋值所以不修改
            nObj.SalesProvince_before__c = null;
            // 所在地区(本部) 借出时 #OLY_OCM-654:因为是赋值所以不修改
            nObj.Salesdepartment_before__c = null;
            // 产品分类(GI/SP)(借出时) #OLY_OCM-654:因为是赋值所以不修改
            nObj.Product_category_text__c = null;
            // 备品分类(借出时) #OLY_OCM-654:因为是赋值所以不修改
            nObj.Equipment_Type_text__c = null;
            // 备品成本(借出时)
            nObj.Asset_cost_del_before__c = null;
            // 备品存放地(借出时)
            nObj.Internal_asset_location_before__c = null;
            //备品名称(借出时)
            nObj.Fixture_Name_text__c = nObj.FSD_Name_CHN__c;
            // 备品管理编码(借出时)
            nObj.EquipmentSet_Managment_Code_text__c = null;
          }
          //20201118 ljh add
          else {
            String ra_RecordTypeId = DEVELOPERNAMEMAP.get('AgencyRequest')
              .getRecordTypeId();
            //System.debug('ra_RecordTypeId:'+ra_RecordTypeId);
            if (
              ra_RecordTypeId != null &&
              nObj.RA_RecordTypeId__c.substring(0, 15) ==
              ra_RecordTypeId.substring(0, 15)
            ) {
              //nObj.Inspection_result__c = 'OK';
              nObj.Inspection_result_NG__c = null;
              nObj.Arrival_in_wh__c = true;
              nObj.Arrival_wh_time__c = System.now();
              nObj.Return_wh_chenk_staff__c = Userinfo.getUserId();
              nObj.Arrival_wh_Result_Agency__c = 'OK';
            }
          }
          //20201118 ljh add
        } else {
          nObj.Cancel_Date__c = null;
          nObj.Cancel_Time__c = null;
          nObj.Cancel_Mem__c = null;
          //nObj.Cancel_Reason__c = null;
        }
      }
      // 归还后CDS
      if (Trigger.isInsert || oObj.CDS_complete__c != nObj.CDS_complete__c) {
        if (nObj.CDS_complete__c) {
          nObj.CDS_complete_time__c = System.now();
          nObj.CDS_staff__c = UserInfo.getUserId();
        } else {
          nObj.CDS_complete_time__c = null;
          nObj.CDS_staff__c = null;
        }
      }
      System.debug(nObj.Return_Status_F__c);
      // 必ず最後で置く
      //効かないの場合がありますのでAfterでやります
      // nObj.Repair_Status_Text__c = nObj.Repair_Status_F__c;
      // nObj.Return_Status_Text__c = nObj.Return_Status_F__c;
      // nObj.Shipment_Status_Text__c = nObj.Shipment_Status_F__c;
      nObj.Canceled_Id__c = nObj.Canceled__c;
      if (
        Trigger.isUpdate &&
        ((oObj.Inspection_result_after_Final__c != 'NG' &&
        nObj.Inspection_result_after_Final__c == 'NG' &&
        nObj.Inspection_result_after_NG_Final__c == '维修') ||
        (oObj.Inspection_result_after__c != 'NG' &&
        nObj.Inspection_result_after__c == 'NG' &&
        nObj.Inspection_result_after_NG__c == '维修'))
      ) {
        nObj.Repair__c = null;
      }

      // OLY_OCM-531 Start 搬工作流规则
      if (
        nObj.Check_lost_Item_F__c == '欠品' &&
        nObj.Loaner_Giveup_Time__c == null &&
        nObj.Lost_item_giveup__c == true
      ) {
        nObj.Loaner_Giveup_Time__c = Datetime.now();
      }

      if (nObj.RAESD_Status__c == '排队中' && nObj.Queue_Day_Text__c == null) {
        nObj.Queue_Day_Text__c = nObj.Queue_Day__c;
        nObj.Queue_Time_Text__c = nObj.Queue_Time__c;
      }

      // OLY_OCM-531 End
      if (
        Trigger.isUpdate &&
        oObj.Confirm_Lost_Date__c != null &&
        oObj.Check_lost_Item_F__c != nObj.Check_lost_Item_F__c &&
        oObj.Check_lost_Item_F__c == '欠品'
      ) {
        nObj.Confirm_Lost_Date__c = null;
      }

      if (
        Trigger.isUpdate &&
        oObj.Shipment_request_time2__c != nObj.Shipment_request_time2__c &&
        nObj.Shipment_request_time2__c != null &&
        nObj.Is_Body__c &&
        shipment_requestedRaIdStaticSet.contains(nObj.Rental_Apply__c) == false
      ) {
        shipment_requestedRaIdStaticSet.add(nObj.Rental_Apply__c);
        shipment_requestedRaIdSet.add(nObj.Rental_Apply__c);
      }
    }
  }
  /*
   * Asset のQuantity更新
   * changeAssetCount()方法でOut_of_wh__c、Rental_Count__c 减1
   */
  private void changeAsset() {
    if (Trigger.isUpdate && Trigger.isAfter) {
      if (assMap.isEmpty()) {
        return;
      }
      for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
        if (!assMap.containsKey(nObj.Asset__c)) {
          continue;
        }
        Rental_Apply_Equipment_Set_Detail__c oObj = null;
        if (Trigger.isUpdate) {
          oObj = oldMap.get(nObj.Id);
        }
        Asset ass = assMap.get(nObj.Asset__c);
        // Abandoned_Inventory__c  null -> 0
        if (ass.Abandoned_Inventory__c == null) {
          ass.Abandoned_Inventory__c = 0;
        }
        // Abandoned_RealThing__c  null -> 0
        if (ass.Abandoned_RealThing__c == null) {
          ass.Abandoned_RealThing__c = 0;
        }
        if (ass.CountForRepair__c == null) {
          ass.CountForRepair__c = 0;
        }

        if (ass.Confirm_Lost_Count__c == null) {
          ass.Confirm_Lost_Count__c = 0;
        }
        if (
          String.isBlank(oObj.Check_lost_Item_F__c) &&
          nObj.Check_lost_Item_F__c == 'OK'
        ) {
          //未入力から欠品に変更時何もしません
        } else if (
          String.isBlank(oObj.Check_lost_Item_F__c) &&
          nObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Lost_item_giveup__c == false
        ) {
          //未入力から欠品に変更時何もしません
        } else if (
          String.isBlank(oObj.Check_lost_Item_F__c) &&
          nObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Lost_item_giveup__c == true
        ) {
          //未入力から欠品放棄に変更時 放弃欠品回收（丢失）のとき 待废弃数(丢失/盘亏)加1
          ass.Abandoned_Inventory__c += 1;
          if (oObj.Confirm_Lost_Date__c != null) {
            ass.Confirm_Lost_Count__c -= 1;
          }
          assUpdMap.put(ass.Id, ass);
        } else if (
          String.isBlank(oObj.Check_lost_Item_F__c) &&
          nObj.Check_lost_Item_F__c == '消耗'
        ) {
          //未入力から消耗に変更時Quantityを-1
          ass.Quantity -= 1;
          ass.ChangeQuantityReason__c = '消耗';
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == 'OK' &&
          String.isBlank(nObj.Check_lost_Item_F__c)
        ) {
          //OKから空白に変更時何もしません
        } else if (
          oObj.Check_lost_Item_F__c == 'OK' &&
          nObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Lost_item_giveup__c == false
        ) {
          //OKから欠品に変更時何もしません
        } else if (
          oObj.Check_lost_Item_F__c == 'OK' &&
          nObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Lost_item_giveup__c == true
        ) {
          //OKから欠品放棄に変更時 放弃欠品回收（丢失）のとき 待废弃数(丢失/盘亏)加1
          ass.Abandoned_Inventory__c += 1;
          if (oObj.Confirm_Lost_Date__c != null) {
            ass.Confirm_Lost_Count__c -= 1;
          }
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == 'OK' &&
          nObj.Check_lost_Item_F__c == '消耗'
        ) {
          //OKから消耗に変更時Quantityを-1
          ass.Quantity -= 1;
          ass.ChangeQuantityReason__c = '消耗';
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == '欠品' &&
          String.isBlank(nObj.Check_lost_Item_F__c) &&
          oObj.Lost_item_giveup__c == false
        ) {
          if (oObj.Confirm_Lost_Date__c != null) {
            ass.Confirm_Lost_Count__c -= 1;
          }
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Check_lost_Item_F__c == 'OK' &&
          oObj.Lost_item_giveup__c == false
        ) {
          if (oObj.Confirm_Lost_Date__c != null) {
            ass.Confirm_Lost_Count__c -= 1;
          }
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Check_lost_Item_F__c == '欠品' &&
          oObj.Lost_item_giveup__c == false &&
          nObj.Lost_item_giveup__c == true
        ) {
          //欠品から欠品放棄に変更時 放弃欠品回收（丢失）のとき 待废弃数(丢失/盘亏)加1
          ass.Abandoned_Inventory__c += 1;
          if (oObj.Confirm_Lost_Date__c != null) {
            ass.Confirm_Lost_Count__c -= 1;
          }
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Check_lost_Item_F__c == '消耗' &&
          oObj.Lost_item_giveup__c == false
        ) {
          //欠品から消耗に変更時Quantityを-1
          ass.Quantity -= 1;
          ass.ChangeQuantityReason__c = '消耗';
          if (oObj.Confirm_Lost_Date__c != null) {
            ass.Confirm_Lost_Count__c -= 1;
          }
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == '欠品' &&
          String.isBlank(nObj.Check_lost_Item_F__c) &&
          oObj.Lost_item_giveup__c == true
        ) {
          //欠品放棄から空白に変更時 待废弃数(丢失/盘亏)减1
          ass.Abandoned_Inventory__c -= 1;
          ass.Out_of_wh__c += 1;
          ass.Rental_Count__c += 1;
          ass.ChangeQuantityReason__c = '欠品' + '->' + '';
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Check_lost_Item_F__c == 'OK' &&
          oObj.Lost_item_giveup__c == true
        ) {
          //欠品放棄からOKに変更時 待废弃数(丢失/盘亏)减1
          ass.Abandoned_Inventory__c -= 1;
          ass.Out_of_wh__c += 1;
          ass.Rental_Count__c += 1;
          ass.ChangeQuantityReason__c = '欠品' + '->' + 'OK';
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Check_lost_Item_F__c == '欠品' &&
          oObj.Lost_item_giveup__c == true &&
          nObj.Lost_item_giveup__c == false
        ) {
          //欠品放棄から欠品に変更時 待废弃数(丢失/盘亏)减1
          ass.Abandoned_Inventory__c -= 1;
          ass.Out_of_wh__c += 1;
          ass.Rental_Count__c += 1;
          ass.ChangeQuantityReason__c = '欠品放弃 -> ' + '欠品';
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Check_lost_Item_F__c == '消耗' &&
          oObj.Lost_item_giveup__c == true
        ) {
          //欠品放棄から消耗に変更時 待废弃数(丢失/盘亏)减1 Quantityを-1
          ass.Abandoned_Inventory__c -= 1;
          ass.Quantity -= 1;
        } else if (
          oObj.Check_lost_Item_F__c == '消耗' &&
          String.isBlank(nObj.Check_lost_Item_F__c)
        ) {
          //消耗から空白に変更時Quantityを+1
          ass.Quantity += 1;
          ass.Out_of_wh__c += 1;
          ass.Rental_Count__c += 1;
          ass.ChangeQuantityReason__c = '消耗 -> ' + '';
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == '消耗' &&
          nObj.Check_lost_Item_F__c == 'OK'
        ) {
          //消耗から空白に変更時Quantityを+1
          ass.Quantity += 1;
          ass.Out_of_wh__c += 1;
          ass.Rental_Count__c += 1;
          ass.ChangeQuantityReason__c = '消耗 -> ' + 'OK';
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == '消耗' &&
          nObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Lost_item_giveup__c == false
        ) {
          //消耗から欠品に変更時Quantityを+1
          ass.Quantity += 1;
          ass.Out_of_wh__c += 1;
          ass.Rental_Count__c += 1;
          ass.ChangeQuantityReason__c = '消耗 -> 欠品';
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Check_lost_Item_F__c == '消耗' &&
          nObj.Check_lost_Item_F__c == '欠品' &&
          nObj.Lost_item_giveup__c == true
        ) {
          //消耗から欠品放棄に変更時 待废弃数(丢失/盘亏)+1 Quantityを+1
          ass.Abandoned_Inventory__c += 1;
          ass.Quantity += 1;
        }
        // 维修
        if (
          oObj.Arrival_in_wh__c == false &&
          nObj.Arrival_in_wh__c == true &&
          nObj.Arrival_wh_Result_Agency__c == '待修理'
        ) {
          ass.CountForRepair__c += 1;
          assUpdMap.put(ass.Id, ass);
        }
        //废弃
        if (
          oObj.Arrival_in_wh__c == false &&
          nObj.Arrival_in_wh__c == true &&
          (nObj.Inspection_result_after_NG_F__c == '废弃' ||
          //出库前检测废弃的时候也需要判断
          nObj.Inspection_result_NG__c == '废弃')
        ) {
          ass.Abandoned_RealThing__c += 1;
          ass.ChangeQuantityReason__c = FixtureUtil.raesdStatusMap.get(
            FixtureUtil.HistoryStatus.Dai_Fei_Qi.ordinal()
          );
          assUpdMap.put(ass.Id, ass);
        } else if (
          oObj.Arrival_in_wh__c == true &&
          nObj.Arrival_in_wh__c == false &&
          (oObj.Inspection_result_after_NG_F__c == '废弃' ||
          //出库前检测废弃的时候也需要判断
          oObj.Inspection_result_NG__c == '废弃')
        ) {
          ass.Abandoned_RealThing__c -= 1;
          ass.Out_of_wh__c += 1;
          ass.Rental_Count__c += 1;
          // ass.Freeze_sign__c = true; // OLY_OCM-689 删除冻结字段的更新
          String rea = nObj.Inspection_result_after_NG_F__c == '废弃'
            ? '待移至报废区'
            : nObj.Inspection_result_after_NG_F__c;
          ass.ChangeQuantityReason__c =
            FixtureUtil.raesdStatusMap.get(
              FixtureUtil.HistoryStatus.Dai_Fei_Qi.ordinal()
            ) +
            ' ->' +
            rea;
          assUpdMap.put(ass.Id, ass);
        }
        //待废弃
        if (
          nObj.RAESD_Status__c ==
          FixtureUtil.raesdStatusMap.get(
            FixtureUtil.HistoryStatus.Dai_Fei_Qi.ordinal()
          ) &&
          oObj.RAESD_Status__c != nObj.RAESD_Status__c &&
          ass.Manage_type__c == '个体管理'
        ) {
          ass.Status = FixtureUtil.assetStatusMap.get(
            FixtureUtil.AssetStatus.Dai_Fei_Qi.ordinal()
          );
          // ass.Freeze_sign__c = true;
          assUpdMap.put(ass.Id, ass);
        }
        // 办事处回库结果修改
        if (
          oObj.Arrival_in_wh__c &&
          nObj.Arrival_in_wh__c &&
          oObj.Arrival_wh_Result_Agency__c != nObj.Arrival_wh_Result_Agency__c
        ) {
          switch on oObj.Arrival_wh_Result_Agency__c {
            when '移至报废区' {
              ass.Abandoned_RealThing__c -= 1;
            }
            when '待修理' {
              ass.CountForRepair__c -= 1;
            }
          }
          switch on nObj.Arrival_wh_Result_Agency__c {
            when '移至报废区' {
              ass.Abandoned_RealThing__c += 1;
            }
            when '待修理' {
              ass.CountForRepair__c += 1;
            }
          }
          assUpdMap.put(ass.Id, ass);
        }
        // //已消耗
        // else if (nObj.Check_lost_Item_Final__c == '消耗'
        //         && oObj.Check_lost_Item_Final__c != nObj.Check_lost_Item_Final__c
        //         && ass.Manage_type__c == '个体管理') {
        //     ass.Status = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Xiao_Hao.ordinal());
        //     assUpdMap.put(ass.Id, ass);
        // }
        //丢失
        // else if (nObj.Lost_item_giveup__c == true
        //         && oObj.Lost_item_giveup__c != nObj.Lost_item_giveup__c
        //         && ass.Manage_type__c == '个体管理') {
        // ass.Status = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Diu_Shi.ordinal());
        // assUpdMap.put(ass.Id, ass);
        // }
        // else if (ass.Manage_type__c == '数量管理' && assMap.containsKey(ass.Id)) {
        //     if (ass.Quantity != null && ass.Quantity > 0) {
        //         if (ass.Status != FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal())) {
        //             ass.Status = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal());
        //             assUpdMap.put(ass.Id, ass);
        //         }
        //     }
        //     else {
        //         if (ass.Status != FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal())) {
        //             ass.Status = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal());
        //             assUpdMap.put(ass.Id, ass);
        //         }
        //     }
        // }
      }
    }
  }
  /*
   * 回库确认 OFF -> ON:
   * 取消分配 OFF -> ON:
   * 放弃欠品 OFF -> ON
   * 已消耗
   *
   *  清空Asset 最新备品申请借出明细 Last_Reserve_RAES_Detail__c
   *  (nObj.Asset__c 変更しないため、changeAssetLast()でクリアできないため、ここでクリア)
   *
   * クラスの assUpdMap を更新するだけ
   */
  private void clearLastReserveRAESD() {
    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
      // 主体和附属品
      if (finishOrChangeAsset(Trigger.isDelete, oObj, nObj)) {
        Asset ass = assMap.get(nObj.Asset__c);
        if (assUpdMap.containsKey(nObj.Asset__c)) {
          ass = assUpdMap.get(nObj.Asset__c);
        }
        // 这里 会出现 assUpdMap 有 但是 assMap 没有的情况
        if (
          ass == null &&
          //分配备品有变化 (下架前)
          (oObj.Asset__c != null &&
          oObj.Asset__c != nObj.Asset__c &&
          nObj.StockDown__c == false)
        ) {
          ass = new Asset(Id = oObj.Asset__c);
        }
        if (ass == null) {
          continue;
        }
        // 暂时放在这里
        if (oObj.Manage_type_F__c == '个体管理') {
          ass.Last_Reserve_RAES_Detail__c = null;
          assUpdMap.put(ass.Id, ass);
        }
      }
    }
  }
  //nObj.Asset__cがある場合、変更した場合
  private void changeAssetLast() {
    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
      Asset nass = assMap.get(nObj.Asset__c);
      if (assUpdMap.containsKey(nObj.Asset__c)) {
        nass = assUpdMap.get(nObj.Asset__c);
      } else if (String.isNotBlank(nObj.Asset__c)) {
        nass = new Asset(Id = nObj.Asset__c);
      }
      Asset oass = assMap.get(oObj.Asset__c);
      if (assUpdMap.containsKey(oObj.Asset__c)) {
        oass = assUpdMap.get(oObj.Asset__c);
      } else if (String.isNotBlank(oObj.Asset__c)) {
        oass = new Asset(Id = oObj.Asset__c);
      }
      //nObj.Asset__cがある場合、変更した場合
      if (
        nObj.Asset__c != null &&
        oObj.Asset__c != nObj.Asset__c &&
        (oObj.Manage_type_F__c == '个体管理' ||
        nObj.Manage_type_F__c == '个体管理')
      ) {
        if (nObj.Manage_type_F__c == '个体管理') {
          nass.Last_Reserve_RAES_Detail__c = nObj.Id;
          assUpdMap.put(nass.Id, nass);
        }
        if (oObj.Manage_type_F__c == '个体管理') {
          oass.Last_Reserve_RAES_Detail__c = null;
          assUpdMap.put(oass.Id, oass);
        }
      }
    }
  }
  // 取消分配 的时候, 需要在 beforeSetValue() 里把 Asset__c 清除
  //明細終了とAsset変更の時Out_of_wh__cを更新
  //afterupdateのみ実行
  private void changeAssetCount() {
    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
      Asset nass = assMap.get(nObj.Asset__c);
      if (assUpdMap.containsKey(nObj.Asset__c)) {
        nass = assUpdMap.get(nObj.Asset__c);
      } else if (String.isNotBlank(nObj.Asset__c)) {
        nass = new Asset(Id = nObj.Asset__c);
      }
      Asset oass = assMap.get(oObj.Asset__c);
      if (assUpdMap.containsKey(oObj.Asset__c)) {
        oass = assUpdMap.get(oObj.Asset__c);
      } else if (String.isNotBlank(oObj.Asset__c)) {
        oass = new Asset(Id = oObj.Asset__c);
      }
      //MapにAssetを新規push時値を設定
      if (
        oass != null &&
        (oass.Out_of_wh__c == null ||
        oass.Rental_Count__c == null ||
        oass.Confirm_Lost_Count__c == null)
      ) {
        oass.Out_of_wh__c = oObj.Out_of_wh__c;
        oass.Rental_Count__c = oObj.Rental_Count__c;
        oass.Confirm_Lost_Count__c = oObj.Confirm_Lost_Count__c;
      }
      if (
        nass != null &&
        (nass.Out_of_wh__c == null ||
        nass.Rental_Count__c == null ||
        nass.Confirm_Lost_Count__c == null)
      ) {
        nass.Out_of_wh__c = nObj.Out_of_wh__c;
        nass.Rental_Count__c = nObj.Rental_Count__c;
        nass.Confirm_Lost_Count__c = nObj.Confirm_Lost_Count__c;
      }
      // 最終状態及とAsset変更の場合
      if (finishOrChangeAsset(Trigger.isDelete, oObj, nObj)) {
        System.debug('oass is ' + oass);
        if (oass != null) {
          if (oass.Out_of_wh__c != null && oass.Out_of_wh__c > 0) {
            oass.Out_of_wh__c = oass.Out_of_wh__c - 1;
            // assUpdMap.put(oass.Id, oass);
            System.debug(
              'oass.Out_of_wh__c -1' + oass.Out_of_wh__c + ' Id = ' + nObj.Id
            );
          }
          if (nObj.DeliverySlip__c != null) {
            if (oass.Rental_Count__c != null && oass.Rental_Count__c > 0) {
              oass.Rental_Count__c = oass.Rental_Count__c - 1;
            }
          }
          assUpdMap.put(oass.Id, oass);
        }
      } else if (
        oass != null &&
        oObj.DeliverySlip__c != null &&
        nObj.DeliverySlip__c == null
      ) {
        //发货运输单 删除的时候已借出数 -1 发货Asset__c原则不会变所以就直接用上面的oass
        // if (nObj.DeliverySlip__c != null) {
        if (oass.Rental_Count__c != null && oass.Rental_Count__c > 0) {
          oass.Rental_Count__c = oass.Rental_Count__c - 1;
          assUpdMap.put(oass.Id, oass);
        }
        // }
      }
      if (
        oObj.Confirm_Lost_Date__c == null &&
        nObj.Confirm_Lost_Date__c != null
      ) {
        nass.Confirm_Lost_Count__c = nass.Confirm_Lost_Count__c + 1;
        assUpdMap.put(nass.Id, nass);
      } else if (
        nObj.Confirm_Lost_Date__c == null &&
        oObj.Confirm_Lost_Date__c != null &&
        nass.Confirm_Lost_Count__c > 0
      ) {
        nass.Confirm_Lost_Count__c = nass.Confirm_Lost_Count__c - 1;
        assUpdMap.put(nass.Id, nass);
      }
      //发货运输单设置的时候已解除数+1
      if (oObj.DeliverySlip__c == null && nObj.DeliverySlip__c != null) {
        nass.Rental_Count__c = nass.Rental_Count__c + 1;
        assUpdMap.put(nass.Id, nass);
      }
      //nObj.Asset__cがある場合、変更した場合
      System.debug(LoggingLevel.INFO, '*** nObj.Asset__c: ' + nObj.Asset__c);
      if (nObj.Asset__c != null && oObj.Asset__c != nObj.Asset__c) {
        nass.Out_of_wh__c = nass.Out_of_wh__c + 1;
        System.debug(
          'nass.Out_of_wh__c +1' + nass.Out_of_wh__c + ' Id = ' + nObj.Id
        );
        assUpdMap.put(nass.Id, nass);
      }
    }
  }
  // 同じblock の 排队レコード Queue_Number__c をrefresh
  // private void refreshQueueNumberByBlock() {
  //     for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
  //         Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
  //         // 同じblock に 排队変更がある場合
  //         if (oObj.Cancel_Select__c == false
  //                 && String.isBlank(oObj.Fixture_Model_No_text__c) == false
  //                 && String.isBlank(oObj.Salesdepartment_before__c) == false
  //                 && String.isBlank(oObj.Product_category_text__c) == false
  //                 && String.isBlank(oObj.Equipment_Type_text__c) == false
  //                 && oObj.Queue_Number__c > 0
  //                 // 変化を確認
  //                 && (oObj.Cancel_Select__c != nObj.Cancel_Select__c
  //                     || oObj.Fixture_Model_No_text__c != nObj.Fixture_Model_No_text__c
  //                     || oObj.Salesdepartment_before__c != nObj.Salesdepartment_before__c
  //                     || oObj.Product_category_text__c != nObj.Product_category_text__c
  //                     || oObj.Equipment_Type_text__c != nObj.Equipment_Type_text__c
  //                     || (nObj.Queue_Number__c == 0 || nObj.Queue_Number__c == null))
  //         ) {
  //             if (executeed_refreshQueueNumber.contains(nObj.Id) && executeed_refreshQueueNumber.contains(oObj.Id)) {
  //                 continue;
  //             }
  //             else if (executeed_refreshQueueNumber.contains(nObj.Id) == false) {
  //                 executeed_refreshQueueNumber.add(nObj.Id);
  //             } else {   //  executeed_refreshQueueNumber.contains(oObj.Id) == false
  //                 executeed_refreshQueueNumber.add(oObj.Id);
  //             }
  //             // TODO 想定 画面からの1 record しかない
  //             List<Rental_Apply_Equipment_Set_Detail__c> updateList = new List<Rental_Apply_Equipment_Set_Detail__c>();
  //             List<Rental_Apply_Equipment_Set_Detail__c> refreshTargetList = [
  //                     Select Id, Queue_Number__c
  //                       from Rental_Apply_Equipment_Set_Detail__c
  //                      where Cancel_Select__c = false
  //                        and Fixture_Model_No_text__c = :oObj.Fixture_Model_No_text__c
  //                        and Salesdepartment_before__c = :oObj.Salesdepartment_before__c
  //                        and Product_category_text__c = :oObj.Product_category_text__c
  //                        and Equipment_Type_text__c = :oObj.Equipment_Type_text__c
  //                        and Queue_Number__c > 0
  //                      Order by Queue_Number__c];
  //             for (Integer i = 0; i < refreshTargetList.size(); i++) {
  //                 Rental_Apply_Equipment_Set_Detail__c refreshTarget = refreshTargetList[i];
  //                 if (refreshTarget.Queue_Number__c != (i + 1)) {
  //                     refreshTarget.Queue_Number__c = i + 1;
  //                     executeed_refreshQueueNumber.add(refreshTarget.Id);
  //                     updateList.add(refreshTarget);
  //                 }
  //             }
  //             if (!updateList.isEmpty()) { update updateList; }
  //         }
  //     }
  // }

  // 4-XX 下架后, 出库前检测的Action一对一分配的话, 和主体一起 Cancel
  private void oneToOne4XX() {
    //主体CnacelSet
    Set<Id> raesdBodyCnacelSet = new Set<Id>();
    Set<Id> raesdBodyNGSet = new Set<Id>();
    //暂时只考虑主体NG或者取消的时候
    Map<Id, String> raesdCancel_Remarks = new Map<Id, String>();
    //检测NG或者本来就Cancel的不需要再更新
    Set<Id> raesdIdSet = new Set<Id>();
    String ra_RecordTypeId = DEVELOPERNAMEMAP.get('AgencyRequest')
      .getRecordTypeId();

    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      // 办事处附属品不需要随主体取消
      if (
        nObj.RA_RecordTypeId__c.substring(0, 15) ==
        ra_RecordTypeId.substring(0, 15)
      ) {
        continue;
      }
      Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
      //Set没有cancel的话都需要拷贝
      //主体出库前检测NG 维修
      if (
        nObj.Is_Body__c == true &&
        nObj.Inspection_result__c == 'NG' &&
        oObj.Inspection_result__c != nObj.Inspection_result__c &&
        nObj.Inspection_result_NG__c == '维修'
      ) {
        //需要重新分配一对一附属品的一览
        raesdBodyNGSet.add(nObj.Rental_Apply_Equipment_Set__c);
        raesdCancel_Remarks.put(
          nObj.Rental_Apply_Equipment_Set__c,
          nObj.Loaner_cancel_Remarks__c
        );
        raesdIdSet.add(nObj.Id);
      }
      //主体出库前检测NG 废弃
      else if (
        nObj.Is_Body__c == true &&
        nObj.Inspection_result__c == 'NG' &&
        oObj.Inspection_result__c != nObj.Inspection_result__c &&
        nObj.Inspection_result_NG__c == '废弃'
      ) {
        //需要重新分配一对一附属品的一览
        raesdBodyNGSet.add(nObj.Rental_Apply_Equipment_Set__c);
        raesdCancel_Remarks.put(
          nObj.Rental_Apply_Equipment_Set__c,
          nObj.Loaner_cancel_Remarks__c
        );
        raesdIdSet.add(nObj.Id);
      }
      //附属品出库前检测NG 维修 并且是一对一分配
      else if (
        nObj.Is_Body__c == false &&
        nObj.Inspection_result__c == 'NG' &&
        oObj.Inspection_result__c != nObj.Inspection_result__c &&
        nObj.Inspection_result_NG__c == '维修' &&
        nObj.OneToOne_Flag__c == true
      ) {
        raesdIdSet.add(nObj.Id);
      }
      //附属品出库前检测NG 废弃 并且是一对一分配
      else if (
        nObj.Is_Body__c == false &&
        nObj.Inspection_result__c == 'NG' &&
        oObj.Inspection_result__c != nObj.Inspection_result__c &&
        nObj.Inspection_result_NG__c == '废弃' &&
        nObj.OneToOne_Flag__c == true
      ) {
        raesdIdSet.add(nObj.Id);
      }
      //OLY_OCM-152 下架后主体取消的话一对一附属品也要一起取消
      else if (
        String.isBlank(nObj.DeliverySlip__c) &&
        nObj.Is_Body__c == true &&
        nObj.StockDown__c == true &&
        oObj.Cancel_Select__c == false &&
        nObj.Cancel_Select__c == true
      ) {
        raesdIdSet.add(nObj.Id);
        raesdBodyCnacelSet.add(nObj.Rental_Apply_Equipment_Set__c);
        raesdCancel_Remarks.put(
          nObj.Rental_Apply_Equipment_Set__c,
          nObj.Loaner_cancel_Remarks__c
        );
      }
    }
    if (raesdBodyNGSet.isEmpty() && raesdBodyCnacelSet.isEmpty()) {
      return;
    }
    List<Rental_Apply_Equipment_Set_Detail__c> raesds = [
      SELECT
        Id,
        UniqueKey__c,
        Rental_Apply_Equipment_Set__c,
        Rental_Apply__c,
        Fixture_Set_Detail__c,
        Cancel_Reason__c
      FROM Rental_Apply_Equipment_Set_Detail__c
      //主体出库前检测NG一览的所有一对一分配的明细
      WHERE
        (Rental_Apply_Equipment_Set__c = :raesdBodyNGSet
        //下架后主体取消一对一附属品也要一起取消
        OR Rental_Apply_Equipment_Set__c = :raesdBodyCnacelSet)
        AND OneToOne_Flag__c = TRUE
        //和主体一起检测NG的不再更新
        AND Id != :raesdIdSet
    ];
    List<Rental_Apply_Equipment_Set_Detail__c> raesdList = new List<Rental_Apply_Equipment_Set_Detail__c>();
    for (Rental_Apply_Equipment_Set_Detail__c raesd : raesds) {
      raesd.OnStock_By_Cancel__c = true;
      raesd.Cancel_Select__c = true;
      // OLY_OCM-163#comment-20120592 通过取消日判断 -》 更新的时候before设置
      //raesd.Cancel_Date__c = Date.today();
      raesd.Cancel_Reason__c = '重新分配';
      raesd.Loaner_cancel_reason__c = '其他'; // 20210830 ljh SFDC-C448KZ add
      //主体出库前检查NG的话取消备注回自动设置为出库前检查NG
      raesd.Loaner_cancel_Remarks__c = raesdCancel_Remarks.get(
        raesd.Rental_Apply_Equipment_Set__c
      );
      // }
      raesdList.add(raesd);
    }
    System.debug('raesdList size' + raesdList.size());
    if (!raesdList.isEmpty()) {
      update raesdList;
    }
  }

  //一览单位取消后的拷贝在一览的Handler里面做
  // 因为cancel是主体的话First应开始拷贝出来的主体所以First的更新逻辑移动到cancelcopy
  private void cancelCopy() {
    List<Rental_Apply_Equipment_Set_Detail__c> raesdList = new List<Rental_Apply_Equipment_Set_Detail__c>();
    List<Rental_Apply_Equipment_Set_Detail__c> raesdListup = new List<Rental_Apply_Equipment_Set_Detail__c>();
    Map<Id, Rental_Apply_Equipment_Set__c> raesMap = new Map<Id, Rental_Apply_Equipment_Set__c>();
    String ra_RecordTypeId = DEVELOPERNAMEMAP.get('AgencyRequest')
      .getRecordTypeId();
    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
      //Set没有cancel的话都需要拷贝
      //Cancel_Select__c はfalseからtrueに変更なのでなのでtrigger二回はしても実行するのは１回だけ
      if (
        nObj.Set_Cancel_Select__c == false &&
        (oObj.Cancel_Select__c == false &&
        nObj.Cancel_Select__c == true) &&
        nObj.StockDown__c == true &&
        nObj.Cancel_Reason__c == '重新分配' &&
        // 办事处取消时不要拷贝明细，在controller里手动造
        nObj.RA_RecordTypeId__c.substring(0, 15) !=
        ra_RecordTypeId.substring(0, 15)
      ) {
        Rental_Apply_Equipment_Set_Detail__c craesd = new Rental_Apply_Equipment_Set_Detail__c();
        craesd.Rental_Apply_Equipment_Set__c = nObj.Rental_Apply_Equipment_Set__c;
        craesd.Rental_Apply__c = nObj.Rental_Apply__c;
        craesd.Fixture_Set_Detail__c = nObj.Fixture_Set_Detail__c;
        craesd.Fixture_Model_No_text__c = nObj.FSD_Fixture_Model_No__c;
        craesd.Fixture_Name_text__c = nObj.FSD_Name_CHN__c;
        craesd.IndexFromUniqueKey_Text__c = nObj.IndexFromUniqueKey_Text__c;
        craesd.Canceled__c = nObj.Id;
        craesd.FSD_Id__c = nObj.FSD_Id__c;
        craesd.FSD_Is_Optional__c = nObj.FSD_Is_Optional_F__c;
        craesd.FSD_Is_OneToOne__c = nObj.FSD_Is_OneToOne_F__c;
        craesd.FSD_Name_CHN__c = nObj.FSD_Name_CHN__c;
        craesd.FSD_OneToOneAccessory_Cnt__c = nObj.FSD_OneToOneAccessory_Cnt_F__c;
        craesd.FSD_Fixture_Model_No__c = nObj.FSD_Fixture_Model_No__c;
        // 20211125 ljh add 排队插队 start
        if (nObj.Is_Body__c) {
          craesd.Allow_Adjust_Queue_Flag__c = true;
          craesd.jumpReason__c = '发货前检测NG重新分配';
        }
        // 20211125 ljh add 排队插队 end
        if (
          nObj.DataMigration_Flag__c == false &&
          (!Trigger.isUpdate || String.isNotBlank(nObj.Fixture_Set_Id__c))
        ) {
          craesd.Rental_Num__c = nObj.Rental_Num__c;
          craesd.IndexFromUniqueKey__c = nObj.IndexFromUniqueKey__c;
        }
        //cancel重新分配的不算追加附属品 272チケット
        craesd.Create_State__c = 0;
        raesdList.add(craesd);
      }
      // 如果是主体 cancel的话First应该是拷贝出来的主体
      if (
        (oObj.Cancel_Select__c == false &&
        nObj.Cancel_Select__c == true) &&
        nObj.Is_First_RAESD_F__c == true &&
        nObj.Set_Cancel_Select__c == false &&
        nObj.DataMigration_Flag__c == false &&
        (!Trigger.isUpdate || String.isNotBlank(nObj.Fixture_Set_Id__c))
      ) {
        Rental_Apply_Equipment_Set__c raes = new Rental_Apply_Equipment_Set__c(
          Id = nObj.Rental_Apply_Equipment_Set__c,
          First_RAESD__c = null
        );
        raesMap.put(nObj.Rental_Apply_Equipment_Set__c, raes);
      }
    }
    //没下架的字段清空在before里面做
    if (!raesdList.isEmpty()) {
      insert raesdList;
    }
    if (!raesMap.isEmpty()) {
      List<Rental_Apply_Equipment_Set_Detail__c> raess = [
        SELECT Id, Rental_Apply_Equipment_Set__c
        FROM Rental_Apply_Equipment_Set_Detail__c
        WHERE
          Rental_Apply_Equipment_Set__c = :raesMap.keySet()
          AND Cancel_Select__c = FALSE
        ORDER BY
          Rental_Apply_Equipment_Set__c,
          Fixture_Set_Detail__r.SortInt__c ASC NULLS LAST
      ];
      System.debug(raess);
      Id raesId = null;
      // 一件目をFirst_RAESD__cに設定
      for (Rental_Apply_Equipment_Set_Detail__c raes : raess) {
        if (raesId != raes.Rental_Apply_Equipment_Set__c) {
          raesMap.get(raes.Rental_Apply_Equipment_Set__c)
            .First_RAESD__c = raes.Id;
          raesId = raes.Rental_Apply_Equipment_Set__c;
        }
      }
    }
    //一览First更新
    if (!raesMap.isEmpty()) {
      update raesMap.values();
    }
  }

  // afterdeleteのみ
  private void deleteReFirst() {
    Map<Id, Rental_Apply_Equipment_Set__c> raesMap = new Map<Id, Rental_Apply_Equipment_Set__c>();
    for (Rental_Apply_Equipment_Set_Detail__c oObj : oldList) {
      if (oObj.Is_First_RAESD_F__c == true) {
        Rental_Apply_Equipment_Set__c raes = new Rental_Apply_Equipment_Set__c(
          Id = oObj.Rental_Apply_Equipment_Set__c,
          First_RAESD__c = null
        );
        raesMap.put(oObj.Rental_Apply_Equipment_Set__c, raes);
      }
    }
    //修改一览的FirstMap
    if (raesMap.isEmpty()) {
      return;
    }
    if (!raesMap.isEmpty()) {
      List<Rental_Apply_Equipment_Set_Detail__c> raess = [
        SELECT Id, Rental_Apply_Equipment_Set__c
        FROM Rental_Apply_Equipment_Set_Detail__c
        WHERE
          Rental_Apply_Equipment_Set__c = :raesMap.keySet()
          AND Cancel_Select__c = FALSE
          //一覧も削除したら更新しません
          AND IsDeleted = FALSE
        // RAESD_SortInt_F__c -> IndexFromUniqueKey_Text__c(备品配套明细.SortInt__c)
        // 1应该是主体
        ORDER BY
          Rental_Apply_Equipment_Set__c,
          IndexFromUniqueKey_Text__c ASC NULLS LAST
      ];
      Id raesId = null;
      // 一件目をFirst_RAESD__cに設定
      for (Rental_Apply_Equipment_Set_Detail__c raes : raess) {
        if (raesId != raes.Rental_Apply_Equipment_Set__c) {
          raesMap.get(raes.Rental_Apply_Equipment_Set__c)
            .First_RAESD__c = raes.Id;
          raesId = raes.Rental_Apply_Equipment_Set__c;
        }
      }
    }
    //一览First更新
    if (!raesMap.isEmpty()) {
      update raesMap.values();
    }
  }
  // 最終状態及びAsset変更
  private Boolean finishOrChangeAsset(
    Boolean isDelete,
    Rental_Apply_Equipment_Set_Detail__c oObj,
    Rental_Apply_Equipment_Set_Detail__c nObj
  ) {
    Boolean rtn = false;
    if (isDelete) {
      // oObj を確認する、oldで もともと finishのもの、falseを返す、
      rtn = !//回库确认
      ((oObj.Arrival_in_wh__c) ||
      //取消分配, (下架后, 原则需要上架, 所以不能单纯的断开)
      (oObj.Cancel_Select__c == true &&
      oObj.StockDown__c == false) ||
      //下架前, 分配备品有变化 (变成别的配套, or 变 null)
      (oObj.Asset__c == null &&
      oObj.StockDown__c == false) ||
      //取消分配, (下架后, 原则需要上架, 所以不能单纯的断开)
      (oObj.Cancel_Select__c == true &&
      nObj.StockDown__c == false) ||
      //放弃欠品
      (oObj.Lost_item_giveup__c == true) ||
      //已消耗
      (oObj.Check_lost_Item_F__c == '消耗'));
    } else {
      rtn =
        //回库确认
        ((!oObj.Arrival_in_wh__c && nObj.Arrival_in_wh__c) ||
        //取消分配, (下架后, 原则需要上架, 所以不能单纯的断开)
        (oObj.Cancel_Select__c == false &&
        nObj.Cancel_Select__c == true &&
        nObj.StockDown__c == false) ||
        //下架前, 分配备品有变化 (变成别的配套, or 变 null)
        (oObj.Asset__c != null &&
        oObj.Asset__c != nObj.Asset__c &&
        nObj.StockDown__c == false) ||
        //取消分配, (下架后, 原则需要上架, 所以不能单纯的断开)
        (oObj.Cancel_Select__c == false &&
        nObj.Cancel_Select__c == true &&
        nObj.StockDown__c == false) ||
        //放弃欠品
        (oObj.Lost_item_giveup__c == false &&
        nObj.Lost_item_giveup__c == true &&
        oObj.Check_lost_Item_F__c != '消耗') ||
        //已消耗
        (oObj.Check_lost_Item_F__c != '消耗' &&
        nObj.Check_lost_Item_F__c == '消耗' &&
        oObj.Lost_item_giveup__c == false));
    }
    return rtn;
  }
  //before 数式の値がnullになる可能性がありますのでここでも一回チェックします
  private void formulaToTextCheck() {
    List<Rental_Apply_Equipment_Set_Detail__c> raesds = new List<Rental_Apply_Equipment_Set_Detail__c>();
    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      //明细状态没有修理完毕所以修理完毕的时候不拷贝状态到Text字段
      if (
        (nObj.Repair_Status_Text__c != nObj.Repair_Status_F__c &&
        nObj.Repair_Status_F__c != '修理完毕') ||
        nObj.Return_Status_Text__c != nObj.Return_Status_F__c ||
        nObj.Shipment_Status_Text__c != nObj.Shipment_Status_F__c ||
        (nObj.ApplyPersonAppended__c != nObj.ApplyPersonAppended_F__c &&
        Trigger.isInsert)
      ) {
        Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c(
          Id = nObj.Id
        );
        //明细状态没有修理完毕所以修理完毕的时候不拷贝状态到Text字段
        if (nObj.Repair_Status_F__c != '修理完毕') {
          raesd.Repair_Status_Text__c = nObj.Repair_Status_F__c;
        }
        raesd.Return_Status_Text__c = nObj.Return_Status_F__c;
        raesd.Shipment_Status_Text__c = nObj.Shipment_Status_F__c;
        if (Trigger.isInsert) {
          raesd.ApplyPersonAppended__c = nObj.ApplyPersonAppended_F__c;
        }
        raesds.add(raesd);
      }
    }
    if (!raesds.isEmpty()) {
      // 备品优化追加 20230518 lc Start
      if (skipUpdateAgain) {
        Oly_TriggerHandler.bypass('RentalApplyEquipmentSetDetailHandler');
        update raesds;
        Oly_TriggerHandler.clearBypass('RentalApplyEquipmentSetDetailHandler');
      } else {
        update raesds;
      }
      // 备品优化追加 20230518 lc End
    }
  }
  // 20211116 ljh 下一次借用预计出库时间  的赋值 回收后-检测结果OK逻辑 start
  /*
    根据当前状态，if 回收后-检测结果 Inspection_result_after_F_New__c 有值 && new =OK old != OK {
        检测OK时间+3个工作日(奥林巴斯日历)
    }
    */
  private void NextShippmentDate() {
    Date minDate = Date.newInstance(4000, 12, 31);
    Date maxDate = Date.newInstance(1700, 1, 1);
    Map<Date, List<Rental_Apply_Equipment_Set_Detail__c>> dLMap = new Map<Date, List<Rental_Apply_Equipment_Set_Detail__c>>();
    List<Rental_Apply_Equipment_Set_Detail__c> upRdList = new List<Rental_Apply_Equipment_Set_Detail__c>();
    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      if (nObj.RA_RecordTypeId__c != '01210000000NPGK') {
        Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
        if (
          nObj.Inspection_result_after_F_New__c != null &&
          nObj.Inspection_result_after_F_New__c == 'OK' &&
          oObj.Inspection_result_after_F_New__c !=
          nObj.Inspection_result_after_F_New__c
        ) {
          // 检测OK时间+3个工作日(奥林巴斯日历)
          Date date1 = nObj.After_Inspection_time_F_New__c.date();
          if (minDate > date1) {
            minDate = date1;
          }
          if (maxDate < date1) {
            maxDate = date1;
          }
          if (!dLMap.containsKey(date1)) {
            dLMap.put(date1, new List<Rental_Apply_Equipment_Set_Detail__c>());
          }
          dLMap.get(date1).add(nObj);
        }
        // 检测NG和欠品的：不显示时间
        if (
          (// (
          nObj.RAESD_Status__c == '欠品中' ||
          nObj.RAESD_Status__c == '待修理' ||
          nObj.RAESD_Status__c == '待移至报废区') &&
          // || (nObj.Arrival_in_wh__c && oObj.Arrival_in_wh__c != nObj.Arrival_in_wh__c))
          nObj.NextShippmentDate__c != null
        ) {
          Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c();
          raesd.Id = nObj.Id;
          raesd.NextShippmentDate__c = null;
          upRdList.add(raesd);
        }
      }
    }
    if (dLMap.size() > 0) {
      List<OlympusCalendar__c> ocList = [
        SELECT Id, Date__c
        FROM OlympusCalendar__c
        WHERE
          Date__c >= :minDate
          AND Date__c <= :maxDate.addDays(30)
          AND IsWorkDay__c = 1
        ORDER BY Date__c ASC
      ];
      Map<Date, Date> dateadd3Map = new Map<Date, Date>();
      Integer ocListSize = ocList.size();
      if (ocListSize > 3) {
        for (Integer i = 0; i < ocListSize - 3; i++) {
          dateadd3Map.put(ocList[i].Date__c, ocList[i + 3].Date__c);
        }
        for (Date d : dLMap.keySet()) {
          // 因为 检测是工作日 一般不会出现 else 情况
          if (dateadd3Map.containsKey(d)) {
            for (Rental_Apply_Equipment_Set_Detail__c rd : dLMap.get(d)) {
              Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c();
              raesd.Id = rd.id;
              raesd.NextShippmentDate__c = dateadd3Map.get(d);
              upRdList.add(raesd);
            }
          }
          // 很少发生
          else {
            for (Integer i = 0; i < ocListSize - 3; i++) {
              if (d < ocList[i].Date__c) {
                for (Rental_Apply_Equipment_Set_Detail__c rd : dLMap.get(d)) {
                  Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c();
                  raesd.Id = rd.id;
                  raesd.NextShippmentDate__c = ocList[i + 2].Date__c;
                  upRdList.add(raesd);
                }
                break;
              }
            }
          }
        }
      }
    }
    if (upRdList.size() > 0) {
      update upRdList;
    }
  }
  /*
    根据当前状态，if 回收后-检测结果 DeliverySlip__c 有值 && new != old {
        出库最新预定归还日RAES_Final_reply_day__c+8个工作日(奥林巴斯日历)
    }
    */
  private void NextShippmentDate_out() {
    Date minDate = Date.newInstance(4000, 12, 31);
    Date maxDate = Date.newInstance(1700, 1, 1);
    Map<Date, List<Rental_Apply_Equipment_Set_Detail__c>> dLMap = new Map<Date, List<Rental_Apply_Equipment_Set_Detail__c>>();
    List<Rental_Apply_Equipment_Set_Detail__c> upRdList = new List<Rental_Apply_Equipment_Set_Detail__c>();
    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      if (nObj.RA_RecordTypeId__c != '01210000000NPGK') {
        Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
        if (
          nObj.DeliverySlip__c != null &&
          oObj.DeliverySlip__c != nObj.DeliverySlip__c
        ) {
          // 检测OK时间+3个工作日(奥林巴斯日历)
          Date date1 = nObj.RAES_Final_reply_day__c;
          if (minDate > date1) {
            minDate = date1;
          }
          if (maxDate < date1) {
            maxDate = date1;
          }
          if (!dLMap.containsKey(date1)) {
            dLMap.put(date1, new List<Rental_Apply_Equipment_Set_Detail__c>());
          }
          dLMap.get(date1).add(nObj);
        }
      }
    }
    if (dLMap.size() > 0) {
      List<OlympusCalendar__c> ocList = [
        SELECT Id, Date__c
        FROM OlympusCalendar__c
        WHERE
          Date__c >= :minDate
          AND Date__c <= :maxDate.addDays(30)
          AND IsWorkDay__c = 1
        ORDER BY Date__c ASC
      ];
      Map<Date, Date> dateadd3Map = new Map<Date, Date>();
      Integer ocListSize = ocList.size();
      if (ocListSize > 8) {
        for (Integer i = 0; i < ocListSize - 8; i++) {
          dateadd3Map.put(ocList[i].Date__c, ocList[i + 8].Date__c);
        }
        for (Date d : dLMap.keySet()) {
          if (dateadd3Map.containsKey(d)) {
            for (Rental_Apply_Equipment_Set_Detail__c rd : dLMap.get(d)) {
              Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c();
              raesd.Id = rd.id;
              raesd.NextShippmentDate__c = dateadd3Map.get(d);
              upRdList.add(raesd);
            }
          } else {
            for (Integer i = 0; i < ocListSize - 8; i++) {
              if (d < ocList[i].Date__c) {
                for (Rental_Apply_Equipment_Set_Detail__c rd : dLMap.get(d)) {
                  Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c();
                  raesd.Id = rd.id;
                  raesd.NextShippmentDate__c = ocList[i + 7].Date__c;
                  upRdList.add(raesd);
                }
                break;
              }
            }
          }
        }
        if (upRdList.size() > 0) {
          // 备品优化追加 20230518 lc Start
          if (skipUpdateAgain) {
            Oly_TriggerHandler.bypass('RentalApplyEquipmentSetDetailHandler');
            update upRdList;
            Oly_TriggerHandler.clearBypass(
              'RentalApplyEquipmentSetDetailHandler'
            );
          } else {
            update upRdList;
          }
          // 备品优化追加 20230518 lc End
        }
      }
    }
  }
  // 20211116 ljh 下一次借用预计出库时间  的赋值 回收后-检测结果OK逻辑 end
  //added by denny
  public void reQueueAndSequence() {
    Map<Id, Rental_Apply_Equipment_Set_Detail__c> newdetailMap = (Map<Id, Rental_Apply_Equipment_Set_Detail__c>) Trigger.newMap;
    List<Rental_Apply_Equipment_Set_Detail__c> updateList = new List<Rental_Apply_Equipment_Set_Detail__c>();
    List<String> detailIds = new List<String>();
    List<String> externalKeyList = new List<String>();
    Map<String, Decimal> minNumberMap = new Map<String, Decimal>();
    for (
      Rental_Apply_Equipment_Set_Detail__c olddetail : (List<Rental_Apply_Equipment_Set_Detail__c>) Trigger.old
    ) {
      Rental_Apply_Equipment_Set_Detail__c detail;
      if (Trigger.isUpdate) {
        detail = newdetailMap.get(olddetail.Id);
      }
      if (
        (Trigger.isUpdate &&
        ((oldDetail.Queue_Number__c > 0 &&
        detail.Queue_Number__c == 0) || // 暂定分配
        // 20220127 ljh update start
        // || (!oldDetail.Cancel_Select__c && detail.Cancel_Select__c && olddetail.Queue_Number__c >= 0)  //取消(排队中，暂定分配)
        (!oldDetail.Cancel_Select__c &&
        detail.Cancel_Select__c &&
        olddetail.Queue_Number__c > 0) || //取消(排队中，暂定分配)
        // 20220127 ljh update end
        (oldDetail.Queue_Number__c > 0 &&
        detail.Queue_Number__c == null) || //分单
        (oldDetail.Queue_Number__c > 0 &&
        olddetail.ExternalKey__c != detail.ExternalKey__c))) || //重排
        (Trigger.isDelete && olddetail.Queue_Number__c > 0)
      ) {
        updateList.add(olddetail);
        detailIds.add(olddetail.Id);
        externalKeyList.add(olddetail.ExternalKey__c);
        if (!minNumberMap.containsKey(olddetail.Externalkey__c)) {
          minNumberMap.put(olddetail.Externalkey__c, olddetail.Queue_Number__c);
        } else {
          if (
            minNumberMap.get(olddetail.Externalkey__c) >
            olddetail.Queue_Number__c
          ) {
            minNumberMap.put(
              olddetail.Externalkey__c,
              olddetail.Queue_Number__c
            );
          }
        }
      }
    }

    if (!detailIds.isEmpty()) {
      List<String> sequencekeylist = new List<String>();
      List<String> changeSequenceIds = new List<String>();
      Map<String, Decimal> changesequenceMap = new Map<String, Decimal>();
      List<Rental_Apply_Sequence__c> assignSequence = [
        SELECT Id, Series_No__c, Invalid_Flag__c, Externalkey__c
        FROM Rental_Apply_Sequence__c
        WHERE
          Apply_Set_Detail__c IN :detailIds
          AND Invalid_Flag__c = FALSE
          AND Series_No__c > 0
      ];
      for (Rental_Apply_Sequence__c se : assignSequence) {
        // sequencekeylist.add(se.Externalkey__c);
        changeSequenceIds.add(se.Id);
        // if(!changesequenceMap.containsKey(se.Externalkey__c)){
        //     changesequenceMap.put(se.Externalkey__c,se.Series_No__c);
        // }else{
        //     if(changesequenceMap.get(se.Externalkey__c) > se.Series_No__c){
        //         changesequenceMap.put(se.Externalkey__c,se.Series_No__c);
        //     }
        // }
        se.Invalid_Flag__c = true;
        se.Series_No__c = 0;
      }
      List<Rental_Apply_Equipment_Set_Detail__c> changeDetailList = new List<Rental_Apply_Equipment_Set_Detail__c>();
      List<Rental_Apply_Equipment_Set_Detail__c> raesdList = [
        SELECT
          Id,
          Rental_Apply_Equipment_Set__c,
          Asset__c,
          Rental_Apply_Equipment_Set__r.Fixture_Set__r.Product_Type__c,
          FSD_Fixture_Model_No__c,
          Fixture_Model_No_text__c,
          Rental_Apply__r.demo_purpose2__c,
          Queue_Day__c,
          ExternalKey__c,
          Is_Body__c,
          FSD_Is_OneToOne__c,
          Select_Time__c,
          Rental_Apply__r.EquipmentGuaranteeFlg__c,
          Allow_Adjust_Queue_Flag__c,
          Cancel_Select__c,
          Fixture_Model_No_F__c,
          Queue_Number__c,
          Internal_asset_location__c,
          Fixture_Model_No__c,
          Rental_Apply__c,
          Internal_asset_location_before__c,
          Salesdepartment__c,
          Product_category_F__c,
          Product_category_text__c,
          Equipment_Type_text__c,
          Salesdepartment_before__c,
          Rental_Apply__r.Request_shipping_day__c,
          QuenType__c,
          IsAdjust__c,
          Rental_Apply__r.Request_approval_time__c,
          Equipment_Type__c,
          Rental_Apply__r.Internal_asset_location_F__c,
          Cancel_Reason__c,
          Loaner_cancel_reason__c,
          Loaner_cancel_Remarks__c,
          Rental_Apply_Equipment_Set__r.Name
        FROM Rental_Apply_Equipment_Set_Detail__c
        WHERE
          Queue_Number__c > 0
          AND Cancel_Select__c = FALSE
          AND ExternalKey__c IN :externalKeyList
          AND Id NOT IN :detailIds
        ORDER BY Queue_Number__c ASC
      ];
      Map<String, List<Rental_Apply_Equipment_Set_Detail__c>> detailsMap = new Map<String, List<Rental_Apply_Equipment_Set_Detail__c>>();
      for (Rental_Apply_Equipment_Set_Detail__c setdetail : raesdList) {
        if (!detailsMap.containsKey(setdetail.Externalkey__c)) {
          detailsMap.put(
            setdetail.Externalkey__c,
            new List<Rental_Apply_Equipment_Set_Detail__c>()
          );
        }
        detailsMap.get(setdetail.Externalkey__c).add(setdetail);
      }
      for (String key : detailsMap.keySet()) {
        Decimal queueNo = minNumberMap.get(key);
        System.debug(LoggingLevel.INFO, '*** queueNo: ' + queueNo);
        Decimal i = 0;
        for (
          Rental_Apply_Equipment_Set_Detail__c detail : detailsMap.get(key)
        ) {
          System.debug(
            LoggingLevel.INFO,
            '*** detail.Queue_Number__c: ' + detail.Queue_Number__c
          );
          if (detail.Queue_Number__c > queueNo) {
            RentalFixtureSetAssignController.KeyObj dobj = RentalFixtureSetAssignController.getSequenceInfo(
              detail
            );
            sequencekeylist.addAll(dobj.sequencekeylist);
            detail.Queue_Number__c = queueNo + i;
            i++;
            System.debug(
              LoggingLevel.INFO,
              '**111* detail.Queue_Number__c: ' + detail.Queue_Number__c
            );
            changeDetailList.add(detail);
          }
        }
      }
      List<String> nodusequencekeylist = new List<String>(
        new Set<String>(sequencekeylist)
      );
      List<Rental_Apply_Sequence__c> sequenceList = [
        SELECT
          Id,
          ExternalKey__c,
          Demo_Purpose2__c,
          Apply_Set_Detail__c,
          Apply_Set_Detail_ExternalKey__c,
          Series_No__c,
          Salesdepartment__c,
          Product_category__c,
          Rental_Apply__c,
          Internal_asset_location__c,
          Apply_Set_Detail__r.Queue_Number__c,
          Series_Unequal_Queue_Flag__c,
          Fixture_Model_No__c,
          Equipment_Type__c
        FROM Rental_Apply_Sequence__c
        WHERE
          ExternalKey__c IN :nodusequencekeylist
          AND Id NOT IN :changeSequenceIds
          AND Series_No__c > 0
          AND Invalid_Flag__c = FALSE
        FOR UPDATE
      ];
      System.debug(LoggingLevel.INFO, '*** sequenceList: ' + sequenceList);
      Map<String, List<Rental_Apply_Sequence__c>> sequenceMap = new Map<String, List<Rental_Apply_Sequence__c>>();
      List<FixtureUtil.SequenceWrapper> Wrappers = new List<FixtureUtil.SequenceWrapper>();
      for (Rental_Apply_Sequence__c se : sequenceList) {
        Wrappers.add(new FixtureUtil.SequenceWrapper(se));
      }
      Wrappers.sort();
      sequenceList = new List<Rental_Apply_Sequence__c>();
      for (FixtureUtil.SequenceWrapper wrapper : wrappers) {
        sequenceList.add(wrapper.sequence);
      }
      for (Rental_Apply_Sequence__c se : sequenceList) {
        if (!sequenceMap.containsKey(se.Externalkey__c)) {
          sequenceMap.put(
            se.Externalkey__c,
            new List<Rental_Apply_Sequence__c>()
          );
        }
        sequenceMap.get(se.Externalkey__c).add(se);
      }
      List<Rental_Apply_Sequence__c> changeSequenceList = new List<Rental_Apply_Sequence__c>();
      for (String key : sequenceMap.keyset()) {
        Decimal i = 1;
        for (Rental_Apply_Sequence__c se : sequenceMap.get(key)) {
          if (se.Series_No__c != i) {
            se.Series_No__c = i;
            changeSequenceList.add(se);
          }
          i++;
        }
      }
      update assignSequence;
      update changeSequenceList;
      update changeDetailList;
    }
  }

  private void setUniqueKeyQueue() {
    Map<Id, Rental_Apply_Equipment_Set_Detail__c> olddetailMap = (Map<Id, Rental_Apply_Equipment_Set_Detail__c>) Trigger.oldMap;

    System.debug('开始处理------------------------------------');
    System.debug(
      '(List<Rental_Apply_Equipment_Set_Detail__c>) Trigger.new---------------' +
      (List<Rental_Apply_Equipment_Set_Detail__c>) Trigger.new
    );
    for (
      Rental_Apply_Equipment_Set_Detail__c newdetail : (List<Rental_Apply_Equipment_Set_Detail__c>) Trigger.new
    ) {
      System.debug(
        newdetail.Id + ' 申请单号：' + newdetail.Rental_Apply__r.name
      );
      Rental_Apply_Equipment_Set_Detail__c olddetail = olddetailMap.get(
        newdetail.Id
      );
      System.debug('旧排队No：' + olddetail.Queue_Number__c);
      System.debug('新排队No：' + newdetail.Queue_Number__c);

      if (
        (olddetail.Queue_Number__c > 0 &&
        newdetail.Queue_Number__c == 0) || // 暂定分配
        (!olddetail.Cancel_Select__c &&
        newdetail.Cancel_Select__c &&
        olddetail.Queue_Number__c > 0) || //取消(排队中，暂定分配)
        (olddetail.Queue_Number__c > 0 &&
        newdetail.Queue_Number__c == null) //分单
      ) {
        // 清空排队的UniqueKey
        newdetail.UniqueKey_Queue__c = null;
        System.debug(
          '新排队UniqueKey_Queue__c：' + newdetail.UniqueKey_Queue__c
        );
      }

      // 重排或者排队No变化时更新
      if (
        !newdetail.Cancel_Select__c &&
        newdetail.Queue_Number__c > 0 &&
        newdetail.ExternalKey__c != null &&
        (newdetail.Queue_Number__c != olddetail.Queue_Number__c ||
        newdetail.ExternalKey__c != olddetail.ExternalKey__c)
      ) {
        // 排队的UniqueKey设值
        newdetail.UniqueKey_Queue__c =
          newdetail.ExternalKey__c +
          ':' +
          newdetail.Queue_Number__c;
        System.debug(
          '新排队UniqueKey_Queue__c：' + newdetail.UniqueKey_Queue__c
        );
      }
    }
    System.debug('结束处理------------------------------------');
  }

  /*
    private void reQueueNumber() {
        Map<String, List<Rental_Apply_Equipment_Set_Detail__c>> queueRaesdMap = new Map<String, List<Rental_Apply_Equipment_Set_Detail__c>>();
        String wher = '';
        for (Rental_Apply_Equipment_Set_Detail__c oObj : oldList) {
            Rental_Apply_Equipment_Set_Detail__c nObj;
            if (Trigger.isUpdate) {
                nObj = newMap.get(oObj.Id);
            }
            if ((Trigger.isUpdate && (oObj.Queue_Number__c != 0  && nObj.Queue_Number__c == 0
                        || (!oObj.Cancel_Select__c && nObj.Cancel_Select__c )
                        || (String.isBlank(oObj.Fixture_Model_No_text__c) == false
                            // #OLY_OCM-654 因为是排队的逻辑。所以不需要删除。因为只有主体才能排队 Start
                            && String.isBlank(oObj.Salesdepartment_before__c) == false
                            && String.isBlank(oObj.Product_category_text__c) == false
                            && String.isBlank(oObj.Equipment_Type_text__c) == false
                            // #OLY_OCM-654 因为是排队的逻辑。所以不需要删除。因为只有主体才能排队 End
                            && oObj.Queue_Number__c > 0
                            // 変化を確認
                            && (oObj.Fixture_Model_No_text__c != nObj.Fixture_Model_No_text__c
                                // #OLY_OCM-654 因为是排队的逻辑。所以不需要删除。因为只有主体才能排队 Start
                                || oObj.Salesdepartment_before__c != nObj.Salesdepartment_before__c
                                || oObj.Product_category_text__c != nObj.Product_category_text__c
                                || oObj.Equipment_Type_text__c != nObj.Equipment_Type_text__c))))
                                // #OLY_OCM-654 因为是排队的逻辑。所以不需要删除。因为只有主体才能排队 End
                    || (Trigger.isDelete && oObj.Queue_Number__c != 0 && oObj.Queue_Number__c != null)) {
                if (String.isBlank(oObj.Fixture_Model_No_text__c)) {
                    if (Trigger.isUpdate) {
                        //更新时用nObj
                        if (String.isNotBlank(nObj.Fixture_Set_Id__c)) nObj.addError('备品配套型号不能为空');
                    } else {
                        //因为上面的If文已经判断了只有更新和删除所以这里不再判断删除
                        //删除时用oObj
                        oObj.addError(oObj.Id + '(排队):备品配套明细型号不能为空');
                    }
                    // 不continue的话下面使用的时候会报NullOoint
                    continue;
                }
                String key = oObj.Fixture_Model_No_text__c;
                // 式の左と右 ともに Fixture_Model_No_text__c なので、問題ないです。
                wher += ' ( Fixture_Model_No_text__c = \'' + String.escapeSingleQuotes(oObj.Fixture_Model_No_text__c) + '\'';
                // if (String.isNotBlank(oObj.Internal_asset_location_before__c)) {
                //     wher += ' and Internal_asset_location_before__c =\'' + String.escapeSingleQuotes(oObj.Internal_asset_location_before__c) + '\'';
                // }

                // #OLY_OCM-654 这里是排队的逻辑。只有主体才能排队。所以是不删除的 Start
                if (String.isNotBlank(oObj.Salesdepartment_before__c)) {
                    wher += ' and Salesdepartment_before__c =\'' + String.escapeSingleQuotes(oObj.Salesdepartment_before__c) + '\'';
                }
                if (String.isNotBlank(oObj.Product_category_text__c)) {
                    wher += ' and Product_category_text__c =\'' + String.escapeSingleQuotes(oObj.Product_category_text__c) + '\'';
                }
                if (String.isNotBlank(oObj.Equipment_Type_text__c)) {
                    wher += ' and Equipment_Type_text__c =\'' + String.escapeSingleQuotes(oObj.Equipment_Type_text__c) + '\'';
                }
                // #OLY_OCM-654 这里是排队的逻辑。只有主体才能排队。所以是不删除的 End

                wher += ') OR';
            }
        }
        if (String.isBlank(wher)) {
            return;
        }
        wher = wher.removeEnd('OR');
        wher = '(' + wher + ')';
        String soql = 'Select Id, Queue_Number__c, Fixture_Model_No_text__c, Internal_asset_location_before__c, Product_category_text__c,'
                     + ' Equipment_Type_text__c, Salesdepartment_before__c'
                     + ' From Rental_Apply_Equipment_Set_Detail__c '
                     + ' Where Queue_Number__c > 0 AND Cancel_Select__c = false'
                     + ' AND Queue_Number__c != null AND '
                     + wher
                     + ' order by Queue_Number__c ASC';
        System.debug(soql);
        List<Rental_Apply_Equipment_Set_Detail__c> queueRaesds = Database.query(soql);
        System.debug(queueRaesds.size());
        for (Rental_Apply_Equipment_Set_Detail__c raesd : queueRaesds) {
            String key = raesd.Fixture_Model_No_text__c;
            // if (String.isNotBlank(raesd.Internal_asset_location_before__c)) {
            //     key += '_' + raesd.Internal_asset_location_before__c;
            // }

            // #OLY_OCM-654 这里是排队的逻辑。只有主体才能排队。所以是不删除的 Start
            if (String.isNotBlank(raesd.Salesdepartment_before__c)) {
                key += '_' + raesd.Salesdepartment_before__c;
            }
            if (String.isNotBlank(raesd.Product_category_text__c)) {
                key += '_' + raesd.Product_category_text__c;
            }
            if (String.isNotBlank(raesd.Equipment_Type_text__c)) {
                key += '_' + raesd.Equipment_Type_text__c;
            }
            // #OLY_OCM-654 这里是排队的逻辑。只有主体才能排队。所以是不删除的 End

            if (!queueRaesdMap.containsKey(key)) {
                queueRaesdMap.put(key, new List<Rental_Apply_Equipment_Set_Detail__c>());
            }
            queueRaesdMap.get(key).add(raesd);
        }
        List<Rental_Apply_Equipment_Set_Detail__c> raesdList = new List<Rental_Apply_Equipment_Set_Detail__c>();
        for (String key : queueRaesdMap.keySet()) {
            List<Rental_Apply_Equipment_Set_Detail__c> raesds = queueRaesdMap.get(key);
            for (Integer i = 1; i <= raesds.size(); i++) {
                Rental_Apply_Equipment_Set_Detail__c raesd = raesds[i-1];
                if (raesd.Queue_Number__c != i) {
                    raesd.Queue_Number__c = i;
                    raesdList.add(raesd);
                }
            }
        }
        if (!raesdList.isEmpty()) {
            update raesdList;
        }
    }*/
  //申请者收回NG后明细回寄时的邮件回寄单内容设置
  //只在Afterupdate里面调用
  private void receivedConfirmNGSetReturnDeliverySlipText() {
    //一览Id和对应的回寄发货单ID
    Map<Id, Id> raesRDSMap = new Map<Id, Id>();
    Map<Id, String> raesDateMap = new Map<Id, String>();
    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
      //申请者收货NG的明细
      if (nObj.Received_Confirm_F__c == 'NG') {
        //回寄运输单赋值
        if (
          String.isBlank(oObj.Return_DeliverySlip__c) &&
          String.isNotBlank(nObj.Return_DeliverySlip__c)
        ) {
          //因为是以为一览为单位，所以只有一条回寄单
          //申请者收货NG的明细拆成两个回寄单回寄的情况暂时不考虑（应该没有这种情况）
          if (!raesRDSMap.containsKey(nObj.Rental_Apply_Equipment_Set__c)) {
            raesRDSMap.put(
              nObj.Rental_Apply_Equipment_Set__c,
              nObj.Return_DeliverySlip__c
            );
            raesDateMap.put(
              nObj.Rental_Apply_Equipment_Set__c,
              nObj.Asset_return_time__c.format()
            );
          }
        }
      }
    }
    if (raesRDSMap.isEmpty()) {
      return;
    }
    //NG_Return_DeliverySlip__c为空的一览才做邮件发送
    Map<Id, Rental_Apply_Equipment_Set__c> raessMap = new Map<Id, Rental_Apply_Equipment_Set__c>(
      [
        SELECT Id
        FROM Rental_Apply_Equipment_Set__c
        WHERE Id = :raesRDSMap.keySet() AND NG_Return_DeliverySlip__c = NULL
      ]
    );
    Map<Id, FixtureDeliverySlip__c> fdss = new Map<Id, FixtureDeliverySlip__c>(
      [
        SELECT
          Id,
          Name,
          Combine_Pack__c,
          Wh_Staff__c,
          DeliveryCompany__c,
          Shippment_loaner_time__c,
          Distributor_method__c,
          DeliveryCompany_SlipNo__c,
          DeliveryType__c
        FROM FixtureDeliverySlip__c
        WHERE Id = :raesRDSMap.values()
      ]
    );
    System.debug('fdss is ' + fdss);
    List<Rental_Apply_Equipment_Set__c> raess = new List<Rental_Apply_Equipment_Set__c>();
    for (Id key : raesRDSMap.keySet()) {
      //当NG_Return_DeliverySlip__c不为空时不发邮件
      if (!raessMap.containsKey(key)) {
        continue;
      }
      FixtureDeliverySlip__c fds = fdss.get(raesRDSMap.get(key));
      String message =
        '发货-发货运输单号：' +
        fds.Name +
        '<BR>' +
        '发货-物流公司：' +
        fds.DeliveryCompany__c +
        '<BR>' +
        '发货-运输方式：' +
        fds.Distributor_method__c +
        '<BR>' +
        '物流提货时间：' +
        raesDateMap.get(key) +
        '<BR>';
      raess.add(
        new Rental_Apply_Equipment_Set__c(
          Id = key,
          NG_Return_DeliverySlip_Information__c = message,
          NG_Return_DeliverySlip__c = fds.Id
        )
      );
    }
    if (!raess.isEmpty()) {
      update raess;
    }
  }

  //设置申请书的回寄通知文本
  @future
  private static void setRequestAsset_return_Text(Set<Id> raesdIdSet) {
    List<Rental_Apply_Equipment_Set_Detail__c> raesdList = [
      SELECT
        Id,
        Rental_Apply__c,
        Return_DeliverySlip__c,
        Rental_Apply_Equipment_Set__c,
        Fixture_Model_No_text__c,
        Lost_Item_return__c,
        NoItemReturn__c,
        Rental_Apply__r.Name,
        Rental_Apply__r.Id,
        Return_DeliverySlip__r.Id,
        Return_DeliverySlip__r.Name,
        Return_DeliverySlip__r.DeliveryCompany__c,
        Return_DeliverySlip__r.Distributor_method__c,
        Return_DeliverySlip__r.Shippment_loaner_time__c
      FROM Rental_Apply_Equipment_Set_Detail__c
      WHERE
        Id = :raesdIdSet
        // 回寄通知只发送有链接回寄单的明细信息
        AND Return_DeliverySlip__c != NULL
      ORDER BY Rental_Apply__c, Rental_Apply_Equipment_Set__c, Name
    ];
    // 收集回寄明细 {raesId -> raesdList}
    Map<Id, List<Rental_Apply_Equipment_Set_Detail__c>> raesdListMap = new Map<Id, List<Rental_Apply_Equipment_Set_Detail__c>>();
    Map<Id, FixtureDeliverySlip__c> return_DeliverySlipMap = new Map<Id, FixtureDeliverySlip__c>();
    for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList) {
      if (!raesdListMap.containsKey(raesd.Rental_Apply_Equipment_Set__c)) {
        raesdListMap.put(
          raesd.Rental_Apply_Equipment_Set__c,
          new List<Rental_Apply_Equipment_Set_Detail__c>()
        );
      }

      raesdListMap.get(raesd.Rental_Apply_Equipment_Set__c).add(raesd);
      /* --------- 设置运输单Map Start --------- */
      if (return_DeliverySlipMap.containsKey(raesd.Rental_Apply__c) == false) {
        FixtureDeliverySlip__c fds = raesd.Return_DeliverySlip__r;
        // 无实物回寄的回寄单不显示物流单信息
        if (fds.Name == raesd.Rental_Apply__r.Name + '_Dummy') {
          continue;
        }
        return_DeliverySlipMap.put(raesd.Rental_Apply__c, fds);
      }
      /* --------- 设置运输单Map End --------- */
    }
    if (raesdListMap.isEmpty()) {
      return;
    }
    // 检索回寄的一览 {raId -> raesList}
    Map<Id, List<Rental_Apply_Equipment_Set__c>> raesListMap = new Map<Id, List<Rental_Apply_Equipment_Set__c>>();
    List<Rental_Apply_Equipment_Set__c> raesList = [
      SELECT
        Id,
        Loaner_code_F__c,
        Rental_Apply__c,
        Asset_return_Status__c,
        Received_Confirm__c
      FROM Rental_Apply_Equipment_Set__c
      WHERE Id = :raesdListMap.keySet()
    ];
    for (Rental_Apply_Equipment_Set__c raes : raesList) {
      if (!raesListMap.containsKey(raes.Rental_Apply__c)) {
        raesListMap.put(
          raes.Rental_Apply__c,
          new List<Rental_Apply_Equipment_Set__c>()
        );
      }
      raes.recalculateFormulas();
      System.debug(raes.Wei_Return__c);
      raesListMap.get(raes.Rental_Apply__c).add(raes);
    }
    List<Rental_Apply__c> raList = new List<Rental_Apply__c>();
    List<Rental_Apply__c> raList2 = new List<Rental_Apply__c>();
    String message = '';
    Integer i = 0;
    // 申请书单位都是欠品回寄的明细
    Boolean allLostItemReturnFlag = true;
    // 查看所有的申请书
    for (Id raId : raesListMap.keySet()) {
      allLostItemReturnFlag = true;
      i = 0;
      // 查看申请书下面的所有一览
      for (Rental_Apply_Equipment_Set__c raes : raesListMap.get(raId)) {
        i++;
        message += '配套' + i + '：' + raes.Loaner_code_F__c;
        String message2 = '<BR>';
        Boolean haveLost_Item_return = false;
        // 查看一览下的所有明细
        for (
          Rental_Apply_Equipment_Set_Detail__c nObj : raesdListMap.get(raes.Id)
        ) {
          message2 +=
            '&nbsp;&nbsp;&nbsp;&nbsp;' + nObj.Fixture_Model_No_text__c;
          if (nObj.Lost_Item_return__c) {
            message2 += ' (欠品归还)';
            haveLost_Item_return = true;
          } else {
            // 如果有一条不是欠品回寄那么就不显示欠品回寄
            allLostItemReturnFlag = false;
          }
          if (nObj.NoItemReturn__c == true) {
            message2 += ' (无实物归还)';
          }
          // if (nObj.Received_Confirm_F__c == 'NG') {
          //     message += '(NG归还)';
          // }
          message2 += '<BR>';
        }
        if (haveLost_Item_return == false && raes.Received_Confirm__c == 'NG') {
          message += ' (NG归还)';
        }
        message += message2;
      }

      message += '<BR>';
      FixtureDeliverySlip__c fds = new FixtureDeliverySlip__c();
      if (return_DeliverySlipMap.containsKey(raId)) {
        fds = return_DeliverySlipMap.get(raId);
      }
      message +=
        '回寄-发货运输单号：' +
        (String.isBlank(fds.Name) ? '' : fds.Name) +
        '<BR>';
      message +=
        '回寄-物流公司：' +
        (String.isBlank(fds.DeliveryCompany__c) ? '' : fds.DeliveryCompany__c) +
        '<BR>';
      message +=
        '回寄-运输方式：' +
        (String.isBlank(fds.Distributor_method__c)
          ? ''
          : fds.Distributor_method__c) +
        '<BR>';
      String sdate = fds.Shippment_loaner_time__c == null
        ? ''
        : fds.Shippment_loaner_time__c.format();
      message += '物流提货时间：' + sdate + '<BR>';
      if (String.isNotBlank(message)) {
        raList.add(
          new Rental_Apply__c(
            Id = raId,
            Asset_return_Text__c = message,
            Lost_item_Return_Flag__c = allLostItemReturnFlag
          )
        );
        raList2.add(
          new Rental_Apply__c(Id = raId, Asset_return_Text__c = null)
        );
        message = '';
      }
    }
    if (raList.size() > 0) {
      FixtureUtil.withoutUpdate(raList2);
      FixtureUtil.withoutUpdate(raList);
    }
  }

  private void setAssginPerson(Set<Id> raId) {
    List<Rental_Apply__c> raList = [
      SELECT Id, Assign_Person__c
      FROM Rental_Apply__c
      WHERE Id IN :raId
    ];
    List<Rental_Apply__c> updateList = new List<Rental_Apply__c>();
    for (Rental_Apply__c ra : raList) {
      if (ra.Assign_Person__c == null) {
        ra.Assign_Person__c = UserInfo.getUserId();
        updateList.add(ra);
      }
    }
    if (updateList.size() > 0)
      update updateList;
  }

  private void changeAssetConsumable_Guaranteen_end() {
    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      Rental_Apply_Equipment_Set_Detail__c oObj;
      if (Trigger.isUpdate) {
        oObj = oldMap.get(nObj.Id);
      }

      if (
        oObj.Shippment_loaner_time__c == null &&
        nObj.Shippment_loaner_time__c != null &&
        nObj.NeedSet_Consumable_Guaranteen_end_F__c == true
      ) {
        Asset nass = assMap.get(nObj.Asset__c);
        if (assUpdMap.containsKey(nObj.Asset__c)) {
          nass = assUpdMap.get(nObj.Asset__c);
        } else if (String.isNotBlank(nObj.Asset__c)) {
          nass = new Asset(Id = nObj.Asset__c);
        }
        Datetime dt = nObj.Shippment_loaner_time__c.addYears(1);
        nass.Consumable_Guaranteen_end__c = Date.newinstance(
          dT.year(),
          dT.month(),
          dT.day()
        );
        nass.HaveSet_Consumable_Guaranteen_end__c = true;
      }
    }
  }
  // 允许插队邮件  20211125 ljh
  private void setToRa_Email_Text() {
    Set<Id> raesdIdJumpSet = new Set<Id>(); //插队的明细
    for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
      Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
      // 申请插队 && 插队原因发生变化的
      if (
        (nObj.Allow_Adjust_Queue_Flag__c &&
        oObj.Allow_Adjust_Queue_Flag__c != nObj.Allow_Adjust_Queue_Flag__c) ||
        (!String.isBlank(nObj.jumpReason__c) &&
        oObj.jumpReason__c != nObj.jumpReason__c)
      ) {
        raesdIdJumpSet.add(nObj.Id);
      }
    }
    System.debug('zheli:' + raesdIdJumpSet);
    List<Rental_Apply__c> raList = new List<Rental_Apply__c>();
    List<Rental_Apply__c> raList2 = new List<Rental_Apply__c>();
    if (raesdIdJumpSet.size() > 0) {
      Map<ID, List<Rental_Apply_Equipment_Set_Detail__c>> radMap = new Map<ID, List<Rental_Apply_Equipment_Set_Detail__c>>();
      List<Rental_Apply_Equipment_Set_Detail__c> radList = [
        SELECT
          Id,
          Name,
          RAESD_Status__c,
          Rental_Apply__c,
          Fixture_Model_No__c,
          Rental_Apply_Equipment_Set__c,
          Rental_Apply_Equipment_Set__r.Name,
          Allow_Adjust_Queue_Flag__c,
          jumpReason__c
        FROM Rental_Apply_Equipment_Set_Detail__c
        WHERE Id = :raesdIdJumpSet AND Allow_Adjust_Queue_Flag__c = TRUE
        ORDER BY Rental_Apply__c
      ];
      for (Rental_Apply_Equipment_Set_Detail__c rad : radList) {
        List<Rental_Apply_Equipment_Set_Detail__c> tempL = new List<Rental_Apply_Equipment_Set_Detail__c>();
        if (radMap.containsKey(rad.Rental_Apply__c)) {
          tempL = radMap.get(rad.Rental_Apply__c);
        }
        tempL.add(rad);
        radMap.put(rad.Rental_Apply__c, tempL);
      }
      for (Id raId : radMap.keySet()) {
        Rental_Apply__c tempRa = new Rental_Apply__c();
        Rental_Apply__c tempRa2 = new Rental_Apply__c();
        tempRa.Id = raId;
        tempRa2.Id = raId;
        String htmlStr = '';
        htmlStr += '<table border="1">';
        htmlStr += '<tr> <th>一览No.</th><th>型号</th><th>借出备品一览明细状态</th><th>插队原因</th></tr>';
        for (Rental_Apply_Equipment_Set_Detail__c rad : radMap.get(raId)) {
          htmlStr +=
            '<tr><td>' +
            rad.Rental_Apply_Equipment_Set__r.Name +
            '</td><td>' +
            rad.Fixture_Model_No__c +
            '</td><td>' +
            rad.RAESD_Status__c +
            '</td><td>' +
            rad.jumpReason__c +
            '</td></tr>';
        }
        htmlStr += '</table>';
        tempRa.Email_Jump_List__c = htmlStr;
        tempRa2.Email_Jump_List__c = null;
        tempRa.Email_Jump__c = true;
        tempRa2.Email_Jump__c = false;
        raList.add(tempRa);
        raList2.add(tempRa2);
      }
    }
    if (raList.size() > 0) {
      FixtureUtil.withoutUpdate(raList2);
      FixtureUtil.withoutUpdate(raList);
    }
  }

  // 20220121 排队上线
  //备品任务完成判断   mzy  2021-12-14
  /*private void FinishRentalTask() {
        Set<String> RentalList = new Set<String>();
        for (Rental_Apply_Equipment_Set_Detail__c nObj : newList) {
            Rental_Apply_Equipment_Set_Detail__c oObj = oldMap.get(nObj.Id);
            //回寄日不为空
            if(oObj.Asset_return_Day__c == null&&nObj.Asset_return_Day__c!=null){
                RentalList.add(nObj.Rental_Apply__c);
            }else if(oObj.Confirm_Lost_Date__c == null&&nObj.Confirm_Lost_Date__c!=null){
            //确认遗失
                RentalList.add(nObj.Rental_Apply__c);
            }else if(oObj.Loaner_Giveup_Time__c == null&&nObj.Loaner_Giveup_Time__c!=null ){
            //断念时间 
                RentalList.add(nObj.Rental_Apply__c);
            }else if(oObj.LoseReportApprovaled__c==false&&nObj.LoseReportApprovaled__c){
            //遗失报告已批准
                RentalList.add(nObj.Rental_Apply__c);
            }
        }
        if(RentalList.size()>0){
            //备品申请Map
            Map<String,List<Rental_Apply_Equipment_Set_Detail__c>> RentalMap = new Map<String,List<Rental_Apply_Equipment_Set_Detail__c>>();
            //备品申请所对应的所有明细
            List<Rental_Apply_Equipment_Set_Detail__c> RAESetList = [SELECT Id,Rental_Apply__c,Asset_return_Day__c,Confirm_Lost_Date__c,Loaner_Giveup_Time__c,LoseReportApprovaled__c,Cancel_Time__c FROM Rental_Apply_Equipment_Set_Detail__c WHERE Rental_Apply__c in :RentalList];
            //做备品申请的Map
            for(Rental_Apply_Equipment_Set_Detail__c tempRd :RAESetList){
                List<Rental_Apply_Equipment_Set_Detail__c> tempRdList = new List<Rental_Apply_Equipment_Set_Detail__c>();
                //第一次
                if(RentalMap.get(tempRd.Rental_Apply__c)==null){
                    tempRdList.add(tempRd);
                }else {
                //以后    
                    tempRdList = RentalMap.get(tempRd.Rental_Apply__c);
                    tempRdList.add(tempRd);
                }
                RentalMap.put(tempRd.Rental_Apply__c,tempRdList);
            }
            //判断哪些备品是完成哪些任务
            // 1>回收任务
            List<String> finishTaskRental_recovery = new List<String>();
            // 2>欠品任务(完成)
            List<String> finishTaskRental_Inferior = new List<String>();
            // 3>欠品任务(未执行)
            List<String> unexecutedTaskRental_Inferior = new List<String>();
            // 4>遗失任务
            List<String> finishTaskRental_lose = new List<String>();

            //遍历判断
            for(String tempRentId :RentalMap.keySet()){
                
                //明细总数
                Integer tempTotal = RentalMap.get(tempRentId).size();
                //回寄日不为空的数量
                Integer returnDayCount = 0;
                //确认遗失的数量
                Integer confirmLostCount = 0;
                //断念时间有值的数量
                Integer LoanerGiveupCount = 0;
                //遗失报告批准
                Integer LoseReportApprovaledCount = 0;
                //取消时间有值的数量
                Integer CancelTimeCount = 0;

                for(Rental_Apply_Equipment_Set_Detail__c tempRAESet :RentalMap.get(tempRentId)){
                    //回寄日不为空
                    if(tempRAESet.Asset_return_Day__c !=null){
                        returnDayCount += 1;
                    }
                    //确认遗失
                    if(tempRAESet.Confirm_Lost_Date__c !=null){
                        confirmLostCount += 1;
                    }
                    //断念时间有值
                    if(tempRAESet.Loaner_Giveup_Time__c !=null){
                        LoanerGiveupCount += 1;
                    }
                    //遗失报告批准
                    if(tempRAESet.LoseReportApprovaled__c){
                        LoseReportApprovaledCount += 1;
                    } 
                    //取消时间有值
                    if(tempRAESet.Cancel_Time__c != null){
                        CancelTimeCount += 1;
                    }                   

                }

                //回收
                if((returnDayCount + confirmLostCount + CancelTimeCount) == tempTotal ){
                    finishTaskRental_recovery.add(tempRentId);
                }

                //欠品 (完成)
                if((returnDayCount + confirmLostCount + CancelTimeCount) == tempTotal && (LoanerGiveupCount < tempTotal)){
                    finishTaskRental_Inferior.add(tempRentId);
                }

                //欠品 (未执行)
                if(LoanerGiveupCount == tempTotal && LoanerGiveupCount >0 ){
                    unexecutedTaskRental_Inferior.add(tempRentId);
                }

                //遗失 
                if((returnDayCount + LoseReportApprovaledCount + CancelTimeCount) == tempTotal){
                    finishTaskRental_lose.add(tempRentId);
                }   

            }

            //所有需要更新的任务
            List<Task__c> AllNeedUpdateTask = new List<Task__c>();

            //回收任务(完成)
            if(finishTaskRental_recovery.size()>0){                
                //根据备品借出申请查询任务
                List<task__c> RentTaskList_recovery = [SELECT Id FROM Task__c WHERE RentalApply__c = :finishTaskRental_recovery AND RecordType.Name = '备品回收任务' AND taskStatus__c not in ('01 分配','03 完成')];
                if(RentTaskList_recovery.size()>0){
                    for(Task__c t:RentTaskList_recovery){
                        t.taskStatus__c = '03 完成';
                    }
                    AllNeedUpdateTask.addAll(RentTaskList_recovery);
                }
            }
            //欠品任务(完成)
            if(finishTaskRental_Inferior.size()>0){                
                //根据备品借出申请查询任务
                List<task__c> RentTaskList_recovery = [SELECT Id FROM Task__c WHERE RentalApply__c = :finishTaskRental_Inferior AND RecordType.Name = '备品欠品任务' AND taskStatus__c not in ('01 分配','03 完成','07 未执行')];
                if(RentTaskList_recovery.size()>0){
                    for(Task__c t:RentTaskList_recovery){
                        t.taskStatus__c = '03 完成';
                    }
                    AllNeedUpdateTask.addAll(RentTaskList_recovery);
                }
            }
            //欠品任务(未执行)
            if(unexecutedTaskRental_Inferior.size()>0){                
                //根据备品借出申请查询任务
                List<task__c> RentTaskList_recovery = [SELECT Id FROM Task__c WHERE RentalApply__c = :unexecutedTaskRental_Inferior AND RecordType.Name = '备品欠品任务' AND taskStatus__c not in ('01 分配','03 完成','07 未执行')];
                if(RentTaskList_recovery.size()>0){
                    for(Task__c t:RentTaskList_recovery){
                        t.taskStatus__c = '07 未执行';
                    }
                    AllNeedUpdateTask.addAll(RentTaskList_recovery);
                }
            }

            //遗失任务
            if(finishTaskRental_lose.size()>0){                
                //根据备品借出申请查询任务
                List<task__c> RentTaskList_recovery = [SELECT Id FROM Task__c WHERE RentalApply__c = :unexecutedTaskRental_Inferior AND RecordType.Name = '备品遗失任务' AND taskStatus__c not in ('01 分配','03 完成','07 未执行')];
                if(RentTaskList_recovery.size()>0){
                    for(Task__c t:RentTaskList_recovery){
                        t.taskStatus__c = '03 完成';
                    }
                    AllNeedUpdateTask.addAll(RentTaskList_recovery);
                }
            }


            if(AllNeedUpdateTask.size()>0){
                update AllNeedUpdateTask;
            }

        }
    }*/
  // 20220121 排队上线
}
