/**
 * 附属品选择の設定
 * AccessorySelectControllerTest
 * RentalFixtureManage1Test
 * RentalFixtureManage2Test
 */
public with sharing class AccessorySelectController extends CreateRelationListPagingCtrlBase {
        public override Integer getSearchNumMax() {
        //各ページに制御あれば、最大件数を指定する
        searchNumMax = Integer.valueOf(Label.Product_Select_Limit);
        searchNumMax = 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 = false';
        selectedDataSql += '   and Cancel_Select__c = False';
        selectedDataSql += '   and (ApplyPersonAppended_F__c = false OR (' ;
        selectedDataSql += '  ApplyPersonAppended_F__c = true AND (Add_Request_approval_time__c != null OR Select_Time__c != null)))';
        selectedDataSql += ' order by Name ASC nulls last';   // order by Fixture_Set_Detail__r.SortInt__c
        return selectedDataSql;
    }

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

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

    public override List<String> getColumnFieldList() {
        // strColumus 里加 field
        // FixtureUtil#raesdGroupBy()の項目も必要
        return new List<String>{'Id', 'Rental_Apply_Equipment_Set__c', 'FSD_Id__c', 'Select_Time__c', 'Fixture_Model_No_F__c',
                'IndexFromUniqueKey__c', 'FSD_Fixture_Model_No__c', 'Is_Body_F__c', 'SalesProvince__c', 'OneToOne_Flag__c',
                'Rental_Apply__c', 'Rental_Apply__r.Salesdepartment__c', 'DeliverySlip__c', 'Is_Body__c', 
                'Rental_Apply__r.Equipment_Type_F__c', 'Rental_Apply__r.Internal_asset_location_F__c',
                'Rental_Apply__r.Salesdept__c', 'Rental_Apply__r.Product_category__c',
                'Rental_Apply__r.demo_purpose2__c','Rental_Apply__r.Follow_UP_Opp__r.Shipping_Finished_Day_Func__c',
                'Rental_Apply__r.next_action__c','Rental_Apply__r.QIS_number__r.ReplaceDeliveryDate__c'};
    }
    // 备品智能化项目对应 20231122 by lc Start
    public override List<String> getHiddenFieldList() {
        return new List<String>{'Intervention_Reason__c'};
    }
    // 备品智能化项目对应 20231122 by lc End
    // 画面里直接可以输入的項目 List
    public override List<String> getWritableColumnFieldList() {
        return new List<String>{'Cancel_Reason__c','Loaner_cancel_reason__c','Loaner_cancel_Remarks__c'};
        // 20210818 ljh  SFDC-C448KZ add
    }
    // getObjName 连 getOriginObjName 的 FK
    public override String getFKColumnField() {
        return 'Asset__c';
    }

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

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

    }

    public override Boolean getIsNeedRunSearch() {
        return false;
    }

    // ClickEvent用URL
    public String goAccessoryAdd { get; set; }

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


    /*****************ソート時再検索条件（画面からの入力条件を無視するため）******************/

    public String saveType { get; set; }

    public Rental_Apply_Equipment_Set__c parentObj { get; set; }
    public Rental_Apply_Equipment_Set_Detail__c sonObj { get; set; } // 20210817 ljh   SFDC-C448KZ add

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

    List<Boolean> showButtonList = new List<Boolean>();

    public String bieCunFangDi { get; set; }     //别存放地, 肯定有值 不为null
    // #OLY_OCM-654 因为MA本部和产品培训本部还是需要检索条件,所以需要别本部的检索条件 Start
    public String bieBenBu { get; set; }         //别本部
    public Set<String> benbuSet;
    // #OLY_OCM-654 因为MA本部和产品培训本部还是需要检索条件,所以需要别本部的检索条件 End

    // 备品智能化项目对应 20231122 by lc Start
    public String interventionReason { get; set; }
    public String interventionType { get; set; }
    public Boolean isMainAssign { get; set; }
    // 备品智能化项目对应 20231122 by lc End
    public Boolean hgerqi { set; get; } // WYL 贸易合规2期
    public String rentalApplyStatus { set;get; }    //2024-1-11 sx add 申请单合规状态
    public String rentalApplyId { set;get; }        //20240204 sx add 合规发邮件
    // #OLY_OCM-654 Start
    // public String bieChanPinFenLei { get; set; } //产品分类
    // public String bieBiePinFenLei { get; set; }  //别备品分类
    // #OLY_OCM-654 End
    public Rental_Apply_Equipment_Set_Detail__c pageRaesd {get; set;}


    public AccessorySelectController() {
        Integer i = 0;
       
        parentId = ApexPages.currentPage().getParameters().get('pt_recid');
        pageRaesd = new Rental_Apply_Equipment_Set_Detail__c();
        this.bieField = true;
        benbuSet = new Set<String>();
        isMainAssign = false;  // 备品智能化项目对应
        hgerqi = false;			//贸易合规二期add  sx
        //借出备品一览の情報を取得
        if (!String.isBlank(this.parentId)) {
            List<Rental_Apply_Equipment_Set__c> parentObjs = [
                    SELECT Id, Rental_Apply__r.Name,
                           Rental_Apply__r.Owner.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,
                           Fixture_Set__r.Product_Category_GI_SP__c,
                           Rental_Apply__r.Product_category__c,
                           Fixture_Set__r.Equipment_Type__c,
                           Rental_Apply__r.Equipment_Type_F__c,
                           Rental_Apply__r.Internal_asset_location_F__c,
                           Rental_Apply__r.Request_return_day__c,
                           Fixture_Set__r.Fixture_Set_Body_Model_No__c,
                           Rental_Apply__r.Salesdepartment__c,
                           Rental_Apply__r.Cross_Region_Assign__c,
                           Rental_Apply__r.Manually_Flag__c,
                           SerialNumber_F__c,
                           Rental_Start_Date__c,
                           Rental_End_Date__c,
                           Irreplaceable_flag__c,
                           RequestNoJoinStr2__c,
                           First_RAESD__c, First_RAESD__r.Is_Body__c,
                           Rental_Apply__r.AccDealerBlacklist__c,	//贸易合规二期add  sx
                           Rental_Apply__c                          //贸易合规二期add  sx 邮件发送
                    FROM Rental_Apply_Equipment_Set__c
                    where Id = :parentId];
            if(parentObjs.size()>0){
                parentObj = parentObjs.get(0);
                rentalApplyStatus = parentObj.Rental_Apply__r.AccDealerBlacklist__c;	//贸易合规二期add  sx
                rentalApplyId = parentObj.Rental_Apply__c;                              //贸易合规二期add  sx 邮件发送
                String rsdid=System.label.Rental_Apply_id;
                List<Rental_Apply_Equipment_Set_Detail__c> raesdObjs = [
                    SELECT Id, Rental_Apply_Equipment_Set__c, 
                           Cancel_Reason__c, // 20210817 ljh  SFDC-C448KZ add
                           Loaner_cancel_reason__c,// 20210817 ljh  SFDC-C448KZ add
                           Loaner_cancel_Remarks__c// 20210817 ljh  SFDC-C448KZ add 
                     FROM Rental_Apply_Equipment_Set_Detail__c
                    WHERE Rental_Apply__c =:rsdid limit 1];

                if (!raesdObjs.isEmpty()) {
                    sonObj = raesdObjs[0];
                }
                // 主体 or 第一条
                List<Rental_Apply_Equipment_Set_Detail__c> bodyObjs = [
                    SELECT Id, Internal_asset_location_before__c, Salesdepartment_before__c,
                            Product_category_text__c, Equipment_Type_text__c, Select_Time__c,
                            // 备品智能化项目对应 20231122 by lc Start
                            Asset__c, Is_Body__c
                            // 备品智能化项目对应 20231122 by lc End
                     FROM Rental_Apply_Equipment_Set_Detail__c
                    WHERE Rental_Apply_Equipment_Set__c = :parentId
                      and Id =: parentObj.First_RAESD__c
                      and Cancel_Select__c = false];
                if (!bodyObjs.isEmpty()) {
                    if (bodyObjs[0].Select_Time__c != null) {
                        bieCunFangDi = bodyObjs[0].Internal_asset_location_before__c;
                        bieBenBu = bodyObjs[0].Salesdepartment_before__c;   // #OLY_OCM-654 MA和产品检测本部是需要检索的,所以不注释
                        // #OLY_OCM-654 Start
                        // bieChanPinFenLei = bodyObjs[0].Product_category_text__c;
                        // bieBiePinFenLei = bodyObjs[0].Equipment_Type_text__c;
                        // #OLY_OCM-654 End
                    }

                    // 备品智能化项目对应 20231122 by lc Start
                    // 没有主体的配套可以直接操作，有主体并且主体有保有也可以直接操作
                    if ((bodyObjs[0].Is_Body__c && String.isNotBlank(bodyObjs[0].Asset__c)) 
                        || !bodyObjs[0].Is_Body__c) {
                       isMainAssign = true;
                    }
                    // 备品智能化项目对应 20231122 by lc End
                } else {
                    throw new ControllerUtil.myException('不能明确第一条明细, 请确认数据。');
                }
                if (String.isBlank(bieCunFangDi)) {
                    bieCunFangDi = parentObj.Rental_Apply__r.Internal_asset_location_F__c;
                    bieBenBu = parentObj.Rental_Apply__r.Salesdepartment__c;    // #OLY_OCM-654 MA和产品检测本部是需要检索的,所以不注释
                    // #OLY_OCM-654 Start
                    // bieChanPinFenLei = parentObj.Rental_Apply__r.Product_category__c;
                    // bieBiePinFenLei = parentObj.Rental_Apply__r.Equipment_Type_F__c;
                    // #OLY_OCM-654 End
                }
                if (String.isBlank(bieCunFangDi)) {
                    throw new ControllerUtil.myException('不能明确存放地, 请确认数据。');
                }
            }
        
        }
        // 20210817 ljh SFDC-C448KZ update end
    }

    //20240111 sx 贸易合规二期校验 start 
    public PageReference tradeCheckTwo(){
        Set<Id> assetId = new Set<Id>();
        List<String> assList = new List<String>();   //20240204 sx add 贸易合规二期邮件
        for (WrapperInfo wprInfo : viewList) {
            Rental_Apply_Equipment_Set_Detail__c robj = (Rental_Apply_Equipment_Set_Detail__c) wprInfo.sobj;
            // 状态只有是可以分配时才会保存
            if (FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal()) == robj.Fu_Shu_Pin_Fen_Pei_Jia__c) {
                if (!String.isBlank(robj.Asset__c) && wprInfo.check) {
                    assetId.add(robj.Asset__c);
                }
            }
        }
        System.debug('assetId==='+assetId);
        if(assetId.size()>0){
            List<Asset> aSetList =
                    [Select Id, Product2.ProTradeComplianceStatus__c From Asset
                      where Id IN :assetId for Update];
            if(aSetList.size()>0){
                if(System.Label.TradeComplianceStatusFlagBP =='true' && rentalApplyStatus == '2'){
                    for(Asset ass: aSetList){
                        if(ass.Product2.ProTradeComplianceStatus__c == '0'){
                            assList.add(ass.Id);		//20240204 sx add 贸易合规二期邮件
                            this.hgerqi = true;
                        }
                    }
                }
            }
			//20240204 sx add 贸易合规二期邮件 start
            if(assList.size()>0){
                SendEmailUtil.tradeTempleSend(rentalApplyId, '附属品选择', assList , null);
            }
            //20240204 sx add 贸易合规二期邮件  end
        }
        return null;
    }
    //20240111 sx 贸易合规二期校验 end 

    public void init() {
        isNeedCheckEvent = true;

        searchOppSetParam();

        getSqlWhereStr();

        // #OLY_OCM-654 保有设备合并后,取出的第一条一览明细的本部可能为空,所以biebenbu为空时,也要添加检索条件 Start
        List<SelectOption> opList = FixtureUtil.bieBenBuOpsMap.get(bieCunFangDi);
        Set<String> needSalesdepartment = FixtureUtil.needSalesdepartment;
        for (SelectOption op : opList) {
            if (needSalesdepartment.contains(op.getValue())) {
                benbuSet.add(op.getValue()); // Where文用Set,因为OLY_OCM-654数据合并后合并的本部都为空,所以这里也是需要空的
            }
        }
        // 如果本部不在可选本部内的话检索营业本部的保有设备,附属品营业本部因为合并所以本部为空
        if (benbuSet.contains(bieBenBu) == false) {
            bieBenBu = '';
        }
        // #OLY_OCM-654 保有设备合并后,取出的第一条一览明细的本部可能为空,所以biebenbu为空时,也要添加检索条件 End

    }

    //别存放地 SelectOption
    public List<SelectOption> getbieCunFangDiOps() {
        return new List<SelectOption>{
            new SelectOption(bieCunFangDi, bieCunFangDi)
        };
    }

    // #OLY_OCM-654 别本部 页面没有检索所以不改 SelectOption
    public List<SelectOption> getbieBenBuOps() {
        return new List<SelectOption>{
            new SelectOption(bieBenBu, bieBenBu)
        };
        // return FixtureUtil.bieBenBuOpsMap.get('本部');
    }

    private void searchOppSetParam() {

    }

    public PageReference searchOpp() {
        searchOppSetParam();

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

        getSqlWhereStr();

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

    //ToDo返回到哪个界面
    // 如果配套有主体则返回主题分配画面 没有则返回标准画面
    public PageReference turnback() {
        String url;
        PageReference pg;
        if (parentObj.First_RAESD__r.Is_Body__c) {
            pg = new PageReference('/apex/MainFixtureSelect');
            pg.getParameters().put('pt_recid',parentId);
            pg.setRedirect(true);
        } else {
            pg = new PageReference('/' + parentId);
        }
        return pg;
    }



    public PageReference save() {
        List<Id> delIds = new List<String>();

        Savepoint sp = Database.setSavepoint();
        Set<String> clearUniqueKeySet = new Set<String>();

        try {
            List<Id> assetIdList = new List<Id>();

            for (WrapperInfo wprInfo : viewList) {
                Rental_Apply_Equipment_Set_Detail__c robj = (Rental_Apply_Equipment_Set_Detail__c) wprInfo.sobj;

                // 状态只有是可以分配时才会保存
                if (FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal()) == robj.Fu_Shu_Pin_Fen_Pei_Jia__c
                ) {
                    if (!String.isBlank(robj.Asset__c)) {
                        assetIdList.add(robj.Asset__c);
                    }
                }
            }
            System.debug('assetIdList' + assetIdList);
            // lock Asset
            if (assetIdList.size() > 0) {
                //20170906 upsert by UniqueKey__c
                List<Rental_Apply_Equipment_Set_Detail__c> mfUpsert = new List<Rental_Apply_Equipment_Set_Detail__c>();
                Map<Id, Asset> aSetMap = new Map<Id, Asset>([
                        Select Id, Quantity,
                                Out_of_wh__c,
                                Manage_type__c,
                                Ji_Zhong_Guan_Li_Ku_Cun__c, // 20220118 ljh SFDC-C9V84U start
                                Last_Reserve_RAES_Detail__c
                        From Asset
                        where Id = :assetIdList
                        for Update]);
                Map<Id, Asset> assetUpdateMap = new Map<Id, Asset>();

                // 状态只有是可以分配时才会保存
                for (Integer indexNum = 0; indexNum < viewList.size(); indexNum++) {
                    WrapperInfo wprInfo = viewList[indexNum];
                    if (wprInfo.check == false) {
                        continue;
                    }
                    Rental_Apply_Equipment_Set_Detail__c robj = (Rental_Apply_Equipment_Set_Detail__c) wprInfo.sobj;
                    //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
                    // 可以分配の場合 (Asset__c 从 null 到 有值)
                    if (FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal()) == robj.Fu_Shu_Pin_Fen_Pei_Jia__c
                    ) {
                        Asset aSet = aSetMap.get(robj.Asset__c);
                        // 不能lock到数据的时候
                        if (aSet == null) {
                            throw new ControllerUtil.myException('第' + (indexNum + 1) +'行，不是有效的附属品，请刷新画面后重新操作');
                        }
                        // 分配时间 (Asset__c 从 null 到 有值)
                        if (robj.Select_Time__c == null) {
                            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;
                            }
                            // 备品有效库存 = 备品数量(Quantity) - 借出数(Out_of_wh__c)
                            Integer num = Integer.valueof(aSet.Quantity - aSet.Out_of_wh__c);
                            // 备品有效库存没有时,程序返回并提示错误信息
                            if (num < 1) {
                                throw new ControllerUtil.myException('第' + (indexNum + 1) +'行，没有足够有效库存，请刷新画面后重新操作');
                            }
                            // 20220118 ljh SFDC-C9V84U start
                            if(aSet.Ji_Zhong_Guan_Li_Ku_Cun__c <= 0){
                                throw new ControllerUtil.myException('第' + (indexNum + 1) +'行，集中库库存不足，请刷新画面后重新操作');
                            }
                            // 20220118 ljh SFDC-C9V84U end
                            //aSet.Out_of_wh__c = aSet.Out_of_wh__c + 1;

                            //assetUpdateMap.put(aSet.Id, aSet);
                        }

                        String uniqueKeyStr = parentObj.RequestNoJoinStr2__c + ':'+ robj.Rental_Apply_Equipment_Set__c
                                + ':' + robj.FSD_Id__c + ':' + ((Integer) Math.round(robj.IndexFromUniqueKey__c));

                        robj.UniqueKey__c = uniqueKeyStr;

                        // 备品智能化项目对应 20231122 by lc Start
                        // 因为前台的附属品不全值，后台没有拿到，所以此处追加判断
                        if (String.isBlank(robj.Intervention_Reason__c) 
                            && parentObj.Rental_Apply__r.Demo_purpose1__c != '其他' 
                            && String.isBlank(parentObj.Rental_Apply__r.Cross_Region_Assign__c)
                            && !parentObj.Rental_Apply__r.Manually_Flag__c) {
                            if (robj.Fu_Shu_Pin_Fen_Pei_Jia__c != '已分配') {
                                robj.Intervention_Reason__c = '附属品不全';
                            } else if (!String.isBlank(interventionReason)) {
                                robj.Intervention_Reason__c = interventionReason;
                            }
                        }
                        // 备品智能化项目对应 20231122 by lc End

                        // 附属品为个体管理的情况下更新
                        // if (FixtureUtil.managetypeMap.get(FixtureUtil.Managetype.Ge_Ti_Guan_Li) == aSet.Manage_type__c) {
                        //     if (aSet.Last_Reserve_RAES_Detail__c != robj.Id) {
                        //         aSet.Last_Reserve_RAES_Detail__c = robj.Id;
                        //         assetUpdateMap.put(aSet.Id, aSet);
                        //     }
                        // }
                        mfUpsert.add(robj);
                    }
                }

                //update assetUpdateMap.values();
                // Upsert
                FixtureUtil.withoutUpsertRaesd(mfUpsert);
            }
        } catch (Exception ex) {
            ApexPages.addMessages(ex);
            Database.rollback(sp);
            return null;
        }

        if (saveType == '1') {
            searchOpp();
            saveType = '';
            return null;
        } else if (saveType == '2') {
        // ソート時の変更ある
            myComponentController.sortTable();
            saveType = '';
            return null;
        } else {
            PageReference ret = null;
            if (!String.isBlank(this.parentId)) {
                ret = new PageReference('/' + this.parentId);
            }
            return ret;
            // return cancel();
        }
    }
    /**
    *#OLY_OCM-668 取消附属品分配
    *@return PageReference 刷新附属品选择页面
    */
    public PageReference unassign(){

        Savepoint sp = Database.setSavepoint();

        try {
            List<Id> assetIdList = new List<Id>();
            List<Id> raesdIdList = new List<Id>();

            // 筛出可以取消分配的附属品
            for (WrapperInfo wprInfo : viewList) {
                Rental_Apply_Equipment_Set_Detail__c robj = (Rental_Apply_Equipment_Set_Detail__c) wprInfo.sobj;
                if (!String.isBlank(robj.Asset__c)) {
                        assetIdList.add(robj.Asset__c);
                        raesdIdList.add(robj.Id);
                }
            }

            // 加lock
            Map<Id,Rental_Apply_Equipment_Set_Detail__c> raesdMap = new Map<Id,Rental_Apply_Equipment_Set_Detail__c>([
                    SELECT Id
                         , Asset__c
                         , Select_Time__c
                         , StockDown_time__c
                         , Cancel_Date__c
                         , Fixture_OneToOne_Link_Id__c
                      FROM Rental_Apply_Equipment_Set_Detail__c
                     WHERE Id in :raesdIdList
                       FOR UPDATE]);

            if (raesdMap.size() > 0) {
                Map<String, Rental_Apply_Equipment_Set_Detail__c> mfUpsert = new Map<String, Rental_Apply_Equipment_Set_Detail__c>();
                // 读取已分配的所有附属品
                Map<Id, Asset> aSetMap = new Map<Id, Asset>([
                        Select Id, Quantity,
                                Out_of_wh__c,
                                Manage_type__c,
                                Last_Reserve_RAES_Detail__c
                        From Asset
                        where Id = :assetIdList
                        for Update]);
                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;
                    Rental_Apply_Equipment_Set_Detail__c robjOnline = raesdMap.get(robj.Id);
                    if (!wprInfo.check) {
                        continue;
                    }
                    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.Select_Time__c == null){
                        throw new ControllerUtil.myException('第' + (indexNum + 1) +'行，还没有被分配，不可以取消分配');
                    }
                    // OLY_OCM-668 一对一附属品不能取消分配：系统逻辑保持不变
                    if (String.isNotBlank(robjOnline.Fixture_OneToOne_Link_Id__c)) {
                        throw new ControllerUtil.myException('第' + (indexNum + 1) +'行，一对一分配的附属品，不能取消分配');
                    }

                    Asset aSet = aSetMap.get(robj.Asset__c);
                    // 不能lock到数据的时候
                    if (aSet == null) {
                        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;

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

                    String uniqueKeyStr = parentObj.RequestNoJoinStr2__c + ':'+ robj.Rental_Apply_Equipment_Set__c
                            + ':' + robj.FSD_Id__c + ':' + ((Integer) Math.round(robj.IndexFromUniqueKey__c));
                    robj.UniqueKey__c = uniqueKeyStr;

                    mfUpsert.put(robj.UniqueKey__c, robj);
                }

                if (!mfUpsert.isEmpty()) {
                    FixtureUtil.withoutUpsertRaesd(mfUpsert.values());
                }

            }
            else{
                throw new ControllerUtil.myException('没有下架前已分配的附属品');
            }
        }
        catch (Exception ex) {
            ApexPages.addMessages(ex);
            Database.rollback(sp);
            return null;
        }

        // 刷新画面
        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
    // 一对一的附属品 不能 单独 取消
    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 (robj.OneToOne_Flag__c) {
                        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '一对一分配的附属品不能单独取消'));
                        return null;
                    } else if (robj.DeliverySlip__c != null) {
                        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 = MainFixtureSelectController.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.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/AccessorySelect');
                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 override void setViewList(List<sObject> queryList) {
        viewList = new List<WrapperInfo>();

        if (selectedData.size() == 0) {
            throw new ControllerUtil.myException('配套没有对应的附属品数据。');
        }

        String bieWhere = ' and Internal_asset_location__c = \'' + String.escapeSingleQuotes(bieCunFangDi) + '\'';
        // #OLY_OCM-654 保有设备合并后,取出的第一条一览明细的本部可能为空,本部为空的时候作为营业本部检索本部为空的保有设备。所以不需要isNotBlank的Check了 Start
        if (FixtureUtil.needSalesdepartment.contains(bieBenBu)) {
            bieWhere += ' and Salesdepartment__c = \'' + String.escapeSingleQuotes(bieBenBu) + '\'';
        } else {
            bieWhere += ' and Salesdepartment__c IN ' + FixtureUtil.otherBenbus;
        }
        // #OLY_OCM-654 保有设备合并后,取出的第一条一览明细的本部可能为空,本部为空的时候作为营业本部检索本部为空的保有设备。所以不需要isNotBlank的Check了  End

        // //产品分类
        // if (String.isNotBlank(bieChanPinFenLei)) {
        //     bieWhere += 'and Product_category__c = \'' + String.escapeSingleQuotes(bieChanPinFenLei) + '\'';
        // }
        // //别备品分类
        // if (String.isNotBlank(bieBiePinFenLei)) {
        //     bieWhere += 'and Equipment_Type__c = \'' + String.escapeSingleQuotes(bieBiePinFenLei) + '\'';
        // }
        if (String.isBlank(pageRaesd.Id)) {
            pageRaesd.Id = selectedData[0].Id;
        }
        // 保证分配顺序
        Map<String, List<Asset>> autoSelectMap = new Map<String, List<Asset>>();
        // 自动分配对象
        Map<String, List<Rental_Apply_Equipment_Set_Detail__c>> autoRsdMap = new Map<String, List<Rental_Apply_Equipment_Set_Detail__c>>();
        Map<Rental_Apply_Equipment_Set_Detail__c, Map<String, FixtureUtil.groupBean>> rsdMap = FixtureUtil.raesdGroupBy(selectedData, myComponentController.columus, bieWhere);
        // 選択済みの明细
        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];
                Map<String, FixtureUtil.groupBean> rsdGroupInfo = rsdMap.get(rsdObj);

                for (String apikey : rsdGroupInfo.keySet()) {
                    // これを動態にする必要がある
                    // 附属品分配
                    if (apikey.indexOf('_Jia__c') >= 0) {
                        if (apikey == 'Fu_Shu_Pin_Fen_Pei_Jia__c') {
                            Integer index = rsdGroupInfo.get(apikey).gnum;

                            if (!String.isBlank(rsdObj.Asset__c) && rsdObj.Select_Time__c != null) {
                                rsdObj.put(apikey, FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.assetFixtureStatus.Yi_Fen_Pei.ordinal()));
                            }
                            else {
                                rsdObj.put(apikey, FixtureUtil.assetFixtureStatusMap.get(index));
                            }
                        }
                        // liucheng 20171112
                        else  {
                            rsdObj.put(apikey, rsdGroupInfo.get(apikey).gnum);
                        }
                    }

                    //if (apikey.indexOf('_Jia__c') >= 0 && apikey != 'Fu_Shu_Pin_Fen_Pei_Jia__c') {
                    //    rsdObj.put(apikey, rsdGroupInfo.get(apikey).gnum);
                    //}

                    //// 有效库存
                    //if (apikey.indexOf('_Jia__c') >= 0 && apikey == 'You_Xiao_Kun_Cun_Jia__c') {
                    //    rsdObj.put(apikey, rsdGroupInfo.get(apikey).gnum);
                    //}

                    //// 已借出
                    //if (apikey.indexOf('_Jia__c') >= 0 && apikey == 'Yi_Jie_Chu_Jia__c') {
                    //    rsdObj.put(apikey, rsdGroupInfo.get(apikey).gnum);
                    //}

                    //// 待修理
                    //if (apikey.indexOf('_Jia__c') >= 0 && apikey == 'Dai_Xiu_Li_Jia__c') {
                    //    rsdObj.put(apikey, rsdGroupInfo.get(apikey).gnum);
                    //}

                    //// 别存放地库存
                    //if (apikey.indexOf('_Jia__c') >= 0 && apikey == 'Bie_Cun_Fang_Di_Ku_Cun_Jia__c') {
                    //    rsdObj.put(apikey, rsdGroupInfo.get(apikey).gnum);
                    //}

                    //// 别本部库存
                    //if (apikey.indexOf('_Jia__c') >= 0 && apikey == 'Bie_Ben_Bu_Ku_Cun_Jia__c') {
                    //    rsdObj.put(apikey, rsdGroupInfo.get(apikey).gnum);
                    //}

                    //// 别用途库存
                    //if (apikey.indexOf('_Jia__c') >= 0 && apikey == 'Bie_Yong_Tu_Ku_Cun_Jia__c') {
                    //    rsdObj.put(apikey, rsdGroupInfo.get(apikey).gnum);
                    //}
                }

                // 一对一不能单独分配 TODO 能单独分配
                if (rsdObj.OneToOne_Flag__c) {
                    showButtonList.add(true);
                } else {
                    showButtonList.add(false);
                    // 可以分配の場合
                    if (FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.assetFixtureStatus.Ke_Yi_Fen_Pei.ordinal()) == rsdObj.Fu_Shu_Pin_Fen_Pei_Jia__c) {
                        if (!autoRsdMap.containsKey(rsdObj.FSD_Fixture_Model_No__c)) {
                            autoRsdMap.put(rsdObj.FSD_Fixture_Model_No__c, new List<Rental_Apply_Equipment_Set_Detail__c>());
                            autoSelectMap.put(rsdObj.FSD_Fixture_Model_No__c, new List<Asset>());
                        }
                        List<Rental_Apply_Equipment_Set_Detail__c> autoRsdList = autoRsdMap.get(rsdObj.FSD_Fixture_Model_No__c);
                        autoRsdList.add(rsdObj);
                    }
                }

                // 备品智能化项目对应 20231122 by lc Start
                //viewList.add(new WrapperInfo(rsdObj, myComponentController));
                WrapperInfo info =  new WrapperInfo(rsdObj, myComponentController);
                info.additionalInfoMap.put('Intervention_Reason__c', rsdObj.Intervention_Reason__c==null?'':rsdObj.Intervention_Reason__c);
                viewList.add(info);
                // 备品智能化项目对应 20231122 by lc End

                viewList[viewList.size() - 1].lineNo = viewList.size() - 1;
                viewList[viewList.size() - 1].check = true;
                viewList[viewList.size() - 1].oldCheck = true;
            }

            if (!autoRsdMap.isEmpty()) {
                // Fixture_Model_No_F__c => {Asset.Id => 集中管理库存数}
                Map<String, Map<Id, Integer>> autoKuCunMapMap = new Map<String, Map<Id, Integer>>();
                // 累计借出数が少ないものを優先的に表示
                // OLY_OCM-134#comment-20049943
                Set<String> moset = autoRsdMap.keySet();
                System.debug('moset ===' + moset);

                // 検索条件
                String dateToday = String.valueOf(Date.today());

                String soql =  'SELECT Id, Fixture_Model_No_F__c, Pre_Arrival_wh_time__c, Ji_Zhong_Guan_Li_Ku_Cun__c,'
                        + ' SerialNumber, Salesdepartment__c, Internal_asset_location__c,'
                        + ' You_Xiao_Ku_Cun__c, Out_of_wh__c, Repairing_Count__c'
                        + ' FROM Asset'
                        + ' WHERE Asset_Owner__c = \'Olympus\' AND ' + FixtureUtil.getAssetSoqlBase()
                        + ' and Asset_loaner_category__c != \'耗材\''
                        + ' and RecordTypeId = \''+System.Label.access_1+'\''
                        + ' and Loaner_accsessary__c = true'
                        + ' and Equipment_Type__c != \'检测用备品\''
                        + ' and Delete_Flag__c = False'
                        + ' and Recall_Asset__c = False'
                        + ' and Freeze_sign_Abandoned_Flag__c = False'
                        + ' and (Consumable_Guaranteen_end__c = null or Consumable_Guaranteen_end__c >=' + dateToday + ')'
                        + ' and Fixture_OneToOne_Link__c = null'           // 附属品一对一的个体管理不能检索出来
                        + ' and Internal_asset_location__c != null'
                        + ' and Product2.Fixture_Model_No_T__c IN :moset'
                        + bieWhere +
                        + ' and Ji_Zhong_Guan_Li_Ku_Cun__c > 0' ;           // 有集中管理库存的
                    soql += ' ORDER BY Product2.Fixture_Model_No_T__c, Consumable_Guaranteen_end__c ASC NULLS LAST, Ji_Zhong_Guan_Li_Ku_Cun__c DESC, Pre_Arrival_wh_time__c ASC NULLS FIRST, Id DESC';

                System.debug('bieWhere' + bieWhere);

                List<Asset>  assignList = Database.query(soql);

                for (Asset aSet : assignList) {
                    List<Asset> autoSelectList = autoSelectMap.get(aSet.Fixture_Model_No_F__c);
                    autoSelectList.add(aSet);
                    autoSelectMap.put(aSet.Fixture_Model_No_F__c, autoSelectList);
                    if (!autoKuCunMapMap.containsKey(aSet.Fixture_Model_No_F__c)) {
                        autoKuCunMapMap.put(aSet.Fixture_Model_No_F__c, new Map<Id, Integer>());
                    }
                    Map<Id, Integer> autoKuCunMap = autoKuCunMapMap.get(aSet.Fixture_Model_No_F__c);
                    //修理中的数量减去
                    autoKuCunMap.put(aSet.Id, aSet.Ji_Zhong_Guan_Li_Ku_Cun__c.intValue() - aSet.Repairing_Count__c.intValue());
                }

                // 自动分配
                // Fixture_Model_No_F__c 的 Loop (会有 Fixture_Model_No_F__c 一样的借出明细)
                for (String modelNo : autoKuCunMapMap.keySet()) {
                    List<Asset> autoSelectList = autoSelectMap.get(modelNo);
                    Map<Id, Integer> autoKuCunMap = autoKuCunMapMap.get(modelNo);
                    List<Rental_Apply_Equipment_Set_Detail__c> autoRsdList = autoRsdMap.get(modelNo);
                    // Rental_Apply_Equipment_Set_Detail__c 的 Loop
                    for (Integer autoIdx = 0; autoIdx < autoRsdList.size(); autoIdx++) {
                        Rental_Apply_Equipment_Set_Detail__c rsdObj = autoRsdList[autoIdx];
                        // Asset 的 Loop
                        // autoSelectList より 自动分配 最初有集中有效在库的Asset
                        for (Asset aSet : autoSelectList) {
                            Integer autoKuCun = autoKuCunMap.get(aSet.Id);
                            if (autoKuCun > 0) {
                                rsdObj.Asset__c = aSet.Id;
                                rsdObj.Asset__r = aSet;    // TODO Select Asset より 表示Fieldの設定 myComponentController.strColumus
                                autoKuCun--;
                                autoKuCunMap.put(aSet.Id, autoKuCun);
                                break;          // 下一条借出明细
                            }
                        }
                        if (String.isBlank(rsdObj.Asset__c)) {
                            rsdObj.put('Fu_Shu_Pin_Fen_Pei_Jia__c', FixtureUtil.assetFixtureStatusMap.get(
                                    FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal()));
                        }
                    }
                }
            }
        }

        if (queryList.size() == 0) {
            return;
        }
system.debug('●●●●● setViewList END ' );
    }

    public override void checkEvent() {
        Rental_Apply_Equipment_Set_Detail__c lineInfo = (Rental_Apply_Equipment_Set_Detail__c) viewList[clickLineNo].sobj;

        // 一对一不能单独分配
        if (lineInfo.OneToOne_Flag__c) {
            goAccessoryAdd = null;
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '一对一不能单独分配'));
        } else {
            //回QueuePageByAssetId的URL
            goAccessoryAdd = '/apex/AccessoryAdd?recid=' + String.escapeSingleQuotes(lineInfo.Id);
        }
    }

    // 一对一并且状态是已分配时,button灰调
    public String getBodyModelNoJson() {
        return JSON.serialize(showButtonList);
}


}