/*2021-05-08 mzy
|
* 更新招标信息的询价状态
|
*/
|
global class UpdateTenderInformationBatch01 implements Database.Batchable<sObject>, Database.Stateful {
|
|
Boolean IsNeedExecute = false;
|
String tempOppId ='';
|
|
//邮件信息
|
List<String> emailMessages = new List<String>();
|
|
//招投标: 报错的招投标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<Opportunity> OpportunityList) {
|
|
//定义一个保存点 , 目的 : 如果Batch执行失败,则整体rollback,标识不进行清除
|
Savepoint sp = Database.setSavepoint();
|
|
try {
|
//定义List封装所有询价的招标项目Id
|
Set<String> BiddingProjectID = new Set<String>();
|
//定义List封装需要更新的招标项目
|
List<Tender_information__c> updateTenderList = new List<Tender_information__c>();
|
|
//获取所有招投标标识 字段 为 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<String,List<Opportunity>> 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<saveTenderResults.size();i++) {
|
if(!saveTenderResults.get(i).isSuccess()){
|
if(TenderlogStr.equals('')){
|
TenderlogStr = '招标项目 : ' ;
|
}
|
TenderlogStr += updateTenderList.get(i).id +' ,';
|
TendererrorStr += saveTenderResults.get(i).getErrors() + '\n';
|
TenderfailedCount++ ;
|
}
|
}
|
|
//更新询价,清除标识
|
for(Opportunity tempOp : OpportunityList){
|
tempOp.Bidding_Flag__c = false;
|
//如果询价中 原招投标项目Id有值则清空
|
if(!String.IsBlank(tempOp.Old_BiddingProject_Bid__c)){
|
tempOp.Old_BiddingProject_Bid__c = null;
|
}
|
}
|
|
Database.SaveResult[] saveOppResults = Database.update(OpportunityList,false);
|
OpptotalCount = saveOppResults.size();
|
for(Integer i = 0;i<saveOppResults.size();i++) {
|
if(!saveOppResults.get(i).isSuccess()){
|
if(OpplogStr.equals('')){
|
OpplogStr = '询价 : ' ;
|
}
|
OpplogStr += OpportunityList.get(i).id +' ,';
|
OpperrorStr += saveOppResults.get(i).getErrors() + '\n';
|
OppfailedCount++ ;
|
}
|
}
|
|
}
|
|
}catch(Exception ex){
|
//如果Batch执行失败,则整体rollback,标识不进行清除
|
Database.rollback(sp);
|
}
|
|
|
}
|
|
|
|
global void finish(Database.BatchableContext BC) {
|
UpdateTenderInformationSchedule.assignOneHours();
|
BatchIF_Log__c TenderIfLog = new BatchIF_Log__c();
|
TenderIfLog.Type__c = 'UpdateTenderInformationBatchErrorLog(Tender)';
|
|
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;
|
|
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<String> TenderIdList){
|
//定义一个保存点 , 目的 : 如果Batch执行失败,则整体rollback,标识不进行清除
|
Savepoint sp = Database.setSavepoint();
|
|
//定义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);
|
}
|
|
//查询招标项目下的所有询价
|
Map<String,List<Opportunity>> BiddingProjectOppMap = findTenderRelativeOpp(BiddingProjectID);
|
|
//计算询价数量
|
updateTenderList = updateOpportunityNum(BiddingProjectOppMap,updateTenderList);
|
|
//计算询价状态
|
updateTenderList = updateOpportunityStatus(BiddingProjectOppMap,updateTenderList);
|
|
|
|
//更新
|
if(updateTenderList.size()>0){
|
update updateTenderList;
|
|
//清除询价标识
|
List<Opportunity> updateOppList = new List<Opportunity> ();
|
|
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<Tender_information__c> updateOpportunityNum(Map<String,List<Opportunity>> tempMap,List<Tender_information__c> 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<Tender_information__c> updateOpportunityStatus(Map<String,List<Opportunity>> BiddingProjectOppMap,List<Tender_information__c> TenderList){
|
//询价状态
|
//定义List封装需要更新的招标项目
|
List<Tender_information__c> updateTenderList = new List<Tender_information__c>();
|
|
//遍历Map的key
|
for(Tender_information__c tempTender : TenderList){
|
|
String fifteenId = String.valueOf(tempTender.Id).subString(0,15);
|
//获取当前招投标下的询价
|
List<Opportunity> BiddingDownOppList= BiddingProjectOppMap.get(fifteenId) == null ? new List<Opportunity>() : BiddingProjectOppMap.get(fifteenId);
|
|
//获取当前招投标下的询价的战略科室
|
List<String> OppDepartmentList = new List<String>();
|
//创建招标项目
|
//Tender_information__c tempTender =
|
|
//tempTender.Id = k;
|
|
//判断状态
|
if(BiddingDownOppList.size() > 0){
|
//<!---- 询价状态 start --->
|
//WIN num
|
Integer WinNum = 0;
|
//失单 num
|
Integer SHDNum = 0;
|
|
//获取当前key的List
|
for(Opportunity tempOp :BiddingDownOppList){
|
// 李慧娟备注 : 这里请替换成<SAP上传(WIN)>标识判断
|
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 = '';
|
}
|
//<!---- 询价状态 end --->
|
|
//<!------ 相关性 信息 start ---->
|
//定义Map存放当前招投标项目的五个战略科室
|
Map<String,String> fiveDepartmentMap = new Map<String,String>();
|
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<OppDepartmentList.size();i++){
|
//当招投标项目的五个战略科室赋值完成后将不再赋值
|
Boolean isNeedBreak = false;
|
for(String ApiName : fiveDepartmentMap.keySet()){
|
isNeedBreak = fiveDepartmentMap.get(ApiName)==null?false:true;
|
}
|
if(isNeedBreak){
|
break;
|
}
|
|
//给招投标项目的5个战略科室设值
|
for(String ApiName : fiveDepartmentMap.keySet()){
|
String tempTenderDeptId = fiveDepartmentMap.get(ApiName)==null?'':fiveDepartmentMap.get(ApiName);
|
String oppDeptId = OppDepartmentList.get(i);
|
system.debug('tempTenderDeptId:'+tempTenderDeptId);
|
system.debug('oppDeptId:'+oppDeptId);
|
|
//如果招标项目已经有该战略科室就判断下一个询价的战略科室
|
if(tempTenderDeptId.contains(oppDeptId)){
|
break;
|
}
|
|
//战略科室为空,赋值战略科室(赋值之后进行赋值下一个战略科室)
|
if(String.isBlank( fiveDepartmentMap.get(ApiName) ) ){
|
fiveDepartmentMap.put(ApiName,oppDeptId);
|
break;
|
}
|
}
|
}
|
|
//赋值战略科室
|
tempTender.department__c = fiveDepartmentMap.get('department__c');
|
tempTender.subDepartment1__c = fiveDepartmentMap.get('subDepartment1__c');
|
tempTender.subDepartment2__c = fiveDepartmentMap.get('subDepartment2__c');
|
tempTender.subDepartment3__c = fiveDepartmentMap.get('subDepartment3__c');
|
tempTender.subDepartment4__c = fiveDepartmentMap.get('subDepartment4__c');
|
|
|
//遍历招投标项目下所有询价的战略科室,给招投标项目的5个战略科室赋值 ---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 = '是';
|
}
|
//<!------ 相关性 信息 end ---->
|
|
//<!------ 应标 信息 start---->
|
//如果 是否应标 字段已经选择否,就不应该更新应标及相关的相关信息
|
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 = '是';
|
}
|
//<!------ 应标 信息 end---->
|
|
}else {
|
//清空
|
tempTender.OpportunityStatus__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>>();
|
//查询招标项目下的所有询价
|
List<Opportunity> 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<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[] {};
|
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();
|
}
|
}
|
|
}
|
|
|
}
|