Apex trigger for Number of Time Record is Viewed - apex

I am trying to develop an Apex trigger for an Object Lead. Requirement is like count number of times that record viewed.
I am Sharing my Code with you.
trigger ContactedRecord on Lead (after insert,after update) {
List<ID> lid=new List<ID>();
for(Lead l:Trigger.new)
{
lid.add(l.id);
}
Integer i=0;
List<Lead> leadlist=[Select id,No_of_Times_Contacted__c from Lead where id IN:lid];
System.debug('**List size**'+leadlist.size());
for(Lead li: leadlist)
{
/*Lead l=new Lead();
Lead olddata=Trigger.oldMap.get(li.id);*/
system.debug('No of Contacts');
if(li.size()>0)
{
for(Integer j=0;j<li.Size(0);j++)
{
if(li.No_of_Times_Contacted__c ==li[j].id)
{
i++;
li[j].No_of_Times_Contacted__c =i;
}
}
}
update li;
}

Related

Trigger to run only after checkbox goes rom unchecked to checked

I want to run a trigger on Contact if a checkbox on Contact object goes from unchecked state to checked state and then do some processing on the records. I have this trigger on after insert and after update. The code works fine for update but if I check the box while creating a new contact record, the trigger does not detect the below condition in the code and therefore sends an empty list to contactTriggerHandler class.
if (Trigger.oldMap.get(con.Id).checkbox==false && con.checkbox== true)
trigger Contact on Contact (after update, after insert) {
List<Contact> listofContacts = new List<Contact>();
List<Contact> usersToCreate= new List<Contact>();
if (Trigger.isAfter) {
if(trigger.isInsert){
System.debug('After insert');
if(RecursiveTriggerHandler.isFirstTime){
RecursiveTriggerHandler.isFirstTime = false;
for (Contact con : Trigger.new) {
Contact contacttoUpdate = con.clone(true,true);
contacttoupdate.Nickname__c=contacttoUpdate.firstname;
listofContacts.add(contacttoUpdate);
}
System.debug(listofContacts);
ContactTriggerHandler.AfterInsert(listofContacts);
update listofContacts;
}
}
else if(trigger.isUpdate){
System.debug('After insert and update function');
if(RecursiveTriggerHandler.isFirstTime){
RecursiveTriggerHandler.isFirstTime = false;
for (Contact con : Trigger.new) {
Contact contacttoUpdate = con.clone(true,true);
contacttoupdate.Nickname__c=contacttoUpdate.firstname;
listofContacts.add(contacttoUpdate);
if (Trigger.oldMap.get(con.Id).checkbox==false && con.checkbox== true) {
usersToCreate.add(contacttoUpdate);
}
}
ContactTriggerHandler.AfterInsert(usersToCreate);
update listofContacts;
}
}
}
}
Here is the recursive handler class:
public class RecursiveTriggerHandler{
public static Boolean isFirstTime = true;
}

Salesforce APEX Test Class for Simple Trigger

I've been going nuts over this. Nothing in my IF loop is firing through my test class and I cannot figure out why. I have done a lot of reading online and it appears that I am doing things correctly but it still hasn't solved my code coverage. This is the last line that runs:
If (isWithin == True){
after that I can't get anything to run within that IF loop, I have reversed the logic and it still doesn't run. I feel like I will kick myself when someone points it out but here is my code:
trigger caseCreatedDurringBusinessHours on Case (after insert) {
//Create list and map for cases
List<case> casesToUpdate = new List<case>();
Map<Id, case> caseMap = new Map<Id, case>();
// Get the default business hours
BusinessHours bh = [SELECT Id FROM BusinessHours WHERE IsDefault=true];
// Create Datetime on for now in the local timezone.
Datetime targetTime =System.now();
// Find whether the time now is within the default business hours
Boolean isWithin;
if ( Test.isRunningTest() ){
Boolean isWithin = True;
}
else{
Boolean isWithin = BusinessHours.isWithin(bh.id, targetTime);
}
// Update cases being inserted if during business hours
If (isWithin == True){
// Add cases to map if not null
For(case newcase : trigger.new) {
if(newcase.id != null){
caseMap.put(newcase.Id, newcase);
}
}
// Check that cases are in the map before SOQL query and update
If(caseMap.size() > 0){
// Query cases
casesToUpdate = [SELECT Id, Created_During_Business_Hours__c FROM case WHERE Id IN: caseMap.keySet()];
// Assign new value for checkbox field
for (case c: casesToUpdate){
c.Created_During_Business_Hours__c = TRUE;
}
// if the list of cases isnt empty, update them
if (casesToUpdate.size() > 0)
{
update casesToUpdate;
}
}
}
}
and here is my test class:
#isTest
private class BusinessHoursTest {
#isTest static void createCaseNotInBusinessHours() {
case c = new case();
c.subject = 'Test Subject';
insert c;
}
}
I think you can just copy the main logic to the apex class and just call the method of apex class from the apex trigger.
So it will make it more easy to write the test class.
Let me know if you need more help in this.
I'm sure you've figured this out by now but this block of code is re-defining the isWithin variable inside of the if/else blocks:
Boolean isWithin;
if (Test.isRunningTest()) {
Boolean isWithin = True;
} else {
Boolean isWithin = BusinessHours.isWithin(bh.id, targetTime);
}
That needs to be:
Boolean isWithin;
if (Test.isRunningTest()) {
isWithin = True;
} else {
isWithin = BusinessHours.isWithin(bh.id, targetTime);
}
Or rather a ternary operator for the cleanest code:
Boolean isWithin = !Test.isRunningTest() ? BusinessHours.isWithin(bh.id, targetTime) : true;

Failure Message: "System.QueryException: No such column 'Address' on entity 'Lead'. I

I am passing all test coverage in salesforce apex in sandbox but in deploying to live getting the
error in subject, i dont know how to handle it.
my test class code is:
#isTest(SeeAllData=true)
public class myLeadTest{
public static testMethod void testMyController5() {
Account acc= new Account(name='test');
acc.Order__c='wee';
insert acc;
Campaign camp = new Campaign(Name='test');
insert camp;
Company__c cm= new Company__c();
cm.Company_Id__c=12;
cm.Name='234';
cm.Account__c=acc.id;
insert cm;
Lead l= new Lead();
l.Campaign__c=camp.Id;
l.LastName='test';
l.Company='cmpny';
l.Company_Id__c=cm.Company_Id__c;
l.Email='test#yahoo.com';
l.Status='Closed - Converted';
l.Order__c=acc.Order__c;
// l.Auto_Convert__c=true;
// l.IsConverted=false;
//l.ConvertedAccountId=acc.Id;
Lead[] l2= new Lead[]{l};
insert l2;
Opportunity op= new Opportunity ();
op.StageName='Won (Agency)';
op.Name='test';
op.CloseDate=Date.valueOf('2015-04-28');
op.AccountId=acc.id;
op.LeadSource='web';
op.StageName= 'Won (Agency)';
op.CampaignId=camp.id;
op.TrialStart__c=Date.valueOf('2012-04-28');
insert op;
Contact cnt= new Contact();
cnt.LastName='test';
cnt.AccountId=acc.id;
cnt.ASEO_Company_Id__c=12;
cnt.Email=l.Email;
cnt.Company__c=cm.id;
insert cnt;
///////////////
/* Lead l5= new Lead();
l5.Campaign__c=camp.Id;
l5.LastName='test';
l5.Company='cmpny';
l5.Company_Id__c=12;
l5.Email='test#yahoo.com';
l5.Status='Closed-Converted';
l5.isConverted=false;
//l.ConvertedAccountId=acc.Id;
insert l5; */
Contact cnt1= new Contact();
cnt1.LastName='test';
cnt1.AccountId=acc.id;
cnt1.ASEO_Company_Id__c=12;
cnt1.Email=l.Email;
insert cnt1;
Database.LeadConvert leadConvert = new Database.LeadConvert();
leadConvert.setLeadId(l2[0].Id);
LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
leadConvert.setConvertedStatus(convertStatus.MasterLabel);
leadConvert.setOpportunityName(op.Name);
leadConvert.setConvertedStatus('Closed - Converted');
Database.LeadConvertResult lcResult = Database.ConvertLead(leadConvert);
// MyLead.addCampaign(l2[0], camp.Name);
// MyLead.updateOpportunity(l2[0], lcResult);
// MyLead.updateContact( l2[0], lcResult, cm) ;
// myLead.addCampaignMembers(l2);
}
}
and class code which i call in trigger :
public class MyLead {
public static void convertLead(Lead[] leads) {
Database.LeadConvert leadConvert = new Database.LeadConvert();
for (Lead lead :leads) {
if (!(lead.IsConverted)) {
// Check if an account exists with email. Attach Contact and Account, convert Lead.
Contact[] myContacts = [SELECT Id, AccountId FROM Contact WHERE Email = :lead.Email Limit 1];
if (myContacts.size() == 1) {
System.debug('Existing Contact');
MyLead.attachExistingConvert(lead, myContacts[0]);
}
else {
System.debug('No existing contact');
if (lead.Auto_Convert__c) {
MyLead.addCampaign(lead, lead.Campaign__c);
leadConvert.setLeadId(lead.Id);
leadConvert.setConvertedStatus('Closed - Converted');
Database.LeadConvertResult lcResult = Database.ConvertLead(leadConvert);
// Populate the newly created records with extra data.
MyLead.updateOpportunity(lead, lcResult);
Company__c myCompany = [SELECT Id FROM Company__c WHERE Company_Id__c = :lead.Company_Id__c];
MyLead.updateContact(lead, lcResult, myCompany);
// Must update the Company before Account otherwise the Account lookup will fail.
MyLead.updateCompany(lead, lcResult, myCompany);
MyLead.updateAccount(lead, lcResult, myCompany);
}
}
}
}
}
// Attaches Lead to Contact and Account if matched by Email, converts Lead and creates opportunity if it doesn't exist.
public static void attachExistingConvert(Lead lead, Contact contact) {
MyLead.addCampaign(lead, lead.Campaign__c);
Database.leadConvert leadConvert = new Database.LeadConvert();
leadConvert.setLeadId(lead.Id);
leadConvert.setConvertedStatus('Closed - Converted');
leadConvert.setContactId(contact.Id);
leadConvert.setAccountId(contact.AccountId);
leadConvert.setSendNotificationEmail(True);
// Do not create an opportunity if any exist.
Opportunity[] myOpportunity = [SELECT Id FROM Opportunity WHERE AccountId = :contact.AccountId];
if (myOpportunity.size() > 0) {
leadConvert.setDoNotCreateOpportunity(True);
}
leadConvert.setLeadId(lead.Id);
Database.LeadConvertResult leadConvertResult = Database.convertLead(leadConvert);
// If we created an opportunity, update it with extra stuff.
if (leadConvert.isDoNotCreateOpportunity() == False) {
MyLead.updateOpportunity(lead, leadConvertResult);
}
}
// Updates the newly created Opportunity with extra data
public static void updateOpportunity(Lead lead, Database.LeadConvertResult lcResult) {
Opportunity myOpportunity = [SELECT Id, StageName FROM Opportunity WHERE Id = :lcResult.opportunityId];
myOpportunity.Name = 'Online Upgrade';
myOpportunity.TrialStart__c = lead.CreatedDate.date();
//myOpportunity.Amount = lead.Monthly_Revenue__c;
myOpportunity.Amount = lead.Amount__c;
myOpportunity.Type = 'New Business';
myOpportunity.LeadSource = 'Website';
myOpportunity.Order__c = lead.Order__c;
DateTime dt = System.now();
Date d = dt.date();
myOpportunity.CloseDate = d;
myOpportunity.StageName = lead.Agency__c ? 'Won (Agency)' : 'Won (End User)';
myOpportunity.Probability = 100;
update myOpportunity;
}
// Updates the newly created Account with extra data
public static void updateAccount(Lead lead, Database.LeadConvertResult lcResult, Company__c myCompany) {
Account myAccount = [SELECT Id FROM Account WHERE Id = :lcResult.accountId];
myAccount.Type = 'Customer';
myAccount.ASEO_Company_Id__c = lead.Company_Id__c;
myAccount.Company__c = myCompany.Id; // Setting the company will cause the company account lookup to fail
myAccount.Order__c = lead.Order__c;
update myAccount;
}
// Updates the newly created Contact with extra data
public static void updateContact(Lead lead, Database.LeadConvertResult lcResult, Company__c myCompany) {
Contact myContact = [SELECT Id FROM Contact WHERE Id = :lcResult.contactId];
myContact.ASEO_Company_Id__c = lead.Company_Id__c;
myContact.Company__c = myCompany.Id;
update myContact;
}
// Updates the Company with extra data
public static void updateCompany(Lead lead, Database.LeadConvertResult lcResult, Company__c myCompany) {
myCompany.Account__c = lcResult.accountId;
update myCompany;
}
// Adds a lead to a campaign
public static void addCampaign(Lead lead, String campaign) {
Campaign[] myCampaigns = [Select Id FROM Campaign WHERE Name = :campaign LIMIT 1];
if (myCampaigns.size() == 1) {
CampaignMember campaignMember = new CampaignMember (campaignId=myCampaigns[0].Id, leadId=lead.Id);
insert campaignMember;
}
}
// Create campaign members from leads. Campaign comes from lead.Campaign__c.
public static void addCampaignMembers(Lead[] leads) {
for (Lead lead :leads) {
// Might want to query Campaigns table instead.
//Set<String> campaigns = new Set<String>();
//campaigns.add('Freemium');
Campaign[] myCampaigns = [SELECT Id FROM Campaign WHERE Name = :lead.Campaign__c LIMIT 1];
//if (campaigns.contains(lead.Campaign__c)) {
if (myCampaigns.size() == 1) {
MyLead.addCampaign(lead, lead.Campaign__c);
}
}
}
}
and my lead trigger is:
trigger LeadTrigger on Lead (after insert, after update) {
Lead[] leads = Trigger.new;
//MyLead.createOpportunity(leads);
MyLead.convertLead(leads);
Please any one can help me, i tries 25 times but in deploying to production give me error in the given subject, or any one give code coverage of this class, thank you in advance
Looks like the issue is based on a soql query that is not included in your code. You try to query a field called "Address" but this field doesn't exist. Address is still in beta...
Try to adjust your query and use the fields City, Street, Country and PostalCode.
You can learn more about sObject fields there: http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_objects_lead.htm
Just in case someone else get to this question with this problem.
As Christian said, the code is trying to access the "Address" field from Lead in a SOQL query. Starting from API version 30, the compound fields are available to use in queries (http://www.salesforce.com/us/developer/docs/api/Content/compound_fields_address.htm).
So, if you run into this issue with a query in your code, check for the API version of the class and the visualforce page. Both must be 30 or greater.

trying to write a test for an apex trigger

I'm working on a trigger/test class and i can't figure out how to get the test class to work. I know that i need to update my opportunity to use the trigger but i'm not sure how to and then how to verify that my trigger is working.
Trigger:
trigger add_primary_advisor on Opportunity(before update) {
for(Opportunity o: Trigger.new){
if (o.IsClosed && !Trigger.oldMap.get(o.id).IsClosed) {
OpportunityContactRole contactRole =
[select ContactID from OpportunityContactRole where IsPrimary = true and OpportunityId = :o.id];
if (contactRole != null) {
o.Primary_Advisor__c=contactRole.ContactID;
}
}
}
}
Test class:
#isTest
private class primary_advisor_test {
static testMethod void primary_advisor(){
Opportunity opp = new Opportunity(Name='test opp', StageName='stage', Probability = 95, CloseDate=system.today());
insert opp;
update opp;
}
}
Before going into the solution for the test class I would like to point out the trigger is not builkified as you have a SOQL query inside you for loop which is not a best practice.
I am not aware of the exact functionality of the opportunityContactRole object, I am just assuming that it is a object which will hold the contact id and the opportunityID, more or less like a junction object.
#isTest
private class primary_advisor_test {
static testMethod void primary_advisor(){
//Create a contact that will be added to the opportunityCOntactRole.
contact con = new contact(name='testCon');// add all the required field as per your org settings
insert Con;
Opportunity opp = new Opportunity(Name='test opp', StageName='stage', Probability = 95, CloseDate=system.today());
insert opp;
//Create the opporunityContactRole.
opportunityCOntactRole oppCOn = new new opportunityCOntactRole(OpportunityId=opp.id, contactId= con.Id, isPrimary=true);
insert oppCon;
//update the opportunity so that it is closed and enters the if conditon in your trigger.
opp.stageName='Closed';
update opp;
}
}
The problem is you didn't changed any fields before calling update try this
opp.Probability = 90;
update opp;

MonoTouch CoolStorage OneToMany caching issue

I'm experiencing an issue with CoolStorage where a OneToMany relationship is being cached when reading a list for the first time, that list then fails to update when the data changes later.
When restarting my app the list is correct, so it must be a caching issue and I can't find the solution in the CoolStorage documentation or anywhere.
I've pasted my Unit test code below.
I have a Game class that has an Opponent of type Person. There are many Games, and a Person can be an Opponent for many Games.
My Person class has a CSList called OpponentGames, so at anytime for that Person I can say 'get the games where this person is the Opponent'.
In the unit test the first time I reference 'person.OpponentGames.Count', it correctly tells me there is one game. After creating a second game and adding my person as the opponent, it still reports one game for OpponentGames.
If I remove the first count, the test passes, so the first check result is being cached and from there it's not updated.
I'll greatly appreciate any suggestions!! Thanks.
The SQL (sqlite3) setup:
CSDatabase.ExecuteNonQuery(
"CREATE TABLE Person " +
"(ServerId INTEGER PRIMARY KEY)");
CSDatabase.ExecuteNonQuery(
"CREATE TABLE Game " +
"(ServerId INTEGER PRIMARY KEY," +
"OpponentId INTEGER REFERENCES User(ServerId))");
The CoolStorage .Net classes:
[MapTo("Game")]
public class Game : CSObject<Game,int>
{
//[PrimaryKey]
public int ServerId { get { return (int) GetField("ServerId"); } set { SetField("ServerId", value); } }
[ManyToOne (LocalKey="OpponentId", ForeignKey="ServerId")]
public Person Opponent { get { return (Person) GetField("Opponent"); } set { SetField("Opponent", value); } }
}
[MapTo("Person")]
public class Person : CSObject<Person,int>
{
//[PrimaryKey]
public int ServerId { get { return (int) GetField("ServerId"); } set { SetField("ServerId", value); } }
[OneToMany (LocalKey="ServerId", ForeignKey="OpponentId")]
public CSList<Game> OpponentGames { get { return (CSList<Game>) GetField("OpponentGames"); } }
}
And finally, the Unit test:
// user
Person person = Person.New ();
person.ServerId = 1;
// first game
Game game = Game.New ();
game.ServerId = 1;
game.Opponent = person;
game.Save ();
person.Save ();
// this line correctly returns 1, removing this passes the test
Console.WriteLine ("count0: " + person.OpponentGames.Count);
// second game
Game game2 = Game.New ();
game2.ServerId = 2;
game2.Opponent = person;
game2.Save ();
person.Save ();
// this incorrectly shows 1, should be 2
Console.WriteLine ("count1: " + person.OpponentGames.Count);
// and it fails
Assert.True (person.OpponentGames.Count == 2);