You need to sign in to do that
Don't have an account?
How do I create a trigger which assigns a date to a lookup object?
I have a custom object "Label Order" which has a look-up relationship to the standard object "Product".
Product has two custom date fields, Last_Label_Order_Creation_Date and Last_Label_Order_Modification_Date, which should each contain the value for the last time the Product was ordered or an order was modified.
Since I can't make the standard Product object a "Master", I was advised to try using triggers, but I seem to be unable to save my triggers. The Force.com IDE states for both "Save error: Expression cannot be assigned". If I submit through setup, the error is "Error: Compile Error: Expression cannot be assigned at line -1 column -1".
Here are my codes:
trigger LastLabelOrderCreationDate on Label_Order__c (after insert)
{
Product2.Last_Label_Order_Creation_Date__c = date.today();
}
and
trigger LastLabelOrderModificationDate on Label_Order__c (after update)
{
Product2.Last_Label_Order_Modification_Date__c = date.today();
}
What am I doing wrong?
Extrapolating upon Guyver118's help with a different trigger issue, I have been able to solve these problems. :-)
For the curious, code for the LastLabelOrderCreationDate follows:
trigger LastLabelOrderCreationDate on Label_Order__c (after insert)
{
Set productIds = new Set();
for (Label_Order__c labelOrder: Trigger.new)
{
if(labelOrder.Product__c == null) return;
productIds.add(labelOrder.Product__c);
}
List prodList = new List([
Select Id, Last_Label_Order_Creation_Date__c
from Product2
where Id In : productIds]);
Map productsOrderedMap = new Map();
for (Label_Order__c labelOrder: Trigger.new)
{
if(labelOrder.Product__c == null) return;
if(!prodList.isEmpty())
{
// date CreationDate = NOW();
for(Product2 oldProd : prodList)
{
if (
(oldProd.Last_Label_Order_Creation_Date__c == NULL)
||
(labelOrder.CreatedDate) > (oldProd.Last_Label_Order_Creation_Date__c)
)
{
productsOrderedMap.put (oldProd.id, labelOrder.CreatedDate);
}
}
}
}
for(List updateProdList : [Select Id, Last_Label_Order_Creation_Date__c From Product2 Where Id In : productIds] )
{
for(Product2 p : updateProdList)
{
if(productsOrderedMap.get(p.Id) == null)return;
p.Last_Label_Order_Creation_Date__c = productsOrderedMap.get(p.Id);
}
update updateProdList;
}
}
Code for LastLabelOrderModificationDate was quite similar, except it occurs both after insert and after update, and of course a few variables are named differently.
All Answers
I managed to make code which SalesForce accepts, but it still doesn't work. The two triggers are now coded:
trigger LastLabelOrderCreationDate on Label_Order__c (after insert)
{
for (Label_Order__c lo: Trigger.new)
{
lo.Product__r.Last_Label_Order_Creation_Date__c = date.today();
update lo;
}
}
and
trigger LastLabelOrderModificationDate on Label_Order__c (after update)
{
for (Label_Order__c lo: Trigger.new)
{
lo.Product__r.Last_Label_Order_Modification_Date__c = date.today();
update lo;
}
}
however, when I go to submit a new label order, I get the following error:
Review all error messages below to correct your data.
Apex trigger LastLabelOrderCreationDate caused an unexpected exception, contact your administrator: LastLabelOrderCreationDate: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.LastLabelOrderCreationDate: line 5, column 4
So, what remains wrong? And how do I fix it?
trigger LastLabelOrderCreationDate on Label_Order__c (after insert)
{
for (Label_Order__c labelOrder: Trigger.new)
{
Product2 productOrdered =
[
select Last_Label_Order_Creation_Date__c
from Product2
where ID = :labelOrder.Product__r.id
];
productOrdered.Last_Label_Order_Creation_Date__c = date.today();
update productOrdered;
}
}
It saves ok, but when I go to add a Label Order, I now get this error:
Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger LastLabelOrderCreationDate caused an unexpected exception, contact your administrator: LastLabelOrderCreationDate: execution of AfterInsert caused by: System.QueryException: List has no rows for assignment to SObject: Trigger.LastLabelOrderCreationDate: line 6, column 5
Any ideas?
These are the current codes:
trigger LastLabelOrderCreationDate on Label_Order__c (after insert)
{
for (Label_Order__c labelOrder: Trigger.new)
{
List productOrdered =
[
select Last_Label_Order_Creation_Date__c
from Product2
where ID = :labelOrder.Product__r.id
];
for (Product2 product: productOrdered)
{
product.Last_Label_Order_Creation_Date__c = labelOrder.CreatedDate;
update product;
}
}
}
and
trigger LastLabelOrderModificationDate on Label_Order__c (after update)
{
for (Label_Order__c labelOrder: Trigger.new)
{
List productOrdered =
[
select Last_Label_Order_Modification_Date__c
from Product2
where ID = :labelOrder.Product__r.id
];
for (Product2 product: productOrdered)
{
product.Last_Label_Order_Modification_Date__c = labelOrder.LastModifiedDate;
update product;
}
}
}
Extrapolating upon Guyver118's help with a different trigger issue, I have been able to solve these problems. :-)
For the curious, code for the LastLabelOrderCreationDate follows:
trigger LastLabelOrderCreationDate on Label_Order__c (after insert)
{
Set productIds = new Set();
for (Label_Order__c labelOrder: Trigger.new)
{
if(labelOrder.Product__c == null) return;
productIds.add(labelOrder.Product__c);
}
List prodList = new List([
Select Id, Last_Label_Order_Creation_Date__c
from Product2
where Id In : productIds]);
Map productsOrderedMap = new Map();
for (Label_Order__c labelOrder: Trigger.new)
{
if(labelOrder.Product__c == null) return;
if(!prodList.isEmpty())
{
// date CreationDate = NOW();
for(Product2 oldProd : prodList)
{
if (
(oldProd.Last_Label_Order_Creation_Date__c == NULL)
||
(labelOrder.CreatedDate) > (oldProd.Last_Label_Order_Creation_Date__c)
)
{
productsOrderedMap.put (oldProd.id, labelOrder.CreatedDate);
}
}
}
}
for(List updateProdList : [Select Id, Last_Label_Order_Creation_Date__c From Product2 Where Id In : productIds] )
{
for(Product2 p : updateProdList)
{
if(productsOrderedMap.get(p.Id) == null)return;
p.Last_Label_Order_Creation_Date__c = productsOrderedMap.get(p.Id);
}
update updateProdList;
}
}
Code for LastLabelOrderModificationDate was quite similar, except it occurs both after insert and after update, and of course a few variables are named differently.
If anyone is interested, I've improved the code for this, allowing both updates to occur in a single trigger and improving the batch handling.
Posted in two messages because of the character limit:
trigger UpdateLastLabelOrder
on Label_Order__c (after delete, after insert, after undelete, after update)
{
List<Label_Order__c> triggerList = (trigger.isDelete || trigger.isUndelete ? trigger.old : trigger.new);
Set<Id> productIds = new Set<Id>();
for (Label_Order__c labelOrder: triggerList)
{
if(labelOrder.Product__c == null) return;
productIds.add(labelOrder.Product__c);
}
List<Product2> prodList = new List<Product2>([
Select Id, Last_Label_Order_Creation_Date__c, Last_Label_Order_Modification_Date__c
from Product2
where Id In : productIds]);
Map<Id, datetime> productsOrderCreatedMap = new Map<Id, datetime>();
Map<Id, datetime> productsOrderModifiedMap = new Map<Id, datetime>();
for (Label_Order__c labelOrder: triggerList)
{
if(labelOrder.Product__c == null) return;
if(!prodList.isEmpty())
{
for(Product2 oldProd : prodList)
{
if
(
(
(oldProd.Last_Label_Order_Creation_Date__c == NULL)
||
(labelOrder.CreatedDate) > (oldProd.Last_Label_Order_Creation_Date__c)
)
&&
(
(productsOrderCreatedMap.get(oldProd.id) == NULL)
||
(labelOrder.CreatedDate) > (productsOrderCreatedMap.get(oldProd.id))
)
)
{
productsOrderCreatedMap.put (oldProd.id, labelOrder.CreatedDate);
}