• harryZ
  • NEWBIE
  • 60 Points
  • Member since 2009

  • Chatter
    Feed
  • 2
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 1
    Questions
  • 11
    Replies

Hey everyone.  This must be a redundant question, but it's a hard thread to search for.  I'm coming from rails and the 'active record' pattern so forgive me if this is ignorant.

 

How on earth do i extend an SObject with my own functionality?  Or where does my logic 'live'?

 

Should i make a wrapper object with an Apex Class?

 

I'm aware of formula's, but it's slightly limited for what i'm going for.

 

Thanks for your help in advance!

 

- Brian 

 

 

Example:

 

  So i have a visual force view.  I also have this extension.  So how can i implement roadRage()

 

 

public class MileageExtension {

private final Mileage__c mileageObj;

 

    public MileageExtension(ApexPages.StandardController controller) {

this.mileageObj = (Mileage__c)controller.getSubject();

    }

    

        // where do i put all the methods?

        public void roadRage() {

        Car car = mileageObj.getCar();

        Person driver = mileageObj.getDriver();

        car.honk();

        driver.giveFinger();

        car.swerve();

                driver.slowDownInEmbarrassment();

        }

} 

 

Message Edited by drboolean on 08-22-2009 08:39 PM

Message Edited by drboolean on 08-22-2009 08:40 PM

I haven't worked with the Apex Batch capabilities yet... it looks like the batch size is set to 200. However, some limits are lower than that -- such as the number of callouts allowed in a transaction (10). Is it possible to change the batch size to a lower number?

 

Basically, I need to run through all of the records of a particular object that meet the criteria, and for each, call an external web service (callout) and update the record accordingly.

 

And incidentally, it seems that the query/callout logic and the update logic would have to -- or could -- use different batch limits.

I'm tracking the AsyncApexJob object after execute the batch apex, and it says the execution is failed. Can anyone tell me how to get more detailed exception message in batch apex?

 

BTW, I've run the same code in test method and there is no exception.

  • August 23, 2009
  • Like
  • 0

Until 2 weeks ago I was using Eclipse 3.3. I had a sandbox and a developer org, set up as two projects, and I was able to develop things on either of those, and deploy the changes to the live org. The one things I could no do was change the live org directly - not a problem - I subscribe to the idea of proving in the sandbox forst, then deploying.

 

Unfortunately, I've had to change PCs. I now have Vista (grrr) and as Eclipse 3.4 is now supported, I've installed that. I've then tried to connect with my 3 orgs. Bizarrely, I am completely unable to connect to the sandbox or developer orgs, but can connect to the Live org, AND MAKE DIRECT CHANGES. Seems dangerous to me. When was I given the power to do that?

 

I've tried over and over to connect to the sandbox, which is on server tapp0, and the dev org on server cs1 (neither is on the Test server). I've tried re-generating the tokens, I've tried messing with the SOAP endpoint, but all to no avail.

 

I have spent a lot of time looking through the plethora of documentation and forums about Force.com, the IDE and Eclipse, but cannot find a simple set of instructions on how to connect the IDE to your live environment, then set up your sandbox so that you can deploy from one to another. Can anyone give me these simple instructions? 

 

I would be more grateful than you can imagine! 

Hey everyone.  This must be a redundant question, but it's a hard thread to search for.  I'm coming from rails and the 'active record' pattern so forgive me if this is ignorant.

 

How on earth do i extend an SObject with my own functionality?  Or where does my logic 'live'?

 

Should i make a wrapper object with an Apex Class?

 

I'm aware of formula's, but it's slightly limited for what i'm going for.

 

Thanks for your help in advance!

 

- Brian 

 

 

Example:

 

  So i have a visual force view.  I also have this extension.  So how can i implement roadRage()

 

 

public class MileageExtension {

private final Mileage__c mileageObj;

 

    public MileageExtension(ApexPages.StandardController controller) {

this.mileageObj = (Mileage__c)controller.getSubject();

    }

    

        // where do i put all the methods?

        public void roadRage() {

        Car car = mileageObj.getCar();

        Person driver = mileageObj.getDriver();

        car.honk();

        driver.giveFinger();

        car.swerve();

                driver.slowDownInEmbarrassment();

        }

} 

 

Message Edited by drboolean on 08-22-2009 08:39 PM

Message Edited by drboolean on 08-22-2009 08:40 PM

 I have attached a code snippet below that is confusing me.  When the select statement returns a row the debug statement is executed and the rest of the code is executed also.  But when no row is returned for the select statement everything seems to stop.  Even the debug statement is not executed.  Why is this?  I tried putting in a try-catch statement to catch a dmlexception but nothing was caught.

 

Thanks in advance.

 

 public void ProductGroupChanged() {

  Payment_Type_Group__c ptg;

  ptg = [ SELECT ID FROM Payment_Type_Group__c WHERE Product_Group__c =:ProductGroupID AND Default__c = true LIMIT 1];

  System.debug('Made it here!');

   if (ptg != null) {

      this.opg.Product_Group__c = ProductGroupID;

      this.opg.Payment_Type_Group__c = ptg.ID;

  } else {

      this.opg.Product_Group__c = null;       this.opg.Payment_Type_Group__c = null;

  }

}

