/*根据招投标项目的反应询价标识
|
* 更新招投标上的询价状态和询价数量
|
* 更新招投标上的五个医院
|
* 2021-07-15 mzy
|
*/
|
global class UpdateTenderInformationBatchByTender implements Database.Batchable<sObject>, Database.Stateful {
|
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 UpdateTenderInformationBatchByTender(String tempOppId) {
|
this.tempTenderId = tempOppId;
|
}
|
|
global UpdateTenderInformationBatchByTender(List<String> 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<Tender_information__c> TenderList) {
|
|
//定义List封装需要更新的招标项目
|
List<Tender_information__c> updateTenderList = new List<Tender_information__c>();
|
//定义List封装所有询价的招标项目Id
|
Set<String> BiddingProjectID = new Set<String>();
|
for(Tender_information__c tempTender : TenderList){
|
BiddingProjectID.add(tempTender.Id);
|
}
|
|
//查询招标项目下的所有询价
|
Map<String,List<Opportunity>> BiddingProjectOppMap = findTenderRelativeOpp(BiddingProjectID);
|
|
//计算询价数量
|
List<Tender_information__c> updateTenderNumList = updateOpportunityNum(BiddingProjectOppMap);
|
|
|
//计算询价状态
|
List<Tender_information__c> updateTenderNumStatusList = updateOpportunityStatus(BiddingProjectOppMap,updateTenderNumList);
|
|
|
|
|
updateTenderList.addAll(updateTenderNumStatusList);
|
|
//更新招投标 询价数量和状态
|
if(updateTenderList.size()>0){
|
//一个招投标项目更新失败
|
List<String> failedTenderList = new List<String>();
|
///////////////
|
//测试
|
//updateTenderList.get(1).OwnerId = '00510000003KwKO';
|
///////////////
|
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+' 失败原因:'+ statusCode +' : '+errorMsg + '\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;
|
}
|
}
|
|
}
|
|
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<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);
|
}
|
|
//查询招标项目下的所有询价
|
Map<String,List<Opportunity>> BiddingProjectOppMap = findTenderRelativeOpp(BiddingProjectID);
|
|
//计算询价数量
|
List<Tender_information__c> updateTenderNumList = updateOpportunityNum(BiddingProjectOppMap);
|
|
//计算询价状态
|
List<Tender_information__c> updateTenderNumStatusList = updateOpportunityStatus(BiddingProjectOppMap,updateTenderNumList);
|
|
updateTenderList.addAll(updateTenderNumStatusList);
|
|
//更新
|
if(updateTenderList.size()>0){
|
List<String> failedTenderList = new List<String>();
|
Database.SaveResult[] saveTenderResults = Database.update(updateTenderList,false);
|
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+' 失败原因:'+ statusCode +' : '+errorMsg + '\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;
|
}
|
|
}
|
|
|
}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){
|
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);
|
}
|
|
|
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){
|
//询价状态
|
//定义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){
|
//<!---- 询价状态 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(!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 = '';
|
}
|
//<!---- 询价状态 end --->
|
|
//<!------ 相关性 信息 start ---->
|
//定义Map存放当前招投标项目的五个医院
|
Map<String,String> fiveHospitalMap = new Map<String,String>();
|
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<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
|
|
}
|
|
//如果 是否相关 字段已经选择否, 就不应该更新相关及相关的相关信息
|
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.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<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();
|
}
|
}
|
}
|
|
}
|