/*2021-05-08  mzy
* 更新招标信息的询价状态和询价的数量
* 更新招标信息的5个医院
* 当医院发生变化/招投标项目OCSM省发生变化时,空更新一下招投标
*/
global class UpdateTenderInformationBatch implements Database.Batchable<sObject>, Database.Stateful {

    Boolean IsNeedExecute = false;
    String tempTenderId ='';
    Boolean IsOnlyTrue = true;
    List<String> tempTenderList = new List<String>(); 

    //邮件信息
    List<String> emailMessages = new List<String>();

    //招投标: 报错的招投标Id
    String TenderlogStr = '招标项目 : ';

    //招投标: 报错信息
    String TendererrorStr = '';

    //招投标: 总件数
    Integer TendertotalCount = 0;

    //招投标: 失败件数
    Integer TenderfailedCount = 0; 

    //执行符合条件的指定招投标项目
    global UpdateTenderInformationBatch(String tempTenderId) {
        this.tempTenderId = tempTenderId;
    }
    //执行指定招标项目里符合条件的招投标项目
    global UpdateTenderInformationBatch(List<String> tempTenderList) {
        this.tempTenderList = tempTenderList;
    }
    //处理历史数据  IsOnlyTrue = false  执行所有的招标项目
    global UpdateTenderInformationBatch(String tempOppId, Boolean IsOnlyTrue) {
        this.IsOnlyTrue = IsOnlyTrue;
    }
    //  IsOnlyTrue = false 可以手动 无条件执行多条招投标项目
    global UpdateTenderInformationBatch(String tempOppId, Boolean IsOnlyTrue,List<String> tempTenderList) {
        this.IsOnlyTrue = IsOnlyTrue;
        this.tempTenderList = tempTenderList;
    }
    
    //Batch 链 时使用
    global UpdateTenderInformationBatch(Boolean IsNeedExecute) {
        this.IsNeedExecute = IsNeedExecute;
    }

    global UpdateTenderInformationBatch() {
        
    }

    global Database.QueryLocator start(Database.BatchableContext bc) {
        String query = 'SELECT Id,IsBid__c,NotBidApprovalStatus__c,IsReactionOpp__c,Hospital__c,Hospital1__c,Hospital2__c,Hospital3__c,Hospital4__c, ';
               query += 'Hospital__r.Assume_Change__c,Hospital1__r.Assume_Change__c,Hospital2__r.Assume_Change__c,Hospital3__r.Assume_Change__c,Hospital4__r.Assume_Change__c ';
               query += 'FROM Tender_information__c ';
            if(IsOnlyTrue){               
               query += 'WHERE  ((IsReactionOpp__c = true ) '; 
               //2021-07-29 mzy  update 当医院发生变化/招投标项目OCSM省发生变化时,空更新一下招投标 start
               // 2022-04-08 ssm SWAG-CC58ME 增加所有人无效的判断 start 
               query += 'OR (Owner.IsActive = false) ';
               // 2022-04-08 ssm SWAG-CC58ME end
               query += 'OR (BiddingOCSMAdministration__c = true) OR (Hospital__r.Assume_Change__c = true) '; 
               query += 'OR (Hospital1__r.Assume_Change__c = true) OR (Hospital2__r.Assume_Change__c = true) '; 
               query += 'OR (Hospital3__r.Assume_Change__c = true) OR (Hospital4__r.Assume_Change__c = true) )'; 
               //2021-07-29  mzy update 当医院发生变化/招投标项目OCSM省发生变化时,空更新一下招投标 end
               // DepartmentChanges__c 全部换成 Assume_Change__c 
            }   
            if(String.isNotBlank(this.tempTenderId)){
                if(IsOnlyTrue){
                    query += ' AND ';
                }else {
                    query += ' Where ';
                }
               query += 'Id = :tempTenderId ';
            }
            if(tempTenderList.size()>0){
                if(IsOnlyTrue){
                    query += ' AND ';
                }else {
                    query += ' Where ';
                }

               query += ' Id In :tempTenderList ';
            }

            System.debug('sql语句：'+query);
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, list<Tender_information__c> TenderList) {
        //定义List封装需要空更新的招投标项目
        List<Tender_information__c> EmptyUpdateTenderList = new List<Tender_information__c>();
        Map<String,Tender_information__c> EmptyUpdateTenderMap = new Map<String,Tender_information__c>();
 
        //定义List封装需要更新的招标项目
        List<Tender_information__c> updateTenderList = new List<Tender_information__c>();
        //定义Map保存招投标信息 
        Map<String,Tender_information__c> tenderMap = new Map<String,Tender_information__c>();
        //定义List封装所有询价的招标项目Id
        Set<String> BiddingProjectID = new Set<String>();
        for(Tender_information__c tempTender : TenderList){
            //2021-07-29   mzy  update  当医院发生变化/招投标项目OCSM省发生变化时,空更新一下招投标  start
            if(tempTender.IsReactionOpp__c){
                //如果是  是否反应询价 为 true 则需要进行 反应询价 ,否则就空更新一下                
                BiddingProjectID.add(tempTender.Id);
                tenderMap.put( String.valueOf( tempTender.Id ).substring(0,15) ,tempTender);
            }else {
                //需要空更新的招投标
                EmptyUpdateTenderList.add(tempTender);
                EmptyUpdateTenderMap.put(String.valueOf( tempTender.Id ).substring(0,15) ,tempTender);
            }
            //2021-07-29  mzy  update  当医院发生变化/招投标项目OCSM省发生变化时,空更新一下招投标   end
        }
        //2021-07-29  mzy  update  空更新失败的话不清空医院的标识  start
        // System.debug('EmptyUpdateTenderList: ' + EmptyUpdateTenderList);
        if(EmptyUpdateTenderList.size()>0){
            //空更新招投标
            // fxk 2021/9/28 Star
            StaticParameter.EscapeOtherUpdateTenOwner = false;
            Database.SaveResult[] EmptySaveTenderResult = Database.update(EmptyUpdateTenderList,false);
            StaticParameter.EscapeOtherUpdateTenOwner = true;
            // fxk 2021/9/28 End
            //更新成功的招投标需要将医院的标识清空
            //保存更新失败的医院
            Set<String> faildHospIdSet = new Set<String>(); 
            //查看失败的医院
            for(Integer i = 0;i<EmptySaveTenderResult.size();i++){
                if(!EmptySaveTenderResult.get(i).isSuccess()){
                    String faildTenderId = String.valueOf(EmptyUpdateTenderList.get(i).id).substring(0,15);
                    Tender_information__c  faildtender = EmptyUpdateTenderMap.get(faildTenderId);

                    if(faildtender.Hospital__c != null && faildtender.Hospital__r.Assume_Change__c == true){                        
                        faildHospIdSet.add(faildtender.Hospital__c);
                    }
                    if(faildtender.Hospital1__c != null && faildtender.Hospital1__r.Assume_Change__c == true){                        
                        faildHospIdSet.add(faildtender.Hospital1__c);
                    }
                    if(faildtender.Hospital2__c != null&& faildtender.Hospital2__r.Assume_Change__c == true){                        
                        faildHospIdSet.add(faildtender.Hospital2__c);
                    }
                    if(faildtender.Hospital3__c != null&& faildtender.Hospital3__r.Assume_Change__c == true){                        
                        faildHospIdSet.add(faildtender.Hospital3__c);
                    }
                    if(faildtender.Hospital4__c != null&& faildtender.Hospital4__r.Assume_Change__c == true){                        
                       faildHospIdSet.add(faildtender.Hospital4__c);
                    }
                }
            }
            //查看需要清空标识的医院id
            Set<String> HospitalId = new Set<String>();
            //需要清空标识的医院i
            List<Account> needUpdateHPList = new  List<Account>();
            for(Integer i = 0;i<EmptySaveTenderResult.size();i++){
                String tenderId = String.valueOf(EmptyUpdateTenderList.get(i).id).substring(0,15);
                Tender_information__c  tender = EmptyUpdateTenderMap.get(tenderId);

                //如果失败的Set里没有这个医院,则清空这个医院的标识
                if(tender.Hospital__c != null && tender.Hospital__r.Assume_Change__c == true
                    && (!faildHospIdSet.contains(tender.Hospital__c)) ){  
                    HospitalId.add(tender.Hospital__c);
                }
                if(tender.Hospital1__c != null && tender.Hospital1__r.Assume_Change__c == true
                    && (!faildHospIdSet.contains(tender.Hospital1__c)) ){  
                    HospitalId.add(tender.Hospital1__c);
                }
                if(tender.Hospital2__c != null && tender.Hospital2__r.Assume_Change__c == true
                    && (!faildHospIdSet.contains(tender.Hospital2__c)) ){
                    HospitalId.add(tender.Hospital2__c); 
                }
                if(tender.Hospital3__c != null && tender.Hospital3__r.Assume_Change__c == true
                    && (!faildHospIdSet.contains(tender.Hospital3__c)) ){
                    HospitalId.add(tender.Hospital3__c);  
                }
                if(tender.Hospital4__c != null && tender.Hospital4__r.Assume_Change__c == true
                    && (!faildHospIdSet.contains(tender.Hospital4__c)) ){
                    HospitalId.add(tender.Hospital4__c);
                }
            }

            Iterator<String> HospitalIds = HospitalId.iterator();

            while(HospitalIds.hasNext()){
                Account acc = new Account();
                acc.id = HospitalIds.next();
                acc.Assume_Change__c = false;
                needUpdateHPList.add(acc);  
            }

            if(needUpdateHPList.size()>0){
                 update needUpdateHPList;
            }
        }
        //2021-07-29  mzy  update  空更新失败的话不清空医院的标识  end
  
        //2021-07-29  mzy  update   如果有需要反应询价的在走下面逻辑   start
        if(BiddingProjectID.size()> 0){

            //查询招标项目下的所有询价
            Map<String,List<Opportunity>> BiddingProjectOppMap = findTenderRelativeOpp(BiddingProjectID);

            //计算询价数量
            List<Tender_information__c> updateTenderNumList = updateOpportunityNum(BiddingProjectOppMap);

            //计算询价状态
            List<Tender_information__c> updateTenderNumStatusList = updateOpportunityStatus(BiddingProjectOppMap,updateTenderNumList,tenderMap);


            updateTenderList.addAll(updateTenderNumStatusList);

        }

        //更新招投标 询价数量和状态
        if(updateTenderList.size()>0){
            //一个招投标项目更新失败
            List<String> failedTenderList = new List<String>();
            Database.SaveResult[] saveTenderResults = Database.update(updateTenderList,false);
            //招投标项目的总数
            TendertotalCount += saveTenderResults.size();

            for(Integer i = 0;i<saveTenderResults.size();i++) {
                if(!saveTenderResults.get(i).isSuccess() ){ 
                    /*if(TenderlogStr.equals('')){
                        TenderlogStr = '' ;
                    } */                    
                    TenderlogStr += updateTenderList.get(i).id +' ,';
                    //String statusCode = String.ValueOf(saveTenderResults.get(i).getErrors()[0]).split(';')[2].split('=')[1];
                    //String errorMsg = String.ValueOf(saveTenderResults.get(i).getErrors()[0]).split(';')[1].split('=')[1];
                    TendererrorStr += '失败招标项目 :'+updateTenderList.get(i).id+'  失败原因:'+ String.ValueOf(saveTenderResults.get(i).getErrors()[0]).split(';')[2].split('=')[1] 
                    +' : '+String.ValueOf(saveTenderResults.get(i).getErrors()[0]).split(';')[1].split('=')[1] + '\r\n';
                    TenderfailedCount++ ;
                    //将更新失败的招投标项目添加掉集合中
                    failedTenderList.add(String.valueOf( updateTenderList.get(i).id ).substring(0,15));
                }
            }
            //更新成功后,清除招投标的反应询价标识
            List<Tender_information__c> successTenderList = new List<Tender_information__c>();
            for(Tender_information__c tempTender:TenderList){
                if(failedTenderList.contains( String.valueOf( tempTender.id ).substring(0,15)  )){
                    //更新失败,则不清除标识
                }else {
                    //更新成功,清除标识
                    tempTender.IsReactionOpp__c = false;
                    successTenderList.add(tempTender);
                }
            }

            //清除标识
            if(successTenderList.size()>0){
                update successTenderList;
            }
        }
        // 2021-07-29  mzy  update   如果有需要反应询价的在走下面逻辑   end
    }

    global void finish(Database.BatchableContext BC) {

        UpdateTenderInformationSchedule.assignOneHours();
        BatchIF_Log__c TenderIfLog = new BatchIF_Log__c();
        TenderIfLog.Type__c = 'UpdateTenderInformationBatchByTenderErrorLog';

        if (TenderlogStr.length() > 60000) {
            TenderlogStr = TenderlogStr.substring(0, 60000);
        }
        TenderIfLog.Log__c = TenderlogStr;
        TenderIfLog.Log__c += '\n end';
        if (TendererrorStr.length() > 60000) {
            TenderIfLog.ErrorLog__c = TendererrorStr.substring(0, 60000);
        } else {
            TenderIfLog.ErrorLog__c = TendererrorStr.substring(0, TendererrorStr.length());
        }

        insert TenderIfLog;

        emailMessages.add('失败日志ID为：' + TenderIfLog.Id + '\r\n失败信息:\r\n'+TendererrorStr);

        //发送邮件
        sendFieldEmail();

    }
    //批量更新招投标的询价信息
    @AuraEnabled
    WebService static String updateOpportunityInformation(List<String> TenderIdList){
        //存储错误信息
        String errorMessage = '';
        //目的 : 如果Batch执行失败,则整体rollback,标识不进行清除
        //定义List封装需要更新的招标项目
        List<Tender_information__c> updateTenderList = new List<Tender_information__c>();
        try{

            Set<String> BiddingProjectID = new Set<String>();
            for(String TenderId:TenderIdList){                  
                BiddingProjectID.add(TenderId);
            }
            //查询招投标信息
            List<Tender_information__c> tenderList = [SELECT Id,IsBid__c,NotBidApprovalStatus__c FROM Tender_information__c where id in :BiddingProjectID];
            Map<String,Tender_information__c> tenderMap = new Map<String,Tender_information__c>();
            for(Tender_information__c tempTender :tenderList){
                tenderMap.put( String.valueOf( tempTender.Id ).substring(0,15) ,tempTender);
            }

            //查询招标项目下的所有询价
            Map<String,List<Opportunity>> BiddingProjectOppMap = findTenderRelativeOpp(BiddingProjectID);

            //计算询价数量
            List<Tender_information__c> updateTenderNumList = updateOpportunityNum(BiddingProjectOppMap);

            //计算询价状态
            List<Tender_information__c> updateTenderNumStatusList = updateOpportunityStatus(BiddingProjectOppMap,updateTenderNumList,tenderMap);

            updateTenderList.addAll(updateTenderNumStatusList);

            //更新
            if(updateTenderList.size()>0){
                List<String> failedTenderList = new List<String>();
                // add 只有空更新招投标的时候走招投标触发器 fxk 2021/9/28 Star
                StaticParameter.EscapeOtherUpdateTenOwner = false;     
                Database.SaveResult[] saveTenderResults = Database.update(updateTenderList,false);
                StaticParameter.EscapeOtherUpdateTenOwner = true; 
                // add 只有空更新招投标的时候走招投标触发器 fxk 2021/9/28 End

                for(Integer i = 0;i<saveTenderResults.size();i++) {
                    if(!saveTenderResults.get(i).isSuccess()){ 
                        //String statusCode = String.ValueOf(saveTenderResults.get(i).getErrors()[0]).split(';')[2].split('=')[1];
                        //String errorMsg = String.ValueOf(saveTenderResults.get(i).getErrors()[0]).split(';')[1].split('=')[1];
                        errorMessage += '失败招标项目 :'+updateTenderList.get(i).id+'  失败原因:'
                        + String.ValueOf(saveTenderResults.get(i).getErrors()[0]).split(';')[2].split('=')[1] 
                        +' : '+String.ValueOf(saveTenderResults.get(i).getErrors()[0]).split(';')[1].split('=')[1] + '\r\n';
                        //将更新失败的招投标项目添加掉集合中
                        failedTenderList.add(String.valueOf( updateTenderList.get(i).id ).substring(0,15));
                    }
                }

                //更新成功后,清除招投标的反应询价标识
                List<Tender_information__c> successTenderList = new List<Tender_information__c>();
                for(String tempTenderId:TenderIdList){
                    if(failedTenderList.contains( String.valueOf( tempTenderId ).substring(0,15)  )){
                        //更新失败,则不清除标识
                    }else {
                        //更新成功,清除标识
                        Tender_information__c tempTender = new Tender_information__c();
                        tempTender.Id = String.valueOf( tempTenderId ).substring(0,15);
                        tempTender.IsReactionOpp__c = false;
                        successTenderList.add(tempTender);
                    }
                }

                //清除标识
                if(successTenderList.size()>0){
                    update successTenderList;
                }

            }
            //询价流程改善 fy start
            System.debug('batch2开始');
            Id execBTId = Database.executeBatch(new UpdateTenderInformationBatch2(TenderIdList),100);
            System.debug('batch2结束');
            //询价流程改善 fy end

        }catch(NullPointerException ex){         
            system.debug('aa1:'+ex.getMessage());
            return '空指针 :'+ex.getLineNumber();
        }catch(Exception ex2){          
            system.debug('aa2:'+ex2.getMessage());
            return '出错了!'+ex2.getMessage();
        }

        if(String.isNotBlank(errorMessage)){
            return errorMessage;
        }

        system.debug('aa');
        return 'OK';

    }



    //0.计算询价数量
    public static List<Tender_information__c> updateOpportunityNum(Map<String,List<Opportunity>> tempMap){       
        // 招标-询价关联修改 获取招标信息修改 20210817 start
        // List<Tender_information__c> updateTenderNumList = new List<Tender_information__c>();
        // //遍历Map的key
        // for(String k : tempMap.keySet()){
        //     Tender_information__c tempTender = new Tender_information__c();
        //     tempTender.id = k;
        //     String fifteenId = String.valueOf(tempTender.Id).subString(0,15);
        //     tempTender.OpportunityNum__c = tempMap.get(fifteenId).size();
        //     updateTenderNumList.add(tempTender);
        // }
        List<String> tenders = new List<String>();
        //遍历Map的key
        for(String k : tempMap.keySet()){
            tenders.add(k);
        }
        // 获得招标数据 把从询价里查询的招标字段挪到这里
        List<Tender_information__c> updateTenderNumList = [SELECT Id, Hospital__c, Hospital1__c, 
        Hospital2__c, Hospital3__c, Hospital4__c, OwnerId, IsRelateProject__c, IsBid__c, department__c, 
        subDepartment1__c, subDepartment2__c, subDepartment3__c, subDepartment4__c, NotBidApprovalStatus__c, 
        OpportunityNum__c, OpportunityStatus__c
        //20221010  lt SWAG-CHL5XA【FY23询价改善】-统计主机台数 start
        ,OlyNumberHosts__c, RivalHostsNumber__c, TotalNumberHosts__c
        //20221010  lt SWAG-CHL5XA【FY23询价改善】-统计主机台数 end
        FROM Tender_information__c WHERE Id IN :tenders];
        // 招标-询价关联修改 20210817 end

        return updateTenderNumList;
    }


    //1.计算询价状态
    //2.赋值医院
    //3.赋值战略科室
    //  1)  如果招投标项目的关联医院为空，那么就更新为询价的医院;
    //  2)  如果招投标项目的关联主战略科室为空，那么就更新为询价创建时间最早的询价的战略科室；
    //  3)  如果招投标项目的关联副战略科室为空，那么就更新为排名优先级高的战略科室之外的其他询价的战略科室，也是以创建时间更早为先后顺序；
    //  4） 如果更新满了，多的战略科室就不更新；
    public static List<Tender_information__c> updateOpportunityStatus(Map<String,List<Opportunity>> BiddingProjectOppMap,List<Tender_information__c> updateTenderNumList,Map<String,Tender_information__c> tenderMap){
        //询价状态
        //定义List封装需要更新的招标项目
        List<Tender_information__c> updateTenderList = new List<Tender_information__c>();

        //遍历Map的key
        for(Tender_information__c tempTender : updateTenderNumList){

            String fifteenId = String.valueOf(tempTender.Id).subString(0,15);
            //获取当前招投标下的询价
            List<Opportunity> BiddingDownOppList= BiddingProjectOppMap.get(fifteenId) == null ? new List<Opportunity>() : BiddingProjectOppMap.get(fifteenId);

            //获取当前招投标下的询价的医院
            List<String> OppHospitalList = new List<String>();

            //判断状态
            if(BiddingDownOppList.size() > 0){
                //<!----  所有人 ---->
                //2021-08-09  mzy  如果招标的ownerid是奥林巴斯系统用户 就把询价的所有人写上去
                // 20210817 是不是应该直接判断tender上的？
                // if(BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.OwnerId == '00510000000gmxH'){
                if(tempTender.OwnerId == System.label.tender_3){
                    tempTender.OwnerId = BiddingDownOppList.get(0).ownerId;
                }
                //2021-08-09  mzy  如果招标的ownerid是奥林巴斯系统用户 就把询价的所有人写上去
                //<!----  所有人 ---->
                //<!---- 询价状态 start --->
                //<!--询价状态-->
                //WIN num
                Integer WinNum = 0;
                //失单 num
                Integer SHDNum = 0;
                //XLIU-CG98L5【委托】【评估】新需求-招标项目/询价对应流标、废标改善 fy start
                //取消 num
                Integer QuxNum = 0;
                //XLIU-CG98L5【委托】【评估】新需求-招标项目/询价对应流标、废标改善 fy end
                //中标 2022-6-29 yjk
                Integer bidNum = 0;
                //对手中标 2022-6-29 yjk
                Integer loseNum = 0;

                //20221010  lt SWAG-CHL5XA【FY23询价改善】-统计主机台数 start
                tempTender.OlyNumberHosts__c = 0;
                tempTender.RivalHostsNumber__c = 0;
                tempTender.TotalNumberHosts__c = 0;

                Decimal OlyNum = 0;
                Decimal RivalNum = 0;
                Decimal TotalNum = 0;
                //20221010  lt SWAG-CHL5XA【FY23询价改善】-统计主机台数 end

                //获取当前key的List
                for(Opportunity tempOp :BiddingDownOppList){

                    //20221010  lt SWAG-CHL5XA【FY23询价改善】-统计主机台数 start
                    System.debug('lt123---------------------------------------');

                    if(tempOp.OlyNumberHosts__c == null){
                        tempOp.OlyNumberHosts__c = 0;
                    }
                    if(tempOp.RivalHostsNumber__c == null){
                        tempOp.RivalHostsNumber__c = 0;
                    }

                    OlyNum += tempOp.OlyNumberHosts__c;
                    RivalNum += tempOp.RivalHostsNumber__c;
                    TotalNum += tempOp.InquireNumberHosts__c;
                    //20221010  lt SWAG-CHL5XA【FY23询价改善】-统计主机台数 end

                // 李慧娟备注 ： 这里请替换成<SAP上传(WIN)>标识判断
                    //<!--询价状态-->
                    if(tempOp.SAP_Send_OK__c || '完毕'.equals(tempOp.StageName__c)){ // 2022-6-2 yjk SWAG-CEP9G8
                      //win 
                      WinNum += 1; 
                    }
                    //XLIU-CG98L5【委托】【评估】新需求-招标项目/询价对应流标、废标改善 fy start
                    // else if(tempOp.StageName__c.equals('失单') || tempOp.StageName__c.equals('取消')){ //2022-5-23 yjk SWAG-CEP9G8
                    //   //失单  
                    //   SHDNum += 1;
                    // }
                    else if(tempOp.StageName__c.equals('失单')){ //2022-5-23 yjk SWAG-CEP9G8
                            //失单  
                        SHDNum += 1;
                    }
                    else if(tempOp.StageName__c.equals('取消')){ //2022-5-23 yjk SWAG-CEP9G8
                            //失单  
                            QuxNum += 1;
                    }
                    //XLIU-CG98L5【委托】【评估】新需求-招标项目/询价对应流标、废标改善 fy end
                    //获取询价的医院(相关性时用)
                    if(!OppHospitalList.contains(tempOp.Hospital__c)&&tempOp.Hospital__c!=null){
                        OppHospitalList.add(tempOp.Hospital__c);
                    }

                    //2022-6-29 yjk 中标确认赋值 start
                    if('OLY中标'.equals(tempOp.ConfirmationofAward__c)){
                        bidNum++;
                    }else if('竞争对手中标'.equals(tempOp.ConfirmationofAward__c)){
                        loseNum++;
                    }
                    //2022-6-29 yjk 中标确认赋值 end

                }

                //20221010  lt SWAG-CHL5XA【FY23询价改善】-统计主机台数 start
                tempTender.OlyNumberHosts__c = OlyNum;
                tempTender.RivalHostsNumber__c = RivalNum;
                tempTender.TotalNumberHosts__c = TotalNum;
                //20221010  lt SWAG-CHL5XA【FY23询价改善】-统计主机台数 end

                //<!--询价状态-->
                if(WinNum == BiddingDownOppList.size()){
                    //全部为Win,OLY确认状态 为 成交
                    tempTender.OpportunityStatus__c = '成交';
                }else if(SHDNum == BiddingDownOppList.size()){
                    //全部为失单.状态为 失单
                    tempTender.OpportunityStatus__c = '失单';
                }else if(WinNum>0&&SHDNum>0&&(WinNum + SHDNum) == BiddingDownOppList.size() ){
                    //部分Win,部分失单时, 状态为  部分成交
                    tempTender.OpportunityStatus__c = '部分成交';
                }
                //XLIU-CG98L5【委托】【评估】新需求-招标项目/询价对应流标、废标改善 fy start
                else if(QuxNum == BiddingDownOppList.size()){
                        //全部为取消.状态为 取消
                    tempTender.OpportunityStatus__c = '取消';
                }
                //XLIU-CG98L5【委托】【评估】新需求-招标项目/询价对应流标、废标改善 fy end
                else if(tempTender.OpportunityNum__c > 0){
                    //如果询价数量大于0的话就是 跟进中
                    tempTender.OpportunityStatus__c = '跟进中';
                }else{
                    //其他都是 ''
                    tempTender.OpportunityStatus__c = '';
                }
                //<!---- 询价状态  end --->

                //2022-6-29 yjk 中标确认赋值 start
                if(bidNum > 0 && loseNum == 0){
                    tempTender.ConfirmationofAward__c = 'OLY中标';
                }else if(loseNum > 0 && bidNum == 0){
                    tempTender.ConfirmationofAward__c = '竞争对手中标';
                }else if(bidNum > 0 && loseNum > 0){
                    tempTender.ConfirmationofAward__c = '部分OLY中标';
                }else{
                    //DB202304056706  you 20230406 清空
                    tempTender.ConfirmationofAward__c = '';
                }


                //2022-6-29 yjk 中标确认赋值 end

                //<!------ 相关性 信息   start ----> 
                //定义Map存放当前招投标项目的五个医院
                Map<String,String> fiveHospitalMap = new Map<String,String>();
                // 招标-询价关联修改 这里是不是可以直接从当前招标里初始化？询价上不再关联单一的招标项目了 20210818 start
                // fiveHospitalMap.put('Hospital__c',BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.Hospital__c);
                // fiveHospitalMap.put('Hospital1__c',BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.Hospital1__c);
                // fiveHospitalMap.put('Hospital2__c',BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.Hospital2__c);
                // fiveHospitalMap.put('Hospital3__c',BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.Hospital3__c);
                // fiveHospitalMap.put('Hospital4__c',BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.Hospital4__c);
                fiveHospitalMap.put('Hospital__c', tempTender.Hospital__c);
                fiveHospitalMap.put('Hospital1__c', tempTender.Hospital1__c);
                fiveHospitalMap.put('Hospital2__c', tempTender.Hospital2__c);
                fiveHospitalMap.put('Hospital3__c', tempTender.Hospital3__c);
                fiveHospitalMap.put('Hospital4__c', tempTender.Hospital4__c);
                // 招标-询价关联修改 20210818 end

                //如果招投标项目的 是否相关 字段不为否 , 并且 相关医院 相关战略科室 相关普通科室 为空时,则更新 为询价的 医院 战略科室 客户名
                // 招标-询价关联修改 同上修改 从当前招标的数据里获得判断条件 20210818 start
                // if(!'否'.equals(BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.IsRelateProject__c)){
                if(!'否'.equals(tempTender.IsRelateProject__c)){
                // 招标-询价关联修改 20210818 end
                    //一.关联医院
                    //遍历招投标项目下所有询价的医院,给招投标项目的5个医院赋值 ---start
                    //遍历招投标项目下所有询价的医院
                    if(OppHospitalList.size()>0){                        
                        for(Integer i = 0; i<OppHospitalList.size();i++){
                            //当招投标项目的五个医院赋值完成后不再赋值
                            Boolean HospitalIsNeedBreak = false;
                            for(String ApiName :fiveHospitalMap.keySet()){
                                HospitalIsNeedBreak = fiveHospitalMap.get(ApiName)==null?false:true;
                            }
                            
                            if(HospitalIsNeedBreak){
                                break;
                            }

                            //给招投标项目的5个医院设值
                            for(String ApiName : fiveHospitalMap.keySet()){
                                String tempTenderHospId = fiveHospitalMap.get(ApiName)==null?'':fiveHospitalMap.get(ApiName);
                                String oppHospId = OppHospitalList.get(i); 
                                //如果招标项目已经有该医院就判断下一个询价的医院
                                if(tempTenderHospId.contains(oppHospId)){
                                    break;
                                }

                                //医院为空,赋值医院(赋值之后进行赋值下一个医院)
                                if(String.isBlank( fiveHospitalMap.get(ApiName) )){
                                    fiveHospitalMap.put(ApiName,oppHospId);
                                    break;
                                }
                            }

                        }
                    }

                    //赋值医院
                    tempTender.Hospital__c = fiveHospitalMap.get('Hospital__c');
                    tempTender.Hospital1__c = fiveHospitalMap.get('Hospital1__c');
                    tempTender.Hospital2__c = fiveHospitalMap.get('Hospital2__c');
                    tempTender.Hospital3__c = fiveHospitalMap.get('Hospital3__c');
                    tempTender.Hospital4__c = fiveHospitalMap.get('Hospital4__c');
                    //遍历招投标项目下所有询价的医院,给招投标项目的5个医院赋值 ---end

                }

                //如果 是否相关 字段已经选择否, 就不应该更新相关及相关的相关信息
                // 招标-询价关联修改 同上修改 从当前招标的数据里获得判断条件 20210818 start
                // if(!'否'.equals(BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.IsRelateProject__c)
                //     &&!'是'.equals(BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.IsRelateProject__c)){
                //     tempTender.IsRelateProject__c = '是';     
                // }
                if(!'否'.equals(tempTender.IsRelateProject__c)
                    &&!'是'.equals(tempTender.IsRelateProject__c)){
                    tempTender.IsRelateProject__c = '是';     
                }
                // 招标-询价关联修改 20210818 end
                //<!------ 相关性 信息   end ---->

                //<!------ 应标 信息    start---->
                //2021-08-09   mzy   关联询价成功后,不需要设置是否应标 为 是
                //如果 是否应标 字段已经选择否,就不应该更新应标及相关的相关信息
                //if(!'否'.equals(BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.IsBid__c)
                //    &&!'是'.equals(BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.IsBid__c)){
                //    tempTender.IsBid__c = '是';     
                //}
                //2021-08-09  mzy  关联询价成功后,不需要设置是否应标 为 是
                //<!------ 应标 信息    end---->

            }else {
                //清空
                tempTender.OpportunityStatus__c = '';
                //DB202304056706  you 20230406 清空
                tempTender.ConfirmationofAward__c = '';
            }
            updateTenderList.add(tempTender);
        }


        return updateTenderList;

    }


    //查询招标项目下的所有询价
    //param : 需要查询的招标项目Id
    //return Map<招投标项目Id,List<询价>>
    public static Map<String,List<Opportunity>> findTenderRelativeOpp(Set<String>  BiddingProjectID){
        //定义Map封装数据
        Map<String,List<Opportunity>> BiddingProjectOppMap = new Map<String,List<Opportunity>>();
        //查询招标项目下的所有询价
        // 招标-询价关联修改 多对多关系对应 从关联表中获取询价 20210818 start
        List<Tender_Opportunity_Link__c> links = [SELECT Id, Tender_information__c, Opportunity__c FROM Tender_Opportunity_Link__c WHERE Tender_information__c in :BiddingProjectID];
        List<String> oppIds = new List<String>();
        for (Tender_Opportunity_Link__c link : links) {
            // 多对多关系 需要去重
            if (oppIds.contains(link.Opportunity__c)) {
                continue;
            }
            oppIds.add(link.Opportunity__c);
        }
        List<Opportunity> allRelativeOppList = [SELECT Id ,AccountId,Hospital__c,Department_Class__c,SAP_Send_OK__c,CreatedDate, Whether_Bidding__c,
        Old_BiddingProject_Bid__c, OwnerId, StageName__c, Bidding_Project_Name_Bid__c, ConfirmationofAward__c
        //20221010  lt SWAG-CHL5XA【FY23询价改善】-统计主机台数 start
        ,OlyNumberHosts__c, RivalHostsNumber__c, InquireNumberHosts__c
        //20221010  lt SWAG-CHL5XA【FY23询价改善】-统计主机台数 end
        FROM Opportunity WHERE Id in :oppIds ORDER By createdDate ASC];
        // List<Opportunity> allRelativeOppList = [SELECT Id ,AccountId,Hospital__c,Department_Class__c,SAP_Send_OK__c,CreatedDate, Whether_Bidding__c,
        // Old_BiddingProject_Bid__c,Bidding_Project_Name_Bid__c ,StageName__c ,Bidding_Project_Name_Bid__r.Hospital__c,Bidding_Project_Name_Bid__r.Hospital1__c,
        // Bidding_Project_Name_Bid__r.Hospital2__c,Bidding_Project_Name_Bid__r.Hospital3__c,Bidding_Project_Name_Bid__r.Hospital4__c,
        // Bidding_Project_Name_Bid__r.OwnerId,OwnerId,
        // Bidding_Project_Name_Bid__r.IsRelateProject__c ,Bidding_Project_Name_Bid__r.IsBid__c ,Bidding_Project_Name_Bid__r.department__c,
        // Bidding_Project_Name_Bid__r.subDepartment1__c,Bidding_Project_Name_Bid__r.subDepartment2__c,Bidding_Project_Name_Bid__r.subDepartment3__c,
        // Bidding_Project_Name_Bid__r.subDepartment4__c FROM Opportunity WHERE Bidding_Project_Name_Bid__c in :BiddingProjectID ORDER By createdDate ASC];
       
        //遍历询价集合
        //2.按创建时间排序(正序),创建map
        for(Opportunity tempOp :allRelativeOppList){
            // 循环link，找到询价对应的招标
            for (Tender_Opportunity_Link__c link : links) {
                if (link.Opportunity__c == tempOp.Id) {
                    String fifteenTenderId = String.valueOf(link.Tender_information__c).subString(0,15);
                    //Map里面没有保存当前询价的招标项目下的询价
                    if(!BiddingProjectOppMap.containsKey(fifteenTenderId)){
                        //第一次存放
                        List<Opportunity> tempOppList = new List<Opportunity>();
                        tempOppList.add(tempOp);
                        BiddingProjectOppMap.put(fifteenTenderId,tempOppList);
                    }else {
                        //以后存放
                        List<Opportunity> tempOppListE = BiddingProjectOppMap.get(fifteenTenderId);
                        tempOppListE.add(tempOp);
                        BiddingProjectOppMap.put(fifteenTenderId,tempOppListE);
                    }
                }
            }
            //判断当前询价是否有招标项目
            // if(tempOp.Bidding_Project_Name_Bid__c!=null){
            //     String fifteenTenderId = String.valueOf(tempOp.Bidding_Project_Name_Bid__c).subString(0,15);
            //     //Map里面没有保存当前询价的招标项目下的询价
            //     if(!BiddingProjectOppMap.containsKey(fifteenTenderId)){
            //         //第一次存放
            //         List<Opportunity> tempOppList = new List<Opportunity>();
            //         tempOppList.add(tempOp);
            //         BiddingProjectOppMap.put(fifteenTenderId,tempOppList);
            //     }else {
            //         //以后存放
            //         List<Opportunity> tempOppListE =BiddingProjectOppMap.get(fifteenTenderId);
            //         tempOppListE.add(tempOp);
            //         BiddingProjectOppMap.put(fifteenTenderId,tempOppListE);
            //     } 
            // }
        }
        //完善Map : 询价为0的招投标项目应该也有一列
        for(String TenderId : BiddingProjectID){
            String fifteenTenderId = TenderId.subString(0,15);
            if(!BiddingProjectOppMap.containsKey(fifteenTenderId)){
                List<Opportunity> tempOppList = new List<Opportunity>();
                BiddingProjectOppMap.put(fifteenTenderId,tempOppList);
            }
        }

        return BiddingProjectOppMap;
    }


    // 发送提醒邮件
    private void sendFieldEmail() {
        PretechBatchEmailUtil be = new PretechBatchEmailUtil();
        String[] toList = new String[] {UserInfo.getUserEmail()};
        String title = '招标项目询价状态和询价数量更新失败';
        //String[] ccList = new String[] {'Xiaochen_You@olympus.com.cn'};
        String[] ccList = new String[] {'miaoziyang@prec-tech.com'};
        if (System.Test.isRunningTest()) {
            be.successMail('', 1);
        }
        if (emailMessages.size() > 0 && TenderfailedCount > 0) {
            be.failedMail(toList, ccList, title, this.emailMessages.get(0)+'\n',
                            TendertotalCount, TendertotalCount - TenderfailedCount, TenderfailedCount,'',true);
            if(!Test.isRunningTest()){
                be.send();
            }
        }       
    }
    
    public static void justForTest() {
        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++;
    }
}