Salesforce: Can I associate a completion of a task with a field update? - triggers

I'm trying to see if it's possible for a field in Opportunity to be updated (a checkbox to be checked true) when someone completes a related task. Is there a way to do this?

I don't think this can be done with cross-object workflow, since the WhatId field of a Task is a "polymorphic key". If I'm right, you'll have to use a Trigger on Task.

As Jeremy said you'll need a trigger, code will look something like (I've not checked field names etc. so treat this as almost-real pseudo code)!
trigger TaskAfterInsertUpdate on Task (after update, after insert)
{
list<opportunity> liOpportunities = new list<opportunity>();
list<id> liIDs = new list<id>();
for(Task sTask : trigger.new)
{
if(sTask.Status == 'Complete' && ('' + sTask.WhatId).startsWith('006'))
{
liIDs.add(sTask.WhatId);
}
}
for(Opportunity sOppty : [select Id, CheckBoxField__c from Opportunity where Id in : liIDS])
{
sOppty.CheckBoxField__c = true;
liOpportunities.add(sOppty);
}
update liOpportunities;
}
Hope this is of some help!

Related

OrderMgr getOrder() method always return null

I am writing a simple job that fetches the order status from external service.
Then I want to use this data to update the order.
Whenever I call a static method getOrder(id : String) on the OrderMgr I receive null.
The order with given ID exists and is visible in BM.
Can someone advise me what am I doing incorrectly?
importPackage(dw.order);
function execute( pdict : PipelineDictionary ) : Number
{
var mgr : OrderMgr = OrderMgr;
var logH : Logger = Logger.getLogger("test1", "test1");
var order : Order = mgr.getOrder("00000101");
if (order == null){
// always null, even if the order exists
logH.info("The order is null");
}
return PIPELET_NEXT;
}
Check in scope of what site you are running the job. If it’s in Organization scope, you have to change to the site scope.
Second when you will do update, don’t forget to use Transactions.
I think you need to use getOrder() method from a batch job in dw business manager, there are some scripts that does not allow you to call them from storefront

Apex Triggers - Trailhead

The code itself doesn't give any errors, but anytime I run it Trailhead gives me this message:
"Challenge not yet complete... here's what's wrong:
Executing the trigger did not work as expected. "
Here are the instructions:
For this challenge, you need to create a trigger that, before insert or update, checks for a checkbox. If the checkbox field is true, it sets the Shipping Postal Code (whose API name is ShippingPostalCode) to be the same as the Billing Postal Code (BillingPostalCode).
The Apex trigger must be called AccountAddressTrigger.
The Account object will need a new custom checkbox that should have the Field Label 'Match Billing Address' and Field Name of Match_Billing_Address. The resulting API Name should be Match_Billing_Address__c.
With AccountAddressTrigger active, if an Account has a Billing Postal Code and Match_Billing_Address__c is true, the record should have the Shipping Postal Code set to match on insert or update.
My code:
trigger AccountAddressTrigger on Account (before insert,before update) {
for(Account a : [SELECT Id FROM Account WHERE Match_Billing_Address__c = TRUE AND BillingPostalCode != NULL])
{
a.ShippingPostalCode = a.BillingPostalCode;
update a;
}//end for
}
Your Trigger is like this way.
trigger AccountAddressTrigger on Account (before insert,before update) {
//Iterate all accounts that is updated or inserted.
for(Account acc :Trigger.New){
//if match is true set values.
if(acc.Match_Billing_Address__c){
acc.ShippingPostalCode = acc.BillingPostalCode;
}
}
}
trigger AccountAddressTrigger on Account (before insert,before update) {
for(Account a : Trigger.new){
If (a.Match_Billing_Address__c == true && a.BillingPostalCode!=Null) {
a.ShippingPostalCode = a.BillingPostalCode;
}
}
}
First need to create check box field with name Match billing address in Account tab then open developer console and write the code and save it .Finally check that whether its working or not again in ur salesforce instance
here is the code :
trigger accountAddressTrigger on Account (before insert, before update) {
for(Account acct : trigger.new){
if(acct.Match_Billing_Address__c == true)
acct.ShippingPostalCode = acct.BillingPostalCode;
}
}
Trigger Name_of_Trigger on Object (Event 1,Event 2) {
for(Each Object's Event1/Event2) {
if (Check box is selected) {
Assign Billing address to Shipping address (i.e using '=' operator);
}
}
}

Salesforce Checking if Values Changed (Trigger Handler)

I am trying to check if Account field changed from a specific value.
If old Account's flag was "Open" and new Account flag is not open
Then perform some check.
private void doCheck(map<Id, Account> oldAccounts, map<Id, Account> newAccounts){
List<Account>newList= new List<Account>();
List<Account>oldList= new List<Account>();
oldList= oldAccounts.values();
newList= newAccounts.values();
//check if old account flag changed from "open"
}
private void doCheck(map<Id, Account> oldAccounts, map<Id, Account> newAccounts){
for(Id i : oldAccounts.keyset()){
Account old = oldAccounts.get(i).Flag__c;
if(old.Flag__c == 'Open' && old.Flag__c != newAccounts.get(i).Flag__c){
// do your magic here
}
}
}
If you're going to run some queries for that - you shouldn't make queries in a loop. Some helper Set<Id> where you'd put the Ids and later run the queries for all Account Id's in that set might be best idea... hard to say what exactly do you need.
the keyset() and get(someKey) methods from Map collection are described in Apex help: http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_map.htm#apex_System_Map_methods

