0

I have the following situation/challenge: Custom field data from an external "Connected App" is transferred via Javascript to the account (custom fields) you came from before. This means that you have an AccountID that creates or enables the relationship. So far, it works perfectly.

But now we also have situations in which we don't have this account ID and therefore have to reference via a "identificationnumber", which is present in the connected app. This means that there is already a (custom) field "identificationnumber" in the account, too. The Connected App also sends (or has already sent) this "identificationnumber" to the account, so that a relationship could be established.

What would have to be done is, to provide this additional possibility in the Apex controller. If no account ID is available, then transfer the data to the correct account, that contains the "identificationnumber". I think, we would have to look for the account (ID), that contains the respective "identificationnumber" and then update the account as we do usually, right? How can I do this?

UPDATE: Here's the controller code, with SOQL statement, as David recommended, resulting in an error, when account Id is unknown. If account ID is known, update works!

"Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call: []"


public BestClientController() {

}

@RemoteAction
global static String saveAccount(String sData) {

    String sStatus = 'SUCCESS';
    String sMessage = '';

    try {

        BestClient bc = (BestClient)JSON.deserialize(sData, BestClient.class);

Account acc = new Account(Id=bc.accountId);

        if(bc.accountId != 'undefined' ){  
        acc                     = new Account(Id=bc.accountId); 
        }
        else {
        acc = [SELECT Id FROM Account WHERE bcsf__IdentificationNumber__c = :bc.identificationnumber];
        }                 
        acc.ArchiveId__c                = bc.archiveId;
        acc.IdentificationNumber__c     = bc.identificationnumber;          
        acc.Foundation__c               = bc.foundation;                         

        update acc;

    } catch (Exception ex) {

        System.debug('BestClient.BestClientController.saveAccount: ' + ex);
        sStatus = 'FAILED';
        sMessage = ex.getMessage();

    }   

    JSONGenerator gen = JSON.createGenerator(true);

    gen.writeStartObject();
    gen.writeStringField('status', sStatus);
    gen.writeStringField('message', sMessage);
    gen.writeEndObject();

    return gen.getAsString();                              

}


public PageReference refresh() {

    ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,this.Message));        
    return null;

}


public class BestClient {

    public String accountId;
    public String identificationnumber;
    public String archiveId;
    public String foundation;

}

0

1 Answer 1

0

It looks like what you need to do is an upsert here:

        BestClient bc = (BestClient)JSON.deserialize(sData, BestClient.class);

        Account acc                     = new Account(Id=bc.accountId);                         
        acc.ArchiveId__c                = bc.archiveId;
        acc.IdentificationNumber__c     = bc.identificationnumber;          
        acc.Foundation__c               = bc.foundation;                         

        update acc;

If IdentificationNumber__c is an External Id field, as it probably should be, you may use it as a unique identifier to update a matching existing record, if any, or insert a new record.

Instead of update, you'd do

upsert acc IdentificationNumber__c;

Edit

If you cannot make IdentificationNumber__c an External Id, you'll have to run a SOQL query to identify records with the given value, and use one of their Ids instead of bc.accountId.

Bear in mind that query/update is not atomic. Be prepared to handle race conditions in creating new records, and consider using FOR UPDATE to lock records you retrieve to prevent multiple concurrent clients overwriting each other's changes.

4
  • Yes, I've read about this possibility, but the field IdentificationNumber__c is already part of a managed package, so I can't change this attribute (unique identifier) anymore.,,
    – Rainer H.
    Commented Feb 12, 2020 at 15:29
  • Hey David - thanks a lot, I've updated my question with result of your recommendation.
    – Rainer H.
    Commented Feb 21, 2020 at 11:08
  • @RainerH. Apex doesn't work like JavaScript - compare to null, not 'undefined', if you want to know whether the field is populated.
    – David Reed
    Commented Feb 21, 2020 at 13:57
  • Thank you, David - Problem solved!
    – Rainer H.
    Commented Feb 27, 2020 at 15:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .