/*2021-05-08 mzy * 更新招标信息的询价状态 */ global class UpdateTenderInformationBatch01 implements Database.Batchable, Database.Stateful { Boolean IsNeedExecute = false; String tempOppId =''; //邮件信息 List emailMessages = new List(); //招投标: 报错的招投标Id String TenderlogStr = ''; //招投标: 报错信息 String TendererrorStr = ''; //招投标: 总件数 Integer TendertotalCount = 0; //招投标: 失败件数 Integer TenderfailedCount = 0; //询价 : 报错的询价Id String OpplogStr = ''; //询价 : 报错信息 String OpperrorStr = ''; //询价 : 总件数 Integer OpptotalCount = 0; //询价 : 失败件数 Integer OppfailedCount = 0; global UpdateTenderInformationBatch01() { } global UpdateTenderInformationBatch01(String tempOppId) { this.tempOppId = tempOppId; } global UpdateTenderInformationBatch01(Boolean NeedExecute) { this.IsNeedExecute = NeedExecute; } global Database.QueryLocator start(Database.BatchableContext bc) { //查询 招投标标识 字段 为 true 的询价 String query = 'SELECT Id,StageName__c,Bidding_Project_Name_Bid__c, ' + 'Old_BiddingProject_Bid__c FROM Opportunity ' + 'WHERE Bidding_Flag__c = true'; if(String.isNotBlank(this.tempOppId)){ query += ' AND Id = :tempOppId'; } return Database.getQueryLocator(query); } global void execute(Database.BatchableContext BC, List OpportunityList) { //定义一个保存点 , 目的 : 如果Batch执行失败,则整体rollback,标识不进行清除 Savepoint sp = Database.setSavepoint(); try { //定义List封装所有询价的招标项目Id Set BiddingProjectID = new Set(); //定义List封装需要更新的招标项目 List updateTenderList = new List(); //获取所有招投标标识 字段 为 true 的询价的招标项目 for(Opportunity tempOp :OpportunityList){ //如果询价上记录了原来招投标项目的信息,则在batch里面需要重新计算询价状态和询价数量。 if(!String.IsBlank(tempOp.Old_BiddingProject_Bid__c)){ BiddingProjectID.add(tempOp.Old_BiddingProject_Bid__c); } if(!String.IsBlank(tempOp.Bidding_Project_Name_Bid__c)){ BiddingProjectID.add(tempOp.Bidding_Project_Name_Bid__c); } } //查询招标项目下的所有询价 Map> BiddingProjectOppMap = findTenderRelativeOpp(BiddingProjectID); //计算询价数量 updateTenderList = updateOpportunityNum(BiddingProjectOppMap,updateTenderList); //计算询价状态 updateTenderList = updateOpportunityStatus(BiddingProjectOppMap,updateTenderList); //更新招标项目 if(updateTenderList.size()>0){ //update updateTenderList; Database.SaveResult[] saveTenderResults = Database.update(updateTenderList,false); TendertotalCount = saveTenderResults.size(); for(Integer i = 0;i 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; BatchIF_Log__c OppIfLog = new BatchIF_Log__c(); OppIfLog.Type__c = 'UpdateTenderInformationBatchErrorLog(Opp)'; if (OpplogStr.length() > 60000) { OpplogStr = OpplogStr.substring(0, 60000); } OppIfLog.Log__c = OpplogStr; OppIfLog.Log__c += '\n end'; if (OpperrorStr.length() > 60000) { OppIfLog.ErrorLog__c = OpperrorStr.substring(0, 60000); } else { OppIfLog.ErrorLog__c = OpperrorStr.substring(0, OpperrorStr.length()); } insert OppIfLog; emailMessages.add('失败日志ID为:' + TenderIfLog.Id ); emailMessages.add('失败日志ID为:' + OppIfLog.Id ); //发送失败邮件 sendFieldEmail(); } //更新招投标的询价信息 WebService static String updateOpportunityInformation(List TenderIdList){ //定义一个保存点 , 目的 : 如果Batch执行失败,则整体rollback,标识不进行清除 Savepoint sp = Database.setSavepoint(); //定义List封装需要更新的招标项目 List updateTenderList = new List(); try{ Set BiddingProjectID = new Set(); for(String TenderId : TenderIdList){ BiddingProjectID.add(TenderId); } //查询招标项目下的所有询价 Map> BiddingProjectOppMap = findTenderRelativeOpp(BiddingProjectID); //计算询价数量 updateTenderList = updateOpportunityNum(BiddingProjectOppMap,updateTenderList); //计算询价状态 updateTenderList = updateOpportunityStatus(BiddingProjectOppMap,updateTenderList); //更新 if(updateTenderList.size()>0){ update updateTenderList; //清除询价标识 List updateOppList = new List (); for(String TenderId : TenderIdList){ if(BiddingProjectOppMap.get(TenderId)!= null){ for(Opportunity opp : BiddingProjectOppMap.get(TenderId)){ Opportunity tempOp = new Opportunity(); tempOp.Id = opp.Id; tempOp.Bidding_Flag__c = false; //如果询价中 原招投标项目ID有值则清空 if(!String.IsBlank(opp.Old_BiddingProject_Bid__c)){ tempOp.Old_BiddingProject_Bid__c = null; } updateOppList.add(tempOp); } } } if(updateOppList.size()>0){ update updateOppList; } } }catch(NullPointerException ex){ Database.rollback(sp); return '空指针 :'+ex.getLineNumber(); }catch(Exception ex2){ Database.rollback(sp); return '出错了!'+ex2.getMessage(); } return 'OK'; } //计算询价数量 public static List updateOpportunityNum(Map> tempMap,List updateTenderList ){ /*//询价数量 for(Tender_information__c tempTender :updateTenderList){ String fifteenId = String.valueOf(tempTender.Id).subString(0,15); tempTender.OpportunityNum__c = tempMap.get(fifteenId).size(); if(tempMap.get(fifteenId).size() == 0){ tempTender.OpportunityStatus__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(); updateTenderList.add(tempTender); } return updateTenderList; } //1.计算询价状态 //2.赋值战略科室 // 1) 如果招投标项目的关联医院为空,那么就更新为询价的医院; // 2) 如果招投标项目的关联主战略科室为空,那么就更新为询价创建时间最早的询价的战略科室; // 3) 如果招投标项目的关联副战略科室为空,那么就更新为排名优先级高的战略科室之外的其他询价的战略科室,也是以创建时间更早为先后顺序; // 4) 如果更新满了,多的战略科室就不更新; public static List updateOpportunityStatus(Map> BiddingProjectOppMap,List TenderList){ //询价状态 //定义List封装需要更新的招标项目 List updateTenderList = new List(); //遍历Map的key for(Tender_information__c tempTender : TenderList){ String fifteenId = String.valueOf(tempTender.Id).subString(0,15); //获取当前招投标下的询价 List BiddingDownOppList= BiddingProjectOppMap.get(fifteenId) == null ? new List() : BiddingProjectOppMap.get(fifteenId); //获取当前招投标下的询价的战略科室 List OppDepartmentList = new List(); //创建招标项目 //Tender_information__c tempTender = //tempTender.Id = k; //判断状态 if(BiddingDownOppList.size() > 0){ // //WIN num Integer WinNum = 0; //失单 num Integer SHDNum = 0; //获取当前key的List for(Opportunity tempOp :BiddingDownOppList){ // 李慧娟备注 : 这里请替换成标识判断 if(tempOp.SAP_Send_OK__c){ //win WinNum += 1; }else if(tempOp.StageName__c.equals('失单')){ //失单 SHDNum += 1; } //获取询价的战略科室(相关性时用) if(!OppDepartmentList.contains(tempOp.Department_Class__c)){ OppDepartmentList.add(tempOp.Department_Class__c); } } 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 = '部分成交'; }else if(tempTender.OpportunityNum__c > 0){ //如果询价数量大于0的话就是 跟进中 tempTender.OpportunityStatus__c = '跟进中'; }else{ //其他都是 '' tempTender.OpportunityStatus__c = ''; } // // //定义Map存放当前招投标项目的五个战略科室 Map fiveDepartmentMap = new Map(); fiveDepartmentMap.put('department__c',BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.department__c); fiveDepartmentMap.put('subDepartment1__c',BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.subDepartment1__c); fiveDepartmentMap.put('subDepartment2__c',BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.subDepartment2__c); fiveDepartmentMap.put('subDepartment3__c',BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.subDepartment3__c); fiveDepartmentMap.put('subDepartment4__c',BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.subDepartment4__c); //如果招投标项目的 是否相关 字段不为否 , 并且 相关医院 相关战略科室 相关普通科室 为空时,则更新 为询价的 医院 战略科室 客户名 if(!'否'.equals(BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.IsRelateProject__c)){ //关联医院 if(BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.Hospital__c == null){ tempTender.Hospital__c = BiddingDownOppList.get(0).Hospital__c; } //遍历招投标项目下所有询价的战略科室,给招投标项目的5个战略科室赋值 ---start //遍历招投标项目下所有询价的战略科室 for(Integer i = 0; i // //如果 是否应标 字段已经选择否,就不应该更新应标及相关的相关信息 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 = '是'; } // }else { //清空 tempTender.OpportunityStatus__c = ''; } updateTenderList.add(tempTender); } return updateTenderList; } //查询招标项目下的所有询价 //param : 需要查询的招标项目Id //return Map<招投标项目Id,List<询价>> public static Map> findTenderRelativeOpp(Set BiddingProjectID){ //定义Map封装数据 Map> BiddingProjectOppMap = new Map>(); //查询招标项目下的所有询价 List allRelativeOppList = [SELECT Id ,AccountId,Hospital__c,Department_Class__c,SAP_Send_OK__c,CreatedDate, Old_BiddingProject_Bid__c,Bidding_Project_Name_Bid__c ,StageName__c ,Bidding_Project_Name_Bid__r.Hospital__c, 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){ //判断当前询价是否有招标项目 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 tempOppList = new List(); tempOppList.add(tempOp); BiddingProjectOppMap.put(fifteenTenderId,tempOppList); }else { //以后存放 List 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 tempOppList = new List(); 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[] {}; 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(); } } be = new PretechBatchEmailUtil(); title = '询价更新失败'; if (System.Test.isRunningTest()) { be.successMail('', 1); } if (emailMessages.size() > 0 && OppfailedCount > 0){ be.failedMail(toList, ccList, title,this.emailMessages.get(1)+'\n', OpptotalCount, OpptotalCount - OppfailedCount, OppfailedCount,'',true); if(!Test.isRunningTest()){ be.send(); } } } }