• nil_von_9wo
  • NEWBIE
  • 225 Points
  • Member since 2009

  • Chatter
    Feed
  • 9
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 24
    Questions
  • 39
    Replies

 

My client would not only like to be able to backup his SalesForce environment, but also be able to restore from that backup.

 

So far as I know, while many options make it possible to replicate SalesForce data elsewhere, there are no easy options for restoring data, so I've been trying to figure out how to do this.

 

Among the obstacles,  it is my understanding that Autonumber fields can not be overridden.  So, to properly restore sObjects with Autonumber fields, it will be necessary to first convert Autonumber fields to Text, and then restore them to Autonumber after the data has been restored (inserted).

 

Would it be possible to do this through the SalesForce API using PHP to develop the restoration solution?

 

If so,  how?

 

 

-Brian. 

 

My client has two record types ("Label Clients" and "Project Clients") for each of the standard sObjects "Leads", "Accounts", and "Objects".

 

As should seem obvious, when my client converts a Lead, the resulting Accounts and Opportunities *should* be of the corresponding type.

 

However, in practice, all conversions results in conversions to "Label Client" records.

 

"Map Lead Fields" doesn't seem to include "Record Type" as mappable.

 

Is there somewhere else I should look to map this?

 

Or can I create some sort of custom Convert using Apex?

 

Or, is the best solution to make a trigger which will change the record type based upon a picklist?  Would conversion be considered an "insert" or an "update"?

 

-Brian. 

 

 

We have a custom object called "Label Orders" which stores a number "Number of Labels" and two rollups (of a custom object "Label Lookups") "Total Lookups" and "Total Unique Lookups").  The last rollup filters by Label_Lookup__c.First_Lookup = true, which is made true as required by a trigger on Label Lookup.

 

Each "Label Order" is associated with both an Account object and a Product object. 

 

For each Account object and Product object, we need to keep track of:

 

1. Total Number of Labels

2. Total Number of Lookups

3. Total Number of Unique Lookups.

 

Unfortunately, due to limitations within SalesForce,  I can't simply use rollups of the Label Orders since I can't make either Account and Product as master's of Label Order.

 

As SalesForce govern's lines of script execution and database queries, I'm wondering what might be the best way to keep these totals accurate. 

... So, I have a custom object called "Label_Lookup__c".

 

Whenever a user visits our custom portal (not hosted on SalesForce), the server will record which label number has been looked at and when.  We wish to be able to record all look-ups, but also to distinguish the first time that each label has been looked up.

 

To this end, the Label_Lookup__c object has a checkbox field "First_Lookup__c".

 

I'd like to make sure that whenever Label_Lookup__c objects are created or modified, the earliest and only the earliest "First_Lookup__c" record for each unique "Label_Number__c" is true.

 

To this end, I wrote the following code:

 

 

