• Natalya Murphy 8
  • NEWBIE
  • 0 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 1
    Likes Received
  • 0
    Likes Given
  • 6
    Questions
  • 2
    Replies
Tried the following code in a Winter20 and a Summer19 sandbox.  Checkbox is clickable in Summer19 but not in Winter20.
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
	       <lightning:recordEditForm aura:id="formDataTmp"
                              objectApiName="Contact"
                              recordId="{! v.recordId }">
        <lightning:messages />
        <lightning:inputField fieldName="DoNotCall"/>
       </lightning:recordEditForm>
</aura:component>
#Winter20
 
I'm using a lightning:datatable to retreive data and want the date-formatted columns to be right-aligned.  I've figured out how to right-align the actual data, but the column heading is still left-aligned and I can't find any documentation on how to right-align it.

datatable definition:
<lightning:datatable
                keyField="id"
                data="{! v.eeObject.serviceBranches }"
                columns="{! v.serviceColumns }"
                hideCheckboxColumn="true"/>

...and a snippet of the column definition setting the right-align of the data:
component.set('v.serviceColumns', [
    {label: 'Entry Date', fieldName: 'serviceEntryDate', type: 'date-local', 
    typeAttributes:{ month: "numeric", day: "numeric" }, cellAttributes: { alignment: 'right' }},
    {label: 'Exit Date', fieldName: 'serviceExitDate', type: 'date-local', 
    typeAttributes:{ month: "numeric", day: "numeric" }, cellAttributes: { alignment: 'left' }}
]);

Also attaching a picture showing the problem.
Misaligned heading and data in column
I need some help with analyzing Event Monitoring data.   Specifically, does anyone know the complete list of event types that I need to pull from our event logs so that the event counts in the logs add up to the numbers on the 7 Day API Usage Report?
Here are some sample numbers that illustrate my dilemma:  Our 7 Day API Usage Report says there were 14,165 API requests made on Thursday, April 4. However, when I add up the rows in the event logs from April 4 for event types of API, REST API, and Bulk API, there are only 9,345 entries. There are no other generated logs from that day with "API" anywhere in the name.  What additional event logs do I need to pull in so that the row counts from the event logs add up to the 14,165 request count from that day?
I have a requirement to call Flow 2 after all transaction processing from Flow 1 has been completed and to avoid creating duplicate records in Flow 2.   The issue is that I need all records, including cascading record updates, to all be fully finished before I call Flow 2. 

I'm using an Apex Action to watch the transaction processing and determine when it's safe to call Flow 2, and also to prevent duplicate records from getting sent for processing.  But the way I have the Apex code written right now, all invoked flows are getting started sequentially rather than in parallel, and therefore the queries in the flows aren't bulkified.  This causes me to hit the dreaded Too Many SOQL Queries limit.

How do I invoke multiple flows in parallel so that their SOQL operations get bulkified?   I haven't found any documentation online that answers this.

Details of the required automation below, and code snippet follows after.

Automation Requirement
Flow 1 is an automation that runs when a Campaign Member is updated.  This Flow, in some scenarios, may update or create other Campaign Member records (which triggers a cascading Process Builder).

Flow 2 is an automation that runs and sums up the Campaign Member status at the Account level.  It creates/updates records in a junction object called Account Campaign Status having the following fields:
- Account (lookup)
- Campaign (lookup)
- Overall status (text field)  - logic-derived status based on the "highest ranking" status of any contact in this account that belongs to the given Campaign

If I try to call Flow 2 directly from Flow 1, I run into 1 of 2 problems:
- If a record already exists in Account Campaign Status, I hit a governor limit if more than 12 Contacts from the same Account are in the Campaign.  The limit is around preventing more than 12 concurrent updates.
If a record doesn't already exist in Account Campaign Status, and I have multiple Contacts from the same Account, I get multiple new rows created instead of just 1 row.  I think this is because all the flows are running in parallel and therefore none of them find a record in the system at first, and then all of them try to therefore create a record.  So instead of 1 record getting created, I get 12 if there are 12 separate contacts.

