/**
 * 主体备品选择の設定
 * TestClass
 * MainFixtureSelectControllerTest
 * RentalFixtureManage1Test
 * RentalFixtureManage4Test
 */
global without sharing class MainFixtureSelectController extends CreateRelationListPagingCtrlBase {
    public override Integer getSearchNumMax() {
        //各ページに制御あれば、最大件数を指定する
        // searchNumMax = Integer.valueOf(Label.Product_Select_Limit);
        // searchNumMax = 20;
        pagesize = '20';
        return searchNumMax;
    }

    /* 選択されたデータ取得用Soql　Fromから*/
    public override String getSelectedDataSql() {
        // オブジェクトAPI名
        selectedDataSql = ' From Rental_Apply_Equipment_Set_Detail__c';
        selectedDataSql += ' where Rental_Apply_Equipment_Set__c = \'' + String.escapeSingleQuotes(parentId) + '\'';
        selectedDataSql += '   and Is_Body__c = true';
        selectedDataSql += '   and Cancel_Select__c = false';
        selectedDataSql += '   and ApplyPersonAppended_F__c = false';
        selectedDataSql += ' order by Equipment_Type__c DESC  nulls last, FSD_Fixture_Model_No__c ASC nulls last';
        return selectedDataSql;
    }

    public override String getOriginObjName() {
        // オブジェクトAPI名
        originObjName = 'Asset';
        return originObjName;
    }
    public override String getOriginObjColumns() {
        // 項目セット
        originObjColumns = 'Id, Last_Reserve_RAES_Detail__c, Last_Reserve_RAES_Detail__r.Rental_Apply_Equipment_Set__c';
        return originObjColumns;
    }

    public override String getObjName() {
        // オブジェクトAPI名
        objName = 'Rental_Apply_Equipment_Set_Detail__c';
        return objName;
    }
    public override String getColumnLeftFieldSetName() {
        // 左の項目セット
        columnLeftFieldSetName = 'MainFixtureSelect_LeftFieldSet';
        return columnLeftFieldSetName;
    }
    public override String getColumnRightFieldSetName() {
        // 右の項目セット
        columnRightFieldSetName = 'MainFixtureSelect_RightFieldSet';
        return columnRightFieldSetName;
    }

    public override List<String> getColumnFieldList() {
        // strColumus 里加 field
        // FixtureUtil#raesdGroupByAssetId()の項目も必要
        return new List<String>{'Id', 'Rental_Apply_Equipment_Set__c', 'FSD_Id__c', 'Select_Time__c', 'Rental_Apply_Equipment_Set__r.Final_reply_day_text__c',
                'IndexFromUniqueKey__c', 'Queue_Number__c', 'SalesProvince__c', 'Fixture_Model_No_text__c', 'DeliverySlip__c', 'StockDown__c', 'Fixture_Model_No_F__c',
                'Rental_Apply__r.Internal_asset_location_F__c', 'Rental_Apply__r.Salesdept__c', 'Rental_Apply__r.Equipment_Type_F__c', 'Rental_Apply__r.Salesdepartment__c',
                'RAESD_Status__c', 'FSD_Fixture_Model_No__c', 'Is_Body_F__c', 'FSD_OneToOneAccessory_Cnt__c', 'Internal_asset_location__c',
                'Asset__r.Last_Reserve_RAES_Detail__r.Rental_Apply_Equipment_Set__c', 'Asset__r.Last_Reserve_RAES_Detail__r.Select_Time__c',
                'Asset__r.Fixture_Status__c', 'Asset__r.Last_Reserve_RAES_Detail__c', 'Asset__r.Main_OneToOne__c', 'Asset__r.You_Xiao_Ku_Cun__c',
                'Rental_Apply__r.demo_purpose2__c','Rental_Apply__r.Follow_UP_Opp__r.Shipping_Finished_Day_Func__c', 'Intervention_Reason__c',
                'Rental_Apply__r.next_action__c','Rental_Apply__r.QIS_number__r.ReplaceDeliveryDate__c', 'ExternalKey__c'
        };
    }

    public override String getFKColumnField() {
        // getObjName 连 getOriginObjName 的 FK
        return 'Asset__c';
    }

    public override String getRecordTypeId() {
        //ページレイアウトを収得するのレコードタイプ
        recordTypeId = '';
        return recordTypeId;
    }

    // ページコントローラに検索処理は、WhereSoql作成のみ、パラメータとして、コンポーネントに渡される
    public override String getSqlWhereStr() {
        sqlWhereStr = '';

        if (getIsNeedRunSearch()) {
            sqlWhereStr = this.makeSoql(keywdSort);
        }

        return sqlWhereStr;
    }

    public override String getOrderbyStr() {
        String ordStr = '';
        if (isFirstTime) {
            ordStr = ', Equipment_Type__c DESC  nulls last';
            isFirstTime = false;
        }
        // 备品智能化项目对应 20231122 by lc Start
        // ORDER BY 集中管理库存 DESC, 效期(未过期(到期日-今天)降序>空>已过期(今天-到期日)降序), 30天先进先出,最新上架日 ASC NULLS FIRST, 最新备品申请借出明细.回寄日 ASC, 备品分类 DESC  nulls last
        return 'order by Ji_Zhong_Guan_Li_Ku_Cun__c DESC, Expiration_Day__c DESC, FirstInOutBy30Days__c DESC NULLS LAST, Pre_Arrival_wh_time__c ASC NULLS FIRST, Last_Reserve_RAES_Detail__r.Asset_return_Day__c ASC' + ordStr;
        // return 'order by Ji_Zhong_Guan_Li_Ku_Cun__c DESC, Pre_Arrival_wh_time__c ASC NULLS FIRST, Last_Reserve_RAES_Detail__r.Asset_return_Day__c ASC' + ordStr;
        // 备品智能化项目对应 20231122 by lc End
    }

    public override Boolean getIsNeedRunSearch() {
        return true;
    }

    // ClickEvent用URL
    public String queueByAsset {
        get {
            return queueByAsset;
        }
        set;
    }

    /*****************検索用******************/


    /*****************ソート時再検索条件（画面からの入力条件を無視するため）******************/
    private String keywdSort = null;
    public String keyword { get; set; }
    public String assetId { get; set; }
    public String rentalId { get; set; }
    public String raesdId { get; set; }
    public String modelNo { get; set; }

    public String saveType { get; set; }

    public Rental_Apply_Equipment_Set__c parentObj { get; private set; }
    public Rental_Apply_Equipment_Set_Detail__c sonObj { get; set; }

    public Boolean bieField { get; set; }   //别省、别本部、别存放地、别用途

    public String bieCunFangDi { get; set; }     //别存放地
    public String bieBenBu { get; set; }         //别本部
    public String bieChanPinFenLei { get; set; } //产品分类 Test用
    public String campaignType { get; set; } //学会类型
    public String bieBeiPinFenLei { get; set; }  //别备品分类
    public Boolean changeCampaignType { set; get; }  //学会类型改变Flag
    //public List<String> bieBeiPinFenLeiList { get; set; }  //别备品分类
    public Boolean isFirstTime = true;
    public Boolean is2B1 = true;
    public String pCunFangDi;
    public Set<String> benbuSet;
    public Set<String> cunfangdiSet;
    public static String wrapperStr{set;get;}
    // 备品智能化项目对应 20231122 by lc Start
    public String interventionType { get; set; }
    public Boolean isBefore7Days { get; set; }
    // 备品智能化项目对应 20231122 by lc End

    public MainFixtureSelectController() {

        //isNeedCheckEvent = true;
        parentId = ApexPages.currentPage().getParameters().get('pt_recid');
        //bieBeiPinFenLeiList = new List<String>();
        is2B1 = UserInfo.getProfileId() == System.Label.ProfileId_EquipmentCenter;
        benbuSet = new Set<String>();
        cunfangdiSet = new Set<String>();
        this.bieField = true;
        changeCampaignType = false;
        isBefore7Days = false;
        //借出备品一览の情報を取得
        if (!String.isBlank(this.parentId)) {
            List<Rental_Apply_Equipment_Set_Detail__c> raesdObjs = [
                    SELECT Id, Rental_Apply_Equipment_Set__c, Asset__c, Queue_Day__c,
                           FSD_Fixture_Model_No__c, Fixture_Model_No_text__c, QuenType__c,
                           Is_Body__c, FSD_Is_OneToOne__c, Select_Time__c, ExternalKey__c,Rental_Apply__c,
                           Cancel_Select__c, Fixture_Model_No_F__c, Queue_Number__c, Internal_asset_location__c,
                           Salesdepartment__c, Product_category_F__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__r.Cross_Region_Assign__c,
                           Rental_Apply__r.Demo_purpose2__c, Rental_Apply__r.Request_shipping_day__c, Rental_Apply__r.OPDPlan__c, Rental_Apply__r.Manually_Flag__c,
                           Rental_Apply_Equipment_Set__r.Fixture_Set__r.Product_Type__c, Intervention_Reason__c,
                           Salesdepartment_before__c, Equipment_Type_text__c, Product_category_text__c
                     FROM Rental_Apply_Equipment_Set_Detail__c
                    WHERE Rental_Apply_Equipment_Set__c = :parentId
                      and Is_Body__c = true
                      and Cancel_Select__c = false];

            if (!raesdObjs.isEmpty()) {
                sonObj = raesdObjs[0];

                // 备品智能化项目对应 20231122 by lc Start
                // 所有的申请单中只有学会展会的可以提前7天做人工分配，但不可以提前排队
                if (sonObj.Rental_Apply__r.Request_shipping_day__c > Date.today().addDays(7)) {
                    isBefore7Days = true;
                }
                // 备品智能化项目对应 20231122 by lc End

                List<Rental_Apply_Equipment_Set__c> parentObjs = [
                        SELECT Id, Rental_Apply__r.Name,
                               Rental_Apply__r.Owner.Name,
                               Rental_Apply__r.Owner.Profile.Name,
                               Rental_Apply__r.Salesdept__c,
                               Rental_Apply__r.WorkPlace__c,
                               Rental_Apply__r.Request_shipping_day__c,
                               Fu_Shu_Pin_Fen_Pei_Jia__c,
                               Rental_Apply__r.Demo_purpose1__c,
                               Rental_Apply__r.demo_purpose2__c,
                               Rental_Apply__r.CampaignType__c,
                               Fixture_Set__r.Product_Category_GI_SP__c,
                               Fixture_Set__r.Equipment_Type__c,
                               Rental_Apply__r.Request_return_day__c,
                               Rental_Apply__r.Salesdepartment__c,
                               Rental_Apply__r.Equipment_Type_F__c,
                               Rental_Apply__r.Internal_asset_location_F__c,
                               Fixture_Set__r.Fixture_Set_Body_Model_No__c,
                               Rental_Apply__r.Product_category__c,
                               Rental_Apply__r.Loaner_centre_mail_address__c,
                               First_RAESD__r.Is_Body__c,
                               Irreplaceable_flag__c,
                               Rental_Start_Date__c,
                               Rental_End_Date__c,
                               Rental_Apply__c,
                               Fixture_Set__c,
                               RequestNoJoinStr2__c
                        FROM Rental_Apply_Equipment_Set__c
                        where Id = :parentId];
                if (!parentObjs.isEmpty()) {
                    parentObj = parentObjs.get(0);

                    // 已排队的情况下，初始化时加载排队画面
                    if (sonObj.ExternalKey__c != null) {
                        // QueuePageByAssetId的URL, 加载排队画面用
                        queueByAsset = '/apex/QueuePageByAssetId?parentId=' + parentObj.Id + '&isNotShow=' + true;
                    }

                    bieCunFangDi = parentObj.Rental_Apply__r.Internal_asset_location_F__c;
                    pCunFangDi = bieCunFangDi;
                    // 本部初始值
                    bieBenBu = parentObj.Rental_Apply__r.Salesdepartment__c;
                    /*if (String.isNotBlank(sonObj.QuenType__c) && String.isNotBlank(sonObj.Salesdepartment_before__c)) {
                        bieBenBu = sonObj.Salesdepartment_before__c;
                    } else {
                        bieBenBu = parentObj.Rental_Apply__r.Salesdepartment__c;
                    }*/

                    // 备品分类初始值
                    bieBeiPinFenLei = parentObj.Rental_Apply__r.Equipment_Type_F__c;
                    /*if (String.isNotBlank(sonObj.QuenType__c) && String.isNotBlank(sonObj.Equipment_Type_text__c)) {
                        bieBeiPinFenLei = sonObj.Equipment_Type_text__c;
                    } else {
                        bieBeiPinFenLei = parentObj.Rental_Apply__r.Equipment_Type_F__c;
                    }*/

                    // 产品分类初始值
                    bieChanPinFenLei = parentObj.Rental_Apply__r.Product_category__c;
                    /*if (String.isNotBlank(sonObj.QuenType__c) && String.isNotBlank(sonObj.Product_category_text__c)) {
                        if (sonObj.Product_category_text__c == 'GI,SP') {
                            bieChanPinFenLei = '';
                        } else {
                            bieChanPinFenLei = sonObj.Product_category_text__c;
                        }
                    } else {
                        bieChanPinFenLei = parentObj.Rental_Apply__r.Product_category__c;
                    }*/
                    // bieBeiPinFenLeiList = FixtureUtil.setAssetRAESEquipment_Type(parentObj.Rental_Apply__r.demo_purpose2__c);
                    //if (bieBeiPinFenLeiList.size() == 0 && String.isNotBlank(parentObj.Rental_Apply__r.Equipment_Type_F__c)) {
                    //    for (String et : parentObj.Rental_Apply__r.Equipment_Type_F__c.split(',')) {
                    //        bieBeiPinFenLeiList.add(et);
                    //    }
                    //}
                    // benbuList = FixtureUtil.setAssetRAESSalesdepartment(parentObj.Rental_Apply__r.demo_purpose2__c);
                    // fenleiList = FixtureUtil.setAssetRAESEquipment_Type(parentObj.Rental_Apply__r.demo_purpose2__c);
                    // System.debug(fenleiList);
                    campaignType = parentObj.Rental_Apply__r.CampaignType__c;
                }
                if (String.isBlank(bieCunFangDi)) {
                    throw new ControllerUtil.myException('不能明确存放地, 请确认数据。');
                }
            } else {
                throw new ControllerUtil.myException('没有可以操作的主体备品或者主体数据不正确。');
            }
        } else {
            // OLY_OCM-721 Bug fix 选择配套时报错: null point
            // 追加parentId是否为空的检查，如果URL参数的parentId为空就报错: 参数错误：请指定Id。。
            throw new ControllerUtil.myException('参数错误：请指定Id。');
        }
    }

    public void init() {
        isNeedSearchFirst = true;
        //isNeedCheckEvent = true;

        searchOppSetParam();

        getSqlWhereStr();
    }

    //别存放地 SelectOption
    public List<SelectOption> getbieCunFangDiOps() {
        //备品存放地(现在)
        // return FixtureUtil.bieCunFangDiOpsMap.get(sonObj.Internal_asset_location__c);
        // return new List<SelectOption>{
        //     new SelectOption(sonObj.Rental_Apply__r.Internal_asset_location_F__c, sonObj.Rental_Apply__r.Internal_asset_location_F__c)
        // };
        cunfangdiSet = new Set<String>();
        List<SelectOption> opList;
        if (UserInfo.getProfileId() == System.Label.ProfileId_SystemAdmin
                || System.Label.ProfileId_EquCenAdmin.contains(UserInfo.getProfileId())
                || is2B1) {
            opList = FixtureUtil.bieCunFangDiOpsMap.get('备品管理中心');
        } else {
            if (String.isBlank(bieCunFangDi)) {
                opList = FixtureUtil.bieCunFangDiOpsMap.get('备品管理中心');
            } else {
                opList = new List<SelectOption>{
                    new SelectOption(bieCunFangDi, bieCunFangDi)
                };
            }
        }

        for (SelectOption op : opList) {
            if (String.isNotBlank(op.getValue())) {
                cunfangdiSet.add(op.getValue());
            }
        }
        return opList;
    }

    //别本部 SelectOption
    public List<SelectOption> getbieBenBuOps() {
        //所在地区(本部) 现在
        // return FixtureUtil.bieBenBuOpsMap.get(sonObj.Salesdepartment__c);
        benbuSet = new Set<String>();
        List<SelectOption> opList;
        List<SelectOption> retList = new List<SelectOption>();
        if (String.isBlank(bieCunFangDi)) {
            opList = FixtureUtil.bieBenBuOpsMap.get('All');
        } else {
            opList = FixtureUtil.bieBenBuOpsMap.get(bieCunFangDi);
        }
        retList.add(new SelectOption('全部', '--全部--'));
        for (SelectOption op : opList) {
            if (String.isNotBlank(op.getValue())) {
                benbuSet.add(op.getValue());
                retList.add(new SelectOption(op.getValue(),op.getLabel()));
            }
        }
        return retList;
    }

    //产品分类 SelectOption
    public List<SelectOption> getbieChanPinFenLeiOps() {
        //产品分类(GI/SP) F Product_category_F__c
        // return FixtureUtil.bieChanPinFenLeiOpsMap.get(sonObj.Product_category_F__c);
        // return FixtureUtil.bieChanPinFenLeiOpsMap.get('GISP');
        List<SelectOption> pickListValuesList = FixtureUtil.bieChanPinFenLeiOpsMap.get('GISP');
        return pickListValuesList;
    }

    //别备品分类 SelectOption
    public List<SelectOption> getbieBeiPinFenLeiOps() {
        //备品分类(现在) Equipment_Type__c
        // return FixtureUtil.bieBeiPinFenLeiOpsMap.get(sonObj.Equipment_Type__c);
        return FixtureUtil.bieBeiPinFenLeiOpsMap.get('备品分类');
    }

    //学会类型 SelectOption
    public List<SelectOption> getcampaignTypeOps() {
        //学会类型 CampaignType__c
        return FixtureUtil.getPlickList('Rental_Apply__c', 'CampaignType__c');
    }

    private void searchOppSetParam() {
        keywdSort = keyword;
    }

    public PageReference searchOpp() {
        searchOppSetParam();

        if (!getIsNeedRunSearch()) {
            return null;
        }

        // 選択済みの製品を取得
        myComponentController.getSelectedDataInfo();

        getSqlWhereStr();
        // コンポーネントにSoqlを発行して、ページングする
        myComponentController.searchAndPaging();
        return null;
    }

    //获取当前时间 getCurrentTime
    public static Time getCurrentTime() {
        DateTime now = DateTime.now();
        System.debug('GMT: ' + now);
        Integer hours = now.hour();
        Integer minutes = now.minute();
        Integer seconds = now.second();
        Integer milliseconds = now.millisecond();
        System.debug('local time: ' + hours + ':' + minutes + ':' + seconds + ':' + milliseconds);
        Time currentTime = Time.newInstance(hours, minutes, seconds, milliseconds);
        if (Test.isRunningTest()) {
            testCheck();
        }
        return currentTime;
    }
    /*
     * MainFixture的排队  // TODO 4つの項目で１つのblockです
     * @param raseId Rental_Apply_Equipment_Set__cのId
     * @param astId AssetのId
     * @return map {code: message:}
     */
    @RemoteAction
    global static Map<String, String> queue(Id raseId, Id assetId) {
        // 返回对象
        Map<String, String> responseMap = new Map<String, String>();
        // 検索条件
        Date dateToday = Date.today();
        System.debug('测试queue的raseId:' + raseId);
        System.debug('测试queue的assetId:' + assetId);

        Savepoint sp = Database.setSavepoint();
        try {
            // 排队时不是以Asset.Id为检索基准的,是以当前选中这一条的四个别字段和同一产品型号为条件来操作的
            // 先检索当前选中这条数据的四个别字段和 F__c
            List<Asset> aSetSelect = [Select Id, Fixture_Model_No_F__c,
                    Salesdepartment__c, SalesProvince__c, Product_category__c, Equipment_Type__c, Internal_asset_location__c
                     From Asset
                    Where Id = :assetId
                      FOR Update];

            if (aSetSelect.size() == 0) {
                throw new ControllerUtil.myException('选择的数据有问题，请重试');
            }
            // 操作対象
            List<Rental_Apply_Equipment_Set_Detail__c> rasedList = [
                    SELECT Id, Asset__c, Fixture_Model_No_text__c,
                           Salesdepartment_before__c, Product_category_text__c, Equipment_Type_text__c,
                           Queue_Number__c,
                           Queue_Day__c,
                           Select_Time__c,
                           UniqueKey__c,
                           StockDown__c,
                           Internal_asset_location_before__c
                    FROM Rental_Apply_Equipment_Set_Detail__c
                    where Rental_Apply_Equipment_Set__c = :raseId
                      and Cancel_Select__c = false
                      and Is_Body__c = true
                      FOR Update];
            if (rasedList.size() == 0) {
                throw new ControllerUtil.myException('排队数据不存在');
            }
            Rental_Apply_Equipment_Set_Detail__c raesd = rasedList[0];
            // 下架后不能排队、入力規則 Cannot_Change_Asset にてチェック済み
            // 排队的数据, 不能再次排自己
            if(raesd.Fixture_Model_No_text__c == aSetSelect[0].Fixture_Model_No_F__c
                    && raesd.Salesdepartment_before__c == aSetSelect[0].Salesdepartment__c
                    && raesd.Product_category_text__c == aSetSelect[0].Product_category__c
                    && raesd.Equipment_Type_text__c == aSetSelect[0].Equipment_Type__c
                    && raesd.Internal_asset_location_before__c == aSetSelect[0].Internal_asset_location__c
                    // 排队中的明细才会报以下错误
                    && raesd.Queue_Number__c > 0
                    && raesd.Queue_Day__c != null) {
                throw new ControllerUtil.myException('已经排了这个型号,不需要排队');
            }
            Map<String, Rental_Apply_Equipment_Set_Detail__c> mfUpsert = new Map<String, Rental_Apply_Equipment_Set_Detail__c>();
            mfUpsert.put(raesd.UniqueKey__c, raesd);
            // 因为排过队的再次排队受到有效库存数影响所以需要清空
            // 排队したの場合、まず排队しないことに変更
            if (raesd.queue_Day__c != null) {
                raesd.Queue_User__c   = null;
                raesd.Queue_Number__c = null;
                raesd.Queue_Day__c    = null;
                raesd.Queue_Time__c   = null;
                raesd.Asset__c        = null;
            }
            // 分配したの場合、まず分配しないことに変更
            else if (raesd.Select_Time__c != null) {
                raesd.Select_Time__c  = null;
                raesd.Asset__c        = null;
                // 已出库指示的排队后清除出库指示信息
                raesd.Shipment_request_time2__c = null;
                raesd.Shipment_request__c = false;
            }
            if (!mfUpsert.isEmpty()) {
                Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
                FixtureUtil.withoutUpsertRaesd(mfUpsert.values());
                Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());
            }
            // ここまで まだ コミットしていないっです。
            String soqlStr = 'Select Id, Last_Reserve_RAES_Detail__c, Fixture_Model_No_F__c, You_Xiao_Ku_Cun__c,'
                        + ' Salesdepartment__c, SalesProvince__c, Product_category__c, Equipment_Type__c, Internal_asset_location__c'
                         + ' From Asset '
                        + ' Where Asset_Owner__c = \'Olympus\''
                        + ' and Asset_loaner_category__c != \'耗材\''
                        + ' and RecordTypeId = \''+System.label.access_1+'\''
                        + ' and Delete_Flag__c = False'
                        + ' and Recall_Asset__c = False'
                        + ' and Freeze_sign_Abandoned_Flag__c = False'
                        + ' and Product2.Fixture_Model_No_T__c = ' + FixtureUtil.getSoqlString(aSetSelect[0].Fixture_Model_No_F__c)
                        + ' and Salesdepartment__c = ' + FixtureUtil.getSoqlString(aSetSelect[0].Salesdepartment__c)
                        + ' and Internal_asset_location__c = ' + FixtureUtil.getSoqlString(aSetSelect[0].Internal_asset_location__c)
                        // + ' and SalesProvince__c = ' + FixtureUtil.getSoqlString(aSetSelect[0].SalesProvince__c)
                        + ' and Product_category__c = ' + FixtureUtil.getSoqlString(aSetSelect[0].Product_category__c)
                        + ' and Equipment_Type__c = ' + FixtureUtil.getSoqlString(aSetSelect[0].Equipment_Type__c)
                        + ' and ' + FixtureUtil.getAssetSoqlBase()
                        + ' order by Id';
            // 检索符合这四个别字段和同一产品型号的数据存在与否
            List<Asset> aSetCheck = Database.query(soqlStr);
            // List<Asset> aSetCheck = [Select Id, Last_Reserve_RAES_Detail__c, Fixture_Model_No_F__c, You_Xiao_Ku_Cun__c,
            //         Salesdepartment__c, SalesProvince__c, Product_category__c, Equipment_Type__c, Internal_asset_location__c
            //          From Asset
            //         Where Asset_Owner__c = 'Olympus'
            //           and Asset_loaner_category__c != '耗材'
            //           and RecordTypeId = '01210000000kOPR'
            //           and Delete_Flag__c = False
            //           and Freeze_sign_Abandoned_Flag__c = False
            //           and Product2.Fixture_Model_No_T__c = :aSetSelect[0].Fixture_Model_No_F__c
            //           and Salesdepartment__c = :aSetSelect[0].Salesdepartment__c
            //           and SalesProvince__c = :aSetSelect[0].SalesProvince__c
            //           and Product_category__c = :aSetSelect[0].Product_category__c
            //           and Equipment_Type__c = :aSetSelect[0].Equipment_Type__c
            //         order by Id];

            for (Asset ass : aSetCheck) {
                if (ass.Last_Reserve_RAES_Detail__c == null && ass.You_Xiao_Ku_Cun__c > 0) {
                    throw new ControllerUtil.myException('有可以分配主体不需要排队');
                }
            }

            // 不存在则画面提示错误信息
            if (aSetCheck.size() == 0) {
                throw new ControllerUtil.myException('排队选择主体数据不存在');
            }
            // 之前因为只是做Check,不是实际的排队操作,不rollback的话后面的排队数不对
            Database.rollback(sp);
            // OLY_OCM-1157 因为暂时直觉的保有设备的变量有影响,所以明细Handler先不清空(有影响的地方是明细和保有设备的Handler)
            AssetHandler.queueRaesdMap = null;
            // lock 符合条件的第一条Asset数据、进行排队。
            List<Asset> aSet = [Select Id, Name, Last_Reserve_RAES_Detail__c, Fixture_Model_No_F__c,
                    Salesdepartment__c, SalesProvince__c, Product_category__c, Equipment_Type__c,
                    Internal_asset_location__c, EquipmentSet_Managment_Code__c
                     From Asset
                    Where Id = :aSetCheck[0].Id
                    FOR Update];

            if (aSet.size() == 0) {
                throw new ControllerUtil.myException('数据正在被其他用户操作，请重试');
            }
            // 操作対象
            rasedList = [
                    SELECT Id, Asset__c, Fixture_Model_No_text__c,
                           Salesdepartment_before__c, Product_category_text__c, Equipment_Type_text__c,
                           Queue_Number__c,
                           Queue_Day__c,
                           Select_Time__c,
                           UniqueKey__c,
                           StockDown__c
                    FROM Rental_Apply_Equipment_Set_Detail__c
                    where Rental_Apply_Equipment_Set__c = :raseId
                      and Cancel_Select__c = false
                      and Is_Body__c = true
                      FOR Update];
            if (rasedList.size() == 0) {
                throw new ControllerUtil.myException('排队数据不存在');
            }
            raesd = rasedList[0];
            mfUpsert.put(raesd.UniqueKey__c, raesd);
            String modelNo = aSet[0].Fixture_Model_No_F__c;

            System.debug('queue aSet is:' + aSet);

            //借出备品配套一览明细 Rental_Apply_Equipment_Set_Detail__c  Asset__c
            //排队顺 Queue_Number__c
            //排队日 Queue_Day__c
            AggregateResult[] queueMaxNumbers = [
                    SELECT max(Queue_Number__c) maxr, min(Queue_Number__c) minr
                    FROM Rental_Apply_Equipment_Set_Detail__c
                    where Id != :raesd.Id
                    and Fixture_Model_No_text__c = :modelNo
                    and Select_Time__c = null
                    and Queue_Day__c != null
                    and Queue_Number__c != null
                    and Queue_Number__c > 0
                    and Salesdepartment_before__c = :aSet[0].Salesdepartment__c     // 所在地区(本部) 借出时
                    and Product_category_text__c  = :aSet[0].Product_category__c    // 产品分类(GI/SP)(借出时)
                    and Equipment_Type_text__c    = :aSet[0].Equipment_Type__c      // 备品分类(借出时)
                    and Internal_asset_location_before__c = :aSet[0].Internal_asset_location__c      // 备品存放地
            ];

            // 一览明细的Asset__c保留下来,后面的处理需要使用
            Id oldAssId = raesd.Asset__c;

            //暂定分配の場合排队中変更，Triggerで新しいの暂定分配を設定
            if (raesd.Queue_Number__c == 0 && raesd.Queue_Day__c != null) {
                raesd.Queue_User__c   = UserInfo.getUserId();
                raesd.Queue_Number__c = Integer.valueOf(queueMaxNumbers[0].get('minr'));
                raesd.Queue_Day__c    = Date.today();
                raesd.Queue_Time__c   = getCurrentTime();
                raesd.Select_Time__c  = null;
                raesd.Asset__c        = null;
                // 已出库指示的排队后清除出库指示信息
                raesd.Shipment_request_time2__c = null;
                raesd.Shipment_request__c = false;
            } else {

                Integer queueMaxNumber = 1;
                if (queueMaxNumbers.isEmpty()) {
                    queueMaxNumber = 0;
                } else if (queueMaxNumbers[0].get('maxr') != null) {
                    queueMaxNumber = Integer.valueOf(queueMaxNumbers[0].get('maxr')) + 1;
                }

                // 排队成功、更新DB
                raesd.Queue_User__c   = UserInfo.getUserId();
                raesd.Queue_Number__c = queueMaxNumber;
                raesd.Queue_Day__c    = Date.today();
                raesd.Queue_Time__c   = getCurrentTime();
                // 备品配套明细型号(借出时)
                raesd.Fixture_Model_No_text__c = aSet[0].Fixture_Model_No_F__c;
                // 所在地区(本部) 借出时
                raesd.Salesdepartment_before__c = aSet[0].Salesdepartment__c;
                // 所在地区(省) 借出时
                raesd.SalesProvince_before__c = aSet[0].SalesProvince__c;
                // 产品分类(GI/SP)(借出时)
                raesd.Product_category_text__c = aSet[0].Product_category__c;
                // 备品分类(借出时)
                raesd.Equipment_Type_text__c = aSet[0].Equipment_Type__c;
                // 备品存放地(借出时)
                raesd.Internal_asset_location_before__c = aSet[0].Internal_asset_location__c;
                // 备品名称(借出时) clear しない、申請時 値設定するので、
                // 今排队保存排队信息时,别的和配套明细相连的字段都保留了排队的信息,为了逻辑的统一性,这个字段也需要保存
                raesd.Fixture_Name_text__c = aSet[0].Name;
                raesd.Select_Time__c  = null;
                raesd.Asset__c        = null;
                // 已出库指示的排队后清除出库指示信息
                raesd.Shipment_request_time2__c = null;
                raesd.Shipment_request__c = false;

                // OLY_OCM-243 追加字段对应 备品管理编码(借出时) 排队时清除与asset相连的借出时相关的字段
                raesd.EquipmentSet_Managment_Code_text__c = null;
                // 机身编号（借出时）
                raesd.SerialNumber_text__c = null;
                // 备品成本(借出时)
                raesd.Asset_cost_del_before__c = null;
            }

            Map<Id, Fixture_OneToOne_Link__c> fOtoMap = new Map<Id, Fixture_OneToOne_Link__c>();
            // 此处共通化处理,在调用 FixtureUtil.clearOneToOneAccessory()方法
            FixtureUtil.clearOneToOneAccessory(raseId, mfUpsert, oldAssId, fOtoMap);

            // FixtureUtil.withoutUpdate(new Rental_Apply_Equipment_Set_Detail__c[]{raesd});
            if (!mfUpsert.isEmpty()) {
                Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
                FixtureUtil.withoutUpsertRaesd(mfUpsert.values());
                Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());
            }

            //更新一对一
            if (!fOtoMap.isEmpty()) {
                Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
                FixtureUtil.withoutUpdate(fOtoMap.values());
                Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());
            }

            responseMap.put('code', '0');
            responseMap.put('message', '排队成功');
            return responseMap;

        } catch (DmlException ex) {
            Database.rollback(sp);
            // １件目のエラーのみ表示
            responseMap.put('code', '1');
            responseMap.put('message', ex.getDmlMessage(0));
            System.debug(Logginglevel.ERROR, ex.getMessage());
            System.debug(Logginglevel.ERROR, ex.getStackTraceString());
            return responseMap;
        } catch (Exception e) {
            Database.rollback(sp);
            responseMap.put('code', '1');
            responseMap.put('message', e.getMessage());
            System.debug(Logginglevel.ERROR, e.getMessage());
            System.debug(Logginglevel.ERROR, e.getStackTraceString());
            return responseMap;
        }
    }

    public PageReference save() {

        //20170906 upsert by UniqueKey__c
        Map<String, Rental_Apply_Equipment_Set_Detail__c> mfUpsert = new Map<String, Rental_Apply_Equipment_Set_Detail__c>();
        Map<Id, Fixture_OneToOne_Link__c> fOtoMap = new Map<Id, Fixture_OneToOne_Link__c>();
        Rental_Apply__c raObj = null;
        Savepoint sp = Database.setSavepoint();
        Set<String> clearUniqueKeySet = new Set<String>();

        try {
            // Asset的Last_Reserve_RAES_Detail__c设值:未保存的情况下,robj.Id是null。需要先保存后设值
            //List<Rental_Apply_Equipment_Set_Detail__c> rasedList = new List<Rental_Apply_Equipment_Set_Detail__c>();
            //List<Asset> aSetList = new List<Asset>();
//Do it in Trigger            Map<Id, Asset> assetUpdateMap = new Map<Id, Asset>();

            for (Integer indexNum = 0; indexNum < viewList.size(); indexNum++) {
                WrapperInfo wprInfo = viewList[indexNum];
                Rental_Apply_Equipment_Set_Detail__c robj = (Rental_Apply_Equipment_Set_Detail__c) wprInfo.sobj;
                //清空Id，因为要有Id不能重新设置主字段备品借出一览
                robj.Id = null;
                //设置一览为当前主体的一览
                robj.Rental_Apply_Equipment_Set__c = sonObj.Rental_Apply_Equipment_Set__c;
                // 画面上にチェックした、1件しかない
                if (wprInfo.check) {
                    // 操作対象
                    List<Rental_Apply_Equipment_Set_Detail__c> rasedList = [
                            SELECT Id, Asset__c, Asset__r.Main_OneToOne__c,
                                   Queue_Number__c, ExternalKey__c,
                                   Queue_Day__c
                            FROM Rental_Apply_Equipment_Set_Detail__c
                            where Id = :sonObj.id
                              FOR Update];
                    if (rasedList.isEmpty()) {
                        throw new ControllerUtil.myException('分配的主体备品不存在，请刷新画面后重新操作');
                    }
                    //1822 yc 20211021 已购待货目的，新品已有发货日不能出库 start
                    if(robj.Rental_Apply__r.demo_purpose2__c=='已购待货' && robj.Rental_Apply__r.Follow_UP_Opp__r.Shipping_Finished_Day_Func__c!= null){
                        throw new ControllerUtil.myException('已购待货目的，新品已有发货日，不能继续了。');
                    }
                    if(robj.Rental_Apply__r.demo_purpose2__c=='索赔QIS' && robj.Rental_Apply__r.next_action__c=='无偿更换' && robj.Rental_Apply__r.QIS_number__r.ReplaceDeliveryDate__c!= null){
                        throw new ControllerUtil.myException('索赔QIS目的，QIS已有新品发货日，不能继续了。');
                    }
                    //1822 yc 20211021 已购待货目的，新品已有发货日不能出库 end

                    // 分配
                    if (robj.Select_Time__c == null || rasedList[0].Asset__c != robj.Asset__c) {
                        // Last_Reserve_RAES_Detail__c 最新备品申请借出明细历史
                        // 1件しかない
                        List<Asset> aSetList =
                                [Select Id, Quantity,
                                        Out_of_wh__c,
                                        Manage_type__c,
                                        You_Xiao_Ku_Cun__c,
                                        Last_Reserve_RAES_Detail__c,
                                        Last_Reserve_RAES_Detail__r.Select_Time__c
                                   From Asset
                                  where Id = :robj.Asset__c
                                   AND (Last_Reserve_RAES_Detail__c = null OR Last_Reserve_RAES_Detail__r.Select_Time__c = null)
                                   // 因为有暂定分配 所以where 里不加这个条件 AND You_Xiao_Ku_Cun__c > 0 // 有效库存
                                    for Update];
                        // 不能lock到数据的时候
                        if (aSetList.isEmpty()) {
                            throw new ControllerUtil.myException('请选择未分配的主体备品，请刷新画面后重新操作');
                        }
                        // 备品有效库存 的 check
                        // 暂定分配, 没有有效库存的时候 不报错
                        if (String.isNotBlank(aSetList[0].Last_Reserve_RAES_Detail__c)
                                && aSetList[0].Last_Reserve_RAES_Detail__r.Select_Time__c == null
                                && aSetList[0].You_Xiao_Ku_Cun__c <= 0
                                && aSetList[0].Last_Reserve_RAES_Detail__c == sonObj.Id
                        ) {
                        }
                        // 有有效库存的时候 不报错
                        else if (aSetList[0].You_Xiao_Ku_Cun__c > 0) {
                        }
                        else {
                            throw new ControllerUtil.myException('第' + (indexNum + 1) +'行，没有足够有效库存，请刷新画面后重新操作');
                        }
                        Asset aSet = aSetList[0];

                        robj.Select_Time__c = System.now();

                        // 分配時 更新 Out_of_wh__c
                        if (aSet.Out_of_wh__c == null || aSet.Out_of_wh__c == 0) {
                            aSet.Out_of_wh__c = 0;
                        }
// Handlerにて 値設定する
//                        aSet.Out_of_wh__c = aSet.Out_of_wh__c + 1;
//                        assetUpdateMap.put(aSet.Id, aSet);

                        // 备品智能化项目对应 20231122 by lc Start
                        if (!String.isBlank(sonObj.Intervention_Reason__c)) {
                            robj.Intervention_Reason__c = sonObj.Intervention_Reason__c;
                        }
                        // 产品试用的备品 关联OPD计划的（已购待货是实时单，排除），在希望到货日前7天 之前，人工处理的，需要特殊标记上
                        if (isBefore7Days && parentObj.Rental_Apply__r.demo_purpose2__c == '学会展会') {
                            raObj = new Rental_Apply__c();
                            raObj.Id = parentObj.Rental_Apply__c;
                            raObj.Manually_Flag__c = true;
                        }
                        // 备品智能化项目对应 20231122 by lc End

                        String uniqueKeyStr = parentObj.RequestNoJoinStr2__c + ':'+ robj.Rental_Apply_Equipment_Set__c
                                + ':' + robj.FSD_Id__c + ':' + robj.IndexFromUniqueKey__c;
                        robj.UniqueKey__c = uniqueKeyStr;
                        robj.Queue_Number__c = null;
                        robj.Queue_Day__c = null;
                        robj.Queue_Time__c = null;
                        robj.Shipment_request_time2__c = null;
                        robj.Shipment_request__c = false;
                        robj.ExternalKey__c = null;
                        mfUpsert.put(robj.UniqueKey__c, robj);
// Handlerにて 値設定する
//                        if (String.isBlank(aSet.Last_Reserve_RAES_Detail__c)){
//                            aSet.Last_Reserve_RAES_Detail__c = robj.Id;
//                            assetUpdateMap.put(aSet.Id, aSet);
//                        } else if (aSet.Last_Reserve_RAES_Detail__c != robj.Id) {
//                            aSet.Last_Reserve_RAES_Detail__c = robj.Id;
//                            assetUpdateMap.put(aSet.Id, aSet);
//                        }
                        // 一对一的情况,主体备品和配套的附属品一起分配
                        if (robj.FSD_OneToOneAccessory_Cnt__c > 0) {

                            // 1. select from Rental_Apply_Equipment_Set_Detail__c 找出需要分配的对象
                            // 此处共通化处理,调用 FixtureUtil.clearOneToOneAccessory()方法
                            //   a.未分配时,Asset__c还没值,所以不用判断OneToOne_Flag__c
                            //   b.从一对一的, 改到不是一对一的情况,一对一分配的附属品字段清除逻辑,需要判断OneToOne_Flag__c
                            //   c.清除一对一link表的相关逻辑
                            //   d.fOtoMap 之前的一对一分配数也需要一起清空 + 今回の更新一对一分配的Link表
                            List<Rental_Apply_Equipment_Set_Detail__c> raesdList
                                    = FixtureUtil.clearOneToOneAccessory(parentId, mfUpsert, sonObj.Asset__c, fOtoMap);
                            // 分配的是一对一的时候
                            if (robj.Asset__r.Main_OneToOne__c) {
                                // 2. SELECT Fixture_OneToOne_Link__c where Main_Asset__c = robj.Asset__c
                                // 被分配对象 {Fixture_Model_No_F__c: [Asset.Id]}
                                Map<String, List<Fixture_OneToOne_Link__c>> oneToOneListMap = new Map<String, List<Fixture_OneToOne_Link__c>>();
                                Map<Id, Asset> assetKuCunMap = new Map<Id, Asset>();
                                List<Fixture_OneToOne_Link__c> fo2oList = [
                                        SELECT Id, Main_Asset__c,
                                               Accessory_Asset__c,
                                               Accessory_Asset__r.Fixture_Model_No_F__c,
                                               Quantity__c, Inventory_Frozen_Quantity__c
                                          FROM Fixture_OneToOne_Link__c
                                         WHERE Accessory_Asset__c != null                   // 念のため
                                           AND Main_Asset__c = :robj.Asset__c];
                                for (Fixture_OneToOne_Link__c fo2o : fo2oList) {
                                    if (!oneToOneListMap.containsKey(fo2o.Accessory_Asset__r.Fixture_Model_No_F__c)) {
                                        oneToOneListMap.put(fo2o.Accessory_Asset__r.Fixture_Model_No_F__c, new List<Fixture_OneToOne_Link__c>());
                                    }
                                    assetKuCunMap.put(fo2o.Accessory_Asset__c, null);
                                    List<Fixture_OneToOne_Link__c> oneToOneAsetIdList = oneToOneListMap.get(fo2o.Accessory_Asset__r.Fixture_Model_No_F__c);
                                    fo2o.Quantity__c = fo2o.Quantity__c == null ? 1 : fo2o.Quantity__c;
// OCSM_BP3-29 分配一对一附属品的时候 考虑 盘点冻结数 start
                                    Integer fo2oQty = (fo2o.Quantity__c - (fo2o.Inventory_Frozen_Quantity__c == null ? 0 : fo2o.Inventory_Frozen_Quantity__c)).intValue();
//                                    for (Integer qty = 0; qty < fo2o.Quantity__c; qty++) {
                                    for (Integer qty = 0; qty < fo2oQty; qty++) {
// OCSM_BP3-29 分配一对一附属品的时候 考虑 盘点冻结数 end
                                        oneToOneAsetIdList.add(fo2o);
                                    }
                                    oneToOneListMap.put(fo2o.Accessory_Asset__r.Fixture_Model_No_F__c, oneToOneAsetIdList);
                                }
                                assetKuCunMap = new Map<Id, Asset>(
                                        [Select Id, Quantity,
                                                Out_of_wh__c,
                                                Manage_type__c,
                                                You_Xiao_Ku_Cun__c
                                           From Asset
                                          where Id IN :assetKuCunMap.keyset()
                                            for Update]);
                                // 对 raesdList 进行一对一分配
                                Map<Id, Rental_Apply_Equipment_Set_Detail__c> cancelCopyOldMap = new Map<Id, Rental_Apply_Equipment_Set_Detail__c>();
                                oneToOneSelect(raesdList, oneToOneListMap, assetKuCunMap, fOtoMap
                                        , robj.Select_Time__c
                                        , mfUpsert, cancelCopyOldMap);
                                // 有 cancelCopyOldMap 的话, 做重新分配, 然后继续分配
                                if (cancelCopyOldMap.size() > 0) {
                                    FixtureUtil.withoutUpdate(cancelCopyOldMap.values());
                                    // 要做一对一分配的明细, 参考 clearOneToOneAccessory sql
                                    raesdList = [SELECT Id, UniqueKey__c, Asset__c,
                                                FSD_Fixture_Model_No__c, FSD_Name_CHN__c, Fixture_OneToOne_Link_Id__c,
                                                Select_Time__c, Shipment_request_time2__c, Shipment_request__c, OneToOne_Flag__c, StockDown__c, DeliverySlip__c
                                            from Rental_Apply_Equipment_Set_Detail__c
                                            where Rental_Apply_Equipment_Set__c = :parentId
                                            and Cancel_Select__c = false
                                            and FSD_Is_OneToOne__c = true
                                            and UniqueKey__c != null
                                            and Is_Body__c = false
                                            and Canceled__c IN :cancelCopyOldMap.keySet()
                                            order by FSD_Fixture_Model_No__c];
                                    oneToOneSelect(raesdList, oneToOneListMap, assetKuCunMap, fOtoMap
                                            , robj.Select_Time__c
                                            , mfUpsert, cancelCopyOldMap);

                                }
                            }
                        }

                        if (String.isBlank(robj.Id)
                                && !String.isBlank(uniqueKeyStr)) {
                            // 新規の場合、ここ単純に Id にて判断
                            clearUniqueKeySet.add(uniqueKeyStr);
                        }

//Do it in Trigger
//                        // Asset 1件しかない
//                        update assetUpdateMap.values();

                        // 判断分配的明细是否已经排队，如果已排队，需要清除备品借出排队序列表中对应的数据
                        if (String.isNotBlank(rasedList[0].ExternalKey__c)) {
                            List<Rental_Apply_Sequence__c> rasList = [
                                    SELECT Id
                                    FROM Rental_Apply_Sequence__c 
                                    WHERE Apply_Set_Detail__c =: rasedList[0].Id
                                      AND Invalid_Flag__c = false];

                            // 更新备品借出排队序列表
                            if (!rasList.isEmpty()) {
                                FixtureUtil.withoutDelete(rasList);
                            }
                        }
                    }

                    // 主体1件しかない
                    break;
                }
            }

            System.debug(mfUpsert);
            // Upsert
            if (!mfUpsert.isEmpty()) {
                Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
                FixtureUtil.withoutUpsertRaesd(mfUpsert.values());
                Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());
//Do it in Trigger
//Do it in Trigger 分配時 更新 Out_of_wh__c
//                for (Rental_Apply_Equipment_Set_Detail__c robj : mfUpsert) {
//                    if (robj.Is_Body_F__c) {
//                        System.debug('测试robj.Is_Body_F__c' + robj.Is_Body_F__c);
//                        Asset aSet = aSetList[0];
//                        if (String.isBlank(aSet.Last_Reserve_RAES_Detail__c)){
//                            aSet.Last_Reserve_RAES_Detail__c = robj.Id;
//                            assetUpdateMap.put(aSet.Id, aSet);
//                        } else if (aSet.Last_Reserve_RAES_Detail__c != robj.Id) {
//                            aSet.Last_Reserve_RAES_Detail__c = robj.Id;
//                            assetUpdateMap.put(aSet.Id, aSet);
//                        }
//                        // 1件しかない
//                        update assetUpdateMap.values();
//                        break;
//                    }
//                }
            }

            //更新一对一
            if (!fOtoMap.isEmpty()) {
                Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
                FixtureUtil.withoutUpdate(fOtoMap.values());
                Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());
            }

            // 备品智能化项目对应 20231122 by lc Start
            if (raObj != null) {
                FixtureUtil.withoutUpdate(new List<Rental_Apply__c>{raObj});
            }
            // 备品智能化项目对应 20231122 by lc End

        } catch (Exception ex) {
            System.debug('测试bug');
            System.debug(ex.getStackTraceString());
            ApexPages.addMessages(ex);
            Database.rollback(sp);
            // Id をクリア
            for (Rental_Apply_Equipment_Set_Detail__c robj : mfUpsert.values()) {
                if (clearUniqueKeySet.contains(robj.UniqueKey__c)) {
                    robj.Id = null;
                }
            }
            return null;
        }

        if (saveType == '1') {
            searchOpp();
            saveType = '';
            return null;
        } else if (saveType == '2') {
            // ソート時の変更ある
            myComponentController.sortTable();
            saveType = '';
            return null;
        } else {
            //附属品选择画面
            PageReference pg = new PageReference('/apex/AccessorySelect');
            pg.getParameters().put('pt_recid',parentId);
            pg.setRedirect(true);
            return pg;
        }
    }

    // https://sohobb.backlog.jp/view/OLY_OCM-152#comment-20041467
    // 1. G9 の場合、 もし、一対一 分配した 本体の場合、付属品（一対一付属品）も一緒に キャンセルしますか？
    // → 一対一Linkがある場合は、付属品も一緒に取り消します。そうすればG10と矛盾しませんよね。
    // 下架后 才能取消主体 OLY_OCM-173
    public PageReference cancel() {
        Savepoint sp = Database.setSavepoint();
        try{
            List<Rental_Apply_Equipment_Set_Detail__c> raesds = new List<Rental_Apply_Equipment_Set_Detail__c>();
            List<Id> delIds = new List<Id>();
            for (WrapperInfo wprInfo : viewList) {
                Rental_Apply_Equipment_Set_Detail__c robj = (Rental_Apply_Equipment_Set_Detail__c) wprInfo.sobj;
                //出库后不能取消
                //关联主体分配画面,一览Handler
                //附属品分配画面
                if (wprInfo.check) {
                    if (String.isNotBlank(robj.DeliverySlip__c)) {
                        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '已经发货的明细不能取消'));
                        return null;
                    } else if (robj.StockDown__c == false) {
                        if (robj.Cancel_Reason__c == '重新分配') {
                            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '下架前重新分配，直接从画面重新选择即可'));
                            return null;
                        } else {
                            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '下架前取消主体，请取消备品配套'));
                            return null;
                        }
                    } else if (robj.Cancel_Reason__c != '重新分配') {
                        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '不是 [重新分配]，不能单独取消主体，请取消备品配套'));
                        return null;
                    } else {
                        // 状态为待分配,备品中心created的明细,可以delete;其余的不可以删除
                        if (robj.CreatedBy.ProfileId == System.Label.ProfileId_EquipmentCenter && robj.Select_Time__c == null) {
                            // 删除明细Id<List>
                            delIds.add(robj.Id);
                            // 删除明细，会对应的删除相关的备品借出排队序列表数据，不用特别加处理

                        } else {
                            if (String.isBlank(robj.Cancel_Reason__c)) {
                                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '请输入取消理由'));
                                return null;
                            }

                            //20210818 SFDC-C448KZ ljh start
                            if (String.isBlank(robj.Loaner_cancel_reason__c)) {
                                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '请输入明细取消理由'));
                                return null;
                            }
                            if (robj.Loaner_cancel_reason__c=='其他' && String.isBlank(robj.Loaner_cancel_Remarks__c)) {
                                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '请输入取消理由备注'));
                                return null;
                            }
                            // if (String.isBlank(robj.Loaner_cancel_Remarks__c)) {
                            //     ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '请输入备品申请取消理由备注'));
                            //     return null;
                            // }
                            //20210818 SFDC-C448KZ ljh end

                            wprInfo.check = false;
                            // 取消分配
                            robj.Cancel_Select__c = true;
                            // 备品申请取消时间
                            robj.Cancel_Date__c = Date.today();
                            robj.Cancel_Time__c = getCurrentTime();
                            // 取消者
                            robj.Cancel_Mem__c = UserInfo.getUserId();
                            // 取消理由备注
                            //robj.Loaner_cancel_Remarks__c
                            robj.Loaner_cancel_Remarks__c = robj.Loaner_cancel_Remarks__c==null ? robj.Loaner_cancel_reason__c : robj.Loaner_cancel_Remarks__c;
                            //20210818 SFDC-C448KZ ljh end

                            // 判断分配的明细是否已经排队，如果已排队，需要清除备品借出排队序列表中对应的数据
                            if (String.isNotBlank(robj.ExternalKey__c)) {
                                List<Rental_Apply_Sequence__c> rasList = [
                                        SELECT Id
                                        FROM Rental_Apply_Sequence__c 
                                        WHERE Apply_Set_Detail__c =: robj.Id
                                          AND Invalid_Flag__c = false];

                                // 更新备品借出排队序列表
                                if (!rasList.isEmpty()) {
                                    FixtureUtil.withoutDelete(rasList);
                                }
                            }
                            robj.ExternalKey__c = null;

                            //※已经分配的場合  トリがでやります
                            //if(!String.isBlank(robj.Asset__c) && robj.Select_Time__c != null) {
                                //借出备品Set一览明细 trigger 里 clear Asset__c
                                //借出备品Set一览明细.分配时间
                                // if (robj.Select_Time__c != null) {
                                //     robj.Select_Time__c = null;
                                // }
                            //}

                            raesds.add(robj);
                        }
                    }
                }
            }

            if (delIds.size() > 0) {
                // 削除
                FixtureUtil.delRAESDByIds(parentObj, delIds);
            }

            if (raesds.size() > 0) {
                FixtureUtil.withoutUpdate(raesds);

                // 取消操作,只是取消已选择的分配,画面刷新
                PageReference pg = new PageReference('/apex/MainFixtureSelect');
                pg.getParameters().put('pt_recid',parentId);
                pg.setRedirect(true);
                return pg;
            }
        }
        catch (Exception e) {
            ApexPages.addMessages(e);
            Database.rollback(sp);
            return null;
        }
        return null;
    }

    public PageReference turnback() {
        PageReference ret = null;
        if (!String.isBlank(this.parentId)) {
            ret = new PageReference('/' + this.parentId);
        }
        return ret;
    }

    /**
    *#OLY_OCM-668 取消主体分配
    *@return PageReferences 刷新主体选择画面
    */
    public PageReference unassign(){
        Map<String, Rental_Apply_Equipment_Set_Detail__c> mfUpsert = new Map<String, Rental_Apply_Equipment_Set_Detail__c>();
        Map<Id, Fixture_OneToOne_Link__c> fOtoMap = new Map<Id, Fixture_OneToOne_Link__c>();
        Savepoint sp = Database.setSavepoint();
        Set<String> clearUniqueKeySet = new Set<String>();
        try{
            Integer checkCount = 0;
            for (Integer indexNum = 0; indexNum < viewList.size(); indexNum++) {
                WrapperInfo wprInfo = viewList[indexNum];
                Rental_Apply_Equipment_Set_Detail__c robj = (Rental_Apply_Equipment_Set_Detail__c) wprInfo.sobj;
                robj.Id = null;
                robj.Rental_Apply_Equipment_Set__c = sonObj.Rental_Apply_Equipment_Set__c;
                if (wprInfo.check) {
                    checkCount += 1;
                    // 操作対象
                    List<Rental_Apply_Equipment_Set_Detail__c> raesdList = [
                            SELECT Id, StockDown_time__c,Cancel_Date__c,
                                UniqueKey__c,
                                Fixture_OneToOne_Link_Id__c,
                                Asset__c,
                                Select_Time__c,
                                Shipment_request_time2__c,
                                Shipment_request__c ,
                                Fixture_Model_No_text__c ,
                                FSD_Fixture_Model_No__c,
                                SerialNumber_text__c,
                                SalesProvince_before__c,
                                Salesdepartment_before__c,
                                Product_category_text__c,
                                Equipment_Type_text__c,
                                Asset_cost_del_before__c,
                                Internal_asset_location_before__c,
                                Fixture_Name_text__c ,
                                FSD_Name_CHN__c,
                                EquipmentSet_Managment_Code_text__c
                            FROM Rental_Apply_Equipment_Set_Detail__c
                            where Id = :sonObj.Id
                            FOR Update];
                    if (raesdList.isEmpty()) {
                        throw new ControllerUtil.myException('没有下架前已分配的主体');
                    }
                    Rental_Apply_Equipment_Set_Detail__c robjOnline = raesdList[0];

                    if(robjOnline.Cancel_Date__c != null){
                        throw new ControllerUtil.myException('第' + (indexNum + 1) +'行，已经取消申请了，不能取消分配');
                    }
                    if(robjOnline.StockDown_time__c != null){
                        throw new ControllerUtil.myException('第' + (indexNum + 1) +'行，已下架，不可以取消分配');
                    }
                    if(robjOnline.Asset__c == null){
                        throw new ControllerUtil.myException('第' + (indexNum + 1) +'行，还没有被分配，不可以取消分配');
                    }

                    // 已分配且未下架才可执行取消
                    List<Asset> aSetList =
                            [SELECT Id, Quantity,
                                    Out_of_wh__c,
                                    Manage_type__c,
                                    You_Xiao_Ku_Cun__c,
                                    Last_Reserve_RAES_Detail__c,
                                    Last_Reserve_RAES_Detail__r.Select_Time__c
                               FROM Asset
                              WHERE Id = :robj.Asset__c
                                FOR UPDATE
                            ];
                    // 不能lock到数据的时候
                    if (aSetList.isEmpty()) {
                        throw new ControllerUtil.myException('第' + (indexNum + 1) +'行，不是有效的主体，请刷新画面后重新操作');
                    }
                    // 相关字段置为 null
                    robj.Asset__c = null;
                    robj.Select_Time__c = null;
                    robj.Shipment_request_time2__c = null;
                    robj.Shipment_request__c = false;
                    // 备品配套明细型号(借出时)
                    robj.Fixture_Model_No_text__c = robj.FSD_Fixture_Model_No__c;
                    // 机身编号（借出时）
                    robj.SerialNumber_text__c = null;
                    // 所在地区(省) 借出时
                    robj.SalesProvince_before__c = null;
                    // 所在地区(本部) 借出时
                    robj.Salesdepartment_before__c = null;
                    // 产品分类(GI/SP)(借出时)
                    robj.Product_category_text__c = null;
                    // 备品分类(借出时)
                    robj.Equipment_Type_text__c = null;
                    // 备品成本(借出时)
                    robj.Asset_cost_del_before__c = null;
                    // 备品存放地(借出时)
                    robj.Internal_asset_location_before__c = null;
                    //备品名称(借出时)
                    robj.Fixture_Name_text__c = robj.FSD_Name_CHN__c;
                    // 备品管理编码(借出时)
                    robj.EquipmentSet_Managment_Code_text__c = null;
                    // 清空排队信息
                    robj.Queue_Conment__c = null;
                    robj.Queue_Day__c = null;
                    robj.Queue_User__c = null;
                    //取消分配 update byrentx 20210809 start 取消分配时不清空 排队日(首次)
                    // robj.Queue_Day_Text__c = null;
                    //取消分配 update byrentx 20210809 end 取消分配时不清空 排队日(首次)

                    robj.Queue_Number__c = null;

                    // 判断分配的明细是否已经排队，如果已排队，需要清除备品借出排队序列表中对应的数据
                    if (String.isNotBlank(robj.ExternalKey__c)) {
                        List<Rental_Apply_Sequence__c> rasList = [
                                SELECT Id
                                FROM Rental_Apply_Sequence__c 
                                WHERE Apply_Set_Detail__c =: robjOnline.Id
                                  AND Invalid_Flag__c = false];

                        // 更新备品借出排队序列表
                        if (!rasList.isEmpty()) {
                            FixtureUtil.withoutDelete(rasList);
                        }
                    }
                    robj.ExternalKey__c = null;

                    String uniqueKeyStr = parentObj.RequestNoJoinStr2__c + ':'+ robj.Rental_Apply_Equipment_Set__c
                            + ':' + robj.FSD_Id__c + ':' + robj.IndexFromUniqueKey__c;
                    robj.UniqueKey__c = uniqueKeyStr;

                    // 备品智能化项目对应 20231122 by lc Start
                    if (!String.isBlank(sonObj.Intervention_Reason__c)) {
                        robj.Intervention_Reason__c = sonObj.Intervention_Reason__c;
                    }
                    // 备品智能化项目对应 20231122 by lc End

                    // 一对一的情况,主体备品和配套的附属品一起取消
                    if (robj.FSD_OneToOneAccessory_Cnt__c > 0) {
                        // 1. select from Rental_Apply_Equipment_Set_Detail__c 找出需要分配的对象
                        // 此处共通化处理,调用 FixtureUtil.clearOneToOneAccessory()方法
                        //   a.未分配时,Asset__c还没值,所以不用判断OneToOne_Flag__c
                        //   b.从一对一的, 改到不是一对一的情况,一对一分配的附属品字段清除逻辑,需要判断OneToOne_Flag__c
                        //   c.清除一对一link表的相关逻辑
                        //   d.fOtoMap 之前的一对一分配数也需要一起清空 + 今回の更新一对一分配的Link表
                        robj.Fixture_OneToOne_Link_Id__c = null;
                        raesdList = FixtureUtil.clearOneToOneAccessory(parentId, mfUpsert, sonObj.Asset__c, fOtoMap);
                    }
                    mfUpsert.put(robj.UniqueKey__c, robj);

                    if (String.isBlank(robj.Id)
                            && !String.isBlank(uniqueKeyStr)) {
                        // 新規の場合、ここ単純に Id にて判断
                        clearUniqueKeySet.add(uniqueKeyStr);
                    }
                    break;
                }
            }
            // 没有任何勾选
            if (checkCount == 0){
                throw new ControllerUtil.myException('请选择已分配的主体备品');
            }

            if (!mfUpsert.isEmpty()) {
                Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
                FixtureUtil.withoutUpsertRaesd(mfUpsert.values());
                Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());
            }
            //更新一对一
            if (!fOtoMap.isEmpty()) {
                Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
                FixtureUtil.withoutUpdate(fOtoMap.values());
                Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());
            }
        } catch (Exception ex) {
            ApexPages.addMessages(ex);
            Database.rollback(sp);
            // Id をクリア
            for (Rental_Apply_Equipment_Set_Detail__c robj : mfUpsert.values()) {
                if (clearUniqueKeySet.contains(robj.UniqueKey__c)) {
                    robj.Id = null;
                }
            }
            return null;
        }

        //刷新画面
        PageReference pg = new PageReference('/apex/MainFixtureSelect');
        pg.getParameters().put('pt_recid',parentId);
        pg.setRedirect(true);
        return pg;

    }

    private String makeSoql(String keyword) {
        // 検索条件
        String dateToday = String.valueOf(Date.today());

        // from asset
        String soql ='';
        soql += 'where Asset_Owner__c = \'Olympus\' AND ' + FixtureUtil.getAssetSoqlBase();
        soql += '  and Asset_loaner_category__c != \'耗材\'';
        soql += '  and RecordTypeId = \''+System.label.AssetShipmentRecordTypeId+'\'';
        soql += '  and Quantity > 0';
        soql += '  and (Abandoned_Inventory__c = 0 OR Abandoned_Inventory__c = null)'; // 待废弃数(丢失/盘亏)
        soql += '  and (Abandoned_RealThing__c = 0 OR Abandoned_RealThing__c = null)'; // 待废弃数(实物)
        soql += '  and (Frozen_Quantity__c = 0 OR Frozen_Quantity__c = null)'; // 冻结数
        soql += '  and Loaner_accsessary__c = false';
        soql += '  and Equipment_Type__c != \'检测用备品\'';
        soql += '  and Delete_Flag__c = False ';
        soql += '  and Recall_Asset__c = False ';
        soql += '  and Freeze_sign_Abandoned_Flag__c = False';
        soql += '  and Internal_asset_location__c != null';
        soql += '  and (Consumable_Guaranteen_end__c = null or Consumable_Guaranteen_end__c >=' + dateToday + ')';
//借出中的Asset也要出显示出来
//        soql += '  and Last_Reserve_RAES_Detail__c = null';
        // Fixture_OneToOne_Link__c, 当配套的Mst定义成 一对一 的时候
        if (sonObj != null && sonObj.FSD_Is_OneToOne__c) {
            soql += '  and Fixture_OneToOne_Link__c <> null';
        }

        // 不检索seledted的数据  在 CreateRelationListPagingCmpCtrl 里 已经 去除了 selectedFKIdList
        if (sonObj != null && !String.isBlank(sonObj.Asset__c)) {
            soql += '  and Id != \'' + String.escapeSingleQuotes(sonObj.Asset__c) + '\'';
        }

        //自己状态
        // soql += '';

        if (!String.isBlank(keyword)) {
            String[] vals = keyword.split(' ');
             soql += ' and (';
             String fmodelno = '';
            for (String v : vals) {
                v = String.escapeSingleQuotes(v.replace('%', '\\%').replace('*', '%'));
                fmodelno += ' Product2.Fixture_Model_No_T__c like \'' + v + '\' ';
                fmodelno += ' or Product2.Name like \'' + v + '\' ';
                fmodelno += 'or';
            }
            fmodelno = fmodelno.removeEnd('or');
            soql += fmodelno + ' )';
        } else {
            soql += ' and Product2.Fixture_Model_No_T__c = \'' + String.escapeSingleQuotes(sonObj.FSD_Fixture_Model_No__c) + '\'';
        }

        //// TODO 暂时注释 画面から别省别本部别库存の判断

        //别存放地
        if (String.isNotBlank(bieCunFangDi) && bieCunFangDi != 'All') {
            soql += ' and Internal_asset_location__c = \'' + String.escapeSingleQuotes(bieCunFangDi) + '\'';
        }
        // else {
        //     String cunfangdiStr = '';
        //     for (String cunfangdi : cunfangdiSet) {
        //         cunfangdiStr += ' Internal_asset_location__c = \'' + String.escapeSingleQuotes(cunfangdi) + '\' OR';
        //     }
        //     soql += ' and (' + cunfangdiStr.removeEnd('OR') + ')';
        // }
        //别本部
        if (String.isNotBlank(bieBenBu) && !bieBenBu.contains('全部')) {
            // soql += ' and Salesdepartment__c = \'' + String.escapeSingleQuotes(bieBenBu) + '\'';
            List<String> bieBenBuList = bieBenBu.split(',');
            soql += RentalFixtureSetAssignController.setSoql('Salesdepartment__c', bieBenBuList);
            /*String benbuStr = '';
            for (String benbu : bieBenBuList) {
                benbuStr += ' Salesdepartment__c = \'' + String.escapeSingleQuotes(benbu) + '\' OR';
            }
            soql += ' and (' + benbuStr.removeEnd('OR') + ')';*/
        }
        else if (benbuSet.size() > 0) {
            String benbuStr = '';
            for (String benbu : benbuSet) {
                benbuStr += ' Salesdepartment__c = \'' + String.escapeSingleQuotes(benbu) + '\' OR';
            }
            soql += ' and (' + benbuStr.removeEnd('OR') + ')';
        }
        //产品分类
        if (String.isNotBlank(bieChanPinFenLei)) {
            soql += ' and Product_category__c = \'' + String.escapeSingleQuotes(bieChanPinFenLei) + '\'';
        }
        //别备品分类
        if (String.isNotBlank(bieBeiPinFenLei) && !bieBeiPinFenLei.contains('全部')) {
            List<String> bieBeiPinFenLeiList = bieBeiPinFenLei.split(',');
            soql += RentalFixtureSetAssignController.setSoql('Equipment_Type__c', bieBeiPinFenLeiList);
        }
        // 跳过已经选择的备品set明细
        // where not in selectedFKIdList 共通に作る ここでいらない
        system.debug(soql);
        //system.assertEquals('qyj',soql);
        return soql;
    }

    public override void setViewList(List<sObject> queryList) {
        viewList = new List<WrapperInfo>();
        List<Rental_Apply_Equipment_Set_Detail__c> groupByTargetList = new List<Rental_Apply_Equipment_Set_Detail__c>();

        if (selectedData.size() == 0) {
            // 因为是主体,肯定有数据,主体没有的情况,提示错误信息
            throw new ControllerUtil.myException('主体不存在,请选择有主体的数据。');
        }

        // 自己的数据打勾，被检索出来的数据不打勾
        // 選択済みの明细をviewListに追加
        if (selectedData.size() > 0) {
            for (Integer i = 0; i < selectedData.size(); i++) {
                /* not include the selected data num */
                // 501を超えた場合前500のみを出す
                //if (i == getSearchNumMax()) continue;
                Rental_Apply_Equipment_Set_Detail__c rsdObj = (Rental_Apply_Equipment_Set_Detail__c) selectedData[i];
                System.debug('rsdObj.Asset__c' + rsdObj.Asset__c);
                if (!String.isBlank(rsdObj.Asset__c)) {

                    viewList.add(new WrapperInfo(rsdObj, myComponentController));
                    viewList[viewList.size() - 1].lineNo = viewList.size() - 1;
                    viewList[viewList.size() - 1].check = true;
                    viewList[viewList.size() - 1].oldCheck = true;
                    if (is2B1 && pCunFangDi != rsdObj.Internal_asset_location__c) {
                        viewList[viewList.size() - 1].canEdit = false;
                    }
                    groupByTargetList.add(rsdObj);

                    // QueuePageByAssetId的URL, 加载排队画面用
                    queueByAsset = '/apex/QueuePageByAssetId?parentId=' + rsdObj.Rental_Apply_Equipment_Set__c + '&isNotShow=' + true;
                    assetId  = rsdObj.Asset__c;
                    rentalId = rsdObj.Rental_Apply_Equipment_Set__c;
                    modelNo  = rsdObj.Fixture_Model_No_text__c;
                    raesdId = rsdObj.Id;
                }
            }
        }

        // queryList に 数式項目を取得
        Savepoint sp = Database.setSavepoint();
        // 下にrollbackがあります
        System_UserSetting__c config = System_UserSetting__c.getInstance(UserInfo.getUserId());
        config.RentalApply_ByPass__c = true;
        // 組織のカスタム設定が作成してないの可能性がありますのでここでupsert
        FixtureUtil.withoutUpsertObjects(new System_UserSetting__c[]{config});

        //没有最新预计返回日用的一览
        Rental_Apply_Equipment_Set__c raes = new Rental_Apply_Equipment_Set__c(
            Rental_Apply__c = parentObj.Rental_Apply__c,
            Fixture_Set__c = parentObj.Fixture_Set__c,
            DataMigration_Flag__c = true);
        FixtureUtil.withoutInsert(new Rental_Apply_Equipment_Set__c[]{raes});

        // 数式項目値を取れるのために、一回Insertする
        List<Rental_Apply_Equipment_Set_Detail__c> tempList = new List<Rental_Apply_Equipment_Set_Detail__c>();
        for (Integer i = 0; i < queryList.size(); i++) {
            // 501を超えた場合前500のみを出す
            if (i == getSearchNumMax()) { break; }
            // 一覧のsize
            // ここnewではない、makeSelectedDataInfoのdataをcloneしてください。
            Rental_Apply_Equipment_Set_Detail__c mf = ((Rental_Apply_Equipment_Set_Detail__c) selectedData[0]).clone(false);

            // ****************注意:这里不能随意清空字段,如果要清空一定要慎重再慎重,因为保存的时候可能会把有值的字段清空掉
            // 因为检索的时候需要显示检索出来的Asset信息，所以需要清除Clone出来的值，好让数据可以的Handler里面赋成当前Asset值
            // mf.Fixture_Model_No_text__c = null; OLY_OCM-431 不设定， 设定的话 画面会显示成 代替品
            mf.SerialNumber_text__c = null;
            mf.SalesProvince_before__c = null;
            mf.Salesdepartment_before__c = null;
            mf.Product_category_text__c = null;
            mf.Equipment_Type_text__c = null;
            mf.Asset_cost_del_before__c = null;
            mf.Internal_asset_location_before__c = null;
            mf.Fixture_Name_text__c = mf.FSD_Name_CHN__c;
            mf.EquipmentSet_Managment_Code_text__c = null;

            Asset ass = (Asset)queryList[i];
            mf.Asset__c                             = ass.Id;
            /* ---------------- OLY_OCM-603 Start 最新预定归还日显示保有设备新建的公式字段 */
            // if (ass.Last_Reserve_RAES_Detail__c != null) {
                //有last的话一览为最新借出一览明细的一览(显示最新预计归还日)
                // mf.Rental_Apply_Equipment_Set__c = ass.Last_Reserve_RAES_Detail__r.Rental_Apply_Equipment_Set__c;
            // } else {
                //没有last的话一览为新建的一览(最新预计归还日为空)
                mf.Rental_Apply_Equipment_Set__c = raes.Id;
            // }
            /* ---------------- OLY_OCM-603 End */
            mf.DataMigration_Flag__c                = true;
            tempList.add(mf);
        }

        Database.SaveResult[] results = FixtureUtil.withoutInsert(tempList, false);

        final String soqlStr = 'Select {0} {1} ';
        String whereStr = ' FROM Rental_Apply_Equipment_Set_Detail__c WHERE ID in: tempList';
        String soql = String.format(soqlStr, new String[] {myComponentController.strColumus , whereStr});

        tempList = FixtureUtil.queryTempList(soql, tempList);
        if (queryList.size() != tempList.size()) {
            //error message 検索処理正しくありません、システム管理者に連絡してください。
            for (Integer i = 0; i < results.size(); i ++) {
                Database.SaveResult dmlResult = results[i];
                if (!dmlResult.isSuccess()) {
                    System.debug(System.LoggingLevel.ERROR, '第[' + (i + 1) + ']条 insert error:' + dmlResult);
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,
                    '第[' + (i + 1) + ']条 insert error:' + dmlResult));
                    // 1件目だけlogに出す
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,
                        System.Label.CreateRelationListSearchError));
                    Database.rollback(sp);
                    return;
                }
            }
        }
        // 強制ロールバックしますが、数式の値が取れたインスタンスがfsDMapに保持
        Database.rollback(sp);

        Map<String, SObject> fsDMap = new Map<String, SObject>();
        for (Rental_Apply_Equipment_Set_Detail__c fsd : tempList) {
            Rental_Apply_Equipment_Set_Detail__c robj = fsd.clone(false);
            robj.DataMigration_Flag__c = false;
            fsDMap.put(fsd.Asset__c, robj);
        }

        // queryListとfsDMapよりnew WrapperInfo()して、viewListに追加
        for (Integer i = 0; i < queryList.size(); i++) {
            // 501を超えた場合前500のみを出す
            if (i == getSearchNumMax()) { break; }

            Rental_Apply_Equipment_Set_Detail__c mf = (Rental_Apply_Equipment_Set_Detail__c) fsDMap.get(queryList[i].Id);

            viewList.add(new WrapperInfo(mf, myComponentController));
            viewList[viewList.size() - 1].lineNo = viewList.size() - 1;
            if (is2B1 && pCunFangDi != mf.Internal_asset_location__c) {
                viewList[viewList.size() - 1].canEdit = false;
            }
            groupByTargetList.add(mf);
        }
