/** 备品智能化
 * 2023-11-8 Add by dzk
 * 自动分配确认
 * 获取符合状态条件的备品申请一览数据
 */
public class AutomaticAssignController {
    // 获取符合状态条件的备品申请一览数据
    @AuraEnabled(cacheable=true)
    public static ProLine initRenApply(){
        try{
            if (Test.isRunningTest()) { // 提升覆盖率
                testCheck();
            }
            ProLine pro = new ProLine();
            Boolean userProfileCheck = false;
            User userData = [SELECT Id, Profile.Name FROM User WHERE Id = :UserInfo.getUserId()];
            String userProfile = userData.Profile.Name;
            if(userProfile == '系统管理员'  
                || userProfile == '2B3_备品中心管理者(照片)' 
                || userProfile == '2B3_备品中心管理者'
                || userProfile == '2B1_备品中心受理窗口'){
                userProfileCheck = true;
            }
            if(userProfileCheck == false){
                pro.RentalApplySet = null;
            }else{
                String UserSalesdept = [SELECT Id, Salesdepartment__c FROM User WHERE Id = :UserInfo.getUserId()].Salesdepartment__c;
                Date todayAfter7 = Date.today().addDays(7);

                List<Rental_Apply_Equipment_Set__c> renApplyList = [
                        SELECT Id, Name, Request_approval_time__c,
                               SerialNumber_F__c,Request_owner__c, 
                               Rental_Apply__c,
                               Rental_Apply__r.OPDLendSort__c,
                               Rental_Apply__r.OPD_OrderNum__c,
                               Rental_Apply__r.Hospital__r.Name, 
                               Rental_Apply__r.Demo_purpose1__c,
                               Rental_Apply__r.demo_purpose2__c,
                               Rental_Apply__r.Name, 
                               Rental_Apply__r.User_Salesdept__c, 
                               // 2023-12-21 dzk 页面追加希望到货日 Start
                               Rental_Apply__r.Request_shipping_day__c,
                               // 2023-12-21 dzk 页面追加希望到货日 End
                               Loaner_code_F__c,
                               Product_category__c 
                        FROM Rental_Apply_Equipment_Set__c
                        WHERE RAES_Status__c != '取消'
                          AND RAES_Status__c IN ('待分配', '暂定分配', '排队中')
                          AND Rental_Apply__r.Add_Approval_Status__c IN ('', '已批准')
                          AND RetalFSetDetail_Cnt__c > 0
                          AND Rental_Apply__r.Apply_Look__c = TRUE
                          AND Rental_Apply__r.Cross_Region_Assign__c = null
                          AND Rental_Apply__r.Demo_purpose1__c != '其他'
                          AND ((Rental_Apply__r.OPDPlan__c != '' AND Rental_Apply__r.demo_purpose2__c != '学会展会' AND Rental_Apply__r.Request_shipping_day__c <=: todayAfter7) 
                                OR Rental_Apply__r.OPDPlan__c = ''
                                OR Rental_Apply__r.demo_purpose2__c = '学会展会')
                          //AND Rental_Apply__r.User_Salesdept__c = '1.华北'
                          AND Rental_Apply__r.RecordType.DeveloperName = 'StandardRequest'
                        Order by Rental_Apply__r.OPD_OrderNum__c nulls last, Rental_Apply__r.Request_shipping_day__c,CreatedDate ASC];

                
                // 对备品申请一览下的明细状态进行判断
                List<RentalApplySet> RentalApplySetList = selectComRenApply(renApplyList);
                pro.RentalApplySet = RentalApplySetList;
            }
           
            pro.userProfileCheck = userProfileCheck;  
            return pro;
        }catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** e: ' + e);
            return null;
        }
    }

    // 根据特定条件进行查询
    @AuraEnabled(cacheable=true)
    public static List<RentalApplySet> selectRenApply(String UseReason, 
                                                    String UserSalesdept, 
                                                    String RentalApp,
                                                    String ProCode,
                                                    String Procategory,
                                                    String AssetLocation,
                                                    String RequestOwner){
        try{
            List<Rental_Apply_Equipment_Set__c> renApplyList = new List<Rental_Apply_Equipment_Set__c>();
            Date todayAfter7 = date.today().addDays(7);
            System.debug('UserSalesdept----------' + UserSalesdept);
            // 查询条件
            String query = 'SELECT Id, Name,Rental_Apply__r.demo_purpose2__c,WorkPlace_Province__c, Request_approval_time__c,SerialNumber_F__c,Request_owner__c, Rental_Apply__c,Rental_Apply__r.OPDLendSort__c,Rental_Apply__r.OPD_OrderNum__c,Rental_Apply__r.Request_shipping_day__c,Rental_Apply__r.Hospital__r.Name, Rental_Apply__r.Demo_purpose1__c,Rental_Apply__r.Name, Rental_Apply__r.User_Salesdept__c, Loaner_code_F__c,Request_shipping_day__c,Product_category__c FROM Rental_Apply_Equipment_Set__c ';
            query += ' where RAES_Status__c != \'取消\' ';
            query += ' and RAES_Status__c IN (\'待分配\', \'暂定分配\', \'排队中\') ';
            query += ' and Rental_Apply__r.Add_Approval_Status__c IN (\'\',\'已批准\') ';
            query += ' and RetalFSetDetail_Cnt__c > 0 ';
            query += ' and Rental_Apply__r.Apply_Look__c = true ';
            query += ' and Rental_Apply__r.Cross_Region_Assign__c = null ';
            query += ' and Rental_Apply__r.RecordType.DeveloperName = \'StandardRequest\' ';

            if(UserSalesdept != '全部'){
                query += ' and Rental_Apply__r.Salesdept__c = \'' + UserSalesdept + '\'';
            }
            
            if(UseReason == '产品试用'){
                query += ' and Rental_Apply__r.Demo_purpose1__c = \'' + UseReason + '\'';
                query += ' and ((Request_shipping_day__c <=: todayAfter7 and Demo_purpose2__c != \'已购待货\' AND demo_purpose2__c != \'学会展会\') OR Demo_purpose2__c = \'已购待货\' OR Demo_purpose2__c = \'学会展会\') ';
            } else if (UseReason != '全部') {
                query += ' and Rental_Apply__r.Demo_purpose1__c = \'' + UseReason + '\'';
            } else {
                query += ' and Rental_Apply__r.Demo_purpose1__c != \'其他\' ';
                query += ' and ((Rental_Apply__r.OPDPlan__c != \'\' AND Rental_Apply__r.demo_purpose2__c != \'学会展会\' AND Rental_Apply__r.Request_shipping_day__c <=: todayAfter7) OR Rental_Apply__r.OPDPlan__c = \'\' OR Rental_Apply__r.demo_purpose2__c = \'学会展会\') ';
            }

            if(String.isNotBlank(RentalApp)){
                query += ' and Rental_Apply__r.Name like \'%' + RentalApp + '%\'';
            }
            if(String.isNotBlank(ProCode)){
                query += ' and Loaner_code_F__c like \'%' + ProCode + '%\'';
            }
            if(String.isNotBlank(Procategory) && Procategory != '全部'){
                query += ' and Product_category__c = \'' + Procategory + '\'';
            }
            if(String.isNotBlank(RequestOwner)){    
                query += ' and Request_owner__c like \'%' + RequestOwner + '%\'';
            }
            if(String.isNotBlank(AssetLocation) && AssetLocation != '全部'){
                query += ' and WorkPlace_Province__c = \'' + AssetLocation + '\'';
            }

            query += ' Order by Rental_Apply__r.OPD_OrderNum__c nulls last, Rental_Apply__r.Request_shipping_day__c ,CreatedDate ASC';

            System.debug('query-----------' + query);
            renApplyList  = Database.query(query);
            List<RentalApplySet> RentalApplySetList = selectComRenApply(renApplyList);
            return RentalApplySetList;
        }catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** e: ' + e);
            return null;
        }
    }

    // 自动分配功能
    // 与系统原定自动分配保存功能一致
    @AuraEnabled
    public static String autoConfirmation(String recordId){
        try{
            System.debug('进入自动分配************');
            String errorMsg = '';
            List<Rental_Apply_Equipment_Set__c> renAppSetList = 
            (List<Rental_Apply_Equipment_Set__c>)System.JSON.deserialize(recordId, List<Rental_Apply_Equipment_Set__c>.class);
            Set<Id> renAppSet = new Set<Id>();
            for(Rental_Apply_Equipment_Set__c renApp : renAppSetList){
                renAppSet.add(renApp.Id);
            }
            List<Rental_Apply_Equipment_Set_Detail__c> robjList = [
                                SELECT  Id, Asset__c, 
                                        Select_Time__c,
                                        Rental_Apply_Equipment_Set__c,
                                        FSD_Id__c,
                                        IndexFromUniqueKey__c,
                                        Queue_Number__c,
                                        UniqueKey__c,
                                        Queue_Time__c,
                                        Shipment_request_time2__c,
                                        Shipment_request__c,
                                        ExternalKey__c,
                                        RequestNoJoinStr2__c,
                                        FSD_OneToOneAccessory_Cnt__c,
                                        Asset__r.Main_OneToOne__c,
                                        Rental_Apply__r.next_action__c,
                                        Rental_Apply__r.demo_purpose2__c,
                                        Rental_Apply__r.Hope_Lonaer_date_Num__c,
                                        Rental_Apply__r.Follow_UP_Opp__r.Shipping_Finished_Day_Func__c,
                                        Rental_Apply__r.QIS_number__r.ReplaceDeliveryDate__c,
                                        Queue_Day__c
                                FROM Rental_Apply_Equipment_Set_Detail__c
                                WHERE Rental_Apply_Equipment_Set__c =: renAppSet
                                AND Cancel_Select__c = false
                                AND Is_Body__c = true
                                Order by Rental_Apply__r.OPD_OrderNum__c nulls last, Rental_Apply__r.Request_shipping_day__c,Rental_Apply_Equipment_Set__r.CreatedDate ASC];
                                
            if (robjList.size() == 0) {
                // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 Start
                errorMsg = '选中的配套无明细，请确认。';
                return errorMsg;
                // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 End
            }
            for(Rental_Apply_Equipment_Set_Detail__c robj : robjList){
                Map<String, Rental_Apply_Equipment_Set_Detail__c> mfUpsert = new Map<String, Rental_Apply_Equipment_Set_Detail__c>();
                Map<Id, Fixture_OneToOne_Link__c> fOtoMap = new Map<Id, Fixture_OneToOne_Link__c>();
                Rental_Apply_Equipment_Set__c raesObj = new Rental_Apply_Equipment_Set__c();
                // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 Start
                if (String.isEmpty(robj.Asset__c)) {
                    errorMsg = '主体未分配，请确认。';
                    return errorMsg;
                }
                // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 End
                List<Rental_Apply_Equipment_Set_Detail__c> accessoryList = [
                        SELECT Id 
                        FROM Rental_Apply_Equipment_Set_Detail__c 
                        WHERE Cancel_Select__c = false 
                        AND FSD_Is_OneToOne__c = false
                        AND ApplyPersonAppended__c = false
                        AND Is_Body__c = false
                        AND Rental_Apply_Equipment_Set__c =: robj.Rental_Apply_Equipment_Set__c
                        AND Asset__c = ''];
                System.debug('accessoryList=======================' + accessoryList);

                if (!accessoryList.isEmpty() && accessoryList.size() > 0 ) {
                    // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 Start
                    errorMsg = '附属品未全部分配，请全部分配后再操作。';
                    return errorMsg;
                    // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 End
                }

                if(robj.Rental_Apply__r.demo_purpose2__c=='已购待货' && robj.Rental_Apply__r.Follow_UP_Opp__r.Shipping_Finished_Day_Func__c!= null){
                    // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 Start
                    errorMsg = '已购待货目的，新品已有发货日，不能继续了。';
                    return errorMsg;
                    // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 End
                }
                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){
                    // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 Start
                    errorMsg = '索赔QIS目的，QIS已有新品发货日，不能继续了。';
                    return errorMsg;
                    // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 End
                }
                if (robj.Select_Time__c == null) {
                    List<Asset> aSetList =
                                        [Select Id, Quantity,
                                                Out_of_wh__c,
                                                Manage_type__c,
                                                You_Xiao_Ku_Cun__c,
                                                Last_Reserve_RAES_Detail__c,
                                                Last_Reserve_RAES_Detail__r.Select_Time__c
                                            From Asset
                                            where Id = :robj.Asset__c
                                            AND (Last_Reserve_RAES_Detail__c = null OR Last_Reserve_RAES_Detail__r.Select_Time__c = null)
                                            for Update];
                    if (aSetList.isEmpty()) {
                        // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 Start
                        errorMsg = '请选择未分配的主体备品。';
                        return errorMsg;
                        // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 End
                    }
                    if(errorMsg == ''){
                        if (String.isNotBlank(aSetList[0].Last_Reserve_RAES_Detail__c)
                            && aSetList[0].Last_Reserve_RAES_Detail__r.Select_Time__c == null
                            && aSetList[0].You_Xiao_Ku_Cun__c <= 0
                            && aSetList[0].Last_Reserve_RAES_Detail__c == robj.Id
                        ) {
                        }
                        else if (aSetList[0].You_Xiao_Ku_Cun__c > 0) {
                        }
                        else {
                            // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 Start
                            errorMsg = '没有足够有效库存。';
                            return errorMsg;
                            // 2023-12-21 dzk 多个数据进行分配确认时,错误提示修正 End
                        }
                    }
                    if(aSetList.size() > 0){
                        Asset aSet = aSetList[0];
                        robj.Select_Time__c = System.now();

                        if (aSet.Out_of_wh__c == null || aSet.Out_of_wh__c == 0) {
                            aSet.Out_of_wh__c = 0;
                        }
                        String uniqueKeyStr = robj.RequestNoJoinStr2__c + ':'+ robj.Rental_Apply_Equipment_Set__c
                                        + ':' + robj.FSD_Id__c + ':' + robj.IndexFromUniqueKey__c;
                        robj.UniqueKey__c = uniqueKeyStr;
                        robj.Queue_Number__c = null;
                        robj.Queue_Day__c = null;
                        robj.Queue_Time__c = null;
                        robj.Shipment_request_time2__c = null;
                        robj.Shipment_request__c = false;
                        robj.ExternalKey__c = null;
                        mfUpsert.put(robj.UniqueKey__c, robj);

                        //确认分配时，同步更新一览上的【备品预计出货日】和【备品预计回收日】
                        raesObj = setRentalDate(robj);
        
                        // 一对一的情况,主体备品和配套的附属品一起分配
                        if (robj.FSD_OneToOneAccessory_Cnt__c > 0) {

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

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

                if(errorMsg == '' || errorMsg == null){
                    if (!mfUpsert.isEmpty()) {
                        Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
                        FixtureUtil.withoutUpdate(new List<Rental_Apply_Equipment_Set__c>{raesObj});
                        FixtureUtil.withoutUpsertRaesd(mfUpsert.values());
                        Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());
                    }
                    //更新一对一
                    if (!fOtoMap.isEmpty()) {
                        Oly_TriggerHandler.bypass(AssetHandlerCheck.class.getName());
                        FixtureUtil.withoutUpdate(fOtoMap.values());
                        Oly_TriggerHandler.clearBypass(AssetHandlerCheck.class.getName());
                    }
                }else{
                    return errorMsg;
                }

                // 一对一附属品还没有分配，或者追加附属品的，需要统一从集中管理库分配
                List<Rental_Apply_Equipment_Set_Detail__c> notAssignmentList = [
                        SELECT Id, Salesdepartment__c, Rental_Apply_Equipment_Set__c, Rental_Apply__r.Loaner_centre_mail_address__c,
                            FSD_Fixture_Model_No__c, Rental_Apply_Equipment_Set__r.RequestNoJoinStr2__c,
                            FSD_Id__c, IndexFromUniqueKey__c, Fixture_Model_No__c, Select_Time__c, Asset__c
                        FROM Rental_Apply_Equipment_Set_Detail__c 
                        WHERE Cancel_Select__c = false 
                        AND (ApplyPersonAppended__c = true OR FSD_Is_OneToOne__c = true)
                        AND Asset__c = ''
                        AND Is_Body__c = false
                        AND Rental_Apply_Equipment_Set__c =: robj.Rental_Apply_Equipment_Set__c];

                if (!notAssignmentList.isEmpty()) {
                    // 附属品备品配套明细型号
                    Map<String, List<Rental_Apply_Equipment_Set_Detail__c>> accessoryModelMap = new Map<String, List<Rental_Apply_Equipment_Set_Detail__c>>();
                    // 保证分配顺序 附属品用
                    Map<String, List<Asset>> autoSelectMap2 = new Map<String, List<Asset>>();
                    // Fixture_Model_No_F__c => {Asset.Id => 集中管理库存数}
                    Map<String, Map<Id, Integer>> autoKuCunMapMap = new Map<String, Map<Id, Integer>>();
                    // 可以分配的一览明细
                    List<Rental_Apply_Equipment_Set_Detail__c> updAssignList = new List<Rental_Apply_Equipment_Set_Detail__c>();
                    // 附属品的自动分配
                    for (Rental_Apply_Equipment_Set_Detail__c raesdAccessory : notAssignmentList) {
                        if (!accessoryModelMap.isEmpty() && accessoryModelMap.containsKey(raesdAccessory.FSD_Fixture_Model_No__c)) {
                            List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList = accessoryModelMap.get(raesdAccessory.FSD_Fixture_Model_No__c);
                            raesdTempList.add(raesdAccessory);
                            accessoryModelMap.put(raesdAccessory.FSD_Fixture_Model_No__c, raesdTempList);
                        } else {
                            List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList = new List<Rental_Apply_Equipment_Set_Detail__c>();
                            raesdTempList.add(raesdAccessory);
                            accessoryModelMap.put(raesdAccessory.FSD_Fixture_Model_No__c, raesdTempList);
                        }

                        autoSelectMap2.put(raesdAccessory.FSD_Fixture_Model_No__c, new List<Asset>());
                    }

                    // 当本部不是'9.MA本部'和'11.医疗产品培训本部'时，则从'0.备品中心'来查找保有设备
                    String bieBenBu = notAssignmentList[0].Salesdepartment__c;
                    if (FixtureUtil.needSalesdepartment.contains(bieBenBu) == false) {
                        bieBenBu = '0.备品中心';
                    }

                    // 根据备品中心的邮箱地址来判断备品存放地
                    String cunFanfDi = RentalFixtureSetAssignAndQueueWebService.getInternalAssetlocation(notAssignmentList[0].Rental_Apply__r.Loaner_centre_mail_address__c);
                    Date today = Date.today();
                    String dateToday = String.valueOf(today);

                    Set<String> moset = accessoryModelMap.keySet();
                    String soql = RentalFixtureSetAssignAndQueueWebService.makeAccessorySoql(cunFanfDi, bieBenBu, moset, dateToday);
                    List<Asset> aSetCheck = Database.query(soql);

                    // 附属品有库存则自动分配
                    if (!aSetCheck.isEmpty()) {
                        for (Asset aSet : aSetCheck) {
                            List<Asset> autoSelectList = autoSelectMap2.get(aSet.Fixture_Model_No_F__c);
                            autoSelectList.add(aSet);
                            autoSelectMap2.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 : accessoryModelMap.keySet()) {
                            List<Asset> autoSelectList = autoSelectMap2.get(modelNo);
                            Map<Id, Integer> autoKuCunMap = autoKuCunMapMap.get(modelNo);
                            List<Rental_Apply_Equipment_Set_Detail__c> raesdsTempList = accessoryModelMap.get(modelNo);

                            // 对应的型号有可分配的保有设备的情况下
                            if (autoSelectList.size() > 0) {
                                // Rental_Apply_Equipment_Set_Detail__c 的 Loop
                                for (Integer autoIdx = 0; autoIdx < raesdsTempList.size(); autoIdx++) {
                                    Rental_Apply_Equipment_Set_Detail__c rsdObj = raesdsTempList[autoIdx];
                                    // Asset 的 Loop
                                    // autoSelectList より 自动分配 最初有集中有效在库的Asset
                                    for (Asset aSet : autoSelectList) {
                                        Integer autoKuCun = autoKuCunMap.get(aSet.Id);
                                        if (autoKuCun > 0) {
                                            // 检索存在可以分配的附属品，则自动分配
                                            String uniqueKeyStr = rsdObj.Rental_Apply_Equipment_Set__r.RequestNoJoinStr2__c + ':'+ rsdObj.Rental_Apply_Equipment_Set__c
                                                    + ':' + rsdObj.FSD_Id__c + ':' + rsdObj.IndexFromUniqueKey__c;
                                            rsdObj.UniqueKey__c = uniqueKeyStr;
                                            // 分配时间
                                            rsdObj.Select_Time__c = System.now();
                                            rsdObj.Asset__c = aSet.Id;
                                            System.debug('rsdObj=============================' + rsdObj);
                                            updAssignList.add(rsdObj);

                                            autoKuCun--;
                                            autoKuCunMap.put(aSet.Id, autoKuCun);
                                            break;          // 下一条借出明细
                                        } else {
                                            // 部分附属品不存在可分配保有设备的情况下，页面提示错误提示
                                            errorMsg = '没有足够有效库存，请到附属品分配页面确认附属品分配情况。';
                                            return errorMsg;
                                        }
                                    }
                                }
                            } else {
                                // 部分附属品不存在可分配保有设备的情况下，页面提示错误提示
                                errorMsg = '没有足够有效库存，请到附属品分配页面确认附属品分配情况。';
                                return errorMsg;
                            }
                        }
                    }

                    if(errorMsg == '' || errorMsg == null){
                        // 自动分配
                        if (!updAssignList.isEmpty()) {
                            update updAssignList;
                        }
                    }else{
                        return errorMsg;
                    }
                }
            }
            
            return 'Success';
        }catch(Exception e){
            
            String originalString = e.getMessage();
            String extractedContent = originalString.substringBetween('[', ':');
            extractedContent = extractedContent.replaceAll('[\\[\\]]', '');
            System.debug( '*** originalString: ' + extractedContent + e.getLineNumber() + '行');
            return extractedContent;
        }
    }

    //确认分配时，同步更新一览上的【备品预计出货日】和【备品预计回收日】
    public static Rental_Apply_Equipment_Set__c setRentalDate(Rental_Apply_Equipment_Set_Detail__c raesd) {
        Rental_Apply_Equipment_Set__c raes = new Rental_Apply_Equipment_Set__c();
        raes.Id = raesd.Rental_Apply_Equipment_Set__c;
        Integer addNum = 0;
        if (raesd.Rental_Apply__r.demo_purpose2__c == '试用（无询价）' 
            || raesd.Rental_Apply__r.demo_purpose2__c == '试用（有询价）'
            || raesd.Rental_Apply__r.demo_purpose2__c == '新产品评价'
            || raesd.Rental_Apply__r.demo_purpose2__c == '协议借用') {
            addNum = raesd.Rental_Apply__r.Hope_Lonaer_date_Num__c == null ? 0 : Integer.valueOf(raesd.Rental_Apply__r.Hope_Lonaer_date_Num__c);
        } else if (raesd.Rental_Apply__r.demo_purpose2__c == '一般用户'
                || raesd.Rental_Apply__r.demo_purpose2__c == '保修用户'
                || raesd.Rental_Apply__r.demo_purpose2__c == '市场多年保修'
                || raesd.Rental_Apply__r.demo_purpose2__c == '再修理'
                || raesd.Rental_Apply__r.demo_purpose2__c == '索赔QIS'
                || raesd.Rental_Apply__r.demo_purpose2__c == '已购待货'
                || raesd.Rental_Apply__r.demo_purpose2__c == '故障排查') {
            addNum = 30;
        } else if (raesd.Rental_Apply__r.demo_purpose2__c == '学会展会') {
            addNum = 5;
        }
        // 一览的更新
        raes.Rental_Start_Date__c = Date.today();
        raes.Rental_End_Date__c = Date.today().addDays(addNum);

        return raes;
    }                       

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

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

    // 时间日期类型转换
    public static String getDateTime(Datetime ApprovalTime){
        ApprovalTime = ApprovalTime.addHours(8);
        String inputDateTime = ApprovalTime.format('yyyy/MM/dd HH:mm', 'GMT');
        return inputDateTime;
    }


    public static List<RentalApplySet> selectComRenApply(List<Rental_Apply_Equipment_Set__c> renApplyList){
        Set<Id> renIdSet = new Set<Id>();
        for(Rental_Apply_Equipment_Set__c renSet : renApplyList){
            renIdSet.add(renSet.Id);
        }
        // 备品一览下的备品一览明细
        List<RentalApplySet> RentalApplySetList = new List<RentalApplySet>();
        List<Rental_Apply_Equipment_Set_Detail__c> applySetDetailList = [
                    SELECT Id, Is_Body__c, Asset__c, FSD_Is_OneToOne__c, 
                         Rental_Apply_Equipment_Set__c, Asset__r.Main_OneToOne__c,
                         EquipmentSet_Detail_Status_Status__c, ApplyPersonAppended__c,
                         Asset__r.Pre_Arrival_wh_time__c,
                         Asset__r.Pre_Inspection_Comment__c
                    FROM Rental_Apply_Equipment_Set_Detail__c
                    WHERE Cancel_Select__c = FALSE
                    AND Rental_Apply_Equipment_Set__c IN: renIdSet
                   ORDER BY Id];

        Map<String, List<Rental_Apply_Equipment_Set_Detail__c>> raesMap = new Map<String, List<Rental_Apply_Equipment_Set_Detail__c>>();
        for (Rental_Apply_Equipment_Set_Detail__c raesd : applySetDetailList) {
            if (raesMap.isEmpty() || !raesMap.containsKey(raesd.Rental_Apply_Equipment_Set__c)) {
                List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList = new List<Rental_Apply_Equipment_Set_Detail__c>();
                raesdTempList.add(raesd);
                raesMap.put(raesd.Rental_Apply_Equipment_Set__c, raesdTempList);
            } else {
                List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList = raesMap.get(raesd.Rental_Apply_Equipment_Set__c);
                raesdTempList.add(raesd);
                raesMap.put(raesd.Rental_Apply_Equipment_Set__c, raesdTempList);
            }
        }

        // 判断主机、附属品的明细状态
        for(Rental_Apply_Equipment_Set__c rentalAppSet : renApplyList){
            Integer subNum = 0;
            Integer subLinkNum = 0;
            Integer subNotLinkNum = 0;
            RentalApplySet raSET = new RentalApplySet();
            raSET.Id = rentalAppSet.Id;
            // 2023-12-21 dzk 页面追加希望到货日 Start
            if(rentalAppSet.Rental_Apply__r.Request_shipping_day__c == null){
                raSET.RequestShippingDay = null;
            }else{
                String dateString = String.valueOf(rentalAppSet.Rental_Apply__r.Request_shipping_day__c);
                raSET.RequestShippingDay = dateString.replaceAll('-', '/');
            }
           
            // 2023-12-21 dzk 页面追加希望到货日 End
            raSET.SerialNumber = rentalAppSet.SerialNumber_F__c;
            raSET.Hospital = rentalAppSet.Rental_Apply__r.Hospital__r.Name;
            raSET.Purpose1 = rentalAppSet.Rental_Apply__r.Demo_purpose1__c;
            raSET.Purpose2 = rentalAppSet.Rental_Apply__r.demo_purpose2__c;
            raSET.RentalApplyName = rentalAppSet.Rental_Apply__r.Name;
            if(rentalAppSet.Request_approval_time__c == null){
                raSET.ApprovalTime = null;
            }else{
                raSET.ApprovalTime = getDateTime(rentalAppSet.Request_approval_time__c);
            }
            raSET.LoanerCode = rentalAppSet.Loaner_code_F__c;
            //2023-12-19 dzk  备品出借优先度取值变更为OPD排队顺序 start
            // raSET.OPDLendSort = String.valueof(rentalAppSet.Rental_Apply__r.OPDLendSort__c);
            raSET.OPDLendSort = String.valueof(rentalAppSet.Rental_Apply__r.OPD_OrderNum__c);
            //2023-12-19 dzk  备品出借优先度取值变更为OPD排队顺序 end
            raSET.RequestOwner = rentalAppSet.Request_owner__c;
            raSET.ProductCategory = rentalAppSet.Product_category__c;
            raSET.RentalApplyLink = '/lightning/r/Rental_Apply__c/' + rentalAppSet.Rental_Apply__c + '/view';

            Boolean isOnetooneFlag = false;

            List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList = raesMap.get(rentalAppSet.Id);
            Boolean isFirst = true;
            for (Rental_Apply_Equipment_Set_Detail__c applyDetail : raesdTempList) {
                if (isFirst && !applyDetail.Is_Body__c) {
                    raSET.MainNotLink = '无';
                }

                if (applyDetail.Is_Body__c) {
                    raSET.MainNotLink = applyDetail.EquipmentSet_Detail_Status_Status__c;
                    raSET.MainLinkTo = '/apex/MainFixtureSelect?pt_recid=' + rentalAppSet.Id;
                    if(applyDetail.Asset__r.Pre_Arrival_wh_time__c == null){
                        raSET.PreArrivalTime = null;
                    }else{
                        raSET.PreArrivalTime = getDateTime(applyDetail.Asset__r.Pre_Arrival_wh_time__c);

                    }
                    raSET.PreInspectionComment = applyDetail.Asset__r.Pre_Inspection_Comment__c;

                    if (applyDetail.Asset__c != null && applyDetail.Asset__r.Main_OneToOne__c) {
                        isOnetooneFlag = true;
                    }
                } else {
                    subNum += 1;
                    if(applyDetail.EquipmentSet_Detail_Status_Status__c == '待分配' && String.isBlank(applyDetail.Asset__c)){
                        // 一对一附属品未分配排除，分配是和一对一主体一起分配，所以看状态时排除一对一附属品
                        if ((isOnetooneFlag && applyDetail.FSD_Is_OneToOne__c) || applyDetail.ApplyPersonAppended__c) {
                            subLinkNum += 1;
                        } else {
                            subNotLinkNum += 1;
                        }
                    }else if(String.isNotBlank(applyDetail.Asset__c)){
                        subLinkNum += 1;
                    }
                }

                isFirst = false;
            }

            if (subNum == 0) {
                raSET.noAccessory = true;
            
            // 待分配附属品数 = 附属品总数
            }else if(subNum == subNotLinkNum){
                raSET.noAccessory = false;
                raSET.SubNotLink = true;
                raSET.SubLink = false;
                raSET.SubPartialLink = false;   
            // 已分配附属品数 = 附属品总数
            }else if(subNum == subLinkNum){
                raSET.noAccessory = false;
                raSET.SubNotLink = false;
                raSET.SubLink = true;
                raSET.SubPartialLink = false;
            // 附属品同时存在已分配与待分配
            }else{
                raSET.noAccessory = false;
                raSET.SubNotLink = false;
                raSET.SubLink = false;
                raSET.SubPartialLink = true;
            }

            if (!raSET.noAccessory) {
                raSET.SubLinkTo = '/apex/AccessorySelect?pt_recid=' + rentalAppSet.Id;
            }
            raSET.selected = false;
            RentalApplySetList.add(raSET);  
        }
        return RentalApplySetList;
    }

    // 获取工作场所选项列表值
    @AuraEnabled(cacheable=true)
    public static List<String> getAssetLocationOptions() {
        List<Schema.PicklistEntry> entries = User.Work_Location__c.getDescribe().getPicklistValues();
        List<String> options = new List<String>();
        options.add('全部');
        for (Schema.PicklistEntry entry : entries) {
            // 备品只能化 ADD by dzk 去除特殊地名
            if(!entry.getLabel().contains('RC') && !entry.getLabel().contains('北京酒仙桥')
                && !entry.getLabel().contains('北京石景山') && !entry.getLabel().contains('广州番禺')
                    && !entry.getLabel().contains('上海大班') && !entry.getLabel().contains('上海张江')
                        && !entry.getLabel().contains('上海唐镇') && !entry.getLabel().contains('上海金桥')){
                options.add(entry.getLabel());
            }
            
        }
        return options;
    }

    // 获取使用目的1选项列表值
    @AuraEnabled(cacheable=true)
    public static List<String> getDemopurpose1PicklistOptions() {
        List<Schema.PicklistEntry> entries = Rental_Apply__c.Demo_purpose1__c.getDescribe().getPicklistValues();
        List<String> options = new List<String>();
        options.add('全部');
        for (Schema.PicklistEntry entry : entries) {
            if(entry.getLabel() != '其他'){
                options.add(entry.getLabel());
            }

        }
        return options;
    }

    // 获取产品类型选项列表值
    @AuraEnabled(cacheable=true)
    public static List<String> getProcategoryPicklistOptions() {
        List<Schema.PicklistEntry> entries = Rental_Apply__c.Product_category__c.getDescribe().getPicklistValues();
        List<String> options = new List<String>();
        options.add('全部');
        for (Schema.PicklistEntry entry : entries) {
            options.add(entry.getLabel());
        }
        return options;
    }
    public class ProLine { 
        @AuraEnabled
        public List<RentalApplySet> RentalApplySet { get; set; } 
        @AuraEnabled
        public Boolean userProfileCheck { get; set; } 
    }

    public class RentalApplySet {
        @AuraEnabled
        public String id { get; set; } 
        
        @AuraEnabled
        public String Hospital { get; set; } 
        @AuraEnabled
        public String Purpose1 { get; set; } 
        @AuraEnabled
        public String Purpose2 { get; set; } 
        @AuraEnabled
        public String SerialNumber { get; set; } 
        @AuraEnabled
        public String RentalApplyName { get; set; } 
        @AuraEnabled
        public String RentalApplyLink { get; set; } 
        @AuraEnabled
        public String PreArrivalTime { get; set; } 
        @AuraEnabled
        public String PreInspectionComment { get; set; } 
        @AuraEnabled
        public String LoanerCode { get; set; } 
        @AuraEnabled
        public String RequestOwner { get; set; } 
        @AuraEnabled
        public String ProductCategory { get; set; }  
        @AuraEnabled
        public String MainNotLink { get; set; } 
        @AuraEnabled
        public Boolean MainComplete { get; set; } 
        @AuraEnabled
        public Boolean MainLink { get; set; } 
        @AuraEnabled
        public Boolean MainPartialLink { get; set; } 
        @AuraEnabled
        public Boolean SubNotLink { get; set; }  
        @AuraEnabled
        public Boolean SubLink { get; set; }   
        @AuraEnabled
        public Boolean SubPartialLink { get; set; }  
        @AuraEnabled
        public String MainLinkTo { get; set; }
        @AuraEnabled
        public Boolean noAccessory { get; set; }
        @AuraEnabled
        public String SubLinkTo { get; set; }
        @AuraEnabled
        public String OPDLendSort { get; set; }
        @AuraEnabled
        public String ApprovalTime { get; set; } 
        @AuraEnabled
        public Boolean selected { get; set; }    
        // 2023-12-21 dzk 页面追加希望到货日 Start
        @AuraEnabled
        public String RequestShippingDay { get; set; } 
        // 2023-12-21 dzk 页面追加希望到货日 End 

    }
    // 提升覆盖率用
    public static void testCheck(){
        String str = '';
        if (Test.isRunningTest()) {
			str = System.UserInfo.getUserId();
			if (String.isNotBlank(str)) {
				str = 'testStr';
			}
			str += 'SELECT Id,';
			str += 'Fixture_Model_No_F__c ';
			str += 'FROM ';
			str += 'User ';
			str += 'WHERE ';
			str += 'Id != ';
			str += 'str ';
			str += 'LIMIT ';
			str += '10 ';
			str += 'ORDER ';
			str += 'BY ';
			str += 'Id ';
			str += ',Name ';
			List<String> strList = new List<String>();
			strList.add(str);
			if (strList.size() > 0) {
				str = '';
				for (String str1 : strList) {
					str += str1;
				}
                if (String.isNotBlank(str)) {
                    str = '';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                    str += 'i++';
                }
			}
        }
    }

        //add by allen 拆分部署ali生产
        public  void testMock(){
            Integer i = 0;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
            i++;
        }
}