// public with sharing class EquipmentRentalLostReportController {
public without sharing class EquipmentRentalLostReportController {
    // 备品申请书
    public Rental_Apply__c rentalApply { get; set; }
    // 明细行项目
    public List<LineInfo> lineInfoList { get; set; }
    //备品申请书ID
    public String rentalApplyId { get; private set; }
    public Boolean hasError { get; private set; }

    public Boolean isWarehouse { get; private set; }
    public Boolean isNot2B1 { get; private set; }
    public Boolean isUseAll { get; private set; }
    //现有备品数量（基于备品一览数量）
    public Integer EquipmentSetCnt{get;set;}

    public String sortKey { get; set; }
    public String preSortKey { get; set; }
    public Boolean sortOrderAsc { get; set; }
    public String[] sortOrder { get; set; }                 // TODO sortOrderLeft と sortOrderRight
    public String[] columus { get; private set; }
    public List<List<String>> columnsApi { get; private set; }         // 参照項目用 
    public Set<String> columusSet = new Set<String>();
    public List<String> titleList { get; set; }
    public String lrName;

    //add by rentx 2021-05-08 start 1635
    // 调拨申请单
    public TransferApply__c TransferApply {get;set;}
    // 调拨申请单id
    public String transferApplyId {get;set;}
    //add by rentx 2021-05-08 end 1635

    private static Set<String> mustFieldSet = new Set<String> {'LostReport_Detail__r.LostReport_Status_F__c',
                                                     'Lost_item_giveup__c',
                                                     'DeleteLostReport_Detail_Reason__c',
                                                     'LostReport_Detail__r.CreatedById',
                                                     'Confirm_Lost_Date__c',
                                                     'LostReport_Detail__c',
                                                     'LostReport_Detail__r.CancelLostReport__c',
                                                     'Asset__r.Internal_Asset_number__c',
                                                     'Check_lost_Item_F__c',
                                                     'Loaner_asset_no__c'};

    public EquipmentRentalLostReportController() {
        //add by rentx 2021-05-08 start 1635
        transferApplyId = ApexPages.currentPage().getParameters().get('tid');
        //add by rentx 2021-05-08 end 1635
        rentalApplyId = ApexPages.currentPage().getParameters().get('raid');
        lrName = ApexPages.currentPage().getParameters().get('lrName');
    }

    // 画面初始化
    public void init() {
        if (String.isNotBlank(lrName)) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, '成功保存遗失报告，遗失报告编号为：' + lrName));
        }
        hasError = false;
        rentalApply = new Rental_Apply__c();
        TransferApply = new TransferApply__c();
        isNot2B1 = ((Userinfo.getProfileId() == Label.ProfileId_EquipmentCenter || Userinfo.getProfileId() == Label.ProfileId_SystemAdmin)) == false;
        isWarehouse = System.Label.profile_2b2.contains(UserInfo.getProfileId());
        isUseAll = System.Label.ProfileId_SystemAdmin.contains(UserInfo.getProfileId());
        try {

            if (rentalApplyId != null && rentalApplyId.length() > 0) {
                // 备品借出申请取得
                List<Rental_Apply__c> raList = [
                    select Id, Status__c, RA_Status__c, Name,
                      RecordType.Name// 20210428 1653 you
                      from Rental_Apply__c
                     where Id = :rentalApplyId];

                if (raList.size() > 0) {
                    rentalApply = raList[0];
                } else {
                    throw new ControllerUtil.myException('备品申请书不存在，请确认。');
                }
            //update by rentx 2021-05-08 start 1635
            }else if (transferApplyId != null && transferApplyId != '') {
               // 获取调拨申请
                List<TransferApply__c> tList = [
                    select Id, Name 
                      from TransferApply__c
                     where Id = :transferApplyId];

                if (tList.size() > 0) {
                    TransferApply = tList[0];
                } else {
                    throw new ControllerUtil.myException('调拨申请不存在，请确认。');
                }
            }else{
              throw new ControllerUtil.myException('申请书不存在，请确认。');
            }
            /* else {
                throw new ControllerUtil.myException('备品申请书不存在，请确认。');
            }*/
            //update by rentx 2021-05-08 end 1635

            //update by rentx 20210603 start
            /*String whereStr = ' AND Check_lost_Item_F__c = \'欠品\'' +
                              ' AND Return_DeliverySlip__c = null ' ;
                              // ' AND (LostReport_Detail__c = null ' +
                                    // ' OR LostReport_Detail__r.LostReport__r.Status__c = \'草案中\'' +
                                    // ' OR LostReport_Detail__r.CancelLostReport__c = true)' +
                              // ' ORDER BY LostReport_Detail__c NULLS FIRST, Lost_item_giveup__c, Rental_Apply_Equipment_Set__r.Name, Name';
                              // ' ORDER BY LostReport_Detail__c NULLS FIRST, Lost_item_giveup__c,  Name';
            if (rentalApplyId != null && rentalApplyId.length() > 0) {
              whereStr += ' ORDER BY LostReport_Detail__c NULLS FIRST, Lost_item_giveup__c, Rental_Apply_Equipment_Set__r.Name, Name';
            }else{
              whereStr += ' ORDER BY LostReport_Detail__c NULLS FIRST, Lost_item_giveup__c,  Name';
            }*/
            //update by rentx 20210603 end
            String whereStr = '';
            if (rentalApplyId != null && rentalApplyId.length() > 0) {
              whereStr = ' AND Check_lost_Item_F__c = \'欠品\'' +
                              ' AND Return_DeliverySlip__c = null ' ;
              whereStr += ' ORDER BY LostReport_Detail__c NULLS FIRST, Lost_item_giveup__c, Rental_Apply_Equipment_Set__r.Name, Name';
            }else{
              whereStr += ' ORDER BY LostReport_Detail__c NULLS FIRST, Lost_item_giveup__c,  Name';
            }

            setColumus();
            // 备品借出备品set一览取得 
            // List<Rental_Apply_Equipment_Set_Detail__c> raesdList = getRaesd(null, rentalApply.Id, whereStr);
            // List<SObject> sobList = getRaesd(null, rentalApply.Id, whereStr);

            if (rentalApplyId != null) {
              List<SObject> sobList = getRaesd(null, rentalApply.Id, whereStr);
              List<Rental_Apply_Equipment_Set_Detail__c> raesdList = (List<Rental_Apply_Equipment_Set_Detail__c>)sobList;
              if (raesdList.size() == 0) {
                throw new ControllerUtil.myException('备品申请书没有欠品中的明细。');
              }else{
                  EquipmentSetCnt = raesdList.size();
              }
              // 明细行做成
              reSetInfo(raesdList);
            }else{
              List<SObject> sobList = getRaesd(null, TransferApply.Id, whereStr);
              List<TransferApplyDetail__c> raesdList = (List<TransferApplyDetail__c>) sobList;
            if (raesdList.size() == 0) {
                  throw new ControllerUtil.myException('调拨申请没有欠品中的明细。');
              }else{
                  EquipmentSetCnt = raesdList.size();
              }
              // 明细行做成
              reSetInfo(raesdList);
            }

            // if (raesdList.size() == 0) {
            //     throw new ControllerUtil.myException('备品申请书没有欠品中的明细。');
            // }else{
            //     EquipmentSetCnt = raesdList.size();
            // }
            //update by rentx 2021-05-08 end 1635

            this.sortOrderAsc = true;
            this.sortOrder = new String[columus.size()];
            for (Integer i = 0; i < columus.size(); i++) {
                this.sortOrder[i] = '　';
            }

        }
        catch (Exception ex)    {
            system.debug('=====' + ex.getStackTraceString());
            hasError = true;
            ApexPages.addMessages(ex);
            // ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'ex::' +ex.getLineNumber()));

        }
    }

    private void setColumus() {
        // 获得订单一览
        //update by rentx 2021-05-08 start 1635
        Map<String, Schema.FieldSet> fsMap ;
        if (rentalApplyId != null && rentalApplyId != '') {
          fsMap = Schema.getGlobalDescribe().get('Rental_Apply_Equipment_Set_Detail__c').getDescribe().fieldSets.getMap();
        }else{
          fsMap = Schema.getGlobalDescribe().get('TransferApplyDetail__c').getDescribe().fieldSets.getMap();
        }


        // Map<String, Schema.FieldSet> fsMap = Schema.getGlobalDescribe().get('Rental_Apply_Equipment_Set_Detail__c').getDescribe().fieldSets.getMap();
        //update by rentx 2021-05-08 end 1635
        Schema.FieldSet fs = fsMap.get('Lost_Item_Fields');
        List<FieldSetMember> fsmList = fs.getFields();
        columus = new List<String>();
        titleList = new List<String>();
        columnsApi = new List<List<String>>();
        for (FieldSetMember fsm : fsmList) {
            if (columusSet.contains(fsm.getFieldPath()) == false) {
                // 20210428 1653 you start
                if(rentalApply != null && rentalApply.RecordType.Name=='备品申请（办事处）' && fsm.getLabel()=='备品中心出库日'){
                    titleList.add('办事处出库日');                    
                // 20210428 1653 you end   
                // 20210521 1635 rentx start 
                } else if (TransferApply != null && fsm.getLabel() == '型号') {
                    titleList.add('备品配套明细型号');
                } 
                // 20210521 1635 rentx end
                else{
                    titleList.add(fsm.getLabel());
                }
                columus.add(fsm.getFieldPath());
                columusSet.add(fsm.getFieldPath());
                columnsApi.add(fsm.getFieldPath().split('\\.'));               
            }


        }
    }

    // 保存确认丢失
    public PageReference saveBtn1() {
        hasError = false;
        // 保存
        Savepoint sp = Database.setSavepoint();
        try {
            //备品借出申请时
            if (rentalApplyId != null && rentalApplyId != '') {
              Set<Id> needUpdateRaesdSet = new Set<Id>();
              Set<Id> needRemoveRaesdSet = new Set<Id>();
              for (Integer i = 0; i < lineInfoList.size(); i ++) {
                  LineInfo info = lineInfoList[i];
                  if (info.oldhaveConfirm_Lost_Date != info.haveConfirm_Lost_Date) {
                      if (info.haveConfirm_Lost_Date) {
                          needUpdateRaesdSet.add(info.raesd.Id);
                      }
                      else {
                          needRemoveRaesdSet.add(info.raesd.Id);
                      }
                  }
              }
              if (needUpdateRaesdSet.size() == 0 && needRemoveRaesdSet.size() == 0) {
                  throw new ControllerUtil.myException('请选择想要确认遗失的明细');
              }

              List<Rental_Apply_Equipment_Set_Detail__c> raesdList = [SELECT Id,
                                                                             Confirm_Lost_Date__c
                                                                        FROM Rental_Apply_Equipment_Set_Detail__c
                                                                       WHERE (
                                                                                 (Id = :needUpdateRaesdSet
                                                                                     AND Confirm_Lost_Date__c = null
                                                                                  )
                                                                              OR (Id = :needRemoveRaesdSet
                                                                                      AND Confirm_Lost_Date__c != null
                                                                                  )
                                                                              )
                                                                         AND Cancel_Select__c = false
                                                                         AND Check_lost_Item_F__c = '欠品'
                                                                         // AND Lost_item_giveup__c = false
                                                                         FOR UPDATE];
              if (raesdList.size() == 0 || (needUpdateRaesdSet.size() + needRemoveRaesdSet.size()) != raesdList.size()) {
                  throw new ControllerUtil.myException('选择的备品借出明细不正确,请刷新画面重新选择');
              }

              for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList) {
                  if (needUpdateRaesdSet.contains(raesd.Id)) {
                      raesd.Confirm_Lost_Date__c = Datetime.now();
                      needUpdateRaesdSet.remove(raesd.Id);
                  }
                  if (needRemoveRaesdSet.contains(raesd.Id)) {
                      raesd.Confirm_Lost_Date__c = null;
                      needRemoveRaesdSet.remove(raesd.Id);
                  }
              }
              if (needUpdateRaesdSet.size() > 0 || needRemoveRaesdSet.size() > 0) {
                  throw new ControllerUtil.myException('数据已经被更新过,行刷新画面重试');
              }
              FixtureUtil.withoutUpdate(raesdList);
            }else{
              //调拨申请时
              Set<Id> needUpdateRaesdSet = new Set<Id>();
              Set<Id> needRemoveRaesdSet = new Set<Id>();
              for (Integer i = 0; i < lineInfoList.size(); i ++) {
                  LineInfo info = lineInfoList[i];
                  if (info.oldhaveConfirm_Lost_Date != info.haveConfirm_Lost_Date) {
                      if (info.haveConfirm_Lost_Date) {
                          needUpdateRaesdSet.add(info.raesd1.Id);
                      }
                      else {
                          needRemoveRaesdSet.add(info.raesd1.Id);
                      }
                  }
              }
              if (needUpdateRaesdSet.size() == 0 && needRemoveRaesdSet.size() == 0) {
                  throw new ControllerUtil.myException('请选择想要确认遗失的明细');
              }

              List<TransferApplyDetail__c> raesdList = [SELECT Id,
                                                                             Confirm_Lost_Date__c
                                                                        FROM TransferApplyDetail__c
                                                                       WHERE (
                                                                                 (Id = :needUpdateRaesdSet
                                                                                     AND Confirm_Lost_Date__c = null
                                                                                  )
                                                                              OR (Id = :needRemoveRaesdSet
                                                                                      AND Confirm_Lost_Date__c != null
                                                                                  )
                                                                              )
                                                                         AND Cancel_Select__c = false
                                                                         AND Check_lost_Item_F__c = '欠品'
                                                                         FOR UPDATE];
              if (raesdList.size() == 0 || (needUpdateRaesdSet.size() + needRemoveRaesdSet.size()) != raesdList.size()) {
                  throw new ControllerUtil.myException('选择的调拨申请一览明细不正确,请刷新画面重新选择');
              }

              for (TransferApplyDetail__c raesd : raesdList) {
                  if (needUpdateRaesdSet.contains(raesd.Id)) {
                      raesd.Confirm_Lost_Date__c = Datetime.now();
                      needUpdateRaesdSet.remove(raesd.Id);
                  }
                  if (needRemoveRaesdSet.contains(raesd.Id)) {
                      raesd.Confirm_Lost_Date__c = null;
                      needRemoveRaesdSet.remove(raesd.Id);
                  }
              }
              if (needUpdateRaesdSet.size() > 0 || needRemoveRaesdSet.size() > 0) {
                  throw new ControllerUtil.myException('数据已经被更新过,行刷新画面重试');
              }
              FixtureUtil.withoutUpdate(raesdList);
            }
            
        }
        catch (Exception ex)    {
            system.debug('=====' + ex.getMessage());
            hasError = true;
            ApexPages.addMessages(ex);            
            Database.rollback(sp);
            return null;
        }
        ApexPages.currentPage().getParameters().put('raesdId', null);
        return null;
    }

    // 保存按钮
    // https://sohobb.backlog.jp/view/OLY_OCM-152#comment-20041467
    // TODO OLY_OCM-206 select from 一対一Link, 把 分配数 清 0
    public PageReference saveBtn() {
        hasError = false;
        // 保存
        Savepoint sp = Database.setSavepoint();
        try {
          Map<Id, Integer> needAddLRMap = new Map<Id, Integer>();
          if (rentalApplyId != null && rentalApplyId != '') {
            Map<Id, Rental_Apply_Equipment_Set_Detail__c> needCancelLRMap = new Map<Id, Rental_Apply_Equipment_Set_Detail__c>();
              Boolean isGiveUp = null;
              for (Integer i = 0; i < lineInfoList.size(); i ++) {
                  LineInfo info = lineInfoList[i];
                  System.debug(info.isSelect + ' ' + info.oldSelect);
                  if (info.oldSelect != info.isSelect) {
                      if (info.isSelect) {
                          if (isGiveUp == null) {
                              isGiveUp = info.raesd.Lost_item_giveup__c;
                          }
                          else if (isGiveUp != info.raesd.Lost_item_giveup__c) {
                              // throw new ControllerUtil.myException('请选择欠品明细或者放弃明细');
                          }
                          needAddLRMap.put(info.raesd.id, i + 1);
                      }
                      // 已经提交过遗失申请，草案中，不批准，取消提交状态的话删除遗失申请明细
                      else {
                          // if (info.raesd.LostReport_Detail__r.LostReport__r.Status__c == '草案中') {
                              needCancelLRMap.put(info.raesd.Id, info.raesd);
                          // }
                      }
                  }
              }

              if (needAddLRMap.isEmpty() && needCancelLRMap.isEmpty()) {
                  throw new ControllerUtil.myException('画面没有变更，不能保存');
              }

              LostReport__c lr;
              List<LostReport_Detail__c> upsertLR = new List<LostReport_Detail__c>();
              List<Rental_Apply_Equipment_Set_Detail__c> raesdList = new List<Rental_Apply_Equipment_Set_Detail__c>();
              Map<Id, LostReport_Detail__c> needAddLrdMap = new Map<Id, LostReport_Detail__c>();
              if (needAddLRMap.isEmpty() == false) {
                  // 备品借出备品set一览取得 
                   raesdList = getRaesd(needAddLRMap.keySet(), null, ' FOR UPDATE');
                  if (raesdList.size() <= 0) {
                      throw new ControllerUtil.myException('需要提交遗失的明细不存在，请刷新画面重试');
                  }
                  else {
                      for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList) {
                          if ((raesd.LostReport_Detail__c != null
                                  && raesd.LostReport_Detail__r.CancelLostReport__c == false)
                                || raesd.Check_lost_Item_F__c != '欠品') {
                              throw new ControllerUtil.myException(needAddLRMap.get(raesd.id) + '行明细:' + '需要提交遗失报告的明细已经更新，请刷新画面重试');
                          }
                      }
                  }
                  // String reportStatus = '';
                  // if (isNot2B1) {
                  //     reportStatus = '申请人提交';
                  // }
                  // else {
                  //     reportStatus = '仓库提交';
                  // }
                  List<LostReport__c> lrList = [SELECT Id, Name
                                              FROM LostReport__c
                                             WHERE Rental_Apply__c = :raesdList[0].Rental_Apply__c
                                               AND Status__c = '草案中'
                                               AND CreatedById = :UserInfo.getUserId()
                                               ];

                  if (lrList.size() > 0) {
                      lr = lrList[0];
                      this.lrName = lr.Name;
                  }
                  else {
                      lr = new LostReport__c();
                      lr.Rental_Apply__c = raesdList[0].Rental_Apply__c;
                      // lr.Report_Type__c = reportStatus;
                      FixtureUtil.withoutInsert(new LostReport__c[]{lr});
                      lrList = [SELECT Id, Name
                                  FROM LostReport__c
                                 WHERE Id = :lr.Id
                                   ];
                      this.lrName = lrList[0].Name;
                  }

                  for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList) {
                      LostReport_Detail__c lrd = new LostReport_Detail__c();
                      lrd.LostReport__c = lr.Id;
                      lrd.Rental_Apply_Equipment_Set_Detail__c = raesd.Id;
                      lrd.Asset__c = raesd.Asset__c;
                      lrd.Quantity__c = 1;
                      needAddLrdMap.put(raesd.Id, lrd);
                  }
                  upsertLR = needAddLrdMap.values();
              }

              List<LostReport_Detail__c> deleteLR = new List<LostReport_Detail__c>();
              if (needCancelLRMap.isEmpty() == false) {
                  for (Id deleLRId : needCancelLRMap.keySet()) {
                      upsertLR.add(new LostReport_Detail__c(Id = needCancelLRMap.get(deleLRId).LostReport_Detail__c,
                                                            CancelLostReport__c = true,
                                                            DeleteLostReport_Detail_Reason__c = needCancelLRMap.get(deleLRId).DeleteLostReport_Detail_Reason__c));
                      Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c(Id = deleLRId);
                      raesd.LostReport_Detail__c = null;
                      raesdList.add(raesd);
                  }
              }

              // 追加更新的遗失报告申请明细
              FixtureUtil.withoutUpsertObjects(upsertLR);
              for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList) {
                //update by rentx 20210611 start 1635
                  // if (needCancelLRMap.containsKey(raesd.Id) == false) {
                  if (needCancelLRMap.containsKey(raesd.Id) == false && needAddLrdMap.get(raesd.Id) !=null) {
                    //update by rentx 20210611 end 1635
                      raesd.LostReport_Detail__c = needAddLrdMap.get(raesd.Id).Id;
                  }
              }
              // 更新借出申请明细关联遗失报告明细的字段
              FixtureUtil.withoutUpdate(raesdList);
              reSetInfo(raesdList);
              if (String.isNotBlank(this.lrName)) {
                  PageReference pg = new PageReference('/apex/EquipmentRentalLostReport?raid=' + rentalApplyId);
                  pg.getParameters().put('lrName',lrName);
                  pg.setRedirect(true);
                  return pg;
              }
          }else{
            Map<Id, TransferApplyDetail__c> needCancelLRMap = new Map<Id, TransferApplyDetail__c>();
              Boolean isGiveUp = null;
              for (Integer i = 0; i < lineInfoList.size(); i ++) {
                  LineInfo info = lineInfoList[i];
                  System.debug(info.isSelect + ' ' + info.oldSelect);
                  if (info.raesd1.Loaner_asset_no__c != null && info.raesd1.Loaner_asset_no__c != '') {
                      if (info.oldSelect != info.isSelect) {
                        if (info.isSelect) {
                            if (isGiveUp == null) {
                                isGiveUp = info.raesd1.Lost_item_giveup__c;
                            }
                            else if (isGiveUp != info.raesd1.Lost_item_giveup__c) {
                            }
                            needAddLRMap.put(info.raesd1.id, i + 1);
                        }
                        else {
                            needCancelLRMap.put(info.raesd1.Id, info.raesd1);
                        }
                    }
                  }
                  
              }

              if (needAddLRMap.isEmpty() && needCancelLRMap.isEmpty()) {
                  throw new ControllerUtil.myException('画面没有变更，不能保存');
              }

              LostReport__c lr;
              List<LostReport_Detail__c> upsertLR = new List<LostReport_Detail__c>();
              List<TransferApplyDetail__c> raesdList = new List<TransferApplyDetail__c>();
              Map<Id, LostReport_Detail__c> needAddLrdMap = new Map<Id, LostReport_Detail__c>();
              if (needAddLRMap.isEmpty() == false) {
                   raesdList = getRaesd(needAddLRMap.keySet(), null, ' FOR UPDATE');
                  if (raesdList.size() <= 0) {
                      throw new ControllerUtil.myException('需要提交遗失的明细不存在，请刷新画面重试');
                  }
                  else {
                      for (TransferApplyDetail__c raesd : raesdList) {
                          if ((raesd.LostReport_Detail__c != null
                                  && raesd.LostReport_Detail__r.CancelLostReport__c == false)
                                || raesd.Check_lost_Item_F__c != '欠品') {
                              throw new ControllerUtil.myException(needAddLRMap.get(raesd.id) + '行明细:' + '需要提交遗失报告的明细已经更新，请刷新画面重试');
                          }
                      }
                  }
                  List<LostReport__c> lrList = [SELECT Id, Name
                                              FROM LostReport__c
                                             WHERE TransferApply__c = :raesdList[0].TransferApply__c
                                               AND Status__c = '草案中'
                                               AND CreatedById = :UserInfo.getUserId()
                                               ];

                  if (lrList.size() > 0) {
                      lr = lrList[0];
                      this.lrName = lr.Name;
                  }
                  else {
                      lr = new LostReport__c();
                      lr.TransferApply__c = raesdList[0].TransferApply__c;
                      //add by rentx 20210607 start
                      //设置调拨前地区去保有设备上的备品存放地 明细的备品存放地 = 保有设备的备品存放地
                      lr.From_Location__c = raesdList[0].Internal_asset_location__c;
                      //add by rentx 20210607 end
                      FixtureUtil.withoutInsert(new LostReport__c[]{lr});
                      lrList = [SELECT Id, Name
                                  FROM LostReport__c
                                 WHERE Id = :lr.Id
                                   ];
                      this.lrName = lrList[0].Name;
                  }

                  for (TransferApplyDetail__c raesd : raesdList) {
                      if (raesd.Loaner_asset_no__c != null && raesd.Loaner_asset_no__c != '') {
                        LostReport_Detail__c lrd = new LostReport_Detail__c();
                      lrd.LostReport__c = lr.Id;
                      //
                      lrd.TransferApplyDetail__c = raesd.Id;
                      lrd.Asset__c = raesd.Asset__c;
                      lrd.Quantity__c = 1;
                      needAddLrdMap.put(raesd.Id, lrd);
                      }
                  }
                  upsertLR = needAddLrdMap.values();
              }

              List<LostReport_Detail__c> deleteLR = new List<LostReport_Detail__c>();
              if (needCancelLRMap.isEmpty() == false) {
                  for (Id deleLRId : needCancelLRMap.keySet()) {
                      upsertLR.add(new LostReport_Detail__c(Id = needCancelLRMap.get(deleLRId).LostReport_Detail__c,
                                                            CancelLostReport__c = true,
                                                            DeleteLostReport_Detail_Reason__c = needCancelLRMap.get(deleLRId).DeleteLostReport_Detail_Reason__c));
                      TransferApplyDetail__c raesd = new TransferApplyDetail__c(Id = deleLRId);
                      raesd.LostReport_Detail__c = null;
                      raesdList.add(raesd);
                  }
              }

              // 追加更新的遗失报告申请明细
              FixtureUtil.withoutUpsertObjects(upsertLR);
              for (TransferApplyDetail__c raesd : raesdList) {
                //udate by rentx 20210611 start 1635
                  // if (needCancelLRMap.containsKey(raesd.Id) == false) {
                  if (needCancelLRMap.containsKey(raesd.Id) == false && needAddLrdMap.get(raesd.Id) !=null) {
                      raesd.LostReport_Detail__c = needAddLrdMap.get(raesd.Id).Id;
                  }
              }
              // 更新借出申请明细关联遗失报告明细的字段
              FixtureUtil.withoutUpdate(raesdList);
              reSetInfo(raesdList);
              if (String.isNotBlank(this.lrName)) {
                  PageReference pg = new PageReference('/apex/EquipmentRentalLostReport?tid=' + transferApplyId);
                  pg.getParameters().put('lrName',lrName);
                  pg.setRedirect(true);
                  return pg;
              }
          }
            /*Map<Id, Rental_Apply_Equipment_Set_Detail__c> needCancelLRMap = new Map<Id, Rental_Apply_Equipment_Set_Detail__c>();
            Boolean isGiveUp = null;
            for (Integer i = 0; i < lineInfoList.size(); i ++) {
                LineInfo info = lineInfoList[i];
                System.debug(info.isSelect + ' ' + info.oldSelect);
                if (info.oldSelect != info.isSelect) {
                    if (info.isSelect) {
                        if (isGiveUp == null) {
                            isGiveUp = info.raesd.Lost_item_giveup__c;
                        }
                        else if (isGiveUp != info.raesd.Lost_item_giveup__c) {
                            // throw new ControllerUtil.myException('请选择欠品明细或者放弃明细');
                        }
                        needAddLRMap.put(info.raesd.id, i + 1);
                    }
                    // 已经提交过遗失申请，草案中，不批准，取消提交状态的话删除遗失申请明细
                    else {
                        // if (info.raesd.LostReport_Detail__r.LostReport__r.Status__c == '草案中') {
                            needCancelLRMap.put(info.raesd.Id, info.raesd);
                        // }
                    }
                }
            }

            if (needAddLRMap.isEmpty() && needCancelLRMap.isEmpty()) {
                throw new ControllerUtil.myException('画面没有变更，不能保存');
            }

            LostReport__c lr;
            List<LostReport_Detail__c> upsertLR = new List<LostReport_Detail__c>();
            List<Rental_Apply_Equipment_Set_Detail__c> raesdList = new List<Rental_Apply_Equipment_Set_Detail__c>();
            Map<Id, LostReport_Detail__c> needAddLrdMap = new Map<Id, LostReport_Detail__c>();
            if (needAddLRMap.isEmpty() == false) {
                // 备品借出备品set一览取得 
                 raesdList = getRaesd(needAddLRMap.keySet(), null, ' FOR UPDATE');
                if (raesdList.size() <= 0) {
                    throw new ControllerUtil.myException('需要提交遗失的明细不存在，请刷新画面重试');
                }
                else {
                    for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList) {
                        if ((raesd.LostReport_Detail__c != null
                                && raesd.LostReport_Detail__r.CancelLostReport__c == false)
                              || raesd.Check_lost_Item_F__c != '欠品') {
                            throw new ControllerUtil.myException(needAddLRMap.get(raesd.id) + '行明细:' + '需要提交遗失报告的明细已经更新，请刷新画面重试');
                        }
                    }
                }
                // String reportStatus = '';
                // if (isNot2B1) {
                //     reportStatus = '申请人提交';
                // }
                // else {
                //     reportStatus = '仓库提交';
                // }
                List<LostReport__c> lrList = [SELECT Id, Name
                                            FROM LostReport__c
                                           WHERE Rental_Apply__c = :raesdList[0].Rental_Apply__c
                                             AND Status__c = '草案中'
                                             AND CreatedById = :UserInfo.getUserId()
                                             ];

                if (lrList.size() > 0) {
                    lr = lrList[0];
                    this.lrName = lr.Name;
                }
                else {
                    lr = new LostReport__c();
                    lr.Rental_Apply__c = raesdList[0].Rental_Apply__c;
                    // lr.Report_Type__c = reportStatus;
                    FixtureUtil.withoutInsert(new LostReport__c[]{lr});
                    lrList = [SELECT Id, Name
                                FROM LostReport__c
                               WHERE Id = :lr.Id
                                 ];
                    this.lrName = lrList[0].Name;
                }

                for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList) {
                    LostReport_Detail__c lrd = new LostReport_Detail__c();
                    lrd.LostReport__c = lr.Id;
                    lrd.Rental_Apply_Equipment_Set_Detail__c = raesd.Id;
                    lrd.Asset__c = raesd.Asset__c;
                    lrd.Quantity__c = 1;
                    needAddLrdMap.put(raesd.Id, lrd);
                }
                upsertLR = needAddLrdMap.values();
            }

            List<LostReport_Detail__c> deleteLR = new List<LostReport_Detail__c>();
            if (needCancelLRMap.isEmpty() == false) {
                for (Id deleLRId : needCancelLRMap.keySet()) {
                    upsertLR.add(new LostReport_Detail__c(Id = needCancelLRMap.get(deleLRId).LostReport_Detail__c,
                                                          CancelLostReport__c = true,
                                                          DeleteLostReport_Detail_Reason__c = needCancelLRMap.get(deleLRId).DeleteLostReport_Detail_Reason__c));
                    Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c(Id = deleLRId);
                    raesd.LostReport_Detail__c = null;
                    raesdList.add(raesd);
                }
            }

            // 追加更新的遗失报告申请明细
            FixtureUtil.withoutUpsertObjects(upsertLR);
            for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList) {
                if (needCancelLRMap.containsKey(raesd.Id) == false) {
                    raesd.LostReport_Detail__c = needAddLrdMap.get(raesd.Id).Id;
                }
            }
            // 更新借出申请明细关联遗失报告明细的字段
            FixtureUtil.withoutUpdate(raesdList);
            reSetInfo(raesdList);
            if (String.isNotBlank(this.lrName)) {
                PageReference pg = new PageReference('/apex/EquipmentRentalLostReport?raid=' + rentalApplyId);
                pg.getParameters().put('lrName',lrName);
                pg.setRedirect(true);
                return pg;
            }*/
        } catch (Exception ex)    {
            system.debug('=====' + ex.getStackTraceString());
            hasError = true;
            ApexPages.addMessages(ex);
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'ex::' +ex.getLineNumber()));

            Database.rollback(sp);
            return null;
        }
        return null;
    }

    public void sortTable() {
        String whereStr = ' AND Check_lost_Item_F__c = \'欠品\'' +
                  // ' AND (LostReport_Detail__c = null ' +
                        // ' OR LostReport_Detail__r.LostReport__r.Status__c = \'草案中\'' +
                        // ' OR LostReport_Detail__r.CancelLostReport__c = true)' +
                  ' ORDER BY ';
        String psortKey = ApexPages.currentPage().getParameters().get('psortKey');
        if(String.isNotBlank(psortKey)){
            this.sortKey = psortKey;
        }
        if (this.sortKey == this.preSortKey) {
            if (String.isBlank(this.sortKey) == false) {
                // 方向が変わるのみ
                this.sortOrderAsc = !this.sortOrderAsc;
                this.sortOrder[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
            }
        } else {
            this.sortOrderAsc = true;
            if (String.isBlank(this.preSortKey) == false) {
                this.sortOrder[Integer.valueOf(this.preSortKey)] = '　';
            }
            this.sortOrder[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
        }
        this.preSortKey = this.sortKey;
        whereStr += columus[Integer.valueOf(this.sortKey)] + ' ' + (sortOrderAsc == true ? 'ASC NULLS FIRST' : 'DESC NULLS LAST');
        // whereStr += ' NULLS LAST';
        //update by rentx 2021-05-13 start 1635
        if (rentalApplyId != null && rentalApplyId.length() > 0) {
            reSetInfo(getRaesd(null, rentalApply.Id, whereStr));
        }else{
            reSetInfo(getRaesd(null,TransferApply.Id,whereStr));
        }
        //update by rentx 2021-05-13 end 1635
    }

    private List<SObject> getRaesd(Set<Id> raesdIdSet, String raId, String elseWhere) {
        String strColumus = String.join(columus, ',');
        for (String mustField : mustFieldSet) {
            if (columusSet.contains(mustField) == false) {
                strColumus += ', ' + mustField;
            }
        }
        String soqlStr = '';
        //add by rentx 20210611 1635 start
        if (transferApplyId != null && transferApplyId != '') {
          //查的时候吧调拨一览的收货NG数查出来
          soqlStr = 'SELECT Id,TransferApply__c,RecordType_F__c,TAESD_Status__c,Return_DeliverySlip__c,OneToOneAccessory__c,ArrivalResult__c,TransferApplySummary__r.Number_of_NG_received__c,Internal_asset_location__c,TransferApplySummary__c,' + strColumus +
                         ' FROM TransferApplyDetail__c ' +
                         ' WHERE Id != null ';
          if (raesdIdSet != null) {
              soqlStr += ' AND Id = :raesdIdSet ';
          }
          if (String.isNotBlank(raId)) {
              soqlStr += ' AND TransferApply__c = :raId ';
          }
          //以下是新加的 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
          // 根据记录类型区分

          // soqlStr += ' and ( (Check_lost_Item_F__c = \'欠品\' AND (RecordType_F__c = \'CenterToCenter\' OR RecordType_F__c = \'AgencyToCenter\') ) OR ( RecordType_F__c = \'CenterToAgency\' AND TAESD_Status__c != \'丢失\' AND ((Return_DeliverySlip__c != null and Check_lost_Item_F__c = \'欠品\') OR (Return_DeliverySlip__c = null and Check_lost_Item_F__c = \'欠品\' AND (Is_Body__c = false OR Loaner_accsessary__c = true OR (OneToOneAccessory__c = true AND ArrivalResult__c != \'NG\') ) )) ) )';
          //记录类型 = 办事处到备品中心 或者 备品中心之间
          soqlStr += ' and ( (Check_lost_Item_F__c = \'欠品\' AND (RecordType_F__c = \'CenterToCenter\' OR RecordType_F__c = \'AgencyToCenter\') ) ';
          //记录类型 = 备品中心到办事处 并且 调拨一览明细状态 != 丢失
          soqlStr += ' OR ( RecordType_F__c = \'CenterToAgency\' AND TAESD_Status__c != \'丢失\' AND ';
          //回寄运输单 != 空 并且欠品确认结果 = 欠品
          soqlStr += ' ((Return_DeliverySlip__c != null and Check_lost_Item_F__c = \'欠品\') OR ';
          //回寄运输单 = 空 并且 欠品确认结果 = 欠品 并且 (单一主体(主体 = true 并且 一对一主体 = false) = true 或者
          soqlStr += ' (Return_DeliverySlip__c = null and Check_lost_Item_F__c = \'欠品\' AND ((Is_Body__c = true AND Main_OneToOne__c = false) ';
          //单独附属品(一对一附属品不勾 并且 备品用途附属品 = 打勾) = true
          soqlStr += ' OR (OneToOneAccessory__c = false AND Loaner_accsessary__c = true)';
          //一对一附属品(附属品是勾并且一对一附属品也是勾) = true 并且 主体欠品确认结果(一对一保管主体sys = true 并且欠品确认结果=欠品)并且 (并且配套在其他一对一附属品调拨到货确认都 != NG 在下面的代码循环判断了)
          // soqlStr += ' OR (OneToOneAccessory__c = true AND Loaner_accsessary__c = true AND ArrivalResult__c = \'OK\' AND ArrivalResult__c != \'NG\') ) )) ) )';
          soqlStr += ' OR (OneToOneAccessory__c = true AND Loaner_accsessary__c = true AND ArrivalResult__c != \'NG\') ) )) ) )';

          //以上是新加的 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
          if (String.isNotBlank(elseWhere)) {
              soqlStr += elseWhere;
          }
          //add by rentx 20210604 start
          List<TransferApplyDetail__c> tlist = Database.query(soqlStr);
          List<TransferApplyDetail__c> resultList = new List<TransferApplyDetail__c>();

          Set<Id> ylids = new Set<Id>();
          //一个调拨申请一览中 只要有一个状态是NG就不展示  一对一保管主体=true并且欠品确认结果=OK
          Map<Id,List<TransferApplyDetail__c>> map1 = new Map<Id,List<TransferApplyDetail__c>>();

          if (tList != null && tList.size() > 0) {
              for (TransferApplyDetail__c detail : tList) {
                  //如果符合查询条件
                if (detail.RecordType_F__c == 'CenterToAgency' && detail.TAESD_Status__c != '丢失'
                    && detail.Return_DeliverySlip__c == null && detail.Check_lost_Item_F__c == '欠品' 
                    && detail.OneToOneAccessory__c && detail.ArrivalResult__c != 'NG') {
                    //当调拨明细对应的调拨一览下的所有明细的调拨到货确认结果都不等于NG时,才可展示
                    if (Integer.valueOf(detail.TransferApplySummary__r.Number_of_NG_received__c) == 0) {
                        // resultList.add(detail);

                        if (!map1.containsKey(detail.TransferApplySummary__c)) {
                            map1.put(detail.TransferApplySummary__c, new List<TransferApplyDetail__c>() );
                        }else{
                          List<TransferApplyDetail__c> tempList = map1.get(detail.TransferApplySummary__c);
                          tempList.add(detail);
                          map1.put(detail.TransferApplySummary__c, tempList );
                        }
                    }
                }else {
                    //符合其他条件
                    resultList.add(detail);
                }
              }
          }


          //再过滤一下 一对一附属品并且欠品对应的一览下的所有明细的 一对一保管主体(sys) 和欠品确认结果=OK
          if (map1.size() > 0) {
              List<TransferApplyDetail__c> dlist = [SELECT Id,Name,TransferApply__c,RecordType_F__c,TAESD_Status__c,Return_DeliverySlip__c,
                                              OneToOneAccessory__c,ArrivalResult__c,TransferApplySummary__r.Number_of_NG_received__c,
                                              Internal_asset_location__c,TransferApplySummary__c,LostReport_Detail__r.LostReport_Status_F__c,
                                              Lost_item_giveup__c,DeleteLostReport_Detail_Reason__c,LostReport_Detail__r.CreatedById,
                                              Confirm_Lost_Date__c,LostReport_Detail__c,LostReport_Detail__r.CancelLostReport__c,
                                              Asset__r.Internal_Asset_number__c,Check_lost_Item_F__c,Loaner_asset_no__c,Main_OneToOne__c,Fixture_Model_No_F__c,
                                              SerialNumber_F__c,From_Location__c,Destination_location__c,LostReport_Detail__r.LostReport__c        
                                              FROM TransferApplyDetail__c WHERE TransferApplySummary__c in :map1.keySet()];
              if (dlist !=null && dlist.size() > 0) {
                  for (TransferApplyDetail__c detail : dlist) {
                    //如果 (一对一保管主体(sys) =true 和欠品确认结果 = OK) 是false 那么这个一览下的所有明细都不展示 反之 展示
                      // if (!(detail.Main_OneToOne__c && detail.Check_lost_Item_F__c == 'OK')) {
                      if ((detail.Main_OneToOne__c  && detail.Check_lost_Item_F__c != 'OK') || (!detail.Main_OneToOne__c  && detail.Check_lost_Item_F__c == 'OK')){
                        if (map1.containsKey(detail.TransferApplySummary__c)) {
                            map1.remove(detail.TransferApplySummary__c); 
                        }
                      }
                  }
              }
              for (TransferApplyDetail__c detail : dlist) {
                if (map1.containsKey(detail.TransferApplySummary__c) && detail.Check_lost_Item_F__c == '欠品') {
                    resultList.add(detail);
                }
              }

              Set<TransferApplyDetail__c> tempSet = new Set<TransferApplyDetail__c>();
              tempSet.addAll(resultList);
              resultList = new List<TransferApplyDetail__c>();
              resultList.addAll(tempSet);
          }

          // if (map1.size() > 0) {
          //   for (Id ylid : map1.keySet()) {
          //       resultList.addAll(map1.get(ylid));
          //   }
          // }



          return resultList;
          //add by rentx 20210604 end
          
        }else{
          //add by rentx 20210611 1635 end
          soqlStr = 'SELECT Id,' + strColumus +
                         ' FROM Rental_Apply_Equipment_Set_Detail__c ' +
                       ' WHERE Id != null ';
          if (raesdIdSet != null) {
              soqlStr += ' AND Id = :raesdIdSet ';
          }
          if (String.isNotBlank(raId)) {
              soqlStr += ' AND Rental_Apply__c = :raId ';
          }
          if (String.isNotBlank(elseWhere)) {
              soqlStr += elseWhere;
          }
          return Database.query(soqlStr);
        }
        
        // System.debug(soqlStr);        
        // return Database.query(soqlStr);
    }


    private void reSetInfo(List<SObject> raesdList) {
        lineInfoList = new List<LineInfo>();
        //update by rentx 2021-05-08 start 1635
        /*for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList) {
            LineInfo lineInfo = new LineInfo(raesd, isNot2B1);
            lineInfoList.add(lineInfo);
        }*/
        if (transferApplyId != null && transferApplyId != '') {
          List<TransferApplyDetail__c> traList = (List<TransferApplyDetail__c>) raesdList;
           for (TransferApplyDetail__c raesd : traList) {
              LineInfo lineInfo = new LineInfo(raesd, isNot2B1);
              lineInfoList.add(lineInfo);
          }
        }else{
          List<Rental_Apply_Equipment_Set_Detail__c> raeLust = (List<Rental_Apply_Equipment_Set_Detail__c>) raesdList;
          for (Rental_Apply_Equipment_Set_Detail__c raesd : raeLust) {
              LineInfo lineInfo = new LineInfo(raesd, isNot2B1);
              lineInfoList.add(lineInfo);
          }
        }
        //update by rentx 2021-05-08 end 1635
        
    }

    @TestVisible
    class LineInfo {
        // 选择
        public boolean isSelect { get; set; }
        public boolean oldSelect { get; set; }
        public Boolean haveConfirm_Lost_Date { get; set; } // 借出申请人-销售本部
        public Boolean oldhaveConfirm_Lost_Date { get; set; } // 借出申请人-销售本部
        public Boolean lrdApprovaled { get; set; } // 借出申请人-销售本部
        // 借出备品set一览明细
        public Rental_Apply_Equipment_Set_Detail__c raesd { get; set; }
        public String salesdepartment { get; private set; } // 借出申请人-销售本部
        public Boolean haveLostReport { get; private set; } // 借出申请人-销售本部
        public Boolean checkBoxdisabled { get; private set; }

        public LineInfo(Rental_Apply_Equipment_Set_Detail__c r, Boolean isNot2B1) {
            raesd = r;
            haveLostReport = r.LostReport_Detail__c != null;
            isSelect = haveLostReport && r.LostReport_Detail__r.CancelLostReport__c == false && r.LostReport_Detail__r.LostReport_Status_F__c != '取消';
            oldSelect = isSelect;
            haveConfirm_Lost_Date = r.Confirm_Lost_Date__c != null;
            oldhaveConfirm_Lost_Date = haveConfirm_Lost_Date;
            // #OCSM_BP3-110 确认遗失和报告对象的CheckBox,在提交过遗失报告,且明细断念后就不能去掉了
            lrdApprovaled = String.isNotBlank(r.LostReport_Detail__c)
                            || (isNot2B1 == true && r.Lost_item_giveup__c == true)
                            || (r.Lost_item_giveup__c == true && r.Confirm_Lost_Date__c != null);
            checkBoxdisabled = String.isBlank(r.Loaner_asset_no__c)
                                   || !haveConfirm_Lost_Date
                                   || (isNot2B1 == true
                                            && r.Lost_item_giveup__c == true)
                                   || (r.LostReport_Detail__r.CreatedById != UserInfo.getUserId()
                                            && String.isNotBlank(r.LostReport_Detail__r.CreatedById))
                                   || (r.Lost_item_giveup__c == true && String.isNotBlank(r.LostReport_Detail__c));
        }

        //add by rentx 2021-05-08 start 1635
        public TransferApplyDetail__c raesd1 { get; set; }
        public LineInfo(TransferApplyDetail__c r, Boolean isNot2B1) {
            raesd1 = r;
            haveLostReport = r.LostReport_Detail__c != null;
            isSelect = haveLostReport && r.LostReport_Detail__r.CancelLostReport__c == false && r.LostReport_Detail__r.LostReport_Status_F__c != '取消';
            oldSelect = isSelect;
            haveConfirm_Lost_Date = r.Confirm_Lost_Date__c != null;
            oldhaveConfirm_Lost_Date = haveConfirm_Lost_Date;
            // #OCSM_BP3-110 确认遗失和报告对象的CheckBox,在提交过遗失报告,且明细断念后就不能去掉了
            lrdApprovaled = String.isNotBlank(r.LostReport_Detail__c)
                            || (isNot2B1 == true && r.Lost_item_giveup__c == true)
                            || (r.Lost_item_giveup__c == true && r.Confirm_Lost_Date__c != null);
            checkBoxdisabled = String.isBlank(r.Loaner_asset_no__c)
                                   || !haveConfirm_Lost_Date
                                   || (isNot2B1 == true
                                            && r.Lost_item_giveup__c == true)
                                   || (r.LostReport_Detail__r.CreatedById != UserInfo.getUserId()
                                            && String.isNotBlank(r.LostReport_Detail__r.CreatedById))
                                   || (r.Lost_item_giveup__c == true && String.isNotBlank(r.LostReport_Detail__c));
        }
        //add by rentx 2021-05-08 end 1635
    }


    public void addFGL(){
        Integer i = 0;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
    }

}