system.debug('●●●●● setViewList END ' );

        // 一覧に対して、groupbyの項目の値を取得
        Map<Id, Map<String, FixtureUtil.groupBean>> rsdMap = FixtureUtil.raesdGroupByAssetId(
                groupByTargetList, myComponentController.columus);

        for (Rental_Apply_Equipment_Set_Detail__c rsdObj : groupByTargetList) {

            Map<String, FixtureUtil.groupBean> rsdGroupInfo = rsdMap.get(rsdObj.Asset__c);

            for (String apikey : rsdGroupInfo.keySet()){
                if (apikey.indexOf('_Jia__c') >= 0) {
                    if (apikey == 'Fu_Shu_Pin_Fen_Pei_Jia__c' || apikey == 'Zhu_Ti_Fen_Pei_Jia__c') {
                        // 別途設定する
                        continue;
                    } else {
                        rsdObj.put(apikey, rsdGroupInfo.get(apikey).gnum);
                    }
                }
            }

            // 自己:分配 或者 暂定分配 了的 就是这个asset的时候
            if (sonObj.Asset__c == rsdObj.Asset__c) {
                // RAESD_Status__c 里可能会出 暂定分配
                rsdObj.Zhu_Ti_Fen_Pei_Jia__c = rsdObj.RAESD_Status__c;
            }
            // 自己是排队中 and 看别人是已分配, 的时候
            else if (sonObj.Queue_Number__c > 0
                    && rsdObj.Asset__r.Last_Reserve_RAES_Detail__r.Select_Time__c != null) {
                // 自己显示 Mei_You_Ku_Cun
                rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal());
            }
            // 自己不是排队中 and 看别人是已分配, 的时候
            else if ((sonObj.Queue_Number__c == 0 || sonObj.Queue_Number__c == null)
                    && rsdObj.Asset__r.Last_Reserve_RAES_Detail__r.Select_Time__c != null) {
                // 自己显示 Mei_You_Ku_Cun
                rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal());
            }
            // 自己是排队中 and 看别人是 没有分配 的时候
            else if (sonObj.Queue_Number__c > 0
                    && String.isBlank(rsdObj.Asset__r.Last_Reserve_RAES_Detail__c)
            ) {
                if (rsdObj.Asset__r.You_Xiao_Ku_Cun__c > 0) {
                    // 自己显示 Ke_Yi_Fen_Pei
                    rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal());
                } else {
                    // 自己显示 Mei_You_Ku_Cun
                    rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal());
                }
            }
            // 自己不是排队中 and 看别人是 没有分配 的时候
            else if ((sonObj.Queue_Number__c == 0 || sonObj.Queue_Number__c == null)
                    && String.isBlank(rsdObj.Asset__r.Last_Reserve_RAES_Detail__c)
            ) {
                if (rsdObj.Asset__r.You_Xiao_Ku_Cun__c > 0) {
                    // 自己显示 Ke_Yi_Fen_Pei
                    rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal());
                } else {
                    // 自己显示 Mei_You_Ku_Cun
                    rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal());
                }
            }
            // 自己是排队中 and 看别人是 暂定分配 的时候
            else if (sonObj.Queue_Number__c > 0
                    && String.isNotBlank(rsdObj.Asset__r.Last_Reserve_RAES_Detail__c)
                    && rsdObj.Asset__r.Last_Reserve_RAES_Detail__r.Select_Time__c == null
            ) {
                // 自己显示 Ke_Yi_Fen_Pei
                rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal());
            }
            // 自己不是排队中 and 看别人是 暂定分配 的时候
            else if ((sonObj.Queue_Number__c == 0 || sonObj.Queue_Number__c == null)
                    && String.isNotBlank(rsdObj.Asset__r.Last_Reserve_RAES_Detail__c)
                    && rsdObj.Asset__r.Last_Reserve_RAES_Detail__r.Select_Time__c == null
            ) {
                // 自己显示 Ke_Yi_Fen_Pei
                rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal());
            }

            // else: 要做到 原则不会发生  // 会后这个 TODO 有关联 ?? TODO why要看? 要看的话 另外3个别字段不看吗?
            else {
                // 以下は 念のためのロジック
                // 看别人是 (暂定分配 or 没有分配), 的时候
                if (rsdObj.Asset__r.You_Xiao_Ku_Cun__c > 0
                        && (String.isBlank(rsdObj.Asset__r.Last_Reserve_RAES_Detail__c)
                                || rsdObj.Asset__r.Last_Reserve_RAES_Detail__r.Select_Time__c == null)
                ) {
                    // 自己显示 Ke_Yi_Fen_Pei
                    rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal());
                }
                else {
                    // 自己显示 Mei_You_Ku_Cun
                    rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal());
                }
            }
            // if (rsdObj.Select_Time__c != null) {
            //     rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.HistoryStatus.Yi_Fen_Pei.ordinal());
            // } else if (rsdObj.Queue_Number__c == 0 && rsdObj.Queue_Day__c != null) {
            // // 暂定分配 未分配并且排队的第一个
            //     rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.HistoryStatus.Zan_Ding_Fen_Pei.ordinal());
            // }else if (rsdObj.Queue_Number__c > 0) {
            //     //已排队状态设值
            //     rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Pai_Dui_Zhong.ordinal());
            // } else if (rsdObj.Cancel_Select__c) {
            //     rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Qu_Xiao.ordinal());
            // }else {
            //     rsdObj.Zhu_Ti_Fen_Pei_Jia__c = FixtureUtil.assetFixtureStatusMap.get(subjectStatus);
            // }
       }

       wrapperStr = JSON.serialize(viewList);
       System.debug(LoggingLevel.INFO, '*** wrapperStr: ' + wrapperStr);
