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
Related
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
So i have written a trigger to prevent user from entering more than one opportunity product to the same opportunity, but the problem is when he adds more than one opportunity product at the same time, my trigger does not fire, salesforce takes it as one product.
What can i add to my trigger to fix this ?
My trigger :
trigger OpportunityLineItemBeforeInsert on OpportunityLineItem (before insert) {
Set<Id>opportunityIds = new Set<Id>();
// get all parent IDs
for(OpportunityLineItem i : trigger.new)
{
opportunityIds.add(i.OpportunityId);
}
// query for related Olis (Opportunity Line Items)
Map<Id, Opportunity> opps = new Map<Id, Opportunity>([SELECT ID,
(SELECT ID
FROM OpportunityLineItems)
FROM Opportunity
WHERE ID IN :opportunityIds]);
for(OpportunityLineItem i : trigger.new)
{
if(opps.get(i.OpportunityId).OpportunityLineItems.size()>0)
{
i.addError('Your Message');
}
}
}
Thank you in advance.
I would probably ignore anything related to the Oppty.
You want only one product created, so on creation, either the number of LI is 0 and you can create exactly one, or it' snot 0 and you can't create any.
I would just create a rollup field on the Oppty, count the products. If the count != 0, then fail the validation. If count = 0, then count the Olis in trigger.new and if !=1, fail.
Instead of writing code to do this you should instead create a field on products that stores the id of the parent opportunity, make that field unique, and populate the value via workflow or process builder with the id of the parent opportunity. That way if a second product gets added the unique constraint would fire and prevent the record from being inserted.
Another option would be to create a rollup on opportunity to count the number of opportunity products, then add a validation rule that show an error if the number of products > 1. The advantage of doing it this way is that you get to set the error message as opposed to the generic duplicate error message with the first option.
This may be a basic question, but it's my first, so please be kind :-).
I have a sap.m.table with two models, one model with transaction data (trxModel) and another model that is used to display a sap.m.select list (reasonCodeModel). The table model is set to trxModel.
The selected value key from the dropdown needs to update a value (ReasonCodeID) in the trxModel when a value from the reason code list is selected.
I can retrieve the selected key in the change event as so
var selKey = evt.getParameter("selectedItem").getKey();
Is there a simple way to find the trxModel relevant model path from the table row Select list value I've just modified? Or is it possible to bind the ReasonCodeID from the trxModel to the ReasonCodeID field in the reasonCodeModel?
Just an extra piece of info, The current row is selected and is accessible
var selItem = dtlTable.getSelectedItem();
2nd question and I guess could be kind of related, is there a way of getting the table model path based on the selected item (highlighted row) of the table? And vice a versa?
More details on Select & Table binding.
var tabTemplate = new sap.m.ColumnListItem(
{
::
new sap.m.Select(
"idReasonCodeSelect",
{
enabled : false,
change : function(evt) {
oS4View.getController().changeReasonCodeSel(evt);
}
}
),
Bind the resource code Select to the Table
// bind the reason codes to the reason code model
sap.ui.getCore().byId("idReasonCodeSelect").setModel(
oReasonCodeModel);
sap.ui.getCore().byId("idReasonCodeSelect").bindAggregation("items", "/results",
new sap.ui.core.Item({
key : "{ReasCodeID}",
text : "{ReasCodeDesc}"
}));
Per Qualiture comment, how do I bind the Select key to the table model ReasonCodeID value?
I found an approach to tackle the first part of my question above
From the change function on the Select, I can find the path of the table model using the following.
var path = evt.getSource().getParent().getBindingContext().sPath;
2nd Update:
On the selectionChange event on the table, there's a couple of options to find the associated model path or model content.
// find the model path
oModelPath = selItem.getBindingContext().getPath();
// model values
oItem = oEvent.getParameter("listItem").getBindingContext().getObject();
So my only remaining issue, While I loop through the table model results (trxModel) and I want the Select List (using setSelectedKey) to reflect the ReasonCodeID value in the trxModel.
I created a custom object XtendedUser which has an id and Name.
I created a custom lookupfield on Opportunity called "XtendedUser__c" which links the opportunity to the corresponding XtendedUser record.
Now I made it so that the name of an opportunityowner corresponds to the name of an XtendedUser-record, so I want the trigger to autopopulate the custom lookup field "XtendedUser__c" on the opportunity with the id of the corresponding XtendedUser-record of which the name matches the name of the opportunityowner.
I never wrote a trigger, always worked with workflows and fieldupdates, but I've got to make this work. So if you could please help me with this? I would be extremely greatfull!
Thanks in advance
You should use a map to link the records and retrieve the value before the insert of a new record and before the update of an existing record. This technique will also allow you to bulk update all your records. It should be something like:
trigger ExtendedUser__c on Opportunity (before insert, before Update) {
list<id> oid = new list<id>();
for(opportunity o: trigger.new){
oid.add(o.id);
}
map<id, ExtendedUser__c> ExtendU = new map<id, ExtendedUser__c>(
[select name from ExtendedUser__c where id in: oid]);
for(opportunity o: trigger.new){
o.name = ExtendU.get(o.id).name;
}
}
I'm new to Salesforce and I'm trying to create a trigger that will basically update fields and create a new Opportunity owner every time a new Opportunity gets added.
For clarity, I've attached my code below:
trigger trig_Opportunity_CreateOppOwner on Opportunity (before insert, before update) {
//Opportunity OppOwner = null;
List<id>OppsID = new List<id>(); //Get the id of all new Opportunities owners
for (Opportunity Opp : Trigger.new) { //If a new Opportunity is added, then create new OppOwner, if not, then don't add.
OppsId.add(Opp.ID); //adds all new Opportunities Id's
}
List<Opportunity>OppToUpdate = [SELECT Id,
Name,
Owner__c,
OppOwner,
FROM Opportunity
WHERE Id IN: Opp.ID // Select Id, OpportunityName,
];
if Trigger.oldMap.get(opp.id).Owner__c != Trigger.oldMap.get(OppToUpdate.id).Owner__c // verify that if previous Opportunity has a matching owner.
OppsId.add(Opp.ID); //populates new oppowner with ID's of all owners.
This is basically what I'm trying to do:
Trigger(Before Update, Before Insert){
Get all Triggered Opportunities.
Verify if old opportunities already has a matching Owner.
If it's not a matching owner, update Opportunity fields and update the opportunity.
I'm not sure how to get from step 2 to step 3. Any help would be appreciated.
By the code that you provided isn't clear where it's finished, from my side seems that after couples of lines that you've provided another couples of lines exists. Could you please post all your code? If it isn't so, and code that you posted is all your code, from my point of view, this code do nothing, absolutely nothing.
Why?
no validation's errors
no DML operation
trigger trig_Opportunity_CreateOppOwner on Opportunity (before insert, before update) {
//Opportunity OppOwner = null;
/*
List<id>OppsID = new List<id>(); //Get the id of all new Opportunities owners
for (Opportunity Opp : Trigger.new) { //If a new Opportunity is added, then create new OppOwner, if not, then don't add.
OppsId.add(Opp.ID); //adds all new Opportunities Id's
}
*/
// 3 started lines might be replaced by the following one
List<id>OppsID = Trigger.newMap.getKeys();
//but the following code perform select on Opportunity object and return the same list as Trigger.new
// OppToUpdate == Trigger.new
// What for? May be you should work with this part on "after insert/update"
List<Opportunity>OppToUpdate = [SELECT Id,
Name,
Owner__c,
OppOwner,
FROM Opportunity
//WHERE Id IN: Opp.ID // Opp - isn't exist and it isn't list/set of id
WHERE Id IN OppsId // I guess you meant this
];
// 1.variable "opp" isn't exist here
// 2. "OppToUpdate.id" - you can't use list in this manner
if Trigger.oldMap.get(opp.id).Owner__c != Trigger.oldMap.get(OppToUpdate.id).Owner__c // verify that if previous Opportunity has a matching owner.
OppsId.add(Opp.ID); //populates new oppowner with ID's of all owners.