Below is the transaction control code I created to compile all the account/campaign combinations and, when all upstream transactions have finished, call Flow 2. 
public class AccountCampaignRollupAction {
 static Map<ID, Set<ID>> toCalculate = new Map<ID, Set<ID>>();    
    @InvocableMethod(label='Launch Account Campaign Rollup' description='If all transactions are done processing, calls an invokable flow to roll up campaign status at the account level')   
    public static void start( List<AccountCampaignRollupRequest> requests ){
        Set<ID> nextSet;
        //go through the list of requests and pull out the unique combinations of account/campaign ID 
        //for later processing
        for( AccountCampaignRollupRequest nextReq : requests ){
            nextSet = toCalculate.get( nextReq.accountId );
            if( nextSet == null ){
                nextSet = new Set<ID>();
            }
            system.debug('Acct: ' + nextReq.accountId + ', Campaign: ' + nextReq.masterCampaignId);
            nextSet.add( nextReq.masterCampaignId );
            toCalculate.put( nextReq.accountId, nextSet );
        }//for
        
        Map<String,Object> flowVars = new Map<String,Object>();
        Flow.Interview myFlow;
        
        //now that we've built up our unique list, see if we're done with all transactions.
        //If we're not done, don't do any processing yet.
        //The static toCalculate variable will keep compiling more IDs for processing.
        if( TransactionControl.activeTransactionCount() < 1 ){
            //all transactions finished.  It's safe to kick off the calculations.
            for( ID nextAcct : toCalculate.keySet() ){
                nextSet = toCalculate.get( nextAcct );
                for( ID nextCampaign : nextSet){
                    flowVars.clear();
                    flowVars.put('InputAccountId', nextAcct );
                    flowVars.put('InputMasterCampaignId', nextCampaign);
                    system.debug('Calling flow with map: ' + flowVars);
              //HERE'S THE PROBLEM SECTION.   Because this flow is invoked in a for-loop, the flows
              //launch sequentially and their queries aren't getting bulkified.  
              //Is it possible to make a bulkified call to launch multiple flows?
              //Or if it's not possible, how do I pass in a list of account-campaign pairs
              //and then query them from the flow?
                    myFlow = Flow.Interview.createInterview( 'Account_Campaign_Status_Rollup', flowVars );
                    myFlow.start();
                }//inner for               
            }//outer for          
        }//if
        else {
            system.debug( 'Transactions still running.  Not calling flow yet' );
        }
    } 
    
    public class AccountCampaignRollupRequest{
        @InvocableVariable(required=true)
        public ID accountId;
        
        @InvocableVariable(required=true)
        public ID masterCampaignId;
    }
}

 
I have a batchable class that's called via a scheduler class nightly.   It's failing from the scheduler with the error message "First error: Read access denied for ChargentSFA__Transaction__c, controller action methods may not execute."

BUT: when I invoke the batchable class directly from Developer Console via Execute Anonymous, the class runs just fine. 

Any ideas on why this would run fine via anonymous execute but fail from the scheduler?

Scheduler class:
global class RecepitBatchScheduler implements Schedulable {
   global void execute(SchedulableContext SC) {
      Database.executeBatch(new Receipt_Batch());
   }
}