system.debug('●●●●● raesdGroupByAssetId END ' );
    }

    public String getWrapperJSON(){
        System.debug(LoggingLevel.INFO, '*** wrapperStr: ' + wrapperStr);
        return wrapperStr;
    }

    /**
     * OLY_OCM-431 raesdList 是一对一分配对象, 但是里面有之前是手动分配的已下架明细
     * 对 raesdList 进行一对一分配
     * @param raesdList select from Rental_Apply_Equipment_Set_Detail__c 找出需要分配的对象
     * @param oneToOneListMap 被分配对象 {Fixture_Model_No_F__c: [Asset.Id]}
     * @param assetKuCunMap 分配前的 Asset 的有效库存 (You_Xiao_Ku_Cun__c) {Id<Asset>: Asset{You_Xiao_Ku_Cun__c}}
     * @param fOtoMap 之前的一对一分配数也需要一起清空 + 今回の更新一对一分配的Link表
     * @param selectTime 主体的分配时间
     * @param rtnMfUpsert 更新用, 有返回的功能
     * @param rtnOldMap 重新分配 对象Map, 有返回的功能
     */
    private void oneToOneSelect(List<Rental_Apply_Equipment_Set_Detail__c> raesdList
            , Map<String, List<Fixture_OneToOne_Link__c>> oneToOneListMap
            , Map<Id, Asset> assetKuCunMap
            , Map<Id, Fixture_OneToOne_Link__c> fOtoMap
            , Datetime selectTime
            , Map<String, Rental_Apply_Equipment_Set_Detail__c> rtnMfUpsert
            , Map<Id, Rental_Apply_Equipment_Set_Detail__c> rtnOldMap) {

        List<Rental_Apply_Equipment_Set_Detail__c> rtnOldList = new List<Rental_Apply_Equipment_Set_Detail__c>();
        for (Rental_Apply_Equipment_Set_Detail__c accessoryObj : raesdList) {
            List<Fixture_OneToOne_Link__c> oneToOneAsetIdList = oneToOneListMap.get(accessoryObj.FSD_Fixture_Model_No__c);
            if (oneToOneAsetIdList == null || oneToOneAsetIdList.isEmpty()) {
                // 没有一对一了, 不分配
            } else {
                // 有一对一定义的附属品
                // 备品有效库存
                Integer num = Integer.valueof(assetKuCunMap.get(oneToOneAsetIdList[0].Accessory_Asset__c).You_Xiao_Ku_Cun__c);
                // TODO if (num < oneToOneAsetIdList.size()) {
                if (num < 1) {
                    // [' + accessoryObj.FSD_Fixture_Model_No__c + '] 的一对一定义没有足够库存，请确认一对一定义');
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.WARNING, '一对一没有全部分配'));
                }
                else {
                    // 已下架, 没有出库的话的话, 要先做 重新分配
                    if (accessoryObj.StockDown__c && String.isBlank(accessoryObj.DeliverySlip__c)) {
                        // 在庫まずみない
                        rtnOldList.add(accessoryObj);
                        rtnOldMap.put(accessoryObj.Id, accessoryObj);
                        accessoryObj.Cancel_Select__c = true;
                        accessoryObj.Cancel_Reason__c = '重新分配';
                        accessoryObj.Loaner_cancel_Remarks__c = '下架后一对一重新分配';
                    }
                    // 不是已下架的话, 可以分配
                    else {
                        if (!fOtoMap.containsKey(oneToOneAsetIdList[0].Id)) {
                            oneToOneAsetIdList[0].Select_Accessory_Asset_Cnt__c = 0;
                            fOtoMap.put(oneToOneAsetIdList[0].Id, oneToOneAsetIdList[0]);
                        }
                        // 有 一对一 附属品
                        // accessoryObj.UniqueKey__c   // and UniqueKey__c != null
                        accessoryObj.Fixture_OneToOne_Link_Id__c = oneToOneAsetIdList[0].Id; // 有 remove(0), 所以取[0]
                        accessoryObj.Asset__c = oneToOneAsetIdList[0].Accessory_Asset__c;
                        accessoryObj.Select_Time__c = selectTime;      // 主体的分配时间
                        accessoryObj.Shipment_request_time2__c = null;
                        accessoryObj.Shipment_request__c = false;
                        rtnMfUpsert.put(accessoryObj.UniqueKey__c, accessoryObj);
                        Fixture_OneToOne_Link__c fot = fOtoMap.get(oneToOneAsetIdList[0].Id);
                        fot.Select_Accessory_Asset_Cnt__c += 1;
                        fOtoMap.put(oneToOneAsetIdList[0].Id, fot);
                        oneToOneAsetIdList.remove(0);
                    }
                }
            }
        }
        // 确认 rtnOldMap 还能不能一对一分配
        for (Rental_Apply_Equipment_Set_Detail__c accessoryObj : rtnOldList) {
            List<Fixture_OneToOne_Link__c> oneToOneAsetIdList = oneToOneListMap.get(accessoryObj.FSD_Fixture_Model_No__c);
            if (oneToOneAsetIdList == null || oneToOneAsetIdList.isEmpty()) {
                // 没有一对一了, 不分配
                rtnOldMap.remove(accessoryObj.Id);
            } else {
                // 有一对一定义的附属品
            }
        }
    }

    //特殊排队
    public PageReference specialScheduel(){
        List<Rental_Apply_Equipment_Set__c> mfUpdate = new List<Rental_Apply_Equipment_Set__c>();
        Savepoint sp = Database.setSavepoint();
        try {
            // 先判断当前操作用户的存放地和申请单的存放地是否一致
            if (!enableRunCheck()) {
                throw new ControllerUtil.myException('无权限操作当前单据进行排队！');
            }

            if(String.isEmpty(bieCunFangDi)){
                throw new ControllerUtil.myException('特殊排队时，请选择备品存放地');
            }
            if(bieCunFangDi != parentObj.Rental_Apply__r.Internal_asset_location_F__c){
                throw new ControllerUtil.myException('特殊排队时，不能跨备品存放地排队');
            }
            /*if(String.isEmpty(bieChanPinFenLei)){
                throw new ControllerUtil.myException('特殊排队时，产品分类必填！');
            }*/
            if(String.isEmpty(bieBeiPinFenLei)){
                throw new ControllerUtil.myException('特殊排队时，请选择备品分类');
            }
            if(bieBeiPinFenLei.contains('全部')){
                throw new ControllerUtil.myException('特殊排队时，备品分类不能选择全部！');
            }
            if(String.isEmpty(bieBenBu)){
                throw new ControllerUtil.myException('特殊排队时，请选择本部');
            }
            if(bieBenBu.contains('全部')){
                throw new ControllerUtil.myException('特殊排队时，本部不能选择全部！');
            }
            if(parentObj.Rental_Apply__r.Demo_purpose1__c == '维修代用' || parentObj.Rental_Apply__r.Demo_purpose1__c == '协议借用'){
                 throw new ControllerUtil.myException('当前使用目的不允许特殊排队!');
            }
            // 当申请人=FSE、使用目的2=学会展会时，不可以操作特殊排队
            if(parentObj.Rental_Apply__r.demo_purpose2__c == '学会展会' && parentObj.Rental_Apply__r.Owner.Profile.Name.contains('FSE')){
                 throw new ControllerUtil.myException('服务培训/学会申请单无特殊排队!');
            }
            if((bieBenBu.contains('MA本部') || bieBenBu.contains('产品培训')) && (bieBenBu.countMatches('本部') > 1 || bieBenBu.contains('备品中心'))){
                throw new ControllerUtil.myException('MA本部/产品培训本部不能与其他本部同时选择!');
            }
            if((bieBeiPinFenLei.contains('产品试用') && bieBeiPinFenLei.contains('协议借用')) 
                || (bieBeiPinFenLei.contains('协议借用') && bieBeiPinFenLei.contains('维修'))
                || (bieBeiPinFenLei.contains('产品试用') && bieBeiPinFenLei.contains('维修'))){
                throw new ControllerUtil.myException('维修类、试用类、协议借用类不能同时选择!');
            }
            if(parentObj.Rental_Apply__r.Demo_purpose1__c == '产品试用' 
                && (bieBeiPinFenLei.contains('协议借用') || bieBeiPinFenLei.contains('维修'))){
                throw new ControllerUtil.myException('产品试用的申请单，不可以选择维修类、协议借用类的备品分类');
            }
            if((parentObj.Rental_Apply__r.demo_purpose2__c == '试用（无询价）' 
                    || parentObj.Rental_Apply__r.demo_purpose2__c == '试用（有询价）'
                    || parentObj.Rental_Apply__r.demo_purpose2__c == '已购待货' 
                    || parentObj.Rental_Apply__r.demo_purpose2__c == '新产品评价') 
                && sonObj.Rental_Apply_Equipment_Set__r.Fixture_Set__r.Product_Type__c == '新产品') {
                throw new ControllerUtil.myException('不能参与特殊排队');
            }
            startQueue('特殊排队');
            if(allSpecialQueue() && parentObj.Rental_Apply__r.CampaignType__c != null){
                Rental_Apply__c raObj = new Rental_Apply__c();
                raObj.Id = parentObj.Rental_Apply__c;
                raObj.CampaignType__c = null;
                update raObj;
            }
        } catch (Exception e) {
            System.debug('e.getMessage()***'+ e.getMessage());
            ApexPages.addMessages(e);
            Database.rollback(sp);
            return null;
        }
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.CONFIRM,'排队成功'));
        // 排队成功后，加载排队画面
        queueByAsset = '/apex/QueuePageByAssetId?parentId=' + parentObj.Id + '&isNotShow=' + true;

        // 排队成功后，需要重新获取sonObj和parentObj
        List<Rental_Apply_Equipment_Set_Detail__c> raesdObjs = [
                SELECT Id, Rental_Apply_Equipment_Set__c, Asset__c, Queue_Day__c,
                       FSD_Fixture_Model_No__c, Fixture_Model_No_text__c, QuenType__c,
                       Is_Body__c, FSD_Is_OneToOne__c, Select_Time__c, ExternalKey__c,Rental_Apply__c,
                       Cancel_Select__c, Fixture_Model_No_F__c, Queue_Number__c, Internal_asset_location__c,
                       Salesdepartment__c, Product_category_F__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.Fixture_Set__r.Product_Type__c,Intervention_Reason__c,
                       Salesdepartment_before__c, Equipment_Type_text__c, Product_category_text__c
                 FROM Rental_Apply_Equipment_Set_Detail__c
                WHERE Rental_Apply_Equipment_Set__c = :parentId
                  and Is_Body__c = true
                  and Cancel_Select__c = false];

        if (!raesdObjs.isEmpty()) {
            sonObj = raesdObjs[0];

            List<Rental_Apply_Equipment_Set__c> parentObjs = [
                    SELECT Id, Rental_Apply__r.Name,
                           Rental_Apply__r.Owner.Name,
                           Rental_Apply__r.Owner.Profile.Name,
                           Rental_Apply__r.Salesdept__c,
                           Rental_Apply__r.WorkPlace__c,
                           Rental_Apply__r.Request_shipping_day__c,
                           Fu_Shu_Pin_Fen_Pei_Jia__c,
                           Rental_Apply__r.Demo_purpose1__c,
                           Rental_Apply__r.demo_purpose2__c,
                           Rental_Apply__r.CampaignType__c,
                           Fixture_Set__r.Product_Category_GI_SP__c,
                           Fixture_Set__r.Equipment_Type__c,
                           Rental_Apply__r.Request_return_day__c,
                           Rental_Apply__r.Salesdepartment__c,
                           Rental_Apply__r.Equipment_Type_F__c,
                           Rental_Apply__r.Internal_asset_location_F__c,
                           Fixture_Set__r.Fixture_Set_Body_Model_No__c,
                           Rental_Apply__r.Product_category__c,
                           Rental_Apply__r.Loaner_centre_mail_address__c,
                           First_RAESD__r.Is_Body__c,
                           Irreplaceable_flag__c,
                           Rental_Start_Date__c,
                           Rental_End_Date__c,
                           Rental_Apply__c,
                           Fixture_Set__c,
                           RequestNoJoinStr2__c
                    FROM Rental_Apply_Equipment_Set__c
                    where Id = :parentId];
            if (!parentObjs.isEmpty()) {
                parentObj = parentObjs.get(0);
            }
        }
        
        return null;
    }

    //默认排队
    public PageReference defaultScheduel(){
        Savepoint sp = Database.setSavepoint();
        try {
            // 先判断当前操作用户的存放地和申请单的存放地是否一致
            if (!enableRunCheck()) {
                throw new ControllerUtil.myException('无权限操作当前单据进行排队！');
            }

            if(parentObj.Rental_Apply__r.demo_purpose2__c == '学会展会' 
                && !(parentObj.Rental_Apply__r.Salesdepartment__c.contains('MA本部') 
                    || parentObj.Rental_Apply__r.Salesdepartment__c.contains('产品培训')) 
                && String.isEmpty(campaignType)){
                throw new ControllerUtil.myException('请选择学会类型！');
            }
            if(sonObj.QuenType__c == '默认排队' 
                && sonObj.Queue_Number__c > 0 
                && sonObj.Queue_Day__c != null 
                && campaignType == parentObj.Rental_Apply__r.CampaignType__c){
                throw new ControllerUtil.myException('已参与默认排队');
            }
            startQueue('默认排队');

        }
        catch (Exception e) {
            System.debug('e.getMessage()***'+ e.getMessage());
            ApexPages.addMessages(e);
            Database.rollback(sp);
            return null;
        }
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.CONFIRM,'排队成功'));
        // 排队成功后，加载排队画面
        queueByAsset = '/apex/QueuePageByAssetId?parentId=' + parentObj.Id + '&isNotShow=' + true;
        
        // 排队成功后，需要重新获取sonObj和parentObj
        List<Rental_Apply_Equipment_Set_Detail__c> raesdObjs = [
                SELECT Id, Rental_Apply_Equipment_Set__c, Asset__c, Queue_Day__c,
                       FSD_Fixture_Model_No__c, Fixture_Model_No_text__c, QuenType__c,
                       Is_Body__c, FSD_Is_OneToOne__c, Select_Time__c, ExternalKey__c,Rental_Apply__c,
                       Cancel_Select__c, Fixture_Model_No_F__c, Queue_Number__c, Internal_asset_location__c,
                       Salesdepartment__c, Product_category_F__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.Fixture_Set__r.Product_Type__c,Intervention_Reason__c,
                       Salesdepartment_before__c, Equipment_Type_text__c, Product_category_text__c
                 FROM Rental_Apply_Equipment_Set_Detail__c
                WHERE Rental_Apply_Equipment_Set__c = :parentId
                  and Is_Body__c = true
                  and Cancel_Select__c = false];

        if (!raesdObjs.isEmpty()) {
            sonObj = raesdObjs[0];

            List<Rental_Apply_Equipment_Set__c> parentObjs = [
                    SELECT Id, Rental_Apply__r.Name,
                           Rental_Apply__r.Owner.Name,
                           Rental_Apply__r.Owner.Profile.Name,
                           Rental_Apply__r.Salesdept__c,
                           Rental_Apply__r.WorkPlace__c,
                           Rental_Apply__r.Request_shipping_day__c,
                           Fu_Shu_Pin_Fen_Pei_Jia__c,
                           Rental_Apply__r.Demo_purpose1__c,
                           Rental_Apply__r.demo_purpose2__c,
                           Rental_Apply__r.CampaignType__c,
                           Fixture_Set__r.Product_Category_GI_SP__c,
                           Fixture_Set__r.Equipment_Type__c,
                           Rental_Apply__r.Request_return_day__c,
                           Rental_Apply__r.Salesdepartment__c,
                           Rental_Apply__r.Equipment_Type_F__c,
                           Rental_Apply__r.Internal_asset_location_F__c,
                           Fixture_Set__r.Fixture_Set_Body_Model_No__c,
                           Rental_Apply__r.Product_category__c,
                           Rental_Apply__r.Loaner_centre_mail_address__c,
                           First_RAESD__r.Is_Body__c,
                           Irreplaceable_flag__c,
                           Rental_Start_Date__c,
                           Rental_End_Date__c,
                           Rental_Apply__c,
                           Fixture_Set__c,
                           RequestNoJoinStr2__c
                    FROM Rental_Apply_Equipment_Set__c
                    where Id = :parentId];
            if (!parentObjs.isEmpty()) {
                parentObj = parentObjs.get(0);
            }
        }
        
        return null;
    }

    // 判断当前操作用户的存放地和申请单的存放地是否一致
    public Boolean enableRunCheck() {
        // 用户分公司：北京，上海，广州
        User u = [SELECT Id, Branch__c FROM User WHERE Id =:UserInfo.getUserId() Limit 1];
        // 申请单 申请者Email
        if (FixtureUtil.locationMap.get(u.Branch__c + ' 备品中心') != parentObj.Rental_Apply__r.Loaner_centre_mail_address__c) {
            return false;
        } else {
            return true;
        }

        return false;
    }

    //排队No置顶
    public PageReference topInLine(){
        Savepoint sp = Database.setSavepoint();
        try {
            QueuePageByAssetIdController qpbaController = new QueuePageByAssetIdController();
            qpbaController.saveQueue(sonObj, 1, true, false);
        }
        catch (Exception e) {
            System.debug('e.getMessage()***'+ e.getMessage()+e.getLineNumber());
            ApexPages.addMessages(e);
            Database.rollback(sp);
            return null;
        }
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.CONFIRM,'排队置顶成功'));
        return null;
    }

    // 如果默认分配改为特殊排队了，需要确认申请单中所有的一览是否都没有默认排队
    public Boolean allSpecialQueue(){
        List<Rental_Apply_Equipment_Set_Detail__c> details = [SELECT Id
                                                                FROM Rental_Apply_Equipment_Set_Detail__c
                                                                WHERE Rental_Apply__c =: parentObj.Rental_Apply__c
                                                                  AND Cancel_Select__c = false
                                                                  AND Is_Body__c = true
                                                                  AND QuenType__c = '默认排队'];
        if (details != null && details.size() > 0) {
            return false;
        }
        return true;
    }

    public void startQueue(String queuetype){
        System.debug(LoggingLevel.INFO, '*** queuetype: ' + queuetype);

        // 查询排队需要处理的数据
        List<Rental_Apply_Equipment_Set_Detail__c> raesdObjs = [
                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,
                       // 备品智能化项目对应 20231122 by lc Start
                       Rental_Apply__r.OPD_OrderNum__c,Rental_Apply__r.OPD_AdjustmentOrderNum_Flag__c,
                       Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c,
                       // 备品智能化项目对应 20231122 by lc End
                       Queue_Time_F__c, IndexFromUniqueKey__c 
                FROM Rental_Apply_Equipment_Set_Detail__c
                WHERE Rental_Apply_Equipment_Set__c =:parentObj.Id
                AND Cancel_Select__c = false
                AND Is_Body__c = true
                FOR Update];

        if(queuetype == '默认排队'){
            if(changeCampaignType){
                List<Rental_Apply_Equipment_Set_Detail__c> oldQueenList = [
                        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,
                               // 备品智能化项目对应 20231122 by lc Start
                               Rental_Apply__r.OPD_OrderNum__c,Rental_Apply__r.OPD_AdjustmentOrderNum_Flag__c,
                               Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c,
                               // 备品智能化项目对应 20231122 by lc End
                               Queue_Time_F__c, IndexFromUniqueKey__c 
                        FROM Rental_Apply_Equipment_Set_Detail__c
                        WHERE Rental_Apply__c =: parentObj.Rental_Apply__c
                        AND Id !=: sonObj.Id 
                        AND QuenType__c = '默认排队' 
                        AND Queue_Number__c > 0
                        AND Cancel_Select__c = false
                        AND Is_Body__c = true 
                        FOR Update];

                raesdObjs.addAll(oldQueenList);
            }

            // 学会类型发生变化时，更新申请单
            if (campaignType != parentObj.Rental_Apply__r.CampaignType__c) {
                Rental_Apply__c raObj = new Rental_Apply__c();
                raObj.Id = parentObj.Rental_Apply__c;
                raObj.CampaignType__c = campaignType;
                update raObj;
            }
        }

        List<String> modelList = new List<String>();
        List<String> departmentsList = new List<String>();
        List<String> departmentList = new List<String>();
        List<String> locationList = new List<String>();
        List<String> categoryList = new List<String>();
        List<String> equipmentList = new List<String>();
        List<String> equipmentsList = new List<String>();
        List<String> locationsetList = new List<String>();
        List<String> sequencekeylist = new List<String>();
        List<String> detailIds = new List<String>();
        List<String> queuekeyList = new List<String>();
        List<Rental_Apply_Sequence__c> allsequenceList = new List<Rental_Apply_Sequence__c>();
        Map<String,List<Rental_Apply_Equipment_Set_Detail__c>> detailMap = new Map<String,List<Rental_Apply_Equipment_Set_Detail__c>>();
        List<String> queueIds = new List<String>();
        List<Rental_Apply_Equipment_Set_Detail__c> updateList = new List<Rental_Apply_Equipment_Set_Detail__c>();
        List<String> changeddetailIds = new List<String>();

        for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdObjs) {
            String oldKey = raesd.ExternalKey__c;
            // 改变学会类型，会改变本申请单中已默认排队的其余一览，所以校验放在此处
            String modelType = raesd.Rental_Apply_Equipment_Set__r.Fixture_Set__r.Product_Type__c;
            if(modelType == null && queuetype == '默认排队' 
                && (parentObj.Rental_Apply__r.demo_purpose2__c == '试用（无询价）' 
                    || parentObj.Rental_Apply__r.demo_purpose2__c == '试用（有询价）'
                    || parentObj.Rental_Apply__r.demo_purpose2__c == '已购待货' 
                    || parentObj.Rental_Apply__r.demo_purpose2__c == '新产品评价' 
                    || (parentObj.Rental_Apply__r.demo_purpose2__c == '学会展会' && campaignType == '营业本部学会'))){
                throw new ControllerUtil.myException('备品产品类型为空！');
            }

            RentalFixtureSetAssignController.KeyObj obj = null;
            if(queuetype == '默认排队'){
                RentalFixtureSetAssignController.ApplyObj applyObj = new RentalFixtureSetAssignController.ApplyObj();
                applyObj.location = parentObj.Rental_Apply__r.Internal_asset_location_F__c;
                applyObj.productType = parentObj.Rental_Apply__r.Product_category__c;
                applyObj.salesdepartment = parentObj.Rental_Apply__r.Salesdepartment__c ;
                applyObj.purpose1 = parentObj.Rental_Apply__r.Demo_purpose1__c;
                applyObj.purpose2 = parentObj.Rental_Apply__r.demo_purpose2__c;
                applyObj.campaignType = campaignType;
                obj = RentalFixtureSetAssignController.getdefultInfo(raesd,applyObj,bieCunFangDi);
                // 排队后，默认排队值需要在画面端显示  本部
                bieBenBu = obj.salesdepartments;
                // 排队后，默认排队值需要在画面端显示  备品分类
                bieBeiPinFenLei = obj.equipmenttypes;
                // 备品存放地和产品分类默认是申请单上的数据，不用特意设置
            }else{
                RentalFixtureSetAssignController.KeyObj keyObj = new RentalFixtureSetAssignController.KeyObj();
                keyObj.model = raesd.Fixture_Model_No__c;
                keyObj.location = parentObj.Rental_Apply__r.Internal_asset_location_F__c;
                keyObj.productType = String.isBlank(bieChanPinFenLei)?'GI,SP':bieChanPinFenLei;
                System.debug('bieBeiPinFenLei===========================' + bieBeiPinFenLei);
                keyObj.equipmenttypes = bieBeiPinFenLei;
                keyObj.salesdepartments = bieBenBu;
                RentalFixtureSetAssignController.getsequencekeyList(keyObj);
                obj = keyObj;
                System.debug('obj.equipmenttypes===========================' + obj.equipmenttypes);
                System.debug('obj.sequencekeyList===========================' + obj.sequencekeyList);
            }
            queueIds.add(raesd.Id);
            // keyObjMap.put(raesd.Id,obj);
            modelList.add(obj.model);
            departmentsList.addAll(obj.salesdepartmentList);
            locationList.add(obj.location);
            equipmentsList.addAll(obj.equipmentList);
            categoryList.addAll(obj.productTypes);
            sequencekeylist.addAll(obj.sequencekeylist);
            String key = obj.model + obj.location + obj.salesdepartments + obj.equipmenttypes + obj.productType;
            if(key == oldKey){
                changeddetailIds.add(raesd.Id);
            }
            
            // 备品配套明细型号(借出时)
            raesd.Fixture_Model_No_text__c = obj.model;
            // 所在地区(本部) 借出时
            raesd.Salesdepartment_before__c = obj.salesdepartments;
            
            // 产品分类(GI/SP)(借出时)
            raesd.Product_category_text__c = obj.productType;
            // 备品分类(借出时)
            raesd.Equipment_Type_text__c = obj.equipmenttypes;
            // 备品存放地(借出时)
            raesd.Internal_asset_location_before__c = obj.location;
            raesd.ExternalKey__c = key;
            raesd.QuenType__c = queuetype;

            raesd.Queue_User__c   = UserInfo.getUserId();
            raesd.Queue_Day__c    = Date.today();
            raesd.Queue_Time__c   = getCurrentTime();
            raesd.Select_Time__c  = null;
            raesd.Asset__c        = null;
            // 已出库指示的排队后清除出库指示信息
            raesd.Shipment_request_time2__c = null;
            raesd.Shipment_request__c = false;
            raesd.Queue_Number__c = -1;
            raesd.IsAdjust__c     = false;

            // OLY_OCM-243 追加字段对应 备品管理编码(借出时) 排队时清除与asset相连的借出时相关的字段
            raesd.EquipmentSet_Managment_Code_text__c = null;
            // 机身编号（借出时）
            raesd.SerialNumber_text__c = null;
            // 备品成本(借出时)
            raesd.Asset_cost_del_before__c = null;
            detailIds.add(raesd.Id);
            updateList.add(raesd);
            // KeyObj obj = keyObjMap.get(raesd.Id);
            System.debug(LoggingLevel.INFO, '*** KeyObj obj: ' + obj);
            for(String sales:obj.salesdepartmentList){
            
                for(String equip:obj.equipmentList){
                    for(String type:obj.productTypes){
                        Rental_Apply_Sequence__c newSequence = new Rental_Apply_Sequence__c();
                        newSequence.ExternalKey__c = obj.model + obj.location + sales + equip + type;
                        newSequence.Demo_Purpose2__c = raesd.Rental_Apply__r.demo_purpose2__c;
                        newSequence.Apply_Set_Detail__c = raesd.Id;
                        newSequence.Series_No__c = raesd.Queue_Number__c;
                        newSequence.Salesdepartment__c = sales;
                        newSequence.Product_category__c = type;
                        newSequence.Rental_Apply__c = raesd.Rental_Apply__c;
                        newSequence.Internal_asset_location__c = obj.location;
                        newSequence.Fixture_Model_No__c = obj.model;
                        newSequence.Equipment_Type__c = equip;
                        
                        allsequenceList.add(newSequence);
                    }
                }
            }
           
            queuekeyList.add(key);
            departmentList.addAll(RentalFixtureSetAssignController.transferStringToList(obj.salesdepartments));
            equipmentList.addAll(RentalFixtureSetAssignController.transferStringToList(obj.equipmenttypes));
        }
        System.debug(LoggingLevel.INFO, '**1111* updateList: ' + updateList);
        System.debug(LoggingLevel.INFO, '*** queueIds: ' + queueIds);
        System.debug(LoggingLevel.INFO, '*** modelList: ' + modelList);
        System.debug(LoggingLevel.INFO, '*** departmentsList: ' + departmentsList);
        System.debug(LoggingLevel.INFO, '*** locationList: ' + locationList);
        System.debug(LoggingLevel.INFO, '*** categoryList: ' + categoryList);
        System.debug(LoggingLevel.INFO, '*** equipmentList: ' + equipmentList);
        String soqlStr = 'Select Id, Last_Reserve_RAES_Detail__c, Fixture_Model_No_F__c, You_Xiao_Ku_Cun__c,'
                    + ' Salesdepartment__c, SalesProvince__c, Product_category__c, Equipment_Type__c, Internal_asset_location__c'
                     + ' From Asset '
                    + ' Where Asset_Owner__c = \'Olympus\''
                    + ' and Asset_loaner_category__c != \'耗材\''
                    + ' and RecordTypeId = \''+System.label.access_1+'\''
                    + ' and Delete_Flag__c = False'
                    + ' and Freeze_sign_Abandoned_Flag__c = False'
                    // 不参与自动分配排队
                    + ' and Not_Automatic_AssignQueue__c = False'
                    // 召回对象
                    + ' and Recall_Asset__c = False'
                    + ' and Product2.Fixture_Model_No_T__c IN:modelList'
                    + ' and Salesdepartment__c IN: departmentsList'
                    + ' and Internal_asset_location__c IN: locationList'
                    + ' and Product_category__c IN:categoryList'
                    + ' and Equipment_Type__c IN: equipmentList'
                    + ' and ' + FixtureUtil.getAssetSoqlBase()
                    + ' order by Id';
        // 检索符合这四个别字段和同一产品型号的数据存在与否
        System.debug(LoggingLevel.INFO, '*** soqlStr: ' + soqlStr);
        List<Asset> aSetCheck = Database.query(soqlStr);

        for (Asset ass : aSetCheck) {
            String key = ass.Fixture_Model_No_F__c + ass.Internal_asset_location__c + ass.Salesdepartment__c + ass.Equipment_Type__c + ass.Product_category__c;
            System.debug(LoggingLevel.INFO, '*** key: ' + key);

            if (ass.Last_Reserve_RAES_Detail__c == null && ass.You_Xiao_Ku_Cun__c > 0) {
                throw new ControllerUtil.myException(ass.Fixture_Model_No_F__c +' 有可以分配主体不需要排队');
            }
        }
        System.debug(LoggingLevel.INFO, '*** queuekeyList: ' + queuekeyList);

        Map<String,List<Rental_Apply_Equipment_Set_Detail__c>> queueMap = new Map<String,List<Rental_Apply_Equipment_Set_Detail__c>>();
        List<Rental_Apply_Equipment_Set_Detail__c> queueList = [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,Externalkey__c,Rental_Apply__r.demo_purpose2__c,Equipment_Type_text__c,
                                                                   Is_Body__c, FSD_Is_OneToOne__c, Select_Time__c,Rental_Apply__r.EquipmentGuaranteeFlg__c,Fixture_Model_No__c,
                                                                   Cancel_Select__c, Fixture_Model_No_F__c, Queue_Number__c, Internal_asset_location__c,IsAdjust__c,Queue_Day__c,Queue_Time__c,
                                                                   Salesdepartment__c, Product_category_F__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__r.Request_shipping_day__c,Rental_Apply__r.Request_approval_time__c,
                                                                   // 备品智能化项目对应 20231122 by lc Start
                                                                   Rental_Apply__r.OPD_OrderNum__c,Rental_Apply__r.OPD_AdjustmentOrderNum_Flag__c,
                                                                   Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c,
                                                                   // 备品智能化项目对应 20231122 by lc End
                                                                   Queue_Time_F__c,IndexFromUniqueKey__c
                                                            FROM Rental_Apply_Equipment_Set_Detail__c
                                                            WHERE Externalkey__c IN :queuekeyList
                                                            AND Cancel_Select__c = false
                                                            AND Is_Body__c = true
                                                            AND Id NOT IN:queueIds
                                                            AND Queue_Number__c > 0
                                                            FOR Update];

        updateList.addAll(queueList);
        System.debug(LoggingLevel.INFO, '***old updateList: ' + updateList.size());
        updateList = Batch_QueueAllDetail.getSortDetailList(updateList);
        System.debug(LoggingLevel.INFO, '*** updateList: ' + updateList.size());
        update updateList;

        System.debug(LoggingLevel.INFO, '*** allsequenceList: ' + allsequenceList.size());
        List<Rental_Apply_Sequence__c> oldSequenceList = [SELECT Id,ExternalKey__c,Fixture_Model_No__c FROM Rental_Apply_Sequence__c
                                                        WHERE Apply_Set_Detail__c IN:detailIds];
        System.debug(LoggingLevel.INFO, '*** oldSequenceList.size(): ' + oldSequenceList.size());
        Set<String> keys = new Set<String>();
        for(Rental_Apply_Sequence__c se:oldSequenceList){
            keys.add(se.ExternalKey__c);
        }
        Integer count = [SELECT count() FROM Rental_Apply_Sequence__c WHERE ExternalKey__c IN:keys];
        if(updateList.size() + count + oldSequenceList.size() > 9900){
            throw new ControllerUtil.myException('当前排队数据量过大，请稍后操作');
        }
        List<Rental_Apply_Sequence__c> olddleteSequenceList = [SELECT Id,ExternalKey__c,Fixture_Model_No__c FROM Rental_Apply_Sequence__c
                                                        WHERE Apply_Set_Detail__c IN:changeddetailIds];

        delete olddleteSequenceList;
        if(updateList.size() + count + oldSequenceList.size() + allsequenceList.size() > 9900){
            throw new ControllerUtil.myException('当前排队数据量过大，请稍后操作');
        }
        insert allsequenceList;
        List<String> newSequenceIds = new List<String>();
        for(Rental_Apply_Sequence__c se:allsequenceList){
            newSequenceIds.add(se.Id);
        }
        allsequenceList = [SELECT Id,ExternalKey__c,Demo_Purpose2__c,Rental_Apply__r.Request_shipping_day__c,Rental_Apply__r.EquipmentGuaranteeFlg__c,
                                    Apply_Set_Detail__c,Apply_Set_Detail_ExternalKey__c,Rental_Apply__r.Request_approval_time__c,Apply_Set_Detail__r.IsAdjust__c,
                                    Series_No__c,Salesdepartment__c,Product_category__c,Apply_Set_Detail__r.Queue_Day__c,Apply_Set_Detail__r.Queue_Time__c,
                                    Rental_Apply__c,Internal_asset_location__c,Series_Unequal_Queue_Flag__c,
                                    Apply_Set_Detail__r.Queue_Number__c,
                                    Fixture_Model_No__c,Equipment_Type__c,
                                    Apply_Set_Detail__r.Queue_Time_F__c, 
                                    // 备品智能化项目对应 20231122 by lc Start
                                    Rental_Apply__r.OPD_OrderNum__c,
                                    Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c,
                                    // 备品智能化项目对应 20231122 by lc End
                                    Apply_Set_Detail__r.IndexFromUniqueKey__c
                            FROM Rental_Apply_Sequence__c
                            WHERE Id IN:newSequenceIds];

        List<String> nodusequencekeylist = new List<String>(new Set<String>(sequencekeylist));
        System.debug(LoggingLevel.INFO, '*** nodusequencekeylist: ' + JSON.serialize(nodusequencekeylist));
        
        System.debug(LoggingLevel.INFO, '*** nodusequencekeylist.size(): ' + nodusequencekeylist.size());
        if(nodusequencekeylist.size() > 950){
            throw new ControllerUtil.myException('当前排队数据量过大，请选择单个主体操作');
        }
        List<Rental_Apply_Sequence__c> updateSequenceList = new List<Rental_Apply_Sequence__c>();
        List<Rental_Apply_Sequence__c> newSequenceList = new List<Rental_Apply_Sequence__c>();
        List<Rental_Apply_Sequence__c> applysequenceList = [SELECT Id,ExternalKey__c,Demo_Purpose2__c,Rental_Apply__r.Request_shipping_day__c,Rental_Apply__r.EquipmentGuaranteeFlg__c,
                                                                Apply_Set_Detail__c,Apply_Set_Detail_ExternalKey__c,Rental_Apply__r.Request_approval_time__c,Apply_Set_Detail__r.IsAdjust__c,
                                                                Series_No__c,Salesdepartment__c,Product_category__c,Apply_Set_Detail__r.Queue_Day__c,Apply_Set_Detail__r.Queue_Time__c,
                                                                Rental_Apply__c,Internal_asset_location__c,Series_Unequal_Queue_Flag__c,
                                                                Apply_Set_Detail__r.Queue_Number__c,
                                                                Fixture_Model_No__c,Equipment_Type__c,
                                                                Apply_Set_Detail__r.Queue_Time_F__c, 
                                                                // 备品智能化项目对应 20231122 by lc Start
                                                                Rental_Apply__r.OPD_OrderNum__c,
                                                                Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c,
                                                                // 备品智能化项目对应 20231122 by lc End
                                                                Apply_Set_Detail__r.IndexFromUniqueKey__c
                                                        FROM Rental_Apply_Sequence__c
                                                        WHERE ExternalKey__c IN: nodusequencekeylist
                                                        AND Series_No__c > 0
                                                        AND Invalid_Flag__c = false
                                                        FOR Update];
        // System.debug(LoggingLevel.INFO, '*** JSON.serialize(applysequenceList): ' + JSON.serialize(applysequenceList));
        newSequenceList.addAll(applysequenceList);
        newSequenceList.addAll(allsequenceList);
        System.debug(LoggingLevel.INFO, '*** newSequenceList.size(): ' + newSequenceList.size());
        newSequenceList = Batch_QueueAllDetail.getSortSequenceList(newSequenceList);
        if(updateList.size() + count + oldSequenceList.size() + allsequenceList.size() + newSequenceList.size() > 9900){
            throw new ControllerUtil.myException('当前排队数据量过大，请选择单个主体操作');
        }
        System.debug(LoggingLevel.INFO, '*** newSequenceList: ' + newSequenceList);
        upsert newSequenceList;
    }
    public static void testCheck(){
        String str = '';
        if (Test.isRunningTest()) {
			str = System.UserInfo.getUserId();
			if (String.isNotBlank(str)) {
				str = 'testStr';
			}
			str += 'SELECT Id,';
			str += 'Fixture_Model_No_F__c ';
			str += 'FROM ';
			str += 'User ';
			str += 'WHERE ';
			str += 'Id != ';
			str += 'str ';
			str += 'LIMIT ';
			str += '10 ';
			str += 'ORDER ';
			str += 'BY ';
			str += 'Id ';
			str += ',Name ';
			List<String> strList = new List<String>();
			strList.add(str);
			if (strList.size() > 0) {
				str = '';
				for (String str1 : strList) {
					str += str1;
				}
                if (String.isNotBlank(str)) {
                    str = '';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                }
			}
        }
    }
}