/*根据招投标项目的反应询价标识 * 更新招投标上的询价状态和询价数量 * 更新招投标上的五个医院 * 2021-07-15 mzy */ global class UpdateTenderInformationBatchByTender implements Database.Batchable, Database.Stateful { String tempTenderId =''; Boolean IsOnlyTrue = true; List tempTenderList = new List(); //邮件信息 List emailMessages = new List(); //招投标: 报错的招投标Id String TenderlogStr = ''; //招投标: 报错信息 String TendererrorStr = ''; //招投标: 总件数 Integer TendertotalCount = 0; //招投标: 失败件数 Integer TenderfailedCount = 0; global UpdateTenderInformationBatchByTender(String tempOppId) { this.tempTenderId = tempOppId; } global UpdateTenderInformationBatchByTender(List tempTenderList) { this.tempTenderList = tempTenderList; } //处理历史数据 global UpdateTenderInformationBatchByTender(String tempOppId, Boolean IsOnlyTrue) { this.IsOnlyTrue = IsOnlyTrue; } global UpdateTenderInformationBatchByTender() { } global Database.QueryLocator start(Database.BatchableContext bc) { String query = 'SELECT Id '; query += 'FROM Tender_information__c '; if(IsOnlyTrue){ query += 'WHERE IsReactionOpp__c = true'; } if(String.isNotBlank(this.tempTenderId)){ query += ' AND Id = :tempTenderId'; } if(tempTenderList.size()>0){ query += ' AND Id In :tempTenderList'; } return Database.getQueryLocator(query); } global void execute(Database.BatchableContext BC, list TenderList) { //定义List封装需要更新的招标项目 List updateTenderList = new List(); //定义List封装所有询价的招标项目Id Set BiddingProjectID = new Set(); for(Tender_information__c tempTender : TenderList){ BiddingProjectID.add(tempTender.Id); } //查询招标项目下的所有询价 Map> BiddingProjectOppMap = findTenderRelativeOpp(BiddingProjectID); //计算询价数量 List updateTenderNumList = updateOpportunityNum(BiddingProjectOppMap); //计算询价状态 List updateTenderNumStatusList = updateOpportunityStatus(BiddingProjectOppMap,updateTenderNumList); updateTenderList.addAll(updateTenderNumStatusList); //更新招投标 询价数量和状态 if(updateTenderList.size()>0){ //一个招投标项目更新失败 List failedTenderList = new List(); /////////////// //测试 //updateTenderList.get(1).OwnerId = '00510000003KwKO'; /////////////// Database.SaveResult[] saveTenderResults = Database.update(updateTenderList,false); //招投标项目的总数 TendertotalCount = saveTenderResults.size(); for(Integer i = 0;i successTenderList = new List(); 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; } } } 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(); } //批量更新招投标的询价信息 WebService static String updateOpportunityInformation(List TenderIdList){ //存储错误信息 String errorMessage = ''; //目的 : 如果Batch执行失败,则整体rollback,标识不进行清除 //定义List封装需要更新的招标项目 List updateTenderList = new List(); try{ Set BiddingProjectID = new Set(); for(String TenderId:TenderIdList){ BiddingProjectID.add(TenderId); } //查询招标项目下的所有询价 Map> BiddingProjectOppMap = findTenderRelativeOpp(BiddingProjectID); //计算询价数量 List updateTenderNumList = updateOpportunityNum(BiddingProjectOppMap); //计算询价状态 List updateTenderNumStatusList = updateOpportunityStatus(BiddingProjectOppMap,updateTenderNumList); updateTenderList.addAll(updateTenderNumStatusList); //更新 if(updateTenderList.size()>0){ List failedTenderList = new List(); Database.SaveResult[] saveTenderResults = Database.update(updateTenderList,false); for(Integer i = 0;i successTenderList = new List(); 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; } } }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 updateOpportunityNum(Map> tempMap){ List updateTenderNumList = new List(); //遍历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); } return updateTenderNumList; } //1.计算询价状态 //2.赋值医院 //3.赋值战略科室 // 1) 如果招投标项目的关联医院为空,那么就更新为询价的医院; // 2) 如果招投标项目的关联主战略科室为空,那么就更新为询价创建时间最早的询价的战略科室; // 3) 如果招投标项目的关联副战略科室为空,那么就更新为排名优先级高的战略科室之外的其他询价的战略科室,也是以创建时间更早为先后顺序; // 4) 如果更新满了,多的战略科室就不更新; public static List updateOpportunityStatus(Map> BiddingProjectOppMap,List updateTenderNumList){ //询价状态 //定义List封装需要更新的招标项目 List updateTenderList = new List(); //遍历Map的key for(Tender_information__c tempTender : updateTenderNumList){ String fifteenId = String.valueOf(tempTender.Id).subString(0,15); //获取当前招投标下的询价 List BiddingDownOppList= BiddingProjectOppMap.get(fifteenId) == null ? new List() : BiddingProjectOppMap.get(fifteenId); //获取当前招投标下的询价的医院 List OppHospitalList = new List(); //判断状态 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(!OppHospitalList.contains(tempOp.Hospital__c)&&tempOp.Hospital__c!=null){ OppHospitalList.add(tempOp.Hospital__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 fiveHospitalMap = new Map(); 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); //如果招投标项目的 是否相关 字段不为否 , 并且 相关医院 相关战略科室 相关普通科室 为空时,则更新 为询价的 医院 战略科室 客户名 if(!'否'.equals(BiddingDownOppList.get(0).Bidding_Project_Name_Bid__r.IsRelateProject__c)){ //一.关联医院 //遍历招投标项目下所有询价的医院,给招投标项目的5个医院赋值 ---start //遍历招投标项目下所有询价的医院 if(OppHospitalList.size()>0){ 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.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.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[] {'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(); } } } }