Batchable class (with identifying information modified).   When running from the scheduler, the job fails at line 26 (pdf.getContent()).  
global class Receipt_Batch implements Database.Batchable<SObject>,database.stateful {
        
   	global List<ChargentSFA__Transaction__c> start(Database.BatchableContext BC){
        
        return [select id,ChargentSFA__Opportunity__r.name,ChargentSFA__Opportunity__r.Costumer__r.name,
              ChargentSFA__Opportunity__r.Costumer__r.email__c 
              from ChargentSFA__Transaction__c
             where To_Process_Receipt_with_Batch__c=true];
        
        
   	}

   	global void execute(Database.BatchableContext BC, List<ChargentSFA__Transaction__c> scope){
       OrgWideEmailAddress[] owea = [select Id from OrgWideEmailAddress where Address = 'example@example.com'];
       Messaging.SingleEmailMessage[] messages = new List<Messaging.SingleEmailMessage>();
    	List<Attachment> L_attachments=new List<Attachment>();
        List<ChargentSFA__Transaction__c> L_transup = new List<ChargentSFA__Transaction__c>();
    	for(ChargentSFA__Transaction__c tra: scope){
        	Blob b;
			PageReference pdf = Page.Receipt;
    		pdf.getParameters().put('id',tra.id);
    		pdf.setRedirect(true);
            if (Test.IsRunningTest())
            	b = Blob.valueOf('UNIT.TEST');    
           	else
				b = pdf.getContent(); //Batch jobs fails at this line when run from scheduler
        
        	Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
            efa.setFileName('Customer Receipt.pdf');
    		efa.setBody(b);
        
        	Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
            message.toAddresses = new String[] {tra.ChargentSFA__Opportunity__r.Costumer__r.email__c};
            message.subject = 'Customer Receipt';
            String Body='Dear '+tra.ChargentSFA__Opportunity__r.Costumer__r.name+',<br/><br/>Thank you for entrusting us with your wellness. Please find attached your receipt --feel free to contact your Coach with any questions or concerns!';
            Body=Body+'<br/><br/>Best Regards,';
            Body=Body+'<br/><br/>The Company';
            message.sethtmlbody(body); 
            
            if (Test.IsRunningTest() == false)
            	message.setOrgWideEmailAddressId(owea.get(0).id);
			message.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
            messages.add(message);
        
        	Attachment att=new Attachment();
			att.Body=b ;
			att.Name='Receipt ' + System.now().format('yyyy_MM_dd_hh_mm_ss') + '.pdf';
			att.parentId=tra.id;
			L_attachments.add(att);
            
            L_transup.add(new ChargentSFA__Transaction__c(id=tra.id,To_Process_Receipt_with_Batch__c=false));

    	}
    	Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);
    
    	insert L_attachments;
        
        update l_transup;
        
     
    }

   	global void finish(Database.BatchableContext BC){
   	}
}

 
We have a VF extensions that's used to render a PDF receipt after a credit card transaction is recorded.  

We have a Rich Text Area field named Signature__c that's used to store a reference to a signature image.   A sample entry into the field looks like this: 
<img src="/servlet/servlet.FileDownload?file=00P1F000000lOkbUAE" width="500" height="200"></img>
The above entry gets saved to the record's Signature__c field during order of execution of the page load.

This field is then rendered on the page via the following code:
<apex:outputfield value="{!Transaction_Record__c.Signature__c}"/>
Now, even though the image has dimensions of 500 x 250 when stored in the database (which allows it to display properly on the normal record page), I want it to render at 50% scale on the custom VF page that will ultimately become a PDF.

Is there any markup I can put on the VF page to make this image show up at half-scale?

So ultimately the problem is:  I want to save the original formatting of 500x250 in the database, but when that Rich Text area field renders on the PDF, I want it all to be at 50%.
I have a requirement to call Flow 2 after all transaction processing from Flow 1 has been completed and to avoid creating duplicate records in Flow 2.   The issue is that I need all records, including cascading record updates, to all be fully finished before I call Flow 2. 

I'm using an Apex Action to watch the transaction processing and determine when it's safe to call Flow 2, and also to prevent duplicate records from getting sent for processing.  But the way I have the Apex code written right now, all invoked flows are getting started sequentially rather than in parallel, and therefore the queries in the flows aren't bulkified.  This causes me to hit the dreaded Too Many SOQL Queries limit.

How do I invoke multiple flows in parallel so that their SOQL operations get bulkified?   I haven't found any documentation online that answers this.

Details of the required automation below, and code snippet follows after.

Automation Requirement
Flow 1 is an automation that runs when a Campaign Member is updated.  This Flow, in some scenarios, may update or create other Campaign Member records (which triggers a cascading Process Builder).

