/*
 * 借出备品配套明细选择画面
 * 只显示Fixture_Set_Detail__c有值的明细
 */
public with sharing class RentalFixtureSetDetilSelectController extends CreateRelationListPagingCtrlBase {
    private List<LineExtraInfo> extraInfoList;  // viewList と同じ順番、同じ件数
    public static Integer FIELDMAX = 200;//20200908 ljh add
    public override Integer getSearchNumMax() {
        //各ページに制御あれば、最大件数を指定する
        searchNumMax = Integer.valueOf(Label.Product_Select_Limit);
        //TODO change
        searchNumMax = 100;
        return searchNumMax;
    }

    public override Boolean getIsNeedRunSearch() {
        return true;
        //isNeedRunSearch = true;
        //return isNeedRunSearch;
    }
    /* 選択されたデータ取得用Soql　Fromから*/
    public override String getSelectedDataSql() {
        // オブジェクトAPI名
        selectedDataSql = ' From Rental_Apply_Equipment_Set_Detail__c';
        selectedDataSql += ' where Rental_Apply_Equipment_Set__r.UniqueKey__c = \'' + String.escapeSingleQuotes(parentId) + '\'';
        //Fixture_Set_Detail__c没有值不能检索出数据
        selectedDataSql += '   and Fixture_Set_Detail__c != null';
        // OLY_OCM-286 まず全部selectして group by Fixture_Set_Detail__c のlogicにてcountしたいですが
        // Fixture_Set_Detail__c を検索時、全部キャンセルした明細の行が表示しなくなるため、
        // and Cancel_Select__c = False を必ず有効にしてください。
        selectedDataSql += '   and Cancel_Select__c = False';
        selectedDataSql += ' order by Fixture_Set_Detail__r.SortInt__c, UniqueKey__c';
        if(parentObj.Rental_Apply__r.demo_purpose2__c != '试用（有询价）' && parentObj.Rental_Apply__r.demo_purpose2__c != '试用（无询价）') {
            String label = Rental_Apply_Equipment_Set_Detail__c.Product_Status_Flag_F__c.getDescribe().getLabel();
            Integer i = myComponentController.titleRight.indexOf(label);
            if(i > -1) {
                myComponentController.titleRight.remove(i);
                myComponentController.columnRightCss.remove(i);
                myComponentController.columnsRightApi.remove(i);
                myComponentController.columnRightRW.remove('Product_Status_Flag_F__c');
            }
        }
        return selectedDataSql;
    }

    // 検索元対象オブジェクトAPI名
    public override String getOriginObjName() {
        // オブジェクトAPI名
        originObjName = 'Fixture_Set_Detail__c';
        return originObjName;
    }
    public override String getOriginObjColumns() {
        // 項目セット
        originObjColumns =  'Id, Quantity__c, Is_Body__c';
        return originObjColumns;
    }

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

    public override List<String> getColumnFieldList() {
        // strColumus 里加 field
        return new List<String>{'Id', 'UniqueKey__c', 'Rental_Apply_Equipment_Set__c', 'Rental_Num__c', 'Cancel_Select__c', 'IndexFromUniqueKey__c', 'Draft_Appended__c', 'Is_Body__c','Loaner_categoryII_F__c',
                 'Fixture_Set_Detail__r.SortInt__c', 'Rental_Apply__r.Status__c', 'Rental_Apply__r.Add_Approval_Status__c', 'Fixture_Set_Detail__r.Is_Optional__c', 'FSD_Is_Optional__c'
                 ,'Fixture_Set_Detail__r.Product_Status_Flag__c','Rental_Apply__r.demo_purpose2__c','Product_Status_Flag_F__c','Rental_Apply_Equipment_Set__r.Substitute_flag__c'};
    }

    // 画面里直接可以输入的項目 List
    public override List<String> getWritableColumnFieldList() {
        return new List<String>{'Rental_Num__c'};
    }
    // getObjName 连 getOriginObjName 的 FK
    public override String getFKColumnField() {
        return 'Fixture_Set_Detail__c';
    }

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

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

        sqlWhereStr = this.makeSoql();

        return sqlWhereStr;
    }
    public override String getOrderbyStr() {
        return 'order by SortInt__c';
    }

    /*****************ソート時再検索条件（画面からの入力条件を無視するため）******************/
    private List<String> sidList;
    public String saveType { get; set; }
    public Rental_Apply_Equipment_Set__c parentObj { get; set; }
    public List<Rental_Apply_Equipment_Set_Detail__c> selectedGroupData { get; set; }
    private String deleteAdd_ApprovalErrorMessage = '第{0}行 付属品{1}件（草案中的追加付属品 {2}件） 更新失败 减少的数量大于草案中的追加付属品的数量';
    private String deleteAdd_ApprovalMessage = '第{0}行 付属品{1}件（草案中的追加付属品 {2}件） 成功更新成 付属品{3}件（草案中的追加付属品 {4}件）';
    public Boolean isNeedReason { get; set; } // 备品智能化项目对应
    public String interventionReason { get; set; } // 备品智能化项目对应

    public RentalFixtureSetDetilSelectController() {

        isNeedRunSearch = true;
        isNeedReason = false;
        String sids = ApexPages.currentPage().getParameters().get('sids');

        sidList = sids.split(',');
        if(sidList.size()>0) {
            // 借出备品配套
            //02517%3Aa2P0k000000PEkjEAG%3A1
            parentId = sidList.get(0);
            //备品配套下的所有明细
            if (!String.isBlank(this.parentId)) {
                //画面上ヘタ表示の項目はここで追加
                List<Rental_Apply_Equipment_Set__c> parentObjs =
                    [select Id, Name,
                            Substitute_Select_Again__c,
                            Fixture_Set_Idx__c,
                            Rental_Apply__r.RequestNoJoinStr2__c,
                            Rental_Apply__r.Request_shipping_day__c,
                            Rental_Apply__r.Request_return_day__c,
                            Rental_Num__c,
                            Same_Accessory_flag__c,
                            Loaner_name__c,
                            Loaner_name_F__c,
                            Loaner_code__c,
                            Fixture_Set__c,
                            Loaner_code_F__c,
                            Rental_Apply__r.Add_Approval_Status__c,
                            Rental_Apply__r.Status__c,
                            Fixture_Set__r.Name,
                            Rental_Apply__c,UniqueKey__c,
                            Substitute_flag__c,
                            Yi_Assigned_Cnt__c,
                            Rental_Apply__r.demo_purpose2__c,
                            // 备品智能化项目对应 20231122 by lc Start
                            Rental_Apply__r.demo_purpose1__c,
                            Rental_Apply__r.Cross_Region_Assign__c,
                            Rental_Apply__r.OPDPlan__c,
                            Rental_Apply__r.Manually_Flag__c,
                            Canceled__c,
                            IsCancelMainAssign__c
                            // 备品智能化项目对应 20231122 by lc End
                    from Rental_Apply_Equipment_Set__c
                    where UniqueKey__c = :parentId
                      AND Cancel_Select__c = false
                      AND Fixture_Set__c != null];

                if (parentObjs.size() > 0) {
                    parentObj = parentObjs.get(0);
                    if (String.isBlank( parentObj.Fixture_Set__c )) {
                        throw new ControllerUtil.myException('借出备品配套一览,没有指定备品配套,不能进行操作!');
                    }

                    // 备品智能化项目对应 20231122 by lc Start
                    // 如果是分配替代品，并且原配套的主体已经分配过，且非跨区分分配申请单 和未提前处理过
                    if (String.isNotBlank(parentObj.Canceled__c) 
                        && parentObj.IsCancelMainAssign__c 
                        && String.isBlank(parentObj.Rental_Apply__r.Cross_Region_Assign__c) 
                        && !parentObj.Rental_Apply__r.Manually_Flag__c) {
                        // 其他目的以外，实时单和7天内的非实时单
                        if (parentObj.Rental_Apply__r.demo_purpose1__c != '其他' 
                            && (String.isEmpty(parentObj.Rental_Apply__r.OPDPlan__c) 
                                || (String.isNotEmpty(parentObj.Rental_Apply__r.OPDPlan__c) 
                                    && parentObj.Rental_Apply__r.Request_shipping_day__c <= Date.today().addDays(7))
                                )
                        ) {
                            isNeedReason = true;
                        }
                    }
                    // 备品智能化项目对应 20231122 by lc End
                } else {
                    throw new ControllerUtil.myException('没有找到借出备品一览,请进行正确的操作!');
                }
                if ([SELECT Id
                       FROM Rental_Apply_Equipment_Set__c
                      WHERE Rental_Apply__c = :parentObj.Rental_Apply__c
                        AND Fixture_Set__c = :parentObj.Fixture_Set__c
                        AND Same_Accessory_flag__c = true
                        AND Cancel_Select__c = false
                        AND Id IN (
                                SELECT Rental_Apply_Equipment_Set__c
                                  FROM Rental_Apply_Equipment_Set_Detail__c
                                 WHERE Rental_Apply_Equipment_Set__r.Rental_Apply__c = :parentObj.Rental_Apply__c
                                   AND Rental_Apply_Equipment_Set__r.Fixture_Set__c = :parentObj.Fixture_Set__c
                                   AND Rental_Apply_Equipment_Set__r.Same_Accessory_flag__c = true
                                   AND Rental_Apply_Equipment_Set__r.Cancel_Select__c = false
                                   AND Is_Body__c = false
                                   AND Cancel_Select__c = true
                                   AND Cancel_Reason__c != '重新分配' // OLY_OCM-163#comment-20120592 通过取消理由判断
                            )
                        ].size() > 0) {

                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,
                            System.Label.SameAccessory_CannotSync));
                }
            }
        }
    }

    public void init() {
        isNeedSearchFirst = true;
        viewList = new List<WrapperInfo>();
        extraInfoList = new List<LineExtraInfo>();  // viewList と同じ順番、同じ件数
        getSqlWhereStr();
    }

    public PageReference searchOpp() {

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

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

    public PageReference save() {

        //20170906 upsert by UniqueKey__c
        List<Rental_Apply_Equipment_Set_Detail__c> mfUpsert = new List<Rental_Apply_Equipment_Set_Detail__c>();
        Savepoint sp = Database.setSavepoint();
        Set<String> clearUniqueKeySet = new Set<String>();
        // 有删除未审批的追加附属品
        Boolean haveAdd_ApprovalDelete = false;

        //20231129 备品智能化 - OPD生成的备品借出配套明细在备品不允许删除 sx start
        List<String> fixtureModels = new List<String>();
        List<Fixture_Set__c> fixSets = new List<Fixture_Set__c>();
        List<Id> fixIds = new List<Id>();
        List<Fixture_Set_Detail__c> fixSetDetails = new List<Fixture_Set_Detail__c>();
        Map<String, Fixture_Set_Detail__c> fixSetDetailMap = new Map<String, Fixture_Set_Detail__c>();
        //20231129 备品智能化 - OPD生成的备品借出配套明细在备品不允许删除 sx end

        try {
            // 同一附属品 一括設定する
            if (parentObj.Same_Accessory_flag__c) {
                if ([SELECT Id
                       FROM Rental_Apply_Equipment_Set__c
                      WHERE Rental_Apply__c = :parentObj.Rental_Apply__c
                        AND Fixture_Set__c = :parentObj.Fixture_Set__c
                        AND Same_Accessory_flag__c = true
                        AND Cancel_Select__c = false
                        AND Id IN (
                                SELECT Rental_Apply_Equipment_Set__c
                                  FROM Rental_Apply_Equipment_Set_Detail__c
                                 WHERE Rental_Apply_Equipment_Set__r.Rental_Apply__c = :parentObj.Rental_Apply__c
                                   AND Rental_Apply_Equipment_Set__r.Fixture_Set__c = :parentObj.Fixture_Set__c
                                   AND Rental_Apply_Equipment_Set__r.Same_Accessory_flag__c = true
                                   AND Rental_Apply_Equipment_Set__r.Cancel_Select__c = false
                                   AND Is_Body__c = false
                                   AND Cancel_Select__c = true
                                   AND Cancel_Reason__c != '重新分配' // OLY_OCM-163#comment-20120592 通过取消理由判断
                            )
                        ].size() > 0) {

                    // 申請から進んだ明細がある場合
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,
                            System.Label.SameAccessory_CannotSync));
                    return null;
                }
            }

            // 画面中チェックされた対象、確定ボタンを押下すると、一つずつ順番に明細を選択のため。
            List<Rental_Apply_Equipment_Set__c> sameRAES_objs = null;

            // 申請書ロック(Add_Approval_Status__c 更新のため)
            //PlanProdDetail__c  20240229 sx 修改为从OPD.计划借出备品取
            List<Rental_Apply__c> raObjs = [
                SELECT Id, Name,
                       Status__c,
                       Add_Approval_Status__c,
                       RequestNoJoinStr2__c,
                       Demo_purpose2__c,
                       OPDplan__r.PlanProdDetail__c			//20240229 sx 修改为从OPD.计划借出备品取
                  FROM Rental_Apply__c
                 WHERE Id = :parentObj.Rental_Apply__c
                   FOR UPDATE];
            if (raObjs.size() == 0) {
                throw new ControllerUtil.myException('没有检索出正确的借出备品申请,不能进行操作');
            }
            Rental_Apply__c raObj = raObjs[0];
            if(raObj.Add_Approval_Status__c == '申请中') {
                throw new ControllerUtil.myException('申请中不可以更新明细');
            }
            //20231129 备品智能化 - OPD生成的备品借出配套明细在备品不允许删除 sx start
            if(raObjs[0].OPDplan__r.PlanProdDetail__c != null){		//由于文本字段超限需要修改字段类型  20240229 sx 修改为从OPD.计划借出备品取
                List<String> fixSetStrings = raObjs[0].OPDplan__r.PlanProdDetail__c.split(';');		//由于文本字段超限需要修改字段类型  20240229 sx 修改为从OPD.计划借出备品取
                if(fixSetStrings.size() > 0){
                    for(String fixSet : fixSetStrings){
                        String tempString = fixSet.trim();
                        if(tempString.indexOf('*')!= -1){
                            fixtureModels.add(tempString.substring(0, tempString.indexOf('*')));
                        }
                    }
                }
            }
            if(fixtureModels.size() > 0){
                fixSets = [SELECT Id, Fixture_Set_Body_Model_No__c FROM Fixture_Set__c WHERE Fixture_Set_Body_Model_No__c IN :fixtureModels];
                for(Fixture_Set__c fix :fixSets){
                    fixIds.add(fix.Id);
                }
                fixSetDetails = [SELECT Id, SortInt__c, Fixture_Set__c, Fixture_Model_No_F__c FROM Fixture_Set_Detail__c WHERE Is_Body__c = true AND Fixture_Set__c IN :fixSets];
                if(fixSetDetails.size()>0){
                    for(Fixture_Set_Detail__c fixDetail : fixSetDetails){
                        if(!fixSetDetailMap.containsKey(fixDetail.Fixture_Set__c)){
                            fixSetDetailMap.put(fixDetail.Fixture_Model_No_F__c, fixDetail);
                        }
                    }
                }
            }
            System.debug('fixSetDetailMap===='+fixSetDetailMap);
            //20231129 备品智能化 - OPD生成的备品借出配套明细在备品不允许删除 sx end
            // parentObj のみ ロック
            sameRAES_objs = [
                SELECT Id, Name,
                       Fixture_Set_Idx__c,
                       Rental_Apply__r.RequestNoJoinStr2__c,
                       Rental_Num__c, Same_Accessory_flag__c,
                       Loaner_name__c,
                       Loaner_name_F__c,
                       Loaner_code__c,
                       Fixture_Set__c,
                       Rental_Apply__c,
                       First_RAESD__c,
                       Loaner_code_F__c,
                       Rental_Apply__r.Strategic_dept__c,//20200825 ljh SWAG-BRY6PF  add
                       IsOPD_Account__c,//20201010 ljh SFDC-BU947L add
                       Canceled__r.First_RAESD__r.Queue_Day_Text__c, //20210903 you SFDC-C6E3WQ
                       Canceled__r.First_RAESD__r.Queue_Time_Text__c, //20210903 you SFDC-C6E3WQ
                       UniqueKey__c
                  FROM Rental_Apply_Equipment_Set__c
                 WHERE Id = :parentObj.Id
                   FOR UPDATE];
            if (sameRAES_objs.size() == 0) {
                throw new ControllerUtil.myException('没有检索出正确的借出备品配套一览,不能进行操作!');
            }
            if (sameRAES_objs[0].Rental_Num__c > 1 && sameRAES_objs[0].Same_Accessory_flag__c) {
                // 同一付属品の一覧もロック
                sameRAES_objs = [
                    SELECT Id, Name,
                           Fixture_Set_Idx__c,
                           Rental_Apply__r.RequestNoJoinStr2__c,
                           Rental_Num__c,Same_Accessory_flag__c,
                           Loaner_name__c,
                           Loaner_name_F__c,
                           Loaner_code__c,
                           Fixture_Set__c,
                           Rental_Apply__c,
                           First_RAESD__c,
                           Loaner_code_F__c,
                           Rental_Apply__r.Strategic_dept__c,//20200825 ljh SWAG-BRY6PF  add
                           IsOPD_Account__c,//20201010 ljh SFDC-BU947L add
                           Canceled__r.First_RAESD__r.Queue_Day_Text__c, //20210903 you SFDC-C6E3WQ
                           Canceled__r.First_RAESD__r.Queue_Time_Text__c, //20210903 you SFDC-C6E3WQ
                           UniqueKey__c
                      FROM Rental_Apply_Equipment_Set__c
                     WHERE Rental_Apply__c = :parentObj.Rental_Apply__c
                       AND Fixture_Set__c = :parentObj.Fixture_Set__c
                       AND Same_Accessory_flag__c = true
                       AND Cancel_Select__c = false
                       FOR UPDATE];
            }


            // SUM出没有还没有批准的追加附属品和已经批准或者不是追加附属品的数量
            // 因为 #getSelectedDataSql() 用 Fixture_Set_Detail__c
            // 所以这里也用 AND Fixture_Set_Detail__c != null
            List<AggregateResult> appendedGroupBy = [
                    SELECT Fixture_Set_Detail__c, Count(Id) cnt, SUM(Draft_Appended__c) Draft_Appended__c, SUM(Not_Draft_Appended__c) Not_Draft_Appended__c
                      FROM Rental_Apply_Equipment_Set_Detail__c
                     WHERE Rental_Apply_Equipment_Set__c = :parentObj.Id
                       AND Cancel_Select__c = false
                       AND Fixture_Set_Detail__c != null
                     GROUP BY Fixture_Set_Detail__c];
            /* Key Fixture_Set_Detail__c value↓
             *                           Draft_Appended -> 未批准的追加附属品数量
             *                           Not_Draft_Appended -> 不是未批准的追加附属品数量
             *                           Accsessarys -> 所有的附属品数量
             */
            Map<String, Map<String, Integer>> add_ApprovalMaps = new Map<String, Map<String, Integer>>();
            for (AggregateResult a : appendedGroupBy) {
                Integer Draft_Appended = a.get('Draft_Appended__c') == null ? 0 : Integer.valueOf(a.get('Draft_Appended__c'));
                Integer Not_Draft_Appended = a.get('Not_Draft_Appended__c') == null ? 0 : Integer.valueOf(a.get('Not_Draft_Appended__c'));
                add_ApprovalMaps.put(String.valueOf(a.get('Fixture_Set_Detail__c')),
                    new Map<String, Integer>{
                        'Draft_Appended' => Draft_Appended,
                        'Not_Draft_Appended' => Not_Draft_Appended,
                        'Accsessarys' => a.get('cnt') == null ? 0 : Integer.valueOf(a.get('cnt'))
                    });
            }
            List<WrapperInfo> targetViewList = new List<WrapperInfo>();
            // 删除未审批追加附属品ERROR信息
            String deleteAdd_ApprovalErrorMessages = '';
            // 删除未审批追加附属品信息
            // 因为有Error的时候不现实成功信息所以需要分开保存最后判断显示什么信息
            String deleteAdd_ApprovalMessages = '';
            Boolean haveError = false;
            for (WrapperInfo wprInfo : viewList) {
                Rental_Apply_Equipment_Set_Detail__c robj = (Rental_Apply_Equipment_Set_Detail__c) wprInfo.sobj;
                //20231129 备品智能化 - OPD生成的备品借出配套明细在备品不允许删除 sx start
                if(robj.Is_Body__c == true && fixIds.contains(parentObj.Fixture_Set__c) && robj.Rental_Num__c == 0){
                    robj.Rental_Num__c.addError('OPD计划的配套主体不能为0');
                    return null;
                }
                //20231129 备品智能化 - OPD生成的备品借出配套明细在备品不允许删除 sx end
                if ((robj.FSD_Is_Optional__c == false || robj.Fixture_Set_Detail__r.Is_Optional__c == false)
                        && robj.Rental_Num__c < 1) {
// From 王硕 20180104 没有强制要求必须申请标配的备品。 非选配的也可以不申请。
//                    robj.Rental_Num__c.addError('非选配明细数量不能为0');
//                    return null;
                }
                // 当数量大于0或者数量为0但是是草案中的追加附属品的话可以修改数量
                if (robj.Rental_Num__c > 0 || robj.Draft_Appended__c == 1) {
                    if (add_ApprovalMaps.containsKey(robj.Fixture_Set_Detail__c)) {
                        Map<String, Integer> add_ApprovalMap = add_ApprovalMaps.get(robj.Fixture_Set_Detail__c);
                        //有删除操作。并且未审批追加附属品大于0
                        if (robj.Rental_Num__c < add_ApprovalMap.get('Accsessarys') && add_ApprovalMap.get('Draft_Appended') > 0) {
                            haveAdd_ApprovalDelete = true;
                            // 明细数量小于已批准的追加附属品加上非追加附属品
                            if (robj.Rental_Num__c < add_ApprovalMap.get('Not_Draft_Appended')
                                    && raObj.Status__c != FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Cao_An_Zhong.ordinal())
                                    && raObj.Add_Approval_Status__c == FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Cao_An_Zhong.ordinal())) {
                                deleteAdd_ApprovalErrorMessages += String.format(deleteAdd_ApprovalErrorMessage,
                                                                new String[]{String.valueOf(wprInfo.lineNo + 1),String.valueOf(add_ApprovalMap.get('Accsessarys')),String.valueOf(add_ApprovalMap.get('Draft_Appended'))});
                                deleteAdd_ApprovalErrorMessages += '\n';
                                haveError = true;
                            }
                            // 有删除操作并且明细数量大于等于已批准的追加附属品加上非追加附属品
                            else if (robj.Rental_Num__c >= add_ApprovalMap.get('Not_Draft_Appended')
                                    && raObj.Status__c != FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Cao_An_Zhong.ordinal())
                                    && raObj.Add_Approval_Status__c == FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Cao_An_Zhong.ordinal())) {
                                deleteAdd_ApprovalMessages += String.format(deleteAdd_ApprovalMessage,
                                                                new String[]{String.valueOf(wprInfo.lineNo + 1),String.valueOf(add_ApprovalMap.get('Accsessarys')),String.valueOf(add_ApprovalMap.get('Draft_Appended')),String.valueOf(robj.Rental_Num__c),String.valueOf(add_ApprovalMap.get('Draft_Appended') - (add_ApprovalMap.get('Accsessarys') - robj.Rental_Num__c))});
                                deleteAdd_ApprovalMessages += '\n';
                            }
                        }
                    }
                    targetViewList.add(wprInfo);
                } else if (String.isNotBlank(robj.Id)) {
                    if (raObj.Status__c != FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Cao_An_Zhong.ordinal())) {
                        if (!parentObj.Substitute_flag__c) {
                            robj.Rental_Num__c.addError('只有在草案中的状态下可以减少数量');
                            return null;
                        } else if (parentObj.Yi_Assigned_Cnt__c > 0) {
                            // 分配代替品后，选择配套明细--'已分配件数 Yi_Assigned_Cnt__c'>0且状态为'草案中'时减少数量，报error
                            robj.Rental_Num__c.addError('有明细已分配，不能减少数量');
                            return null;
                        }
                    }
                }
            }

            if (haveError) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, deleteAdd_ApprovalErrorMessages));
                return null;
            }

            //OLY_OCM-171 与可以选择存放地的简档一致
            Boolean is2B = System.Label.ProfileId_EquCenAdmin.contains(Userinfo.getProfileId())
                                   || Userinfo.getProfileId() == System.Label.ProfileId_SystemAdmin;
                                // || System.Label.ProfileId_EquCenCheckAndDepot.contains(Userinfo.getProfileId())
                                // || Userinfo.getProfileId() == System.Label.ProfileId_EquipmentCenter;

            Map<Id, Rental_Apply_Equipment_Set_Detail__c> setIdFirstDetailMap = new Map<Id, Rental_Apply_Equipment_Set_Detail__c>();
            for (WrapperInfo wprInfo : targetViewList) {
                Rental_Apply_Equipment_Set_Detail__c robj = (Rental_Apply_Equipment_Set_Detail__c) wprInfo.sobj;
                LineExtraInfo extraInfo = extraInfoList.get(wprInfo.lineNo);
                Integer maxIndexInLoop = null;
                for (Integer i = 0; i < robj.Rental_Num__c; i++) {
                    // sameRAES_objs には自分の明細か、申請 直後の明細しかないか の条件があります。
                    // なので、直接cloneしてOKです。
                    for (Rental_Apply_Equipment_Set__c sameRAES_obj : sameRAES_objs) {
                        Rental_Apply_Equipment_Set_Detail__c rupsobj = robj.clone(false);
                        // 借出申请RequestNoJoinStr2__c：借出申请配套一览Id：配套明细Id
                        String uniqueKeyStr = raObj.RequestNoJoinStr2__c + ':' + sameRAES_obj.Id
                                + ':'+ robj.Fixture_Set_Detail__c + ':';
                        // default値は最初に設定した
                        rupsobj.IndexFromUniqueKey__c = i+1;
                        if (i < extraInfo.indexFromUniqueKeyList.size()) {
                            rupsobj.IndexFromUniqueKey__c = extraInfo.indexFromUniqueKeyList[i];
                            uniqueKeyStr += rupsobj.IndexFromUniqueKey__c;
                        } else if (extraInfo.maxIndexFromUniqueKey != null) {
                            if (maxIndexInLoop == null) { maxIndexInLoop = extraInfo.maxIndexFromUniqueKey; }
                            maxIndexInLoop++;
                            uniqueKeyStr = raObj.RequestNoJoinStr2__c + ':' + sameRAES_obj.Id
                                    + ':'+ robj.Fixture_Set_Detail__c + ':'+ maxIndexInLoop;
                            rupsobj.IndexFromUniqueKey__c = maxIndexInLoop;
                        } else {
                            // uniqueKeyStr に default の IndexFromUniqueKey__c を使う
                            uniqueKeyStr += rupsobj.IndexFromUniqueKey__c;
                        }

                        System.debug(rupsobj.IndexFromUniqueKey__c + '测试uniqueKeyStr:' + uniqueKeyStr);
                        rupsobj.UniqueKey__c          = uniqueKeyStr;
                        // 配套（or 申请）·から
                        rupsobj.Rental_Apply_Equipment_Set__c = sameRAES_obj.Id;
                        rupsobj.Rental_Apply__c               = sameRAES_obj.Rental_Apply__c;

                        // 备品智能化项目对应 20231122 by lc Start
                        if (isNeedReason) {
                            // 主体已分配，需要记录填写的人工干预理由
                            rupsobj.Intervention_Reason__c = interventionReason;
                        } else {
                            // 其他目的以外，实时单和7天内的非实时单，人工干预理由系统设置
                            if (String.isBlank(parentObj.Rental_Apply__r.Cross_Region_Assign__c)
                                && !parentObj.Rental_Apply__r.Manually_Flag__c
                                && parentObj.Rental_Apply__r.demo_purpose1__c != '其他' 
                                && String.isNotBlank(parentObj.Canceled__c) 
                                && (String.isEmpty(parentObj.Rental_Apply__r.OPDPlan__c) 
                                    || (String.isNotEmpty(parentObj.Rental_Apply__r.OPDPlan__c) 
                                        && parentObj.Rental_Apply__r.Request_shipping_day__c <= Date.today().addDays(7))
                                    )
                            ){
                                rupsobj.Intervention_Reason__c = '主体无库存';
                            }
                        }
                        // 备品智能化项目对应 20231122 by lc End
                        
                        mfUpsert.add(rupsobj);
                        if (setIdFirstDetailMap.containsKey(sameRAES_obj.Id) == false || rupsobj.Is_Body__c == true) {
                            setIdFirstDetailMap.put(sameRAES_obj.Id, rupsobj);
                        }
                        if (String.isBlank(rupsobj.Id)
                                && !String.isBlank(uniqueKeyStr)) {
                            // IdあるのレコードをIdクリアSetに追加
                            clearUniqueKeySet.add(uniqueKeyStr);
                        }
                    }
                }
            }
            if (mfUpsert.isEmpty()) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,
                        '请输入明细的数量。'));
                return null;
            }
            else {
                //upsert mfUpsert UniqueKey__c;
                // Upsert
                FixtureUtil.withoutUpsertRaesd(mfUpsert);
                // 削除
                FixtureUtil.delRAESD_excludedUpserted(sameRAES_objs, mfUpsert);
                System.debug('备品配套借出一览明细保存成功');
                List<String> StrategicDeptId = new List<String>();//备品借出申请的战略科室
                List<String> FixtureSetId = new List<String>();//备品配套
                List<String> RAESId = new List<String>();//借出备品配套一览
                Map<String, String> RAES_SMap = new Map<String, String>();//借出备品配套一览+备品借出申请的战略科室
                Map<String, String> RAES_FMap = new Map<String, String>();//借出备品配套一览+备品配套
                Map<String, List<String>> sdept_targetMap = new Map<String, List<String>>();//备品借出申请的战略科室+目标
                Map<String, List<String>> RAES_targetMap = new Map<String, List<String>>();//借出备品配套一览+目标
                List<Rental_Apply_Equipment_Set_Detail__c> rupsobjList =new List<Rental_Apply_Equipment_Set_Detail__c>();//20210903 you SFDC-C6E3WQ
                for (Rental_Apply_Equipment_Set__c sameRAES_obj: sameRAES_objs) {
                    Rental_Apply_Equipment_Set_Detail__c rupsobj = setIdFirstDetailMap.get(sameRAES_obj.Id);
                    sameRAES_obj.First_RAESD__c = rupsobj.Id;  //第一条一览明细
                    system.debug(rupsobj.Id+'==Is_Body__c==='+rupsobj.Is_Body__c+'==='+rupsobj);
                    if(rupsobj.Is_Body__c==true){//必须得是主体才会去更新
                        rupsobj.Queue_Time_Text__c = sameRAES_obj.Canceled__r.First_RAESD__r.Queue_Time_Text__c;//20210903 you SFDC-C6E3WQ
                        rupsobj.Queue_Day_Text__c = sameRAES_obj.Canceled__r.First_RAESD__r.Queue_Day_Text__c;//20210903 you SFDC-C6E3WQ
                        rupsobjList.add(rupsobj);//20210903 you SFDC-C6E3WQ 
                    }
                    //20200825 ljh SWAG-BRY6PF  add start
                    if(sameRAES_obj.Rental_Apply__r.Strategic_dept__c !=null){
                        RAESId.add(sameRAES_obj.Id);
                        StrategicDeptId.add(sameRAES_obj.Rental_Apply__r.Strategic_dept__c);
                        FixtureSetId.add(sameRAES_obj.Fixture_Set__c);
                        RAES_SMap.put(sameRAES_obj.Id,sameRAES_obj.Rental_Apply__r.Strategic_dept__c);
                        RAES_FMap.put(sameRAES_obj.Id,sameRAES_obj.Fixture_Set__c);
                    }
                    //20200825 ljh SWAG-BRY6PF  add end
                }
                //20200825 ljh SWAG-BRY6PF  add start
                if(StrategicDeptId != null&&StrategicDeptId.size()>0){
                    //客户这条线
                    // 目标客户重点产品和目标客户产品借出次数
                    List<String> column = new List<String>();
                    List<String> columnNum = new List<String>();
                    SS_Batch_Column_Mapping__c mpdMapping = SS_Batch_Column_Mapping__c.getValues('targetKeyProduct');
                    Map<String,List<String>> tempImportantProduct = new Map<String,List<String>>();
                    Map<String,String> tempImportantProductNum = new Map<String,String>();
                    for (Integer i = 1; i <= FIELDMAX; i++) {
                        String lpadI = ('00' + i).right(3);
                        String fromColumn = 'From_Column_' + lpadI + '__c';
                        String apiStr = String.valueOf(mpdMapping.get(fromColumn));
                        if (String.isBlank(apiStr) == false) {
                            String ssColumn = 'SS_Column_' + lpadI + '__c';
                            String ssApiStr = String.valueOf(mpdMapping.get(ssColumn));
                            if(i<101){
                                column.add(apiStr);
                                List<String> ssApiStrList = new List<String>(ssApiStr.Split(','));
                                tempImportantProduct.put(apiStr,ssApiStrList);
                            }//else{ 20201026 you SWAG-BSC5WP  在101以后添加新的字段 所以限制一下
                                // 20230328 ljh  DB202302341475 start
                                // if(i>=101 && i<116){
                                if(i>=101 && i<118){
                                // 20230328 ljh  DB202302341475 end
                                columnNum.add(apiStr);
                                tempImportantProductNum.put(apiStr,ssApiStr);
                            }
                        }
                    }
                    //所在期数
                    Date dateNow = Date.today();
                    Integer year = dateNow.year();
                    Integer month = dateNow.month();
                    if (month < 4) {
                        year -= 1;
                    }
                    String currentPeriod = String.valueOf(year - 1867 + 'P');
                    //战略科室
                    String StrategicDeptId_s = '(\'';
                    for(Integer i = 0 ; i< StrategicDeptId.size();i++){
                        if(i<StrategicDeptId.size()-1){
                            StrategicDeptId_s += StrategicDeptId[i]+'\',\'';
                        }else{
                            StrategicDeptId_s += StrategicDeptId[i]+'\')';
                        }
                }
                    String soql = 'select Id ,Name,Account__c ';
                    for (Integer i=0;i<column.size();i++) {
                        soql += ',' + column[i];
                    }
                    for (Integer num=0;num<columnNum.size();num++) {
                        soql += ',' + columnNum[num];
                    }
                    soql += '  FROM Account_Number_of_target__c  WHERE  OCM_Period__c = \''+currentPeriod+'\'  and Account__c in '+StrategicDeptId_s;
                    List<Account_Number_of_target__c>  antargetList = Database.query(soql);
                    Map<String,Account_Number_of_target__c> sdept_LendNumMap = new Map<String,Account_Number_of_target__c>();
                    Map<String,Account_Number_of_target__c> RAES_LendNumMap = new Map<String,Account_Number_of_target__c>();
                    for(Account_Number_of_target__c ant:antargetList){
                        List<String> titleAccout = new List<String>();
                        for(Integer i=0;i<column.size();i++){
                            if(1==ant.get(column[i])){
                                titleAccout.addAll(tempImportantProduct.get(column[i]));
                            }
                        }
                        sdept_targetMap.put(ant.Account__c,titleAccout);
                        sdept_LendNumMap.put(ant.Account__c,ant);
                    }
                    //两个Map合并 借出备品配套一览+备品借出申请的战略科室 与 备品借出申请的战略科室+目标=借出备品配套一览+目标
                    Set<String> keySet0 = RAES_SMap.keySet();
                    for(String ks0:keySet0){
                        RAES_targetMap.put(ks0,sdept_targetMap.get(RAES_SMap.get(ks0)));
                        RAES_LendNumMap.put(ks0,sdept_LendNumMap.get(RAES_SMap.get(ks0)));
                    }
                    //备品主体产品这条线
                    List<Fixture_Set_Detail__c> fsDetail = [select  Id,Fixture_Set__c, Product2__c from Fixture_Set_Detail__c where Is_Body__c=true and Fixture_Set__c in:FixtureSetId];
                    List<String> Product2Id = new List<String>();
                    Map<String, String> map1 = new Map<String, String>();
                    Map<String, String> map2 = new Map<String, String>();
                    Map<String, String> map1_2 = new Map<String, String>();
                    Map<String, String> RAES_ImpMap = new Map<String, String>();
                    //RAES_FMap<借出备品配套一览,备品配套> map1<备品配套,重点产品ID>
                    for(Fixture_Set_Detail__c fs1:fsDetail){
                        map1.put(fs1.Fixture_Set__c,fs1.Product2__c);
                        Product2Id.add(fs1.Product2__c);
                    }
                    //map2<重点产品ID,重点产品>
                    List<Product2> product2 = [select id,Key_product_147P__c from Product2 where Id in:Product2Id];
                    for(Product2 p:product2){
                        map2.put(p.Id,p.Key_product_147P__c);
                    }
                    //两个Map1与Map2合并 在与RAES_FMap合并得到 Map<借出备品配套一览,重点产品>
                    Set<String> keySet = map1.keySet();
                    for(String ks:keySet){
                        map1_2.put(ks,Map2.get(map1.get(ks)));
                    }
                    Set<String> keySet1 = RAES_FMap.keySet();
                    for(String ks1:keySet1){
                        RAES_ImpMap.put(ks1,map1_2.get(RAES_FMap.get(ks1)));
                    }
                    //对比是否是重点考察产品
                    Map<String, Integer> mapIdIs = new Map<String, Integer>();
                    Map<String, Integer> LendNumMap = new Map<String, Integer>();
                    Set<String> keySet2 = RAES_ImpMap.keySet();
                    for(String ks2:keySet2){
                        Integer tempIs = 0;
                        Integer LendNum = null;
                        if(RAES_targetMap.get(ks2) != null &&RAES_targetMap.get(ks2).size()>0){
                            if(String.isNotBlank(RAES_ImpMap.get(ks2))&&RAES_targetMap.get(ks2).contains(RAES_ImpMap.get(ks2).substring(3))){
                                tempIs = 1;
                            }
                        }
                        //主体产品借出的次数
                        if(String.isNotBlank(RAES_ImpMap.get(ks2))){
                            //主体产品借出的次数
                            String temp = null ;
                            Set<String> keySet4 = tempImportantProductNum.keySet();
                            for (String ks4:keySet4) {
                                if(tempImportantProductNum.get(ks4).equals(RAES_ImpMap.get(ks2).substring(3))){
                                    temp = ks4;
                                    break;
                                }
                            }
                            if(temp !=null){
                              Account_Number_of_target__c tempANOT= RAES_LendNumMap.get(ks2);
                              if(tempANOT!=null &&tempANOT.get(temp) !=null){
                                LendNum = Integer.valueOf(tempANOT.get(temp));
                              }
                            }
                        }
                        mapIdIs.put(ks2,tempIs);
                        LendNumMap.put(ks2,LendNum);
                    }
                    Set<String> keySet3 = mapIdIs.keySet();
                    for (Rental_Apply_Equipment_Set__c rAES_obj1: sameRAES_objs) {
                        if(keySet3.contains(rAES_obj1.Id)){
                            rAES_obj1.IsOPD_Account__c = mapIdIs.get(rAES_obj1.Id);
                            rAES_obj1.Product2__c = RAES_ImpMap.get(rAES_obj1.Id);
                            rAES_obj1.LendNum__c = LendNumMap.get(rAES_obj1.Id);
                        }
                    }
                }
                //20200825 ljh SWAG-BRY6PF  add end
                //update sameRAES_objs;
                FixtureUtil.withoutUpdate(sameRAES_objs); 
                // Upsert
                FixtureUtil.withoutUpsertRaesd(rupsobjList);//20210903 you SFDC-C6E3WQ
            }

            //申请书的追加附属品状态需
            //因为是申请的状态所以需要要看是不是申请书下所有的追加附属品(不只是这一个一览下的)
            List<AggregateResult> add_Approvals = [Select Count(Id) cnt, SUM(Draft_Appended__c) Draft_Appended__c
                    From Rental_Apply_Equipment_Set_Detail__c
                   Where Rental_Apply__c = :parentObj.Rental_Apply__c
                     AND Cancel_Select__c = false
                     AND Fixture_Set_Detail__c != null
                     AND ApplyPersonAppended_F__c = true
                   Group by Rental_Apply__c];
            Integer Draft_Appended = 0;
            Integer add_ApprovalCount = 0;
            if (!add_Approvals.isEmpty()) {
                Draft_Appended = add_Approvals[0].get('Draft_Appended__c') == null ? 0 : Integer.valueOf(add_Approvals[0].get('Draft_Appended__c'));
                add_ApprovalCount = add_Approvals[0].get('cnt') == null ? 0 : Integer.valueOf(add_Approvals[0].get('cnt'));
            }

            List<Rental_Apply__c> raList = new List<Rental_Apply__c>();
            // 有草案中的追加附属品并且申请书的状态不是草案中，&& 不是分配代替品 的需要改变状态为草案中
            if (Draft_Appended > 0
                    && raObj.Add_Approval_Status__c != FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Cao_An_Zhong.ordinal())
                    && (raObj.Status__c == FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Yi_Pi_Zhun.ordinal())
                        || raObj.Status__c == FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Yi_Chu_Ku_Zhi_Shi.ordinal()))
                    && parentObj.Substitute_Select_Again__c == false) {
                raObj.Add_Approval_Status__c = FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Cao_An_Zhong.ordinal());
                raList.add(raObj);
            }
            // 申请书单位已经没有草案中的附属品
            else if (Draft_Appended == 0) {
                //没有追加附属品状态为空
                if (add_ApprovalCount == 0 && String.isNotBlank(raObj.Add_Approval_Status__c)) {
                    raObj.Add_Approval_Status__c = '';
                }
                // 有追加附属品状态为草案中
                else if (add_ApprovalCount > 0  && raObj.Add_Approval_Status__c != FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Yi_Pi_Zhun.ordinal())) {
                    raObj.Add_Approval_Status__c = FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Yi_Pi_Zhun.ordinal());
                }
                raList.add(raObj);
            }
            if (!raList.isEmpty()) {
                //20201010 ljh SFDC-BU947L add start
                Boolean IsOPDAccountFlag = false;
                //system.debug('112233:'+sameRAES_objs);
                List<Rental_Apply_Equipment_Set__c>  sameRAES_objsIs = [SELECT Id, Name,
                           Fixture_Set_Idx__c,
                           Rental_Apply__r.RequestNoJoinStr2__c,
                           Rental_Num__c,Same_Accessory_flag__c,
                           Loaner_name__c,
                           Loaner_name_F__c,
                           Loaner_code__c,
                           Fixture_Set__c,
                           Rental_Apply__c,
                           First_RAESD__c,
                           Loaner_code_F__c,
                           Rental_Apply__r.Strategic_dept__c,//20200825 ljh SWAG-BRY6PF  add
                           IsOPD_Account__c,//20201010 ljh SFDC-BU947L add
                           UniqueKey__c
                      FROM Rental_Apply_Equipment_Set__c
                     WHERE Rental_Apply__c = :sameRAES_objs[0].Rental_Apply__c
                       AND Cancel_Select__c = false
                       FOR UPDATE ];
                for (Rental_Apply_Equipment_Set__c sameRAES_obj : sameRAES_objsIs) {
                    if(sameRAES_obj.IsOPD_Account__c !=null && sameRAES_obj.IsOPD_Account__c.intValue()==1){
                        IsOPDAccountFlag = true;break;
                    }
                }
                if(IsOPDAccountFlag){
                    raList[0].IsOPD_Account__c = 1;
                }else{
                    raList[0].IsOPD_Account__c = 0;
                }
                //20201010 ljh SFDC-BU947L  add end
                FixtureUtil.withoutUpdate(raList);
            }
            // 更新成功才添加成功信息
            if (haveAdd_ApprovalDelete == true) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.WARNING, deleteAdd_ApprovalMessages));

            }

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

        // 因为不能更新sidList所以需要在更新sidList前return
        if (haveAdd_ApprovalDelete == true) {
            return null;
        }

        if (saveType == '1') {
            searchOpp();
            saveType = '';
            return null;
        } else if (saveType == '2') {
        // ソート時の変更ある
            myComponentController.getSelectedDataInfo();
            getSqlWhereStr();
            myComponentController.sortTable();
            saveType = '';
            return null;
        } else {
            //借出备品配套明细选择画面
            List<String> uniqStrs = parentId.split(':');
            //画面参数为多个配套明细的UniqueKey__c，同一附属品情况下，一括设定该备品配套（group）下的所有借出备品配套明细
            //非同一附属品情况下，依次设定该备品配套所存在的借出备品配套明细的设定
            //判断是否同一附属品
            if(parentObj.Same_Accessory_flag__c){
                sidList.remove(0);
            }else{
                system.debug('●●●●● uniqStrs  ' + uniqStrs );

                String tempSize = uniqStrs.get(uniqStrs.size()-1);
                // 分配代替品画面
                if (parentObj.Substitute_Select_Again__c) {
                    tempSize = tempSize.substring(0, 1);
                }

                if(Integer.valueOf(tempSize) < parentObj.Rental_Num__c){
                    List<String> uniqStrsTemp = new List<String> ();
                    uniqStrsTemp.addall(uniqStrs);
                    uniqStrsTemp.remove(uniqStrsTemp.size()-1);
                    Integer currObjBan = Integer.valueOf(tempSize);
                    uniqStrsTemp.add( (currObjBan + 1) + '');
                    String uniqStrsNew = String.join(uniqStrsTemp, ':');
                    sidList.set(0, uniqStrsNew);
                }else{
                    sidList.remove(0);
                }

            }

            if (sidList.size() > 0) {
                String chkIdsStr = String.join(sidList, ',');
                PageReference pg = new PageReference('/apex/RentalFixtureSetDetilSelect');
                pg.getParameters().put('sids',chkIdsStr);
                pg.setRedirect(true);
                return pg;
            } else {
                // 借出申请页面
                PageReference pg = new PageReference('/'+ parentObj.Rental_Apply__c);
                pg.setRedirect(true);
                return pg;
            }
        }



    }


    public PageReference cancel() {
        PageReference ret = null;
        if (!String.isBlank(parentObj.Rental_Apply__c)) {
            ret = new PageReference('/' + parentObj.Rental_Apply__c);
        }
        return ret;
    }

    public PageReference goBack() {
        PageReference ret = null;
        if (!String.isBlank(parentObj.Rental_Apply__c)) {
            ret = new PageReference('/apex/RentalFixtureSetSelect?pt_recid=' + parentObj.Rental_Apply__c);
        }
        return ret;
    }

    private String makeSoql() {

        String soql ='';
        soql += 'where Id != null';

        //备品配套下的所有明细
        if (!String.isBlank(this.parentId)) {
system.debug('●●●●● parentObj ' + parentObj );
            soql += ' and Fixture_Set__c = \'' + parentObj.Fixture_Set__c + '\'';
        }
        // soql += ' order by SortInt__c';
        system.debug(soql);
        return soql;
    }

    public override void setViewList(List<sObject> queryList) {
        viewList = new List<WrapperInfo>();                             // selectedGroupData と同じ順番、同じ件数
        extraInfoList = new List<LineExtraInfo>();  // viewList と同じ順番、同じ件数
        Set<Id> selectedFSDSet = new Set<Id>();
        // 選択済みの明细
        if (selectedData.size() > 0) {
            selectedGroupData = new List<Rental_Apply_Equipment_Set_Detail__c>();
            Map<Integer, Rental_Apply_Equipment_Set_Detail__c> sltFixtureMap = new Map<Integer, Rental_Apply_Equipment_Set_Detail__c>();
            Map<Integer, Integer> sltFixtureCnt = new Map<Integer, Integer>();
            Map<Integer, LineExtraInfo> sltExtraInfoMap = new Map<Integer, LineExtraInfo>();
            // グループリスト取得
            // group by Fixture_Set_Detail__c
            // order by Fixture_Set_Detail__r.SortInt__c
            for (SObject sobj : selectedData) {
                Rental_Apply_Equipment_Set_Detail__c raesdobj = (Rental_Apply_Equipment_Set_Detail__c) sobj;
                if (!sltFixtureMap.containsKey(raesdobj.Fixture_Set_Detail__r.SortInt__c.intValue())) {
                    if (!raesdobj.Cancel_Select__c) {
                        sltFixtureMap.put(raesdobj.Fixture_Set_Detail__r.SortInt__c.intValue(), raesdobj);
                        selectedGroupData.add(raesdobj);
                        sltFixtureCnt.put(raesdobj.Fixture_Set_Detail__r.SortInt__c.intValue(), 0);
                        LineExtraInfo extraInfo = new LineExtraInfo(raesdobj);
                        extraInfoList.add(extraInfo);
                        sltExtraInfoMap.put(raesdobj.Fixture_Set_Detail__r.SortInt__c.intValue(), extraInfo);
                    }
                } else {
                    LineExtraInfo extraInfo = sltExtraInfoMap.get(raesdobj.Fixture_Set_Detail__r.SortInt__c.intValue());
                    extraInfo.updateExtraInfo(raesdobj);
                }
                if (raesdobj.Cancel_Select__c) {
                    // 念のため追加した
                    continue;
                }

                Rental_Apply_Equipment_Set_Detail__c nobj = sltFixtureMap.get(raesdobj.Fixture_Set_Detail__r.SortInt__c.intValue());
                Integer nCnt = sltFixtureCnt.get(raesdobj.Fixture_Set_Detail__r.SortInt__c.intValue());
                nCnt++;
                sltFixtureCnt.put(raesdobj.Fixture_Set_Detail__r.SortInt__c.intValue(), nCnt);
                nobj.Rental_Num__c = nCnt;
                nobj.VF_Rental_Num__c = nCnt;
                selectedFSDSet.add(raesdobj.Fixture_Set_Detail__c);
            }
            for (Integer i = 0; i < selectedGroupData.size(); i++) {
                // 501を超えた場合前500のみを出す
                if (i >= getSearchNumMax()) { break; }
                Rental_Apply_Equipment_Set_Detail__c raesdobj = selectedGroupData[i];
                viewList.add(new WrapperInfo(raesdobj, myComponentController));

                // 20231026  sx 备品智能化 start
                viewList[viewList.size() - 1].lineNo = viewList.size() - 1;
                if((raesdobj.Rental_Apply__r.demo_purpose2__c == '试用（有询价）' || raesdobj.Rental_Apply__r.demo_purpose2__c == '试用（无询价）')
                  && !raesdobj.Rental_Apply_Equipment_Set__r.Substitute_flag__c){
                    String notLLimit = System.Label.Loaner_categoryII_NOT_LIMIT;
                    List<String> limits = notLLimit.split(';');
                    if(!limits.contains(raesdobj.Loaner_categoryII_F__c)){
                        System.debug('Loaner_categoryII_F__c===' + raesdobj.Loaner_categoryII_F__c);
                        viewList[viewList.size() - 1].canEdit = raesdobj.Fixture_Set_Detail__r.Product_Status_Flag__c;
                    }
                }
                raesdobj.IndexFromUniqueKey_Text__c = viewList.size().format().leftpad(2, '0');
                // 20231026  sx 备品智能化 end
            }
        }
        if (queryList.size() == 0) {
            return;
        }

        Savepoint sp = Database.setSavepoint();

        // 数式項目値を取れるのために、一回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; }
            Rental_Apply_Equipment_Set_Detail__c mf = new Rental_Apply_Equipment_Set_Detail__c();
            mf.Rental_Apply_Equipment_Set__c        = parentObj.Id;
            mf.Rental_Apply__c                      = parentObj.Rental_Apply__c;
            mf.Fixture_Set_Detail__c                = queryList[i].Id;
            Fixture_Set_Detail__c fsdobj            = (Fixture_Set_Detail__c) queryList[i];
            mf.Is_Body__c                           = fsdobj.Is_Body__c;
            if (selectedData.size() > 0) {
                fsdobj.Quantity__c = 0;
            } else {
                fsdobj.Quantity__c = fsdobj.Quantity__c == null ? 0 : fsdobj.Quantity__c;
            }
            mf.Rental_Num__c                        = fsdobj.Quantity__c;
            mf.VF_Rental_Num__c                     = fsdobj.Quantity__c;
            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 = Database.query(soql);
        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;
                }
            }
        }
        // 強制ロールバック
        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;
            robj.FSD_Product_Status_Flag__c = true;
            fsDMap.put(fsd.Fixture_Set_Detail__c, robj);
        }

        Integer addedNum = 0;
        Map<Integer, Rental_Apply_Equipment_Set_Detail__c> sltFixtureMap = new Map<Integer, Rental_Apply_Equipment_Set_Detail__c>();
        for (Integer i = 0; i < queryList.size(); i++) {

            addedNum ++;
            // 501を超えた場合前500のみを出す
            if (addedNum == getSearchNumMax()) { break; }

            if (selectedFSDSet.contains(queryList[i].Id)) {
                continue;
            }

            SObject mf = fsDMap.get(queryList[i].Id);
            Rental_Apply_Equipment_Set_Detail__c raesdobj = (Rental_Apply_Equipment_Set_Detail__c) mf;
            if (!sltFixtureMap.containsKey(raesdobj.Fixture_Set_Detail__r.SortInt__c.intValue())) {
                sltFixtureMap.put(raesdobj.Fixture_Set_Detail__r.SortInt__c.intValue(), raesdobj);
                // 2回目以降、設定してない行は0にする
                // if (!selectedData.isEmpty()) {
                // OLY_OCM-404: 选择配套明细里，无论主体还是附属品，都设置默认数量为0。
                raesdobj.Rental_Num__c    = 0;
                raesdobj.VF_Rental_Num__c = 0;
                // }
                viewList.add(new WrapperInfo(raesdobj, myComponentController));
                // 20231026  sx 备品start
                // WrapperInfo info =  new WrapperInfo(raesdobj, myComponentController);
                // if(raesdobj.Loaner_categoryII_F__c != null){
                //     info.additionalInfoMap.put('Loaner_categoryII_F__c', raesdobj.Loaner_categoryII_F__c); // 20231026 sx add
                // }else{
                //     info.additionalInfoMap.put('Loaner_categoryII_F__c', ''); // 20231026 sx add
                // }
                // viewList.add(info);
                // 20231026 end
                extraInfoList.add(new LineExtraInfo(null));
                viewList[viewList.size() - 1].lineNo = viewList.size() - 1;
                if((raesdobj.Rental_Apply__r.demo_purpose2__c == '试用（有询价）' || raesdobj.Rental_Apply__r.demo_purpose2__c == '试用（无询价）')
                  && !raesdobj.Rental_Apply_Equipment_Set__r.Substitute_flag__c){
                    //20231101 sx 备品智能化  台车和监视器 可编辑放开权限 start
                    // System.debug('raesdobj.Loaner_categoryII_F__c===' + raesdobj.Loaner_categoryII_F__c);
                    String notLLimit = System.Label.Loaner_categoryII_NOT_LIMIT;
                    List<String> limits = notLLimit.split(';');
                    //raesdobj.Loaner_categoryII_F__c != '台车' && raesdobj.Loaner_categoryII_F__c != '监视器' && raesdobj.Loaner_categoryII_F__c != '录像设备'
                    if(!limits.contains(raesdobj.Loaner_categoryII_F__c)){
                        System.debug('Loaner_categoryII_F__c===' + raesdobj.Loaner_categoryII_F__c);
                        viewList[viewList.size() - 1].canEdit = raesdobj.Fixture_Set_Detail__r.Product_Status_Flag__c;
                    }
                    //20231101 sx 备品智能化  台车和监视器 可编辑放开权限 end
                }
                raesdobj.IndexFromUniqueKey_Text__c = viewList.size().format().leftpad(2, '0');
            }
        }