Salesforce.com Trigger- Require primary contact to save opportunity

There are currently two AppExchange apps that do this, but I was wondering if anyone has figured out how to do this without installing an app, as the number of apps I can install in my organization is limited.
The trigger needs to check to see if there is a contact listed, if not, then an error message should display. I tried this with validation rules, but had no luck because the OpportunityContactRole is a separate object.
Could someone provide their thoughts?
trigger OpportunityBeforUpdate on Opportunity (before update) {
set<Id> oppIdSet = new set<Id>();
set<Id> OpportunityContactRoleIdSet = new set<Id>();
for(Opportunity opp:trigger.new){
if("Some condition")oppIdSet.add(opp.Id);
}
for(OpportunityContactRole ocr:[select Id,OpportunityId from OpportunityContactRole where OpportunityId in:oppIdSet]){
OpportunityContactRoleIdSet.add(ocr.OpportunityId);
}
for(Opportunity opp:trigger.new){
if(oppIdSet.contains(opp.Id) && !OpportunityContactRoleIdSet.contains(opp.Id))
opp.addError('Some error');
}
}

EF SaveChanges() throws an exception 'The EntityKey property can only be set when the current value of the property is null'

I have been reading all similar posts I found regarding EF but I can't still manage to found a solution.
I'm very new to the EF and I have been reading some useful info about working with it but I think that I'm missing something.
The scenario is like this:
I want a user to be able to create an account in an ASP.NET webpage. So I have a table named 'Accounts'. The user must agree with the condition terms of the site, that may be updated in the futere, so I have also a table called 'ConditionTerms' that has 1 to many relation with the account (many accounts have an unique condition term).
I wanted to separete the specific personal user data from the data of the account so I also created a table called 'Persons' and I set the relation ship so that a person may have many accounts.
Now, when I want to save an account into the database, I retrieve the last conditionTerm available in the database and I attach it to the account entity. Then when I try to save the data via SaveChanges() I get the exception mentioned in the title of the post. The thing is that if all entities are new, when the associations are created, the EntityState for all the items is 'Detached' and it works, but when I retrieve the existing conditionTerm from the data base and I add it to the account.ConditionTerm, the account changes its state to 'Added' and then it throws the exception.
I read somewhere that when this happens, it means that all the entity tree is considered as already added by the context and I should only need to call SaveChanges() without the AddObject() method since it is already added. I tried this and then I get no exception and the code ends, but then if I check the database (SQL Server 2008 express) the account hasn't been added at all.
This is the code I'm trying and I think it should work but it's clear that I'm missing something:
[TestMethod]
public void TestCreateNewAccount()
{
try
{
AccountRepository accountRepository = new AccountRepository();
Account account = new Account()
{
Username = "TestUsername",
Password = "TestPassword",
Email = "TestEmail",
Nickname = "TestNickName",
Quote = "Test Quote",
AgreedToTermsDate = DateTime.Now,
CreationDate = DateTime.Now,
LastUpdateTime = DateTime.Now
};
// This works (all new entities!)
//ConditionTerm conditionTerm = new ConditionTerm()
//{
// Text = "This is some test condition term.",
// CreationDate = DateTime.Now,
// LastUpdateTime = DateTime.Now
//};
//This does not work (attaching an existing entity to a new one)
ConditionTerm conditionTerm = new ConditionTermsRepository().GetCurrentTerm();
Person person = new Person()
{
FirstName = "TestName",
Surname = "TestSurname",
CreationDate = DateTime.Now,
LastUpdateTime = DateTime.Now
};
account.ConditionTerm = conditionTerm;
account.Person = person;
using (ImproveEntities entities = Connection.GetModel())
{
if (account.ID > 0)
{
Account newAccount = new Account();
newAccount.ID = account.ID;
entities.Accounts.Attach(newAccount);
entities.Accounts.ApplyCurrentValues(account);
}
else
{
entities.Accounts.AddObject(account);
entities.SaveChanges();
}
}
}
catch (Exception)
{
}
}
Any help would be very much apreciated!
EDIT: This is the GetCurrentTerm() method:
public ConditionTerm GetCurrentTerm()
{
using (ImproveEntities entities = Connection.GetModel())
{
ConditionTerm conditionTerm = (from ct in entities.ConditionTerms
orderby ct.CreationDate descending
select ct).FirstOrDefault();
return conditionTerm;
}
}
If I understand correctly you want to insert a new account along with a new user into the database. But you don't want to create a new ConditionTerm but instead assign an existing ConditionTerm to the account.
The problem is that you fetch the existing ConditionTerm in another context (in your GetCurrentTerm) than the context you use for saving the new account. This second context doesn't know anything about the ConditionTerm, so you must EF explicitely tell that this conditionTerm already exists by attaching it to the second context:
// ...
using (ImproveEntities entities = Connection.GetModel())
{
entities.ConditionTerms.Attach(conditionTerm);
account.ConditionTerm = conditionTerm;
account.Person = person;
entities.Accounts.AddObject(account);
entities.SaveChanges();
}
// ...