trigger markFirstLabelLookup on PiqqoLabels__Label_Lookup__c (after insert, after update, after delete, after undelete) { /** * Create and Initialize variables */ // Get Label Lookup List List<PiqqoLabels__Label_Lookup__c> triggerList = (trigger.isDelete || trigger.isUndelete ? trigger.old : trigger.new); // Create set for UNIQUE numbers looked up. Set<String> lookedNumbers = new Set<String>(); // Populate set of unique numbers from the trigger list for (PiqqoLabels__Label_Lookup__c triggerLabelLookup: triggerList) { if(triggerLabelLookup.Label_Number__c == null) return; lookedNumbers.add(triggerLabelLookup.Label_Number__c); } // Create complete list of Label Lookups of these Label Numbers flagged as "First Lookup". List<PiqqoLabels__Label_Lookup__c> labelLookupList = new List<PiqqoLabels__Label_Lookup__c>([ Select Id, First_Lookup__c, Label_Number__c, Lookup_Date__c from PiqqoLabels__Label_Lookup__c where ( (Label_Number__c In : lookedNumbers) AND (First_Lookup__c = true) ) order by Lookup_Date__c asc ]); // Create and initialize map for Earliest Lookups Map<String, datetime> labelLookedEarliestLookupDateMap = new Map<String, datetime>(); Map<String, Id> labelLookedEarliestLookupIdMap = new Map<String, Id>(); // Create list of Lookups which are changed to/from "First Lookup" List<PiqqoLabels__Label_Lookup__c> labelLookedChangedList = new List<PiqqoLabels__Label_Lookup__c>(); //**************************************************************************************************** // Evaluate each in the trigger list to confirm if it is the earliest. for (PiqqoLabels__Label_Lookup__c triggerLabelLookup: triggerList) { if(triggerLabelLookup.Label_Number__c == null) return; if(!labelLookupList.isEmpty()) { // Check each number previously looked for(PiqqoLabels__Label_Lookup__c oldLook: labelLookupList) { // Check if this instance of the trigger label number refereds to the same label number // as retrieved in the complete list. if (triggerLabelLookup.Label_Number__c == oldLook.Label_Number__c) { /** * * isEarliestDate checks 3 dates to verify that the most recent entered is also * the most recent chronologically: * * public static boolean isEarliestDate (newdate, olddate, mapdate) * */ if (triggerDatetimeToolkit.isEarliestDate ( triggerLabelLookup.Lookup_Date__c, // Date from this iteration of the trigger oldLook.Lookup_Date__c, // Date from this iteration of the complete list (labelLookedEarliestLookupDateMap.get(triggerLabelLookup.Label_Number__c)) // Date from the earliest mapping of the id; needed in case a trigger list contains two or more references to the same label number. ) ) { // If Earliest, make sure First Lookup = true labelLookedEarliestLookupDateMap.put (triggerLabelLookup.Label_Number__c, triggerLabelLookup.Lookup_Date__c); labelLookedEarliestLookupIdMap.put (triggerLabelLookup.Label_Number__c, triggerLabelLookup.id); // The default value for First_Lookup is true, thus it shouldn't usually be // necessary to change this value to true; only if (for some strange reason) // the lookup record is modified. /** * * toggleFirstLookup makes sure each labelLook has First Lookup value as desired. * If not, modifies and adds to change list. * * public static PiqqoLabels__Label_Lookup__c toggleFirstLookup(labelLookup, desiredValue, changeList) * */ triggerLabelLookupToolkit.toggleFirstLookup(triggerLabelLookup, true, labelLookedChangedList); // ----------------------------------------------------------- // Unless records have been modified (again, for a strange reason), // it shouldn't usually be necessary to change older values which were true // to false because of a new entry. // Make sure other lookups are now false; if (oldLook.id != triggerLabelLookup.id) { triggerLabelLookupToolkit.toggleFirstLookup(oldLook, false, labelLookedChangedList); } // Needed if two or more records in the same trigger refer to the same // Label Number. If everything in this trigger works, it shouldn't // happen that two old Lookups both refer to the same Label Number and // yet are both flagged first lookup. if (labelLookedEarliestLookupIdMap.get(triggerLabelLookup.Label_Number__c) != triggerLabelLookup.id) { // **** If I understand SalesForce policy well enough, it would be better if I // **** can revisit this record's value without needing to perform this database query. PiqqoLabels__Label_Lookup__c OldEarliestLookup = [ Select First_Lookup__c from PiqqoLabels__Label_Lookup__c where Id = :(labelLookedEarliestLookupIdMap.get(triggerLabelLookup.Label_Number__c)) ]; triggerLabelLookupToolkit.toggleFirstLookup(OldEarliestLookup, false, labelLookedChangedList); } //---------------------------------------------------------------- } else { // If not Earliest, make sure First Lookup = false // By default, First_Lookup__c is true (with the expectation that // each Label Number will usually only be looked at once.) // // If this trigger functions correctly and no Label Lookups are // ever modified after being created, this is should be the only // condition which is ever true and therefore needs to be changed. triggerLabelLookupToolkit.toggleFirstLookup(triggerLabelLookup, false, labelLookedChangedList); } } } } } //**************************************************************************************************** // Update all Label Lookups whose First_Lookup__c changed. upsert labelLookedChangedList;}

 

 

public class triggerLabelLookupToolkit {/** * * Tools for working with "Label Lookup" objects in triggers. * * Label Lookups have an API name: PiqqoLabels__Label_Lookup__c * * This class includes: * * toggleFirstLookup - changes "First Lookup" from true to false (or vice-versa) as necessary; adds to change list. * * @author Brian Kessler * @version 1.0 * */ /** * Makes sure each labelLook has First Lookup value as desired. If not, modifies and adds to change list. * @parameter labelLookup record to check and (if necessary) modify * @parameter desiredValue what the value should be * @parameter changeList the list of Label Lookups which have changed (to update later). * @return labelLookup, with verified or fixed value. */ public static PiqqoLabels__Label_Lookup__c toggleFirstLookup( PiqqoLabels__Label_Lookup__c labelLookup, boolean desiredValue, List<PiqqoLabels__Label_Lookup__c> changeList ) { if (labelLookup.First_Lookup__c != desiredValue) { labelLookup.First_Lookup__c = desiredValue; changeList.add (labelLookup); } return labelLookup; }}

 

 

 However, now when I try to create a new Label Lookup object, I get the following error:

 

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger PiqqoLabels.markFirstLabelLookup caused an unexpected exception, contact your administrator: PiqqoLabels.markFirstLabelLookup: execution of AfterInsert caused by: System.Exception: Record is read-only: Class.PiqqoLabels.triggerLabelLookupToolkit.toggleFirstLookup: line 34, column 6

 

 How can I fix this?

 

 

Message Edited by nil_von_9wo on 08-12-2009 01:04 PM

Currently trying to work through this tutorial, found on page 4, but having at least two problems.

 

After embedding the code from the book into a VisualForce page with standardController="Opportunity" 

 

 

First, without the JavaScript, when I save I get this error:

 

Save error: 

SELECT id, name, recordtype FROM Opportunity WHERE

                 ^

ERROR at Row:1:Column:18

No such column 'recordtype' on entity 'Opportunity'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names.

 

 

I added a record type to Opportunity in order to fix this, but it didn't help. 

 

 

2.  If I comment out the reference to {!Opportunity.RecordType}, I get the error:

 

 

Unknown property 'OpportunityStandardController.Lead' 

 

I tried to change references to "Lead" to "LeadSource", but that only resulted in the error changing to

 

Unknown property 'OpportunityStandardController.LeadSource' 

 

 

 

Any ideas how to fix these? 

 

When making web pages, I prefer to separate the scripts from the markup.  As such, I'd rather put JavaScripts into Static Resources than embed them into my VisualForce pages.

 

I have the following JavaScript (from the Salesforce guide to useful scontrols):

 

 

// Create a map object var map = new YMap(document.getElementById('mapContainer')); // Display the map centered on given address map.drawZoomAndCenter("{!Account.BillingStreet}, {!Account.BillingState}, {!Account.BillingPostalCode}", 3); // Set marker at that address map.addMarker ("{!Account.BillingStreet}, {!Account.BillingState}, {!Account.BillingPostalCode}", 3);

 

Included in the VisualForce page, it works fine.

 

I put it into a static resource "createmap_js", which I reference with  

 

 

<script type="text/javascript" src="{!$Resource.createmap_js}" >

 

 However, when I do this, the map doesn't appear and instead the space is tiled with "We're sorry, the data you have            your browser to try again."

 

I assume this means that the fields are not being rendered when the script executes.

 

Is there any way to seperate the JavaScript from the markup and have a functional VisualForce page?

 

 

 

 

 

Page 196 of the cookbook suggests creating a user specifically for integration.

To do this, they suggest selecting permissions for "API Only" and "Modify All Data".

I don't see these permissions to select them.

Are they available in developer environments?


-Brian

Currently continuing to work through the cookbook. There is a rather long test class from page 155 to 159 which doesn't work.I've discovered at least two errors which I don't know how to fix.

 

First, there is a recurrent error with the statement:

 

 

System.assert(e.getDmlFields(0)[0] == 'Email');

  

This results in:

 

Save Error: Comparison arguments must be compatible types: Schema.SObjectField, String

 

If I comment out these lines (which, to be honest, I don't understand how they are helping the testing), I discover there is another error. The second error occurs during the test to "Make sure that bulk lead duplication prevention works on insert."

  

 

System.assert(e.getNumDml() == 2);

 

 turns out to be false because the value of e.getNumDml() is actually 3.

 

While I could change this value to make the test pass, again, I don't really understand how this test is working, so just arbitrarily changing the value would seem to negate the value of the test, as perhaps this reflects other code being incorrect.

  

 

Can anyone explain how to fix either of these problems?

 

Or better yet, explain what each of these asserts is [supposed to be] doing:

 

 

System.assert(e.getNumDml() == 2); System.assert(e.getDmlIndex(0) == 1); System.assert(e.getDmlFields(0).size() == 1); System.assert(e.getDmlFields(0)[0] == 'Email'); System.assert(e.getDmlMessage(0).indexOf('A lead with this email address already exists.') > -1);

 

...o I can understand how and why this test works... 

 

 

The cookbook describes how to retrieve data for a particular division on page 110.

However, when I attempt to submit the query in Apex Explorer 8.0, I get:

SOSL Test returned and error:
INVALID_SEARCH: divisions are not enabled

How do I enable them?
Currently working my way through the cookbook... I've entered the HTML code starting on page 107... however, when I render the page in my browser, it is blank.

Most of my browsers (Chrome, Safari, Firefox, Flock), don't even hint at an error, but IE7 (which is normally problematic with SalesForce anyway) gives this error:

Line: 605
Char: 9
Error: The system cannot locate the resource specified.
Code: 0
URL: file:///D:/temp/Hunt_for_Phil2.html


.... Note that the code in the book is only 33 lines long!

Assuming that the error is actually in "/soap/ajax/10.0/connection.js", I looked at line 605, but this line states:



if (async && typeof(timeout) !== "undefined") {
this.setTimeoutOn(holder, timeout);
}






I don't see anything problematic here... and if I did, how could I fix this, since this is SalesForce own's script?

-Brian.

I have created a trigger which will reassigns a custom checkbox field (Ready_to_Purchase_Piqqo_Labels__c) on the standard object Opportunity's value to a similar custom checkbox on the standard Account object.

 

I have the code working now, but I don't understand why I needed to make the line below in red as I did, and I'm concerned that there is something else I don't understand in this code which can cause collateral damage.

 

Can anyone explain this to me:

 

 

trigger syncOpportunityReady2Purchase on Opportunity (before insert, before update) { // Get list of all modified Opportunities. List<Opportunity> triggerList = trigger.new; // Initialize sets and maps. Set<Id> accountIds = new Set<Id>(); Set<Id> opportunityIds = new Set<Id>(); Map<Id, boolean> readyToPurchaseMap = new Map<Id, boolean>(); // Collect modified Opportunity IDs into set. for (Opportunity opportunityModified: triggerList) { if(opportunityModified == null) return; opportunityIds.add(opportunityModified.id); } // Collect modified Opportunities into list. List<Opportunity> opportunityList = new List<Opportunity>([ Select AccountId, Ready_to_Purchase_Piqqo_Labels__c from Opportunity where id In : opportunityIds]); // Collect related Account Ids and map "readiness" to Ids. for (Opportunity opportunityModified: opportunityList) { accountIds.add(opportunityModified.AccountId); readyToPurchaseMap.put (opportunityModified.AccountId, opportunityModified.Ready_to_Purchase_Piqqo_Labels__c); } // Collect related Accounts for (Account a: [ select Ready_to_Purchase_Piqqo_Labels__c from Account where id In : accountIds ] ) { if(readyToPurchaseMap.get(a.Id) == null)return; // Assign Opportunity's readiness to Account // ! This code is "weird". I've had to negate the value to get the correct value to appear. a.Ready_to_Purchase_Piqqo_Labels__c = !(readyToPurchaseMap.get(a.Id)); update a; // Sync with Account's other Opportunities

// This function also needs to be debugged, but it is a separate issue. triggerAccountToolkit.syncReady2Purchase(a, a.Ready_to_Purchase_Piqqo_Labels__c); }}

 

Page 39 of Force.com_workbook v2. provides code for testing the class created in Tutorial 5.

No surprisingly, this test code itself is wrong, and running it fails.

How do I correct the code so that these two asserts will work correctly?

System.assert(e.getMessage().contains('Insert failed. First exception on row 0; '+
'first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, '+
'Mileage request exceeds daily limit(500): [Miles__c]'),
e.getMessage());

System.assertEquals(Mileage__c.Miles__c, e.getDmlFields(0)[0]);

I've already discovered that I can get the first assertion to work correctly if change "...daily limit(500): [Miles__c]')," to "daily limit: 500: []')," ... but I imagine that "Miles__c" should have some value that isn't being added in MileageUtil, but should?

And the second assertion, I have no idea how to fix....

-Brian.

I've created an approval process exactly as described between pages 26 and 27.

 

I've activated this process.

 

I've created "Mileage" objects for well over 200 miles.

 

However, these new records are not locking, their approval status is not being set, no e-mails for the approval process are being sent (those for the large mileage, are however).

 

Any idea what else -- other than activation -- might prevent this process from kicking in?

 

-Brian. 

In my developer environment, I've added two custom fields to the Product standard object:

 

Account: Lookup (Account)

Annual Revenue: Formula (Currency) 

 

The formula for Product2.Annual_Revenue is:

 

 Annual_Revenue = Estimated_Monthly_Sales_Volume__c * Total_CO2_Footprint__c *0.0024

 

 

 

I'm trying to create a trigger so that when a Product is added or modified, the AnnualRevenue field in Accounts will automatically reflect the total value of all Products which lookup that account.

 

This is the trigger I've created:

 

trigger UpdateAccountAnnualRevenue 

on Product2 (after delete, after insert, after undelete, after update) 

{

for (Product2 productModified: Trigger.new)

{

List <Product2> accountProduct =

[

select Annual_Revenue__c

from Product2

where ID = :productModified.Account__r.id

];

double Total_Revenue = 0.00;

for (Product2 AP: accountProduct)

{

Total_Revenue += AP.Annual_Revenue__c;

}

for (Account productAccount: 

[

select AnnualRevenue

from Account

where ID = :productModified.Account__r.id

)

{

productAccount.AnnualRevenue = Total_Revenue;

update productAccount;

}

}

 

}

 

 

However, there seems to be a problem with this code.

 

For example, GenWatt Diesel 200kW has an Annual Revenue of $18.67.

 

However, the account Burlington Textiles Corp of America, which has no other assigned products, has an Annual Revenue of $350,000,000

 

 

 

What am I doing wrong and how do I fix it?  

Message Edited by nil_von_9wo on 07-09-2009 07:04 AM

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
I tried to create several record types (Food, Clothing, Electrical) on the standard Product object.

I added the Record Type field to the layout, and made several different layouts.

However, when I click "new", SalesForce does not ask me the record type.

The form shows "Record Type" where it is expected to, but it has no value and this can not be changed.


Have I missed something? Is there something else I need to do?
I would like to add a custom field to a Product object which will summarize the last time the product was ordered.

The 'obvious' way to do this would have been to make Product the master to an object called "Label Order", and then use a roll-up field on "Product".

However, it seems [for some unknown reason] that I can't make Product the Master.

Is this normal? Am I doing something wrong?

Is there a workaround so I can create the "Last_Label_Order" as a formula if Product is a LookUp for "Label Order"?

After using ant to put Chapter 15 on one developer environment and then creating a second developer account and environment, I tried to use the Eclipse Force.com IDE to deploy from one to the other as described on pages 469 through 471.

 

However, when I attempted to validate the code I received a FAIL.

 

The log is unfortunately too long to post, but essentially it seems to be itemizing the fact that nothing exists -- but since the point is to add everything, none of these things should be expected to exist already!

 

How do I get this to work? 

 

 

 

 

Thanks to Simha, I've managed to get past one of many problems I've been having with the developer guide (re: http://community.salesforce.com/sforce/board/message?board.id=general_development&message.id=31371#M31371 ), however, like a hydra, a new problem has emerged.

 

Before creating a new user and logging in, I can see available positions in the tutorial application.

 

However, immediately after signing up for a new user account,  I can see the page structure, however I can no longer see any positions listed.

 

When I log out, positions are listed again.

 

Additionally, if I log out and  attempt to log back in again, I get an error message which states:

 

Error: Insufficient Privileges 


Please 
email us if you need to get in touch.

 

(As that e-mail link would send e-mail to me, it wouldn't help much).

 

What do I need to do to give sufficent privledges to a new Custom Customer Portal User? 

 

 

-Brian. 

 

 

 

 

 

 

 

 

Message Edited by nil_von_9wo on 07-06-2009 12:11 AM
While I still haven't solved the problem of cloning a none-existing "Customer Portal User" profile (re: http://community.salesforce.com/sforce/board/message?board.id=general_development&thread.id=31323 ), I managed to get past it by cloning the "Customer Portal Manager" instead (since this is presumably a manager, I'm sure doing this in a professional environment is probably a formula for trouble, but that's not what this message is about).

I set up the custom portal to accept registrations, but something seems to be wrong.

I go to my portal and try to create a new user. When I submit the details, I get the following error:


Error:
Your request cannot be processed at this time. The site administrator has been alerted.

The e-mail I get states:

The default new user profile is not assigned to the portal. Registration from chapter_14 is not able to create portal users.


How do I assign the default new user profile to the portal? (Shouldn't selecting it as the default be enough?)

 

My client would not only like to be able to backup his SalesForce environment, but also be able to restore from that backup.

 

So far as I know, while many options make it possible to replicate SalesForce data elsewhere, there are no easy options for restoring data, so I've been trying to figure out how to do this.

 

Among the obstacles,  it is my understanding that Autonumber fields can not be overridden.  So, to properly restore sObjects with Autonumber fields, it will be necessary to first convert Autonumber fields to Text, and then restore them to Autonumber after the data has been restored (inserted).

 

Would it be possible to do this through the SalesForce API using PHP to develop the restoration solution?

 

If so,  how?

 

 

-Brian. 

 

We have a custom object called "Label Orders" which stores a number "Number of Labels" and two rollups (of a custom object "Label Lookups") "Total Lookups" and "Total Unique Lookups").  The last rollup filters by Label_Lookup__c.First_Lookup = true, which is made true as required by a trigger on Label Lookup.

 

Each "Label Order" is associated with both an Account object and a Product object. 

 

For each Account object and Product object, we need to keep track of:

 

1. Total Number of Labels

2. Total Number of Lookups

3. Total Number of Unique Lookups.

 

Unfortunately, due to limitations within SalesForce,  I can't simply use rollups of the Label Orders since I can't make either Account and Product as master's of Label Order.

 

As SalesForce govern's lines of script execution and database queries, I'm wondering what might be the best way to keep these totals accurate. 

... So, I have a custom object called "Label_Lookup__c".

 

Whenever a user visits our custom portal (not hosted on SalesForce), the server will record which label number has been looked at and when.  We wish to be able to record all look-ups, but also to distinguish the first time that each label has been looked up.

 

To this end, the Label_Lookup__c object has a checkbox field "First_Lookup__c".

 

I'd like to make sure that whenever Label_Lookup__c objects are created or modified, the earliest and only the earliest "First_Lookup__c" record for each unique "Label_Number__c" is true.

 

To this end, I wrote the following code:

 

 

trigger markFirstLabelLookup on PiqqoLabels__Label_Lookup__c (after insert, after update, after delete, after undelete) { /** * Create and Initialize variables */ // Get Label Lookup List List<PiqqoLabels__Label_Lookup__c> triggerList = (trigger.isDelete || trigger.isUndelete ? trigger.old : trigger.new); // Create set for UNIQUE numbers looked up. Set<String> lookedNumbers = new Set<String>(); // Populate set of unique numbers from the trigger list for (PiqqoLabels__Label_Lookup__c triggerLabelLookup: triggerList) { if(triggerLabelLookup.Label_Number__c == null) return; lookedNumbers.add(triggerLabelLookup.Label_Number__c); } // Create complete list of Label Lookups of these Label Numbers flagged as "First Lookup". List<PiqqoLabels__Label_Lookup__c> labelLookupList = new List<PiqqoLabels__Label_Lookup__c>([ Select Id, First_Lookup__c, Label_Number__c, Lookup_Date__c from PiqqoLabels__Label_Lookup__c where ( (Label_Number__c In : lookedNumbers) AND (First_Lookup__c = true) ) order by Lookup_Date__c asc ]); // Create and initialize map for Earliest Lookups Map<String, datetime> labelLookedEarliestLookupDateMap = new Map<String, datetime>(); Map<String, Id> labelLookedEarliestLookupIdMap = new Map<String, Id>(); // Create list of Lookups which are changed to/from "First Lookup" List<PiqqoLabels__Label_Lookup__c> labelLookedChangedList = new List<PiqqoLabels__Label_Lookup__c>(); //**************************************************************************************************** // Evaluate each in the trigger list to confirm if it is the earliest. for (PiqqoLabels__Label_Lookup__c triggerLabelLookup: triggerList) { if(triggerLabelLookup.Label_Number__c == null) return; if(!labelLookupList.isEmpty()) { // Check each number previously looked for(PiqqoLabels__Label_Lookup__c oldLook: labelLookupList) { // Check if this instance of the trigger label number refereds to the same label number // as retrieved in the complete list. if (triggerLabelLookup.Label_Number__c == oldLook.Label_Number__c) { /** * * isEarliestDate checks 3 dates to verify that the most recent entered is also * the most recent chronologically: * * public static boolean isEarliestDate (newdate, olddate, mapdate) * */ if (triggerDatetimeToolkit.isEarliestDate ( triggerLabelLookup.Lookup_Date__c, // Date from this iteration of the trigger oldLook.Lookup_Date__c, // Date from this iteration of the complete list (labelLookedEarliestLookupDateMap.get(triggerLabelLookup.Label_Number__c)) // Date from the earliest mapping of the id; needed in case a trigger list contains two or more references to the same label number. ) ) { // If Earliest, make sure First Lookup = true labelLookedEarliestLookupDateMap.put (triggerLabelLookup.Label_Number__c, triggerLabelLookup.Lookup_Date__c); labelLookedEarliestLookupIdMap.put (triggerLabelLookup.Label_Number__c, triggerLabelLookup.id); // The default value for First_Lookup is true, thus it shouldn't usually be // necessary to change this value to true; only if (for some strange reason) // the lookup record is modified. /** * * toggleFirstLookup makes sure each labelLook has First Lookup value as desired. * If not, modifies and adds to change list. * * public static PiqqoLabels__Label_Lookup__c toggleFirstLookup(labelLookup, desiredValue, changeList) * */ triggerLabelLookupToolkit.toggleFirstLookup(triggerLabelLookup, true, labelLookedChangedList); // ----------------------------------------------------------- // Unless records have been modified (again, for a strange reason), // it shouldn't usually be necessary to change older values which were true // to false because of a new entry. // Make sure other lookups are now false; if (oldLook.id != triggerLabelLookup.id) { triggerLabelLookupToolkit.toggleFirstLookup(oldLook, false, labelLookedChangedList); } // Needed if two or more records in the same trigger refer to the same // Label Number. If everything in this trigger works, it shouldn't // happen that two old Lookups both refer to the same Label Number and // yet are both flagged first lookup. if (labelLookedEarliestLookupIdMap.get(triggerLabelLookup.Label_Number__c) != triggerLabelLookup.id) { // **** If I understand SalesForce policy well enough, it would be better if I // **** can revisit this record's value without needing to perform this database query. PiqqoLabels__Label_Lookup__c OldEarliestLookup = [ Select First_Lookup__c from PiqqoLabels__Label_Lookup__c where Id = :(labelLookedEarliestLookupIdMap.get(triggerLabelLookup.Label_Number__c)) ]; triggerLabelLookupToolkit.toggleFirstLookup(OldEarliestLookup, false, labelLookedChangedList); } //---------------------------------------------------------------- } else { // If not Earliest, make sure First Lookup = false // By default, First_Lookup__c is true (with the expectation that // each Label Number will usually only be looked at once.) // // If this trigger functions correctly and no Label Lookups are // ever modified after being created, this is should be the only // condition which is ever true and therefore needs to be changed. triggerLabelLookupToolkit.toggleFirstLookup(triggerLabelLookup, false, labelLookedChangedList); } } } } } //**************************************************************************************************** // Update all Label Lookups whose First_Lookup__c changed. upsert labelLookedChangedList;}

 

 

public class triggerLabelLookupToolkit {/** * * Tools for working with "Label Lookup" objects in triggers. * * Label Lookups have an API name: PiqqoLabels__Label_Lookup__c * * This class includes: * * toggleFirstLookup - changes "First Lookup" from true to false (or vice-versa) as necessary; adds to change list. * * @author Brian Kessler * @version 1.0 * */ /** * Makes sure each labelLook has First Lookup value as desired. If not, modifies and adds to change list. * @parameter labelLookup record to check and (if necessary) modify * @parameter desiredValue what the value should be * @parameter changeList the list of Label Lookups which have changed (to update later). * @return labelLookup, with verified or fixed value. */ public static PiqqoLabels__Label_Lookup__c toggleFirstLookup( PiqqoLabels__Label_Lookup__c labelLookup, boolean desiredValue, List<PiqqoLabels__Label_Lookup__c> changeList ) { if (labelLookup.First_Lookup__c != desiredValue) { labelLookup.First_Lookup__c = desiredValue; changeList.add (labelLookup); } return labelLookup; }}

 

 

 However, now when I try to create a new Label Lookup object, I get the following error:

 

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger PiqqoLabels.markFirstLabelLookup caused an unexpected exception, contact your administrator: PiqqoLabels.markFirstLabelLookup: execution of AfterInsert caused by: System.Exception: Record is read-only: Class.PiqqoLabels.triggerLabelLookupToolkit.toggleFirstLookup: line 34, column 6

 

 How can I fix this?

 

 

Message Edited by nil_von_9wo on 08-12-2009 01:04 PM

Currently trying to work through this tutorial, found on page 4, but having at least two problems.

 

After embedding the code from the book into a VisualForce page with standardController="Opportunity" 

 

 

First, without the JavaScript, when I save I get this error:

 

Save error: 

SELECT id, name, recordtype FROM Opportunity WHERE

                 ^

ERROR at Row:1:Column:18

No such column 'recordtype' on entity 'Opportunity'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names.

 

 

I added a record type to Opportunity in order to fix this, but it didn't help. 

 

 

2.  If I comment out the reference to {!Opportunity.RecordType}, I get the error:

 

 

Unknown property 'OpportunityStandardController.Lead' 

 

I tried to change references to "Lead" to "LeadSource", but that only resulted in the error changing to

 

Unknown property 'OpportunityStandardController.LeadSource' 

 

 

 

Any ideas how to fix these? 

 

When making web pages, I prefer to separate the scripts from the markup.  As such, I'd rather put JavaScripts into Static Resources than embed them into my VisualForce pages.

 

I have the following JavaScript (from the Salesforce guide to useful scontrols):

 

 

// Create a map object var map = new YMap(document.getElementById('mapContainer')); // Display the map centered on given address map.drawZoomAndCenter("{!Account.BillingStreet}, {!Account.BillingState}, {!Account.BillingPostalCode}", 3); // Set marker at that address map.addMarker ("{!Account.BillingStreet}, {!Account.BillingState}, {!Account.BillingPostalCode}", 3);

 

Included in the VisualForce page, it works fine.

 

I put it into a static resource "createmap_js", which I reference with  

 

 

<script type="text/javascript" src="{!$Resource.createmap_js}" >

 

 However, when I do this, the map doesn't appear and instead the space is tiled with "We're sorry, the data you have            your browser to try again."

 

I assume this means that the fields are not being rendered when the script executes.

 

Is there any way to seperate the JavaScript from the markup and have a functional VisualForce page?

 

 

 

 

 

I have created a trigger which will reassigns a custom checkbox field (Ready_to_Purchase_Piqqo_Labels__c) on the standard object Opportunity's value to a similar custom checkbox on the standard Account object.

 

I have the code working now, but I don't understand why I needed to make the line below in red as I did, and I'm concerned that there is something else I don't understand in this code which can cause collateral damage.

 

Can anyone explain this to me:

 

 

trigger syncOpportunityReady2Purchase on Opportunity (before insert, before update) { // Get list of all modified Opportunities. List<Opportunity> triggerList = trigger.new; // Initialize sets and maps. Set<Id> accountIds = new Set<Id>(); Set<Id> opportunityIds = new Set<Id>(); Map<Id, boolean> readyToPurchaseMap = new Map<Id, boolean>(); // Collect modified Opportunity IDs into set. for (Opportunity opportunityModified: triggerList) { if(opportunityModified == null) return; opportunityIds.add(opportunityModified.id); } // Collect modified Opportunities into list. List<Opportunity> opportunityList = new List<Opportunity>([ Select AccountId, Ready_to_Purchase_Piqqo_Labels__c from Opportunity where id In : opportunityIds]); // Collect related Account Ids and map "readiness" to Ids. for (Opportunity opportunityModified: opportunityList) { accountIds.add(opportunityModified.AccountId); readyToPurchaseMap.put (opportunityModified.AccountId, opportunityModified.Ready_to_Purchase_Piqqo_Labels__c); } // Collect related Accounts for (Account a: [ select Ready_to_Purchase_Piqqo_Labels__c from Account where id In : accountIds ] ) { if(readyToPurchaseMap.get(a.Id) == null)return; // Assign Opportunity's readiness to Account // ! This code is "weird". I've had to negate the value to get the correct value to appear. a.Ready_to_Purchase_Piqqo_Labels__c = !(readyToPurchaseMap.get(a.Id)); update a; // Sync with Account's other Opportunities

// This function also needs to be debugged, but it is a separate issue. triggerAccountToolkit.syncReady2Purchase(a, a.Ready_to_Purchase_Piqqo_Labels__c); }}

 

I've created an approval process exactly as described between pages 26 and 27.

 

I've activated this process.

 

I've created "Mileage" objects for well over 200 miles.

 

However, these new records are not locking, their approval status is not being set, no e-mails for the approval process are being sent (those for the large mileage, are however).

 

Any idea what else -- other than activation -- might prevent this process from kicking in?

 

-Brian. 

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