Hi,

 

I am getting the below error when i try to save my Apex Controller.

 

line -1, column -1: Dependent class is invalid and needs recompilation: <Namespace.ApexClassName>: <line No> Didn't understand relationship '<Custom Object Name>' in field path. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names.

 

I checked my WSDL file and could see the field in that Object.

 

Can anyone help me why is this issue being faced.

 

Regards,

OnDem

I have a controller extension that needs to have it's own 'customised' !save command. I call it !save2

 

Question 1: how can I force a record to be saved in apex code? Can I call the standard controller's

!save from within my extension's !save2 ?

 

Question 2: how can I edit - in code - the object that is to be saved? I need to set one of the record fields

to a specific value before saving.

 

Question 3: once saved - how do I return to the original record window? How can I redirect to a record

from within apex code?

 

Any pointers to code examples would really behelpful.

TIA.

I want to get the QueueId from the Queue Sobject and assign it to the Case OwnerId field in Apex.

The QueueId will be based on the SobjectType and the Queue Name.

I am using this query for the purpose.
QueueSobject que = [Select Id, SobjectType, QueueId, Queue.Name from QueueSobject where SobjectType = 'Case' AND Queue.Name = 'Water Application Support'];

But since the Queue Name is not unique (unlike RecordType where you can't have same RecordTypeName for an object), if there are two Queues with the same name and related to same SobjectType, the query will fail to return a single record and my assignment of OwnerId will throw an exception.

Salesforce allows you to create duplicate queue records with the same Name and related SobjectType. There will be no difference between these two records except for their Ids.

But I don't want to hard-code the Id value in the query.

Please suggest me in this to get the appropriate QueueId.

Thanks,
Karthik.

Hi,

   I have checkboxes in VF page, and in controller through get/set method I am getting a String array of select value of checkboxes.Is any way to get unselected value of checkboxes in controller.

 

Thanks,

Raj 

Hi all,

 

I currently have a method which simply calls an @future method 10 times. The method that it calls updates the database and stops. The problem is that the first methods dataset doesn't appear to get updated when the @future method fails. I have tried adding a wait to the code by using:

 

 

 

while (iCount < 10) {

runFuture();

 

Double dMilliUntil = System.Now().millisecond() + 100;

while (System.Now().millisecond() <= dMilliUntil ) { } //Wait for 1 second

 

iCount++;

}

 

which waits for 1 second (which should be long enough for the future method to complete). Does anyone know why this doesn't update the original dataset?

 

Thanks

 

James 

 

We use the PRM partner portal, and in order to keep the approvals workflow simple we have set it up so the Partner User's Manager gets approval requests.

 

This Manager field should always be the same as the Partner Account's Owner, and we would like it to be automatically updated for all of the relevant Partner Users when the Owner field changes on the Account.


It should be a simple thing to do, but turned out to be more complex than I thought because Salesforce doesn't allow a User record to be updated in the same transaction as an Account object - which means that you can't update the User object in an Account trigger.

 

The solution is to split the code into two parts: the trigger, and a separate class that does all the work and is marked @future.  In doing this, salesforce executes the code asynchroneously and it all works.

 

In case it's useful to someone, here is the complete functioning code:

 

 

// Trigger on Account changes
// Looks for changes to the Owner field
// When a Partner user is associated with the Account, make sure
// the Manager field on that User is updated to have the same value
//
// This is necessary because the approvals workflow for Partner-entered Leads
// uses on the Manager field.
//
// NOTE: Relies on the userUpdateAsyncClass class for most of the work because
// Salesforce can't update a User in an Account trigger.
//
// VERSION HISTORY
// 8 Aug 2009/Allan M: Initial version
//
trigger PartnerAccountOwnerChange on Account (before update) {
System.Debug('DBG: In PartnerAccountOwnerChange trigger');

List<Account> theAccounts = new List<Account>();
for (Account newAccount:System.Trigger.new) {
Account oldAccount = System.Trigger.oldMap.get(newAccount.Id);
if (oldAccount.OwnerId == newAccount.OwnerId) {
System.Debug('DBG: Owner was "' + oldAccount.OwnerId + '" and is now "' + newAccount.OwnerId + '"');
continue; // Ignore changes that do not affect the Account Owner
}

// We could also filter on Type to consider only Partner accounts
theAccounts.add(newAccount);
}

if (theAccounts.isEmpty()) {
System.debug('DBG: Nothing to do; no relevant changes');
return; // Nothing to do
}

System.debug('UPDATE: There may be something to do.');

List<Id> AccountIds = new List<Id>();
for (Account a: theAccounts)
AccountIds.add(a.Id);

// Perform the change. However, because Salesforce doesn't allow the User object
// to be updated in the same transaction that updates an Account object (which
// is what triggered this trigger, it has to be done in an asynchroneous static
// method annotated as @future.
userUpdateAsyncClass.updatePartnerUsersForAccounts(AccountIds);
} // trigger

 The bulk of the work is done in a separate class called userUpdateAsyncClass:

 

// Class used by the PartnerAccountOwnerChange trigger
//
// Works around the fact that a User cannot be updated by a trigger caused by an Account change
//
// VERSION HISTORY
// 8 Aug 2009/Allan M: Initial version
//
public class userUpdateAsyncClass {

@future
public static void updatePartnerUsersForAccounts(Id[] accountIds) {

// Retrieve the account objects for the Ids
List<Account> theAccounts = new List<Account> (
[select Id, Name, OwnerId from Account where Id in :AccountIds]
);

// Bulk retrieve all Partner User objects
// Might be better to retrieve based on PRM Profile rather than UserType?
List<User> theUsers = new List<User> (
[select Id, Name, ContactId, ManagerId from User where UserType = 'PowerPartner']
);

// Retrieve all of the associated Contact records that relate to the trigger Accounts
Set<Id> ContactIds = new Set<Id>();
for (User u: theUsers)
ContactIds.add(u.ContactId);
Map<Id, Contact> theContacts = new Map<Id, Contact>(
[select Id, AccountId from Contact where Id in :ContactIds and AccountId in :AccountIds]
);

if (theContacts.isEmpty()) {
System.Debug('DBG No matching Partner user objects need updating.');
return; // Nothing to do
}

// I need the actual User objects for the update to work, for some reason :(
Set<Id> theNewOwnerIds = new Set<Id>();
for (Account a: theAccounts)
theNewOwnerIds.add(a.OwnerId);
Map<Id, User> userMap = new Map<Id, User>(
[select Id, Name from User where Id in :theNewOwnerIds]
);

// Now do the actual update
for (User u:theUsers) {
Contact c = theContacts.get(u.ContactId);
if (c == null)
continue; // This user is not affected

System.Debug('DBG: Look for manager for User "' + u.Name + '"');
Id newOwnerId = null;
for (Account a:theAccounts){
System.Debug('DBG: Checking ' + c.AccountId + ' against ' + a.Id );
if (c.AccountId == a.Id)
newOwnerId = a.OwnerId;
} // theAccounts

if (newOwnerId == null) {
System.Debug('ERROR: ??? Cannot find new Owner!?!');
continue;
}

System.Debug('DBG: Setting new Manager to ' + newOwner);
u.ManagerId = newOwnerId;
User newOwner = userMap.get(newOwnerId);
u.Manager = newOwner;

try {
update u;
} catch (DmlException e) {
System.debug('ERROR: ' + e.getMessage());
}
} // theUsers
}
}

 

Thoughts, comments or improvements to get this done easier are much welcome.  Feel free to make use of the code to make your life easier in some way too :)

 

