/**************************************************************************************************
 * Name: Batch_QueueAllDetail
 * Object: Rental_Apply_Equipment_Set_Detail__c
 * Purpose: run all detail to queue
 * Author:  denny chen
 * Create Date: 2021-11-15
 * Modify History:
 * 2021-11-15        Create this class
 **************************************************************************************************/
global class Batch_QueueAllDetail implements Schedulable,Database.Batchable<SObject>,Database.Stateful {
    public String externalkey;

    // public Batch_QueueAllDetail(String key){
    //     externalkey = key;
    // }

    public void execute(SchedulableContext sc) {
        Database.executeBatch(this);
    }
    public Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator([SELECT Id, Rental_Apply_Equipment_Set__c, Asset__c,Rental_Apply_Equipment_Set__r.Fixture_Set__r.Product_Type__c,
                                               FSD_Fixture_Model_No__c, Fixture_Model_No_text__c,Externalkey__c,Rental_Apply__r.Product_category__c,
                                               Rental_Apply__r.demo_purpose2__c,Is_Body__c, FSD_Is_OneToOne__c, Select_Time__c,Rental_Apply__r.Salesdepartment__c,
                                               Rental_Apply__r.EquipmentGuaranteeFlg__c,Fixture_Model_No__c,Salesdepartment_before__c,
                                               Cancel_Select__c, Fixture_Model_No_F__c, Queue_Number__c, Internal_asset_location__c,Rental_Apply__r.Demo_purpose1__c,
                                               IsAdjust__c,Salesdepartment__c, Product_category_F__c, Equipment_Type__c, Internal_asset_location_before__c,
                                               Queue_Time_F__c,IndexFromUniqueKey__c,Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c,Equipment_Type_text__c,
                                                // 20220105 ljh add Queue_Time_F__c,IndexFromUniqueKey__c,
                                               // 备品智能化项目对应 20231122 by lc Start
                                               Rental_Apply__r.OPD_OrderNum__c,Rental_Apply__r.OPD_AdjustmentOrderNum_Flag__c,Rental_Apply__r.Last_Month_Untreated__c,
                                               // 备品智能化项目对应 20231122 by lc End
                                               Rental_Apply__r.Internal_asset_location_F__c,Cancel_Reason__c,Loaner_cancel_reason__c,Rental_Apply__r.Request_shipping_day__c,
                                               Loaner_cancel_Remarks__c ,Rental_Apply__r.CampaignType__c,Queue_Day__c,Queue_Time__c,Rental_Apply__r.Request_approval_time__c
                                        FROM Rental_Apply_Equipment_Set_Detail__c
                                        WHERE Cancel_Select__c = false
                                        AND QuenType__c = null
                                        AND Is_Body__c = true
                                        AND Queue_Number__c > 0
                                        ORDER BY Fixture_Model_No_text__c,Internal_asset_location__c]);
    }
    public void execute(Database.BatchableContext bc,List<Rental_Apply_Equipment_Set_Detail__c> details){
        List<Rental_Apply_Equipment_Set_Detail__c> queueList = (details);
        System.debug('***queueListStart:'+queueList.size());
        System.debug('***queueLisStart[0]:'+queueList[0]);
        String queuetype = '默认排队';
        List<Rental_Apply_Sequence__c> allsequenceList = new List<Rental_Apply_Sequence__c>();

        List<String> sequencekeylist = new List<String>();
        List<String> detailIds = new List<String>();
        List<String> queuekeyList = new List<String>();
        List<String> queueIds = new List<String>();
        for(Rental_Apply_Equipment_Set_Detail__c raesd:details){
            RentalFixtureSetAssignController.ApplyObj applyObj = new RentalFixtureSetAssignController.ApplyObj();
            applyObj.location = raesd.Rental_Apply__r.Internal_asset_location_F__c;
            applyObj.productType = raesd.Rental_Apply__r.Product_category__c;
            applyObj.salesdepartment = raesd.Rental_Apply__r.Salesdepartment__c ;
            applyObj.purpose1 = raesd.Rental_Apply__r.Demo_purpose1__c;
            applyObj.purpose2 = raesd.Rental_Apply__r.demo_purpose2__c;
            applyObj.campaignType = '全国性学会';//raesd.Rental_Apply__r.CampaignType__c;
            // parentObj.Demo_purpose1__c = raesd.Rental_Apply__r.Demo_purpose1__c;
            // parentObj.Demo_purpose2__c = raesd.Rental_Apply__r.demo_purpose2__c;
            // parentObj.Salesdepartment__c = raesd.Salesdepartment_before__c;
            // parentObj.CampaignType__c = raesd.Rental_Apply__r.CampaignType__c;
            queueIds.add(raesd.Id);
            RentalFixtureSetAssignController.KeyObj obj = RentalFixtureSetAssignController.getdefultInfo(raesd,applyObj,raesd.Internal_asset_location_before__c);
             // 备品配套明细型号(借出时)
            raesd.Fixture_Model_No_text__c = obj.model;
            // 所在地区(本部) 借出时
            raesd.Salesdepartment_before__c = obj.salesdepartments;
            
            // 产品分类(GI/SP)(借出时)
            raesd.Product_category_text__c = obj.productType;
            // 备品分类(借出时)
            raesd.Equipment_Type_text__c = obj.equipmenttypes;
            System.debug('***obj.equipmenttypes:'+obj.equipmenttypes);
            // 备品存放地(借出时)
            raesd.Internal_asset_location_before__c = obj.location;
            String key = obj.model + obj.location + obj.salesdepartments + obj.equipmenttypes + obj.productType;
            raesd.ExternalKey__c = key;
            raesd.QuenType__c = queuetype;
            raesd.Queue_Number__c = -1;
            raesd.Allow_Adjust_Queue_Flag__c = true;
            detailIds.add(raesd.Id);
            sequencekeylist.addAll(obj.sequencekeylist);
            queuekeyList.add(key);
            for(String sales:obj.salesdepartmentList){
            
                for(String equip:obj.equipmentList){
                    for(String type:obj.productTypes){
                        Rental_Apply_Sequence__c newSequence = new Rental_Apply_Sequence__c();
                        newSequence.ExternalKey__c = obj.model + obj.location + sales + equip + type;
                        newSequence.Demo_Purpose2__c = raesd.Rental_Apply__r.demo_purpose2__c;
                        newSequence.Apply_Set_Detail__c = raesd.Id;
                        newSequence.Series_No__c = raesd.Queue_Number__c;
                        newSequence.Salesdepartment__c = sales;
                        newSequence.Product_category__c = type;
                        newSequence.Rental_Apply__c = raesd.Rental_Apply__c;
                        newSequence.Internal_asset_location__c = obj.location;
                        newSequence.Fixture_Model_No__c = obj.model;
                        newSequence.Equipment_Type__c = equip;
                        
                        allsequenceList.add(newSequence);
                       
                    }
                }
            }
        }
        List<Rental_Apply_Equipment_Set_Detail__c> updateList = [SELECT Id, Rental_Apply_Equipment_Set__c, Asset__c,Rental_Apply_Equipment_Set__r.Fixture_Set__r.Product_Type__c,
                                                                   FSD_Fixture_Model_No__c, Fixture_Model_No_text__c,Externalkey__c,Rental_Apply__r.demo_purpose2__c,Equipment_Type_text__c,
                                                                   Is_Body__c, FSD_Is_OneToOne__c, Select_Time__c,Rental_Apply__r.EquipmentGuaranteeFlg__c,Fixture_Model_No__c,
                                                                   Cancel_Select__c, Fixture_Model_No_F__c, Queue_Number__c, Internal_asset_location__c,IsAdjust__c,Queue_Day__c,Queue_Time__c,
                                                                   Salesdepartment__c, Product_category_F__c, Equipment_Type__c, Rental_Apply__r.Internal_asset_location_F__c,
                                                                   Queue_Time_F__c,IndexFromUniqueKey__c,Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c,
                                                                    // 20220105 ljh add Queue_Time_F__c,IndexFromUniqueKey__c,
                                                                   // 备品智能化项目对应 20231122 by lc Start
                                                                   Rental_Apply__r.OPD_OrderNum__c,Rental_Apply__r.OPD_AdjustmentOrderNum_Flag__c,Rental_Apply__r.Last_Month_Untreated__c,
                                                                   // 备品智能化项目对应 20231122 by lc End
                                                                   Cancel_Reason__c,Loaner_cancel_reason__c,Loaner_cancel_Remarks__c ,Rental_Apply__r.Request_shipping_day__c,Rental_Apply__r.Request_approval_time__c
                                                            FROM Rental_Apply_Equipment_Set_Detail__c
                                                            WHERE Externalkey__c IN :queuekeyList
                                                            AND Cancel_Select__c = false
                                                            AND Is_Body__c = true
                                                            AND QuenType__c = null
                                                            AND Id NOT IN:queueIds
                                                            AND Queue_Number__c > 0 ];
        // 20240101 ljh 智能化优化 start 
        if(updateList.size() > 0){
            queueList.addAll(updateList);
        }
        System.debug('***queueList:'+queueList.size());
        System.debug('***queueList[0]:'+queueList[0]);
        // 20240101 ljh 智能化优化 end
        updateList = Batch_QueueAllDetail.getSortDetailList(queueList);
        update updateList;
        insert allsequenceList;
        List<String> newSequenceIds = new List<String>();
        for(Rental_Apply_Sequence__c se:allsequenceList){
            newSequenceIds.add(se.Id);
        }
        List<Rental_Apply_Sequence__c> newSequenceList = new List<Rental_Apply_Sequence__c>();
        allsequenceList = [SELECT Id,ExternalKey__c,Demo_Purpose2__c,Rental_Apply__r.Request_shipping_day__c,Rental_Apply__r.EquipmentGuaranteeFlg__c,
                                                        Apply_Set_Detail__c,Apply_Set_Detail_ExternalKey__c,Rental_Apply__r.Request_approval_time__c,Apply_Set_Detail__r.IsAdjust__c,
                                                        Series_No__c,Salesdepartment__c,Product_category__c,Apply_Set_Detail__r.Queue_Day__c,Apply_Set_Detail__r.Queue_Time__c,
                                                        Rental_Apply__c,Internal_asset_location__c,Series_Unequal_Queue_Flag__c,
                                                        Apply_Set_Detail__r.Queue_Number__c,Apply_Set_Detail__r.Queue_Time_F__c,Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c,
                                                        // 20220105 ljh add Apply_Set_Detail__r.Queue_Time_F__c,Apply_Set_Detail__r.IndexFromUniqueKey__c,
                                                        // 备品智能化项目对应 20231122 by lc Start
                                                        Rental_Apply__r.OPD_OrderNum__c,Rental_Apply__r.Last_Month_Untreated__c,
                                                        // 备品智能化项目对应 20231122 by lc End
                                                        Fixture_Model_No__c,Equipment_Type__c
                                                        FROM Rental_Apply_Sequence__c
                                                        WHERE Id IN:newSequenceIds
                                                        ];
        List<String> nodusequencekeylist = new List<String>(new Set<String>(sequencekeylist));
        List<Rental_Apply_Sequence__c> applysequenceList = [SELECT Id,ExternalKey__c,Demo_Purpose2__c,Rental_Apply__r.Request_shipping_day__c,Rental_Apply__r.EquipmentGuaranteeFlg__c,
                                                        Apply_Set_Detail__c,Apply_Set_Detail_ExternalKey__c,Rental_Apply__r.Request_approval_time__c,Apply_Set_Detail__r.IsAdjust__c,
                                                        Series_No__c,Salesdepartment__c,Product_category__c,Apply_Set_Detail__r.Queue_Day__c,Apply_Set_Detail__r.Queue_Time__c,
                                                        Rental_Apply__c,Internal_asset_location__c,Series_Unequal_Queue_Flag__c,
                                                        Apply_Set_Detail__r.Queue_Number__c,Apply_Set_Detail__r.Queue_Time_F__c,Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c,
                                                        // 20220105 ljh add Apply_Set_Detail__r.Queue_Time_F__c,Apply_Set_Detail__r.IndexFromUniqueKey__c,
                                                        // 备品智能化项目对应 20231122 by lc Start
                                                        Rental_Apply__r.OPD_OrderNum__c,Rental_Apply__r.Last_Month_Untreated__c,
                                                        // 备品智能化项目对应 20231122 by lc End
                                                        Fixture_Model_No__c,Equipment_Type__c
                                                        FROM Rental_Apply_Sequence__c
                                                        WHERE ExternalKey__c IN: nodusequencekeylist
                                                        AND Series_No__c > 0
                                                        AND Invalid_Flag__c = false
                                                        FOR Update 
                                                        ];

        newSequenceList.addAll(applysequenceList);
        newSequenceList.addAll(allsequenceList);
        newSequenceList = Batch_QueueAllDetail.getSortSequenceList(newSequenceList);
        update newSequenceList;

    }

    public void finish(Database.BatchableContext bc) {
        if (Test.isRunningTest()) {
            testCheck();
        }
    }

    public static List<Rental_Apply_Equipment_Set_Detail__c> getSortDetailList(List<Rental_Apply_Equipment_Set_Detail__c> details){
        Map<String,List<Rental_Apply_Equipment_Set_Detail__c>> queueMap = new Map<String,List<Rental_Apply_Equipment_Set_Detail__c>>();
        for(Rental_Apply_Equipment_Set_Detail__c detail:details){
            if(!queueMap.containsKey(detail.Externalkey__c)){
                queueMap.put(detail.Externalkey__c,new List<Rental_Apply_Equipment_Set_Detail__c>());
            }
            queueMap.get(detail.Externalkey__c).add(detail);
        }
        List<Rental_Apply_Equipment_Set_Detail__c> queueList = new List<Rental_Apply_Equipment_Set_Detail__c>();
        for(String key:queueMap.keySet()){
            Map<Integer,Rental_Apply_Equipment_Set_Detail__c> detailMap = new Map<Integer,Rental_Apply_Equipment_Set_Detail__c>();
            List<Decimal> adjustIndex = new List<Decimal>();
            List<Rental_Apply_Equipment_Set_Detail__c> queues = queueMap.get(key);
            List<SetDetailWrapper> wrapperList = new List<SetDetailWrapper>();
            for(Rental_Apply_Equipment_Set_Detail__c detail:queues){
                wrapperList.add(new SetDetailWrapper(detail));
            }
            wrapperList.sort();

            // 备品智能化项目对应 20231122 by lc Start
            // 已经按照不存在OPD调整顺序Flag的规则重新调整了，此时需要看OPD调整顺序Flag的数据是否存在，存在的话需要单独调整。
            // 因之前业务沟通，OPD调整顺序Flag的数据都是向上调整，则OPD调整顺序Flag的数据直接放置在临近的OPD排队No附近；
            //     放置在临近的OPD排队No上面的话，则继续向上比较使用目的2的优先级别
            //     放置在临近的OPD排队No下面的话，则继续向下比较使用目的2的优先级别
            List<Rental_Apply_Equipment_Set_Detail__c> raesdOrderNumWithoutFlagList = new List<Rental_Apply_Equipment_Set_Detail__c>();
            List<Rental_Apply_Equipment_Set_Detail__c> raesdOrderNumWithFlagList = new List<Rental_Apply_Equipment_Set_Detail__c>();
            List<Rental_Apply_Equipment_Set_Detail__c> finalList = new List<Rental_Apply_Equipment_Set_Detail__c>();
            for (SetDetailWrapper wrapper:wrapperList) {
                Rental_Apply_Equipment_Set_Detail__c detail = wrapper.detail;
                // 没有调整过的OPD排队No数据
                if (detail.Rental_Apply__r.OPD_OrderNum__c!=null && !detail.Rental_Apply__r.OPD_AdjustmentOrderNum_Flag__c) {
                    raesdOrderNumWithoutFlagList.add(detail);
                }
                // 判断是否存在OPD调整顺序Flag的数据
                else if (detail.Rental_Apply__r.OPD_OrderNum__c!=null && detail.Rental_Apply__r.OPD_AdjustmentOrderNum_Flag__c) {
                    raesdOrderNumWithFlagList.add(detail);
                }

                finalList.add(detail);
            }

            // 只有当OPD调整顺序Flag数据和可以作为比较的OPD排队No的数据两者同时存在时，才需要单独调整
            if (!raesdOrderNumWithoutFlagList.isEmpty() && !raesdOrderNumWithFlagList.isEmpty()) {
                for (Rental_Apply_Equipment_Set_Detail__c compareObj : raesdOrderNumWithFlagList) {
                    for (Integer iTemp = 0; iTemp < finalList.size(); iTemp++) {
                        Rental_Apply_Equipment_Set_Detail__c compareToObj = finalList[iTemp];
                        if (compareToObj.Rental_Apply__r.OPD_OrderNum__c != null 
                            && compareToObj.Rental_Apply__r.OPD_OrderNum__c > compareObj.Rental_Apply__r.OPD_OrderNum__c) {
                            // 比较到要前移的位置时，需要把数据插进去
                            compareObj.Queue_Number__c = -1;
                            finalList.add(iTemp, compareObj);
                            break;
                        }
                    }
                }

                Map<Id, Rental_Apply_Equipment_Set_Detail__c> noDuplicateMap = new Map<Id, Rental_Apply_Equipment_Set_Detail__c>();
                // 上面的比较处理只是数据插入，所以存在重复数据，需要把重复数据中靠后的冗余给去除掉
                for (Rental_Apply_Equipment_Set_Detail__c compareToObj : finalList) {
                    if (noDuplicateMap.isEmpty() || !noDuplicateMap.containsKey(compareToObj.Id)) {
                        noDuplicateMap.put(compareToObj.Id, compareToObj);
                    }
                }

                finalList = noDuplicateMap.values();
                System.debug('finalList==========================' + finalList);
            }
            // 备品智能化项目对应 20231122 by lc End

            Integer i = 1;
            Integer j = 0;
            for(Rental_Apply_Equipment_Set_Detail__c detail:finalList){
                if(detail.IsAdjust__c){
                    adjustIndex.add(detail.Queue_Number__c);
                    detailMap.put(j,detail);
                    j ++;
                    // continue;
                }else{
                    if(adjustIndex.size() > 0){
                        Decimal index = adjustIndex.get(0);
                        System.debug(LoggingLevel.INFO, '*** index: ' + index);
                        System.debug(LoggingLevel.INFO, '*** detail.Queue_Number__c000 : ' + detail.Queue_Number__c );
                        if(i < index){
                            if(detail.Queue_Number__c == -1){
                                index = index + 1;
                                adjustIndex.set(0,index);
                            }
                            Rental_Apply_Equipment_Set_Detail__c ajust1 = null;
                            for(Integer idx1: detailMap.keySet()){
                                ajust1 = detailMap.get(idx1);
                                if(ajust1 != null){
                                    if(ajust1.Queue_Number__c < detail.Queue_Number__c){
                                        ajust1.Queue_Number__c = i;
                                        queueList.add(ajust1);
                                        detailMap.remove(idx1);
                                        adjustIndex.remove(0);
                                        i ++;
                                    }else{
                                        break;
                                    }
                                }
                            }
                            if(detail.Queue_Number__c != i ){
                                detail.Queue_Number__c = i;
                                queueList.add(detail);
                            }
                            i ++;
                        }else if(i == index){
                            System.debug(LoggingLevel.INFO, '**000* i: ' + i);
                            i ++;
                            Integer idx = new List<Integer> (detailMap.keySet()).get(0);
                            Rental_Apply_Equipment_Set_Detail__c ajust = detailMap.get(idx);
                            if(ajust.Queue_Number__c != index){
                                ajust.Queue_Number__c = index;
                                queueList.add(ajust);
                            }
                            
                            detailMap.remove(idx);
                            adjustIndex.remove(0);
                            Rental_Apply_Equipment_Set_Detail__c ajust1 = null;
                            Integer k = 1;
                            for(Integer idx1: detailMap.keySet()){
                                ajust1 = detailMap.get(idx1);
                                if(ajust1 != null){
                                    if(ajust1.Queue_Number__c == index + k){
                                        detailMap.remove(idx1);
                                        adjustIndex.remove(0);
                                        i ++;
                                        k ++;
                                    }else{
                                        break;
                                    }
                                }
                            }
                            if(adjustIndex.size() > 0){
                                for(Integer idx1: detailMap.keySet()){
                                    ajust1 = detailMap.get(idx1);
                                    if(ajust1 != null){
                                        if(ajust1.Queue_Number__c < detail.Queue_Number__c){
                                            ajust1.Queue_Number__c = i;
                                            queueList.add(ajust1);
                                            detailMap.remove(idx1);
                                            adjustIndex.remove(0);
                                            i ++;
                                        }else{
                                            break;
                                        }
                                    }
                                }
                                if(detail.Queue_Number__c != i ){
                                    detail.Queue_Number__c = i;
                                    queueList.add(detail);
                                }
                                i ++;
                            }else{
                                if(detail.Queue_Number__c != i ){
                                    detail.Queue_Number__c = i;
                                    queueList.add(detail);
                                }
                                i ++;
                            }
                        }
                    }else{
                        if(detail.Queue_Number__c != i ){
                            detail.Queue_Number__c = i;
                            queueList.add(detail);
                        }
                        i ++;
                    }
                }
            }
            if(detailMap.keySet().size() > 0){
                Integer idx = new List<Integer> (detailMap.keySet()).get(0);
                Rental_Apply_Equipment_Set_Detail__c ajust = detailMap.get(idx);
                if(ajust.Queue_Number__c != i){
                    ajust.Queue_Number__c = i;
                    queueList.add(ajust);
                }
            }
        }

        return queueList;
    }

    public static List<Rental_Apply_Sequence__c> getSortSequenceList(List<Rental_Apply_Sequence__c> sequenceList){
        Map<String,List<Rental_Apply_Sequence__c>> sequenceMap = new Map<String,List<Rental_Apply_Sequence__c>>();
        for(Rental_Apply_Sequence__c se:sequenceList){
            if(!sequenceMap.containsKey(se.Externalkey__c)){
                sequenceMap.put(se.Externalkey__c,new List<Rental_Apply_Sequence__c>());
            }
            sequenceMap.get(se.Externalkey__c).add(se);
        }
        List<Rental_Apply_Sequence__c> sortSequenceList = new List<Rental_Apply_Sequence__c>();
        for(String key:sequenceMap.keySet()){
            List<Rental_Apply_Sequence__c> sequences = sequenceMap.get(key);
            if(isSinglekey(sequences)){
                System.debug(LoggingLevel.INFO, '*** sequences: ' + JSON.serialize(sequences));
                for(Rental_Apply_Sequence__c se:sequences){
                    if(se.Series_No__c != se.Apply_Set_Detail__r.Queue_Number__c){
                        se.Series_No__c = se.Apply_Set_Detail__r.Queue_Number__c;
                        sortSequenceList.add(se);
                    }
                }
            }else{
                List<SequenceWrapper> wrapperList = new List<SequenceWrapper>();
                for(Rental_Apply_Sequence__c se:sequences){
                    wrapperList.add(new SequenceWrapper(se));
                }
                wrapperList.sort();
                Integer i = 1;
                for(SequenceWrapper wrapper:wrapperList){
                    Rental_Apply_Sequence__c se = wrapper.sequence;
                    if(se.Series_No__c != i){
                        se.Series_No__c = i;
                        System.debug(LoggingLevel.INFO, '*** se: ' + se);
                        sortSequenceList.add(se);
                    }
                    i ++;

                }
            }
            
        }
        return sortSequenceList;
    }

    public static Boolean isSinglekey(List<Rental_Apply_Sequence__c> sequenceList){
        String externalKey = sequenceList[0].Apply_Set_Detail_ExternalKey__c;
        for(Rental_Apply_Sequence__c sequeuece:sequenceList){
            if(externalKey != sequeuece.Apply_Set_Detail_ExternalKey__c){
                return false;
            }
        }
        return true;
    }

    /**
    * 排队队列对象排序
    */
    global class SetDetailWrapper implements Comparable {

        public Rental_Apply_Equipment_Set_Detail__c detail;
        Map<String,Decimal> equipmentMap = new Map<String,Decimal>{
            '一般维修' => 1,
            '保修合同' => 2,
            '产品试用' => 3,
            '学会展会' => 4,
            '协议借用' => 5
        };
        Map<String,Decimal> purposeMap1 = new Map<String,Decimal>{
            '保修用户A' => 1,
            '索赔QIS' => 2,
            '市场多年保修' => 3,
            '保修用户' => 4,
            '再修理' => 5,
            '一般用户' => 6,
            '故障排查' =>7,
            '学会展会' => 8,
            '其他' => 9
        };

        Map<String,Decimal> purposeMap2 = new Map<String,Decimal>{
            '保修用户A' => 1,
            '索赔QIS' => 2,
            '市场多年保修' => 3,
            '保修用户' => 4,
            '其他' => 5
        };
        // 备品智能化项目对应 20231122 by lc Start
        Map<String,Decimal> purposeMap3 = new Map<String,Decimal>{
            '学会展会' => 1,
            '已购待货' => 2,
            '新产品评价' => 2,
            '试用（有询价）' => 3,
            '试用（无询价）' => 3,
            '其他' => 4,
            '无' => 9
        };
        /*Map<String,Decimal> purposeMap3 = new Map<String,Decimal>{
            '学会展会' => 1,
            '试用（有询价）' => 2,
            '试用（无询价）' => 2,
            '已购待货' => 2,
            '新产品评价' => 2,
            '其他' => 3,
            '无' => 9
        };*/
        // 备品智能化项目对应 20231122 by lc End
        Map<String,Decimal> purposeMap4 = new Map<String,Decimal>{
            '学会展会' => 1,
            '其他' => 2,
            '无' => 9
        };
        Map<String,Decimal> purposeMap5 = new Map<String,Decimal>{
            '学会展会' => 1,
            '协议借用' => 2,
            '其他' => 3,
            '无' => 9
        };
        Map<String,Map<String,Decimal>> purposeAllMap = new Map<String,Map<String,Decimal>>{
            '维修代用（一般维修）' => purposeMap1,
            '维修代用（保修合同）' => purposeMap2,
            '产品试用' => purposeMap3,
            '学会展会' => purposeMap4,
            '协议借用' => purposeMap5
        };
        
        // Constructor
        public SetDetailWrapper(Rental_Apply_Equipment_Set_Detail__c setdetail) {
            detail = setdetail;
        }
        
        // Compare opportunities based on the opportunity amount.
        global Integer compareTo(Object compareTo) {
            // Cast argument to SetDetailWrapper
            SetDetailWrapper compareToDetail = (SetDetailWrapper)compareTo;
            
            // The return value of 0 indicates that both elements are equal.
            Integer returnValue = 0;
            if(detail.IsAdjust__c && !compareToDetail.detail.IsAdjust__c){
                returnValue = -1;
            }else if(!detail.IsAdjust__c && compareToDetail.detail.IsAdjust__c){
                returnValue = 1;
            }else if(detail.IsAdjust__c && compareToDetail.detail.IsAdjust__c){
                if(detail.Queue_Number__c < compareToDetail.detail.Queue_Number__c){
                    returnValue = -1;
                }else if(detail.Queue_Number__c > compareToDetail.detail.Queue_Number__c){
                    returnValue = 1;
                }
            }else{
                // 备品智能化项目对应 20231122 by lc Start
                // 上月未处理完的优先处理
                if(detail.Rental_Apply__r.Last_Month_Untreated__c && !compareToDetail.detail.Rental_Apply__r.Last_Month_Untreated__c){
                    returnValue = -1;
                }else if(!detail.Rental_Apply__r.Last_Month_Untreated__c && compareToDetail.detail.Rental_Apply__r.Last_Month_Untreated__c){
                    returnValue = 1;
                }else{
                // 备品智能化项目对应 20231122 by lc End
                    Decimal purposeindex = 0;
                    Decimal comparePurposeIndex = 0;
                    System.debug(LoggingLevel.INFO, '*** detail.Equipment_Type__c: ' + detail.Equipment_Type_text__c);
                    String typeKey = '';
                    if(detail.Equipment_Type_text__c.contains(',')){
                        typeKey = detail.Equipment_Type_text__c.split(',')[0];
                    }else{
                        typeKey = detail.Equipment_Type_text__c;
                    }
                    System.debug(LoggingLevel.INFO, '*** typeKey: ' + typeKey);// 20240101 ljh add
                    Map<String,Decimal> purposeMap = purposeAllMap.get(typeKey);
                    System.debug(LoggingLevel.INFO, '*** purposeMap: ' + purposeMap);
                    String purpose = (detail.Rental_Apply__r.demo_purpose2__c.contains('保修用户') && detail.Rental_Apply__r.EquipmentGuaranteeFlg__c)?'保修用户A':detail.Rental_Apply__r.demo_purpose2__c;
                    System.debug(LoggingLevel.INFO, '*** purpose: ' + purpose);
                    String comparePurpose = (compareToDetail.detail.Rental_Apply__r.demo_purpose2__c.contains('保修用户') && compareToDetail.detail.Rental_Apply__r.EquipmentGuaranteeFlg__c)?'保修用户A':compareToDetail.detail.Rental_Apply__r.demo_purpose2__c;
                    System.debug(LoggingLevel.INFO, '*** comparePurpose: ' + comparePurpose);
                    System.debug(LoggingLevel.INFO, '*** purposeMap.containskey(purpose): ' + purposeMap.containskey(purpose));
                    
                    if(purposeMap.containskey(purpose)){
                        purposeindex = purposeMap.get(purpose);
                    }else{
                        purposeindex = purposeMap.get('无');
                    }
                    System.debug(LoggingLevel.INFO, '*** purposeMap.containskey(comparePurpose): ' + purposeMap.containskey(comparePurpose));
                    
                    if(purposeMap.containskey(comparePurpose)){
                        comparePurposeIndex = purposeMap.get(comparePurpose);
                    }else{
                        comparePurposeIndex = purposeMap.get('无');
                    }

                    // 先不论OPD调整顺序Flag有没有，都按照使用目的2来比较先后顺序，之后按照OPD调整后No来确定排队No来整体排序，后面再查找OPD调整顺序Flag的数据单独调整
                    if(purposeindex > comparePurposeIndex){
                        returnValue = 1;
                    }else if(purposeindex < comparePurposeIndex){
                        returnValue = -1;
                    }else if(purposeindex == comparePurposeIndex){
                        // 备品智能化项目对应 20231122 by lc Start
                        // 先确定是否是空，是空的话，为了后续比较方便，设置为10000，每个月的OPD排序不可能超过有那么多
                        Integer detailOrderNum = detail.Rental_Apply__r.OPD_OrderNum__c!=null?Integer.valueOf(detail.Rental_Apply__r.OPD_OrderNum__c):10000;
                        Integer compareToDetailOrderNum = compareToDetail.detail.Rental_Apply__r.OPD_OrderNum__c!=null?Integer.valueOf(compareToDetail.detail.Rental_Apply__r.OPD_OrderNum__c):10000;
                        // 先比较OPD排序No，后再根据使用目的的不同来比较时间
                        if (detailOrderNum < compareToDetailOrderNum) {
                            returnValue = -1;
                        } else if (detailOrderNum > compareToDetailOrderNum) {
                            returnValue = 1;
                        } else {
                        // 备品智能化项目对应 20231122 by lc End
                            if(purpose.contains('学会展会')){
                                if(detail.Rental_Apply__r.Request_shipping_day__c < compareToDetail.detail.Rental_Apply__r.Request_shipping_day__c){
                                    returnValue = -1;
                                }else if(detail.Rental_Apply__r.Request_shipping_day__c > compareToDetail.detail.Rental_Apply__r.Request_shipping_day__c){
                                    returnValue = 1;
                                }else if(detail.Rental_Apply__r.Request_shipping_day__c == compareToDetail.detail.Rental_Apply__r.Request_shipping_day__c){
                                    if(detail.Rental_Apply__r.Request_approval_time__c < compareToDetail.detail.Rental_Apply__r.Request_approval_time__c){
                                        returnValue = -1;
                                    }else if(detail.Rental_Apply__r.Request_approval_time__c > compareToDetail.detail.Rental_Apply__r.Request_approval_time__c){
                                        returnValue = 1;
                                    }
                                    // 20220105 ljh add start
                                    else if(detail.Rental_Apply__r.Request_approval_time__c == compareToDetail.detail.Rental_Apply__r.Request_approval_time__c){
                                        DateTime queueDt = DateTime.newInstance(detail.Queue_Day__c, detail.Queue_Time__c);
                                        DateTime compareQueueDt = DateTime.newInstance(compareToDetail.detail.Queue_Day__c, compareToDetail.detail.Queue_Time__c);
                                
                                        if(queueDt < compareQueueDt){
                                            returnValue = -1;
                                        }else if(queueDt > compareQueueDt){
                                            returnValue = 1;
                                        }else if(queueDt == compareQueueDt){
                                            if(detail.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c < compareToDetail.detail.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c){
                                                returnValue = -1;
                                            }else if(detail.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c > compareToDetail.detail.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c){
                                                returnValue = 1;
                                            }
                                        }
                                    }
                                    // 20220105 ljh add end
                                }
                            }else{
                                // 备品智能化项目对应 20231122 by lc Start
                                // 批准时间(申请提交) + 排队时间
                                if(detail.Rental_Apply__r.Request_approval_time__c < compareToDetail.detail.Rental_Apply__r.Request_approval_time__c){
                                    returnValue = -1;
                                }else if(detail.Rental_Apply__r.Request_approval_time__c > compareToDetail.detail.Rental_Apply__r.Request_approval_time__c){
                                    returnValue = 1;
                                }else if(detail.Rental_Apply__r.Request_approval_time__c == compareToDetail.detail.Rental_Apply__r.Request_approval_time__c){
                                    DateTime queueDt = DateTime.newInstance(detail.Queue_Day__c, detail.Queue_Time__c);
                                    DateTime compareQueueDt = DateTime.newInstance(compareToDetail.detail.Queue_Day__c, compareToDetail.detail.Queue_Time__c);
                                    if(queueDt > compareQueueDt){
                                        returnValue = 1;
                                    }else if(queueDt < compareQueueDt){
                                        returnValue = -1;
                                    }else if(queueDt == compareQueueDt){
                                        if(detail.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c < compareToDetail.detail.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c){
                                            returnValue = -1;
                                        }else if(detail.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c > compareToDetail.detail.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c){
                                            returnValue = 1;
                                        }
                                    }
                                }
                                // 备品智能化项目对应 20231122 by lc End
                            }
                        }
                    }
                }
            }
            
            return returnValue;
        }
    }

    /**
    * 排队序列对象排序
    */
    global class SequenceWrapper implements Comparable {

        public Rental_Apply_Sequence__c sequence;
        Map<String,Decimal> equipmentMap = new Map<String,Decimal>{
            '一般维修' => 1,
            '保修合同' => 2,
            '产品试用' => 3,
            '学会展会' => 4,
            '协议借用' => 5
        };
        Map<String,Decimal> purposeMap1 = new Map<String,Decimal>{
            '保修用户A' => 1,
            '索赔QIS' => 2,
            '市场多年保修' => 3,
            '保修用户' => 4,
            '再修理' => 5,
            '一般用户' => 6,
            '故障排查' =>7,
            '学会展会' => 8,
            '其他' => 9
        };

        Map<String,Decimal> purposeMap2 = new Map<String,Decimal>{
            '保修用户A' => 1,
            '索赔QIS' => 2,
            '市场多年保修' => 3,
            '保修用户' => 4,
            '其他' => 5
        };
        // 备品智能化项目对应 20231122 by lc Start
        Map<String,Decimal> purposeMap3 = new Map<String,Decimal>{
            '学会展会' => 1,
            '已购待货' => 2,
            '新产品评价' => 2,
            '试用（有询价）' => 3,
            '试用（无询价）' => 3,
            '其他' => 4,
            '无' => 9
        };
        /*Map<String,Decimal> purposeMap3 = new Map<String,Decimal>{
            '学会展会' => 1,
            '试用（有询价）' => 2,
            '试用（无询价）' => 2,
            '已购待货' => 2,
            '新产品评价' => 2,
            '其他' => 3,
            '无' => 9
        };*/
        // 备品智能化项目对应 20231122 by lc End
        Map<String,Decimal> purposeMap4 = new Map<String,Decimal>{
            '学会展会' => 1,
            '其他' => 2,
            '无' => 9
        };
        Map<String,Decimal> purposeMap5 = new Map<String,Decimal>{
            '学会展会' => 1,
            '协议借用' => 2,
            '其他' => 3,
            '无' => 9
        };
        Map<String,Map<String,Decimal>> purposeAllMap = new Map<String,Map<String,Decimal>>{
            '维修代用（一般维修）' => purposeMap1,
            '维修代用（保修合同）' => purposeMap2,
            '产品试用' => purposeMap3,
            '学会展会' => purposeMap4,
            '协议借用' => purposeMap5
        };

        
        // Constructor
        public SequenceWrapper(Rental_Apply_Sequence__c applySequence) {
            sequence = applySequence;
        }
        
        // Compare opportunities based on the opportunity amount.
        global Integer compareTo(Object compareTo) {
            // Cast argument to SequenceWrapper
            SequenceWrapper compareTosequence = (SequenceWrapper)compareTo;
            System.debug(LoggingLevel.INFO, '*** sequence.Apply_Set_Detail__r.Queue_Day__c: ' + sequence.Apply_Set_Detail__r.Queue_Day__c);
            // The return value of 0 indicates that both elements are equal.
            Integer returnValue = 0;

            // 备品智能化项目对应 20231122 by lc Start
            // 上月未处理完的优先处理
            if(sequence.Rental_Apply__r.Last_Month_Untreated__c && !compareTosequence.sequence.Rental_Apply__r.Last_Month_Untreated__c){
                returnValue = -1;
            }else if(!sequence.Rental_Apply__r.Last_Month_Untreated__c && compareTosequence.sequence.Rental_Apply__r.Last_Month_Untreated__c){
                returnValue = 1;
            }else{
            // 备品智能化项目对应 20231122 by lc End
                Decimal purposeindex = 0;
                Decimal comparePurposeIndex = 0;
                Map<String,Decimal> purposeMap = purposeAllMap.get(sequence.Equipment_Type__c);
                String purpose = (sequence.Demo_Purpose2__c.contains('保修用户') && sequence.Rental_Apply__r.EquipmentGuaranteeFlg__c)?'保修用户A':sequence.Demo_Purpose2__c;
                String comparePurpose = (compareTosequence.sequence.Demo_Purpose2__c.contains('保修用户') && compareTosequence.sequence.Rental_Apply__r.EquipmentGuaranteeFlg__c)?'保修用户A':compareTosequence.sequence.Demo_Purpose2__c;
                System.debug(LoggingLevel.INFO, '*** purposeMap.containskey(purpose): ' + purposeMap.containskey(purpose));

                if(purposeMap.containskey(purpose)){
                    purposeindex = purposeMap.get(purpose);
                }else{
                    purposeindex = purposeMap.get('无');
                }
                System.debug(LoggingLevel.INFO, '*** purposeMap.containskey(comparePurpose): ' + purposeMap.containskey(comparePurpose));
                
                if(purposeMap.containskey(comparePurpose)){
                    comparePurposeIndex = purposeMap.get(comparePurpose);
                }else{
                    comparePurposeIndex = purposeMap.get('无');
                }

                if(purposeindex > comparePurposeIndex){
                    returnValue = 1;
                }else if(purposeindex < comparePurposeIndex){
                    returnValue = -1;
                }else if(purposeindex == comparePurposeIndex){
                    // 备品智能化项目对应 20231122 by lc Start
                    // 先确定是否是空，是空的话，为了后续比较方便，设置为10000，每个月的OPD排序不可能超过有那么多
                    Integer sequenceOrderNum = sequence.Rental_Apply__r.OPD_OrderNum__c!=null?Integer.valueOf(sequence.Rental_Apply__r.OPD_OrderNum__c):10000;
                    Integer compareTosequenceOrderNum = compareTosequence.sequence.Rental_Apply__r.OPD_OrderNum__c!=null?Integer.valueOf(compareTosequence.sequence.Rental_Apply__r.OPD_OrderNum__c):10000;
                    // 先比较OPD排序No，后再根据使用目的的不同来比较时间
                    if (sequenceOrderNum < compareTosequenceOrderNum) {
                        returnValue = -1;
                    } else if (sequenceOrderNum > compareTosequenceOrderNum) {
                        returnValue = 1;
                    } else {
                    // 备品智能化项目对应 20231122 by lc End
                        if(purpose.contains('学会展会')){
                            //希望到货日+批准时间（申请提交）+按排队时间+No
                            if(sequence.Rental_Apply__r.Request_shipping_day__c < compareTosequence.sequence.Rental_Apply__r.Request_shipping_day__c){
                                returnValue = -1;
                            }else if(sequence.Rental_Apply__r.Request_shipping_day__c > compareTosequence.sequence.Rental_Apply__r.Request_shipping_day__c){
                                returnValue = 1;
                            }else if(sequence.Rental_Apply__r.Request_shipping_day__c == compareTosequence.sequence.Rental_Apply__r.Request_shipping_day__c){
                                if(sequence.Rental_Apply__r.Request_approval_time__c < compareTosequence.sequence.Rental_Apply__r.Request_approval_time__c){
                                    returnValue = -1;
                                }else if(sequence.Rental_Apply__r.Request_approval_time__c > compareTosequence.sequence.Rental_Apply__r.Request_approval_time__c){
                                    returnValue = 1;
                                }
                                // 20220105 ljh add start
                                else if(sequence.Rental_Apply__r.Request_approval_time__c == compareTosequence.sequence.Rental_Apply__r.Request_approval_time__c){
                                    DateTime queueDt = DateTime.newInstance(sequence.Apply_Set_Detail__r.Queue_Day__c, sequence.Apply_Set_Detail__r.Queue_Time__c);
                                    DateTime compareQueueDt = DateTime.newInstance(compareTosequence.sequence.Apply_Set_Detail__r.Queue_Day__c, compareTosequence.sequence.Apply_Set_Detail__r.Queue_Time__c);
                                    
                                    if(queueDt > compareQueueDt){
                                        returnValue = 1;
                                    }else if(queueDt < compareQueueDt){
                                        returnValue = -1;
                                    }else if(queueDt == compareQueueDt){
                                        if(sequence.Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c < compareTosequence.sequence.Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c){
                                            returnValue = -1;
                                        }else if(sequence.Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c > compareTosequence.sequence.Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c){
                                            returnValue = 1;
                                        }
                                    }
                                }
                                // 20220105 ljh add end
                            }
                        }else{
                            // 备品智能化项目对应 20231122 by lc Start
                            //批准时间（申请提交）+按排队时间
                            if(sequence.Rental_Apply__r.Request_approval_time__c < compareTosequence.sequence.Rental_Apply__r.Request_approval_time__c){
                                returnValue = -1;
                            }else if(sequence.Rental_Apply__r.Request_approval_time__c > compareTosequence.sequence.Rental_Apply__r.Request_approval_time__c){
                                returnValue = 1;
                            }else if(sequence.Rental_Apply__r.Request_approval_time__c == compareTosequence.sequence.Rental_Apply__r.Request_approval_time__c){
                                DateTime queueDt = DateTime.newInstance(sequence.Apply_Set_Detail__r.Queue_Day__c, sequence.Apply_Set_Detail__r.Queue_Time__c);
                                System.debug(LoggingLevel.INFO, '*** queueDt: ' + queueDt);
                                System.debug(LoggingLevel.INFO, '***compareTosequence.sequence.Apply_Set_Detail : ' + compareTosequence.sequence.Apply_Set_Detail__c);
                                DateTime compareQueueDt = DateTime.newInstance(compareTosequence.sequence.Apply_Set_Detail__r.Queue_Day__c, compareTosequence.sequence.Apply_Set_Detail__r.Queue_Time__c);
                                System.debug(LoggingLevel.INFO, '*** compareQueueDt: ' + compareQueueDt);
                                if(queueDt > compareQueueDt){
                                    returnValue = 1;
                                }else if(queueDt < compareQueueDt){
                                    returnValue = -1;
                                }else if(queueDt == compareQueueDt){
                                    if(sequence.Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c < compareTosequence.sequence.Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c){
                                        returnValue = -1;
                                    }else if(sequence.Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c > compareTosequence.sequence.Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c){
                                        returnValue = 1;
                                    }
                                }
                            }
                            // 备品智能化项目对应 20231122 by lc End
                        }
                    }
                }
            }
            return returnValue;       
        }
    }
    public 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++';
                }
			}
        }
    }


}