system.debug('●●●●● setViewList END ' );
    }


    public class LineExtraInfo {
        public Integer maxIndexFromUniqueKey;           // { get; set; }
        public List<Decimal> indexFromUniqueKeyList;    // { get; set; }
        public Set<String> raesdUniqueKeySet;           // { get; set; }

        // Cancel_Select 処理しない
        public LineExtraInfo(Rental_Apply_Equipment_Set_Detail__c raesdobj) {
            // maxIndexFromUniqueKey を null にする
            raesdUniqueKeySet = new Set<String>();
            indexFromUniqueKeyList = new List<Decimal>();
            if (raesdobj == null || String.isBlank(raesdobj.Id)) {
                // 新規行、空のインスタンスを返す
                return;
            }
            if (raesdobj.Cancel_Select__c) {
                throw new ControllerUtil.myException('raesdobj is Canceled.');
            }
            raesdUniqueKeySet.add(raesdobj.UniqueKey__c);
            indexFromUniqueKeyList.add(raesdobj.IndexFromUniqueKey__c);
            maxIndexFromUniqueKey = raesdobj.IndexFromUniqueKey__c.intValue();
        }

        // Cancel_Select も処理対象 (maxIndexFromUniqueKeyを更新するために)
        public void updateExtraInfo(Rental_Apply_Equipment_Set_Detail__c raesdobj) {
            if (raesdobj == null || String.isBlank(raesdobj.Id)
                    || maxIndexFromUniqueKey == null) {
                // 新規行、なにも更新しない
                return;
            }
            if (raesdUniqueKeySet.contains(raesdobj.UniqueKey__c)) {
                return;
            }
            if (!raesdobj.Cancel_Select__c) {
                raesdUniqueKeySet.add(raesdobj.UniqueKey__c);
                indexFromUniqueKeyList.add(raesdobj.IndexFromUniqueKey__c);
            }
            Integer indexFromUniqueKey = raesdobj.IndexFromUniqueKey__c.intValue();
            if (indexFromUniqueKey > maxIndexFromUniqueKey) {
                maxIndexFromUniqueKey = raesdobj.IndexFromUniqueKey__c.intValue();
            }
        }
    }

   
}