Flow 2 is an automation that runs and sums up the Campaign Member status at the Account level.  It creates/updates records in a junction object called Account Campaign Status having the following fields:
- Account (lookup)
- Campaign (lookup)
- Overall status (text field)  - logic-derived status based on the "highest ranking" status of any contact in this account that belongs to the given Campaign

If I try to call Flow 2 directly from Flow 1, I run into 1 of 2 problems:
- If a record already exists in Account Campaign Status, I hit a governor limit if more than 12 Contacts from the same Account are in the Campaign.  The limit is around preventing more than 12 concurrent updates.
If a record doesn't already exist in Account Campaign Status, and I have multiple Contacts from the same Account, I get multiple new rows created instead of just 1 row.  I think this is because all the flows are running in parallel and therefore none of them find a record in the system at first, and then all of them try to therefore create a record.  So instead of 1 record getting created, I get 12 if there are 12 separate contacts.

Below is the transaction control code I created to compile all the account/campaign combinations and, when all upstream transactions have finished, call Flow 2. 
public class AccountCampaignRollupAction {
 static Map<ID, Set<ID>> toCalculate = new Map<ID, Set<ID>>();    
    @InvocableMethod(label='Launch Account Campaign Rollup' description='If all transactions are done processing, calls an invokable flow to roll up campaign status at the account level')   
    public static void start( List<AccountCampaignRollupRequest> requests ){
        Set<ID> nextSet;
        //go through the list of requests and pull out the unique combinations of account/campaign ID 
        //for later processing
        for( AccountCampaignRollupRequest nextReq : requests ){
            nextSet = toCalculate.get( nextReq.accountId );
            if( nextSet == null ){
                nextSet = new Set<ID>();
            }
            system.debug('Acct: ' + nextReq.accountId + ', Campaign: ' + nextReq.masterCampaignId);
            nextSet.add( nextReq.masterCampaignId );
            toCalculate.put( nextReq.accountId, nextSet );
        }//for
        
        Map<String,Object> flowVars = new Map<String,Object>();
        Flow.Interview myFlow;
        
        //now that we've built up our unique list, see if we're done with all transactions.
        //If we're not done, don't do any processing yet.
        //The static toCalculate variable will keep compiling more IDs for processing.
        if( TransactionControl.activeTransactionCount() < 1 ){
            //all transactions finished.  It's safe to kick off the calculations.
            for( ID nextAcct : toCalculate.keySet() ){
                nextSet = toCalculate.get( nextAcct );
                for( ID nextCampaign : nextSet){
                    flowVars.clear();
                    flowVars.put('InputAccountId', nextAcct );
                    flowVars.put('InputMasterCampaignId', nextCampaign);
                    system.debug('Calling flow with map: ' + flowVars);
              //HERE'S THE PROBLEM SECTION.   Because this flow is invoked in a for-loop, the flows
              //launch sequentially and their queries aren't getting bulkified.  
              //Is it possible to make a bulkified call to launch multiple flows?
              //Or if it's not possible, how do I pass in a list of account-campaign pairs
              //and then query them from the flow?
                    myFlow = Flow.Interview.createInterview( 'Account_Campaign_Status_Rollup', flowVars );
                    myFlow.start();
                }//inner for               
            }//outer for          
        }//if
        else {
            system.debug( 'Transactions still running.  Not calling flow yet' );
        }
    } 
    
    public class AccountCampaignRollupRequest{
        @InvocableVariable(required=true)
        public ID accountId;
        
        @InvocableVariable(required=true)
        public ID masterCampaignId;
    }
}

 
Tried the following code in a Winter20 and a Summer19 sandbox.  Checkbox is clickable in Summer19 but not in Winter20.
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
	       <lightning:recordEditForm aura:id="formDataTmp"
                              objectApiName="Contact"
                              recordId="{! v.recordId }">
        <lightning:messages />
        <lightning:inputField fieldName="DoNotCall"/>
       </lightning:recordEditForm>
</aura:component>
#Winter20
 
Hi,

I am trying to envoke an APEX class I wrote to retrieve cases using REST in Postman. I am unable to figure out how to authenticate to get a propper session established. I created the class in the sandbox. Any help would be appreciated.

Steve