Copy Product Price into a Custom Field Object using APEX Trigger in Salesforce - triggers

Trying to just copy the Cost_Price__c field of a product into a custom object when it is updated (if possible inserted too) using an APEX trigger.
I'm so close but the error I am getting at the moment is: Illegal assignment from PricebookEntry to String
trigger updateAccount on Account (after update) {
for (Account oAccount : trigger.new) {
//create variable to store product ID
string productId = oAccount.Product__c;
//SQL statement to lookup price of product using productID
PricebookEntry sqlResult = [SELECT Cost_Price__c
FROM PricebookEntry
WHERE Product2Id =: productId];
//save the returned SQL result inside the field of Industry - Illegal assignment from PricebookEntry to String
oAccount.Industry = sqlResult;
}
}
Am I right in thinking it's because its returning a collective group of results from the SOQL call? I've tried using the sqlResult[0] which still doesn't seem to work.

The Illegal Assignmnet because you are assigning a whole Object i.e PriceBook Entry to a string type of field i.e Industry on Account.
Please use the following code for assignment.
oAccount.Industry = sqlResult[0].Cost_Price__c;
Please mark the answer if this works for you.
Thanks,
Tushar

Related

APEX Trigger when a textfield gets updated

I am trying to create a trigger in APEX, when an custom textfield of an custom sObject gets updated with products (means, when new products get insert or existing one get deleted).
How can I compare in APEX the Trigger.Old values with the Trigger? New values of this field in order to start the Trigger.
It would look something like this:
Trigger NameOfTrigger on CustomSObject__c (after update){
/*there is already an existing list of products that get insert into the custom textfield (probably as Strings)
*/
List <String> textList = new List <String> ();
/*PseudoCode: if the textfield got updated/has changed, copy from every entry of this textfield (entry = product name as a string) and copy fieldX into another sObject
*/
if(CustomSObject.field(OldValues) != CustomSObject.field(NewValues)){
for (String product : textList){
//Trigger e.g. copy the values of a certain field of p and paste them in another sObject
}
Could somebody help me with the syntax?
You can utilize inbuilt Trigger.new and Trigger.old to get the latest and old values of any record. These lists can be used to achieve what you're looking for.
Sample example would be:
Trigger NameOfTrigger on CustomSObject__c (after update){
for(CustomSObject__c customObject : Trigger.new) {
// get old record
CustomSObject__c oldCustomObject = Trigger.oldMap.get(customObject.Id);
// compare old and new values of a particular field
if(customObject.fieldName != oldCustomObject.fieldName){
//Trigger e.g. copy the values of a certain field of p and paste them in another sObject
}
}
}
See documentation of Trigger.new & Trigger.old

Salesforce, accessing TargetObject fields from ProcessInstance object using SOQL

I have the following in my controller for a visualforce page which is consumed by a PageBlockTable.
I can access other standard fields of the p.ProcessInstance.TargetObject such as p.ProcessInstance.TargetObject.Name and .Id etc...
But how can I access custom fields of TargetObject of where the record is related to? Or is this not possible? If its not possible then I assume I can do it in a seperate query, but I cannot figure out how.
Thank you
List<ProcessInstanceWorkitem> results = [Select p.ProcessInstance.Status, p.ProcessInstance.TargetObject.Name, p.ProcessInstance.TargetObject.Id, p.Actor.Name, p.CreatedBy.Name, p.CreatedDate FROM ProcessInstanceWorkitem p];
You have to perform an additional SOQL query on the TargetObject, as ProcessInstance is polymorphic. for example.
List<ProcessInstanceWorkitem> results = [Select p.ProcessInstance.Status, p.ProcessInstance.TargetObject.Name, p.ProcessInstance.TargetObject.Id, p.Actor.Name, p.CreatedBy.Name, p.CreatedDate FROM ProcessInstanceWorkitem p];
List<Id> targetObjectIds = new List<Id>();
for(SObject result : results)
{
targetObjectIds.add(result.p.ProcessInstance.TargetObject.Id);
}
List<SObject> targetObjectFields = [SELECT Id, Field names FROM SObject WHERE Id IN:targetObjectIds];
Edited:
Please change SObject to the object you are currently using.

Apex code to update new Opportunity with values from related object

What would be the proper method to update a list of new Opportunities with the values from a related record.
for (Opportunity opps:Trigger.new){
[SELECT Id, CorpOwner__r, Contact__r,(SELECT Id, AccountLocation from Account)]
o.CorpOwner__r =Account.Id; o.AccountLocation = opps.Account.AccountLocation;
insert opps
Do you call the lookup fields by the __r suffix? Could you do a before insert operation and still look up the Opportunity.CorpOwner__r relationship to values in the CorpOwner__r Account record, or does that relationship not exist since the record has not been created? What would be a proper batchified way to go about it?
Here's a possibility that demonstrates a number of concepts:
trigger UpdateOpptyWithAccountInfo on Opportunity (before insert) {
// Keep this SOQL query out of the FOR loop for better efficiency/batching
Map<Id, Account> relatedAccounts = new Map<Id, Account>(
[SELECT Id, AccountLocation__c
FROM Account
WHERE Id IN
(SELECT AccountId
FROM Opportunity
WHERE Id = :Trigger.new)
]
);
for (Opportunity o : Trigger.new) {
/* Find each opportunity's Account in the map we queried for earlier
* Note: there's probably a more efficient way to use a Map of Opportunity IDs to Account objects...
* This works fine and could be more readable.
*/
for (Account a : relatedAccounts.values()) {
if (a.Id == o.AccountId) {
// Once you've found the account related to this opportunity, update the values
o.CorpOwner__c = a.Id;
o.AccountLocation__c = a.AccountLocation__c;
}
}
}
// We're still inside an `insert` trigger, so no need to call `insert` again.
// The new fields will be inserted along with everything else.
}
If you're establishing the relationship between objects, use the __c suffix:
o.CorpOwner__c = a.Id; // Associate Account `a` as Opportunity `o`'s CorpOwner
If you're looking up a field on a related object, then you would use __r:
System.debug(o.CorpOwner__r.Name); // Print Opportunity `o`'s CorpOwner's name

Apex Trigger to Update Lookup Field (Contact)

Need some advise on how to populate a lookup field (contact) via apex trigger
I've created a lookup field called Contact__c on Idea object.
I would like to populate the Contact__c with the createdby User if it was originated from the web (CreatedBy.Contact.Account.Name == "Web Ideas") and leave it empty for internal idea creation.
I have read up and created the following trigger and was able to save and run. However, upon saving the idea record, i am getting an error : UpdateContactonComplaints: data changed by trigger for field Contact: id value of incorrect type: 005N0000000l9iMIAQ
trigger UpdateContactonComplaints on Idea (before insert, before Update) {
list<id> oid = new list<id>();
for(Idea o: trigger.new){
oid.add(o.id);
}
map<id, Idea> ExtendU = new map<id, Idea>(
[select CreatedbyID from Idea where id in: oid]);
for(Idea o: trigger.new){
o.Contact__c = ExtendU.get(o.id).CreatedbyID;
}
}
In the Trigger, the user id(id of the User who created the idea) is assigned to Contact custom lookup field).
So, it throws an error, data changed by trigger for field Contact: id value of incorrect type:

Entity Framework, How to include related entities in this example

I have a table AccountSecurity which is a many-to-many table that relates Account entities and Securities. When I write the query below it returns all Securities that satisfy the where clause. However each Security instance in the list no longer has the reference to the AccountSecurity it came from. So when I do list[0].AccountSecurity it is empty. Is there anyway to include that information? I know I can rewrite the query to return AccountSecurities instead and use .Include("Security") on that, but I wonder if it can be done another way.
var list = (from acctSec in base.context.AccountSecurities
where acctSec.AccountId == accountId
select acctSec.Security).ToList();
UPDATE
Of course if I do two queries the graph gets populated properly, there has to be a way to do this in one shot.
var securities = (from acctSec in base.context.AccountSecurities
where acctSec.AccountId == accountId
select acctSec.Security).ToList();
//this query populates the AccountSecurities references within Security instances returned by query above
var xref = (from acctSec in base.context.AccountSecurities
where acctSec.AccountId == accountId
select acctSec).ToList();
var list = (from sec in base.context.Securities
.Include("AccountSecurity")
where sec.AccountSecurities.Any(as => as.AccountId == accountId)
select sec).ToList();
Try this:
var list = (from acctSec in base.context.AccountSecurities.Include("Security")
where acctSec.AccountId == accountId
select acctSec).ToList();
Then simply use the Security property as needed, and since it's read at the same time AccountSecurities is (single SQL with join), it will be very efficient.