function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
nil_von_9wonil_von_9wo 

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?

 

 

 

 

Message Edited by nil_von_9wo on 07-02-2009 08:41 AM
Best Answer chosen by Admin (Salesforce Developers) 
nil_von_9wonil_von_9wo

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

nil_von_9wonil_von_9wo

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:

 

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.NullPointerException: Attempt to de-reference a null object: Trigger.LastLabelOrderCreationDate: line 5, column 4

 

 So, what remains wrong?  And how do I fix it?   

 

 

nil_von_9wonil_von_9wo
Still, on my own, trying to hack this issue out... now my code (for the first trigger) looks like:

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?
Message Edited by nil_von_9wo on 07-03-2009 12:57 PM
nil_von_9wonil_von_9wo
Still I try... and still I haven't reached the finish line with this... Now I get no errors, but when I look at the product, the fields I am attempting to modify remain blank.

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;
}
}

}
nil_von_9wonil_von_9wo

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.
This was selected as the best answer
nil_von_9wonil_von_9wo

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);

}

nil_von_9wonil_von_9wo
if
(oldProd.Last_Label_Order_Modification_Date__c == NULL)
          ||
(labelOrder.LastModifiedDate) > (oldProd.Last_Label_Order_Modification_Date__c)
)
&&
(
(productsOrderModifiedMap.get(oldProd.id) == NULL)
          ||
(labelOrder.LastModifiedDate) > (productsOrderModifiedMap.get(oldProd.id))
)
)
{
productsOrderModifiedMap.put (oldProd.id, labelOrder.LastModifiedDate);
}
          } 
    }

}

for(
List<Product2> updateProdList : 
[
Select Id, Last_Label_Order_Creation_Date__c, Last_Label_Order_Modification_Date__c 
From Product2 
Where Id In : productIds
)
{
      for(Product2 p : updateProdList)
      {
             if(productsOrderCreatedMap.get(p.Id) != null)
              {
             p.Last_Label_Order_Creation_Date__c = productsOrderCreatedMap.get(p.Id);
              }
             if(productsOrderModifiedMap.get(p.Id) != null)
              {
             p.Last_Label_Order_Modification_Date__c  = productsOrderModifiedMap.get(p.Id);
              }
      }
 
      update updateProdList;
}



}
Message Edited by nil_von_9wo on 07-10-2009 01:02 AM