| New file |
| | |
| | | /*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 == '00510000000gmxH'){ |
| | | 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中标'; |
| | | } |
| | | |
| | | |
| | | //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 = ''; |
| | | } |
| | | 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++; |
| | | } |
| | | } |