Allan Mertner

 

 

 

 

  • August 21, 2009
  • Like
  • 0

Hi all,

 

I have a dynamic query which returns me some field names 

 

public List<leadStore> getStoredLeadVals() { String myId = getRuleSetId(); String limitClause = ApexPages.currentPage().getParameters().get('lt'); System.debug('LIMIT VAL: ' + limitClause); String query; query = 'select lead_id__c, score__c, map__c '+ ' from lead_store__c ' + ' where ruleSetId__c =\'' + myId + '\' order by lead_id__c limit ' +limitClause; System.debug('Query:' + query); List<lead_store__c> storedLeads = Database.Query(query); String AllIds = ''; String AllIds1 = ''; for (lead_store__c lsc : storedLeads) { AllIds += '\'' + lsc.lead_id__c + '\','; } AllIds1 = AllIds.substring(0, AllIds.length()-1); String allFldNames = ''; // TODO: Get me the fieldNames from the scoringRule List. // Store it in a Map so that we see only right values Map<String, String> ruleNamesMap = new Map<String, String>(); List<ScoringRule__c> scoringFlds = [select rulename__c, Id from ScoringRule__c where RuleSetId__c =: myId]; for(ScoringRule__c s : scoringFlds) { ruleNamesMap.put(s.ruleName__c, s.Id); } Set <String> s = ruleNamesMap.keyset(); for (string si : s) { allFldNames += si + ','; } String lstQry = 'select id, '+ allFldNames + ' name from lead where id in ('+ allIds1+ ')'; System.debug('Lead qry: ' + lstQry); List<Lead> ldSto = Database.Query(lstQry); for (Lead l : ldSto) { for (lead_store__c lsc : storedLeads) { if (lsc.lead_id__c == String.valueOf(l.Id)) { lSt.add(new leadStore(lsc,l)); } } } return lSt; }

 

I want to display the field names taht i get in this list on my visualforce page.

 

Any idea on how can i do that? Any help is much appreciated!!

 

 

Regards

Mukul

 

 

  • August 20, 2009
  • Like
  • 0

I haven't worked with the Apex Batch capabilities yet... it looks like the batch size is set to 200. However, some limits are lower than that -- such as the number of callouts allowed in a transaction (10). Is it possible to change the batch size to a lower number?

 

Basically, I need to run through all of the records of a particular object that meet the criteria, and for each, call an external web service (callout) and update the record accordingly.

 

And incidentally, it seems that the query/callout logic and the update logic would have to -- or could -- use different batch limits.