You need to sign in to do that
Don't have an account?
sumit d
Hi All,
i have a batch in which i am creating a parent child account hierarchy. at this time when i am executing the batch for opportunity with exact same name its creating two Accounts with the same name but i want that opportunity with same name should go to the account which is first created .it should not created duplicate records of Account for opportunity with same name.
my batch is given below:-
public class BatchResellerPartnerToResellerCustomer implements Database.Batchable<sObject>{
//Run method to check the Batch on one record
public static void run( Set<Id> OppIds ) {
List<Opportunity> OppRecords = [SELECT Name, AccountId,
Account.Name, Account.OwnerId,
Account.RecordTypeId, Account.RecordType.Name
FROM Opportunity
WHERE AccountId != null
AND Account.RecordType.Name = 'Time Rack'
AND Account.Customer_Type__c = 'Reseller'
AND Id IN: OppIds ];
executeHelper( OppRecords );
}
public Database.querylocator start(Database.BatchableContext BC){
String query = 'SELECT Name, Account.Name, Account.OwnerId, AccountId, '+
'Account.RecordTypeId, Account.RecordType.Name '+
'FROM Opportunity '+
'WHERE AccountId != null '+
'AND Account.RecordType.Name = \'Time Rack\''+
'AND Account.Customer_Type__c = \'Reseller\'';
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext BC, List<Opportunity> scope){
executeHelper( scope );
}
//Helper method to create respective Accounts of opportunities
public static void executeHelper( List<Opportunity> scope ) {
List<Account> accList = new List<Account>();
List<Opportunity> opptyListToBeUpdated = new List<Opportunity>();
//Create Accounts with Opportunity's EndUser Name and ParentId with Opp's accountId
for(Opportunity Oppty : scope) {
String oppName = '';
//Condition to get the end user name from opp name and give it to the new Account
if(Oppty.Name.startsWith(Oppty.Account.Name)){
oppName = Oppty.Name.removeStart(Oppty.Account.Name);
oppName = oppName.trim();
if(oppName.startsWith(':') ){
oppName = oppName.substringAfter(':');
oppName = oppName.trim();
}
else if( oppName.startsWith('-') ){
oppName = oppName.substringAfter('-');
oppName = oppName.trim();
}
else{
oppName = Oppty.Name;
}
}
//Condition to check opportunity has account with record type
if(oppName != ''
&& Oppty.AccountId != Null
&& Oppty.Account.RecordTypeId != Null){
//create new Account for each opportunity with customerType -'End user'
Account acc = new Account(Parentid = Oppty.AccountId,
Customer_Type__c = 'End User',
RecordTypeId = Oppty.Account.RecordTypeId,
OwnerId = Oppty.Account.OwnerId,
Name = oppName );
accList.add(acc);
}
}
if(accList.size()>0) {
insert accList;
}
// Update Oppty List with newAccountId
for(Account acc : accList) {
for(Opportunity oppty : scope) {
if(oppty.AccountId == acc.ParentId) {
oppty.AccountId = acc.Id;
opptyListToBeUpdated.add(oppty);
}
}
}
if(opptyListToBeUpdated.size()>0) {
update opptyListToBeUpdated;
}
}
public void finish(Database.BatchableContext BC){
}
}
right now its creating duplicate account records with opportunity which has same name.i want to prevent duplicate account creation and simply want that the opportunity should attach with the account which is created already first with the batch.
How can i modify this batch to prevent duplicate accounts creations?
Any suggestions?
prevent duplicate accounts creation in a batch
Hi All,
i have a batch in which i am creating a parent child account hierarchy. at this time when i am executing the batch for opportunity with exact same name its creating two Accounts with the same name but i want that opportunity with same name should go to the account which is first created .it should not created duplicate records of Account for opportunity with same name.
my batch is given below:-
public class BatchResellerPartnerToResellerCustomer implements Database.Batchable<sObject>{
//Run method to check the Batch on one record
public static void run( Set<Id> OppIds ) {
List<Opportunity> OppRecords = [SELECT Name, AccountId,
Account.Name, Account.OwnerId,
Account.RecordTypeId, Account.RecordType.Name
FROM Opportunity
WHERE AccountId != null
AND Account.RecordType.Name = 'Time Rack'
AND Account.Customer_Type__c = 'Reseller'
AND Id IN: OppIds ];
executeHelper( OppRecords );
}
public Database.querylocator start(Database.BatchableContext BC){
String query = 'SELECT Name, Account.Name, Account.OwnerId, AccountId, '+
'Account.RecordTypeId, Account.RecordType.Name '+
'FROM Opportunity '+
'WHERE AccountId != null '+
'AND Account.RecordType.Name = \'Time Rack\''+
'AND Account.Customer_Type__c = \'Reseller\'';
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext BC, List<Opportunity> scope){
executeHelper( scope );
}
//Helper method to create respective Accounts of opportunities
public static void executeHelper( List<Opportunity> scope ) {
List<Account> accList = new List<Account>();
List<Opportunity> opptyListToBeUpdated = new List<Opportunity>();
//Create Accounts with Opportunity's EndUser Name and ParentId with Opp's accountId
for(Opportunity Oppty : scope) {
String oppName = '';
//Condition to get the end user name from opp name and give it to the new Account
if(Oppty.Name.startsWith(Oppty.Account.Name)){
oppName = Oppty.Name.removeStart(Oppty.Account.Name);
oppName = oppName.trim();
if(oppName.startsWith(':') ){
oppName = oppName.substringAfter(':');
oppName = oppName.trim();
}
else if( oppName.startsWith('-') ){
oppName = oppName.substringAfter('-');
oppName = oppName.trim();
}
else{
oppName = Oppty.Name;
}
}
//Condition to check opportunity has account with record type
if(oppName != ''
&& Oppty.AccountId != Null
&& Oppty.Account.RecordTypeId != Null){
//create new Account for each opportunity with customerType -'End user'
Account acc = new Account(Parentid = Oppty.AccountId,
Customer_Type__c = 'End User',
RecordTypeId = Oppty.Account.RecordTypeId,
OwnerId = Oppty.Account.OwnerId,
Name = oppName );
accList.add(acc);
}
}
if(accList.size()>0) {
insert accList;
}
// Update Oppty List with newAccountId
for(Account acc : accList) {
for(Opportunity oppty : scope) {
if(oppty.AccountId == acc.ParentId) {
oppty.AccountId = acc.Id;
opptyListToBeUpdated.add(oppty);
}
}
}
if(opptyListToBeUpdated.size()>0) {
update opptyListToBeUpdated;
}
}
public void finish(Database.BatchableContext BC){
}
}
right now its creating duplicate account records with opportunity which has same name.i want to prevent duplicate account creation and simply want that the opportunity should attach with the account which is created already first with the batch.
How can i modify this batch to prevent duplicate accounts creations?
Any suggestions?
Try with below updated code. Created one map of account name and account so through this map it will prevent duplicate records to be created.
If above code will solve your problem then mark this as best answer. Let me know if there any further help required on the same.
Thanks
Dheeraj
All Answers
Try with below updated code. Created one map of account name and account so through this map it will prevent duplicate records to be created.
If above code will solve your problem then mark this as best answer. Let me know if there any further help required on the same.
Thanks
Dheeraj
i made the test class for it given below:-
@isTest
private class BatchResellerCustomerTest {
static testmethod void TestResellerCustomer(){
// Create Account with recordType-"Timerack" and customer type-"Reseller"
Id recId = Schema.SObjectType.Account.getRecordTypeInfosByName().get('Time Rack').getRecordTypeId();
Account acc =new Account( Name = 'test' ,Customer_Type__c ='Reseller' ,recordtypeid = recId );
insert acc;
//Create opportunity with the Account Opportunity Name with '-'
Opportunity opp = new Opportunity();
opp.StageName = 'Sourcing Demand';
opp.AccountId = acc.id;
opp.CloseDate = System.today();
opp.Name = 'test -ExPay';
insert opp;
// Opportunity Name with ':'
Opportunity oppt = new Opportunity();
oppt.StageName = 'Sourcing Demand';
oppt.AccountId = acc.id;
oppt.CloseDate = System.today();
oppt.Name = 'test :RePay';
insert oppt;
//opportunity Name other than '-' and ':'
Opportunity oppty = new Opportunity();
oppty.StageName = 'Sourcing Demand';
oppty.AccountId = acc.id;
oppty.CloseDate = System.today();
oppty.Name = 'test Pay';
insert oppty;
//Opportunity with same name
Opportunity opp1 = new Opportunity();
opp1.StageName = 'Sourcing Demand';
opp1.AccountId = acc.id;
opp1.CloseDate = System.today();
opp1.Name = 'test -ExPay';
insert opp1;
//Opportunity with some other notation
Opportunity opp2 = new Opportunity();
opp2.StageName = 'Sourcing Demand';
opp2.AccountId = acc.id;
opp2.CloseDate = System.today();
opp2.Name = 'test =ExPay';
insert opp2;
//Execute the test methods
test.startTest();
BatchResellerPartnerToResellerCustomer obj = new BatchResellerPartnerToResellerCustomer();
database.executeBatch(obj);
Set<Id> OppIds = new Set<Id>();
OppIds.add(opp.Id);
BatchResellerPartnerToResellerCustomer.run(OppIds);
test.stopTest();
List<Account> accList = [Select id,Name from Account where ParentId=:acc.id];
System.assertEquals('ExPay', accList[0].Name);
System.assertEquals('RePay', accList[1].Name);
System.assertEquals('test Pay', accList[2].Name);
System.assertEquals('ExPay', accList[3].Name);
System.assertEquals('test =ExPay', accList[4].Name);
}
}
i am not able to understand that the asserts i created is correct or not?
Can you help me out with it?
I am hoping that in my given code you have replaced this code line number 20 'AND Account.RecordTypeId= \'Time Rack\'' to 'AND Account.RecordType.Name= \'Time Rack\''.
There will be only one account will gets created for ExPay account name. Which you have asserted in first assert.
So in this above test class total 4 accounts gets created with below names :
- ExPay
- RePay
- test Pay
- test =ExPay
You could also put a first assert after fetching the account as below which will verify how many accounts got created in batch. So your final assert will be like below :Hope above will solve your problem, Hit like if this will help you.
Thanks
Dheeraj Kumar
my first assertion is failing Assertion Failed: Expected: 4, Actual: 5
Any suggestions?
I have looked into your test class code. For a batch class test method, batch will be completed once code execution reached at Test.stopTest(). Rather then calling run method in b/w Test.startTest() and Test.stopTest(). You need to call run method after Test.stopTest().
Below code needs to be moved after Test.stopTest();
Set<Id> OppIds = new Set<Id>();
OppIds.add(opp.Id);
BatchResellerPartnerToResellerCustomer.run(OppIds);
Because in run method the opportunity id which you are passing will get one opportunity which have the Customer Type as Reseller.
Hope above will solve your problem, Hit like if this will help you.
Thanks
Dheeraj Kumar