top of page
  • Nikos Mitrakis

Forceea Permutations: the power of combinations

Introduction: Forceea Permutations


When we use the Forceea Templates of our DataFactory class, we often need to create records which combine values from the same field or different fields, generating unique records. To make this clear, let's see some use cases:


Use Case #1: Create product names

We want to create 100 different product names (e.g. medicines) to populate the Product2 SObject.


Use Case #2: Combine picklist values with lookup records

We want to create one record for any picklist value of FieldA (e.g. 10 countries) AND any lookup ID of FieldB (e.g. 100 products), so we finally generate 10 x 100 = 1000 records.


The previous use cases define the basic types of Forceea Permutations:

  • Type A: permutations of the same field

  • Type B: permutations of different fields (2 or more)

Note: Forceea Permutations always generate "unique" records. Unique means that each generated record has a different "combination" of the values used in the Permutation process.

Use Case #1


As always, we suppose you have installed Forceea data factory in your Salesforce org and you have created your DataFactory class. Let's say that inside this class, you have the templateProducts, for your Product2 SObject:

public static Forceea.Template templateProducts() {
  return new Forceea.Template()
    .add('Products', new FObject(Product2.SObjectType)
      .setNumberOfRecords('auto')
      .setDefinition(Product2.Name,
        'serial type(list) value(PER,MON,LYC,TYR,LOT) 
           mode(permutation)')
      .setDefinition(Product2.Name,
        'serial type(list) value(AM,AR,OS,ES,IN) mode(permutation)')
      .setDefinition(Product2.Name,
        'serial type(list) value(OL,IN,UL,OD) mode(permutation)')
      .setDefinition(Product2.Name,
        'random type(list) value(" 10ml"," 20ml"," 30ml")')
    );
}

This Template has some new "features" that we should discuss in more detail:

  • setNumberOfRecords: usually this method takes an Integer argument, e.g. setNumberOfRecords(100). Now we use the string "auto" to declare that the number of records will be automatically calculated by Forceea.

  • mode(permutation): this command directs Forceea to create permutations for this field definition.

It's important to remember that the mode(permutation) parameter can be found in serial commands only. The above Template uses the serial type(list) definition. It could use the serial type(picklist) as well (we'll see it in Use Case #2), but here we want to set custom values for generating product names.


The above Template will generate 100 unique values for the Name field:

  • The first definition has 5 values: PER, MON, LYC, TYR, and LOT - 5 permutations.

  • The second definition has 5 values: AM, AR, OS, ES, and IN - 5 x 5 = 25 permutations so far.

  • The third definition has another 4 values: OL, IN, UL, and OD - 25 x 4 = 100 permutations in total.

Additionally:

  • Each definition is a “syllable” of the field values, so we have values like PEROSIN, LYCAMOL or LOTESIN.

  • The last definition random type(list) value(…) creates random “quantities”.

  • The final result will be 100 product names like "LYCAMOL 10ml".

  • If we wanted all different quantities for any product, we could use:

serial type(list) value(" 10ml"," 20ml"," 30ml") mode(permutation)

Since we have 3 values in this definition, the total number of permutations would be 100 x 3 = 300.


Use Case #2


We have the picklist field Language__c with 7 language codes (en, es, el, etc), and we want to create a new record for each product of the Product__c lookup SObject, for each language except "en". Here is the Template for our LocalProduct__c SObject:

public static Forceea.Template templateLocalProducts() {
  return new Forceea.Template()
    .add(templateProducts())
    .add('LocalProducts', new FObject(LocalProduct__c.SObjectType)
        .setNumberOfRecords('auto')
        .setDefinition(LocalProduct__c.Language__c,
          'serial type(picklist) except(en) mode(permutation)')
        .setDefinition(LocalProduct__c.Product__c,
          'serial lookup(Product2) mode(permutation) source(forceea)')
      );
}

Let's see the basic points of this Template:

  • The new templateLocalProducts encapsulates templateProducts we created in Use Case #1 (line 3).

  • As previously, we use setNumberOfRecords('auto') (line 5), to allow Forceea handle permutations.

  • The definition serial type(picklist) except(en) mode(permutation) will get all the picklist values (7 values) and will remove "en", so we have 6 permutations so far.

  • The definition serial lookup(Product2) mode(permutation) source(forceea) will get the ID of the Product2 records that Forceea created from templateProducts. There are 100 Product2 records, so we have 6 x 100 = 600 permutations in total.

Permutations without setNumberOfRecords('auto')


If you've ever wondered, yes you can use Permutations without setNumberOfRecords('auto'). In practice, when you handle the number of records, you should pay extra attention to some details.


To give an example, let's suppose we use setNumberOfRecords(20) in templateProducts, instead of setNumberOfRecords('auto'). Remember we have 100 permutations, so Forceea would create 100 Product2 records. But now:

  • We ask for only 20 records.

  • Forceea will start the (standard) data generation with Permutations and will stop to Permutation#20.

If that was your intention, you are fine! There is no problem when you set a number of records (20) that is less than the number of Permutations (100).


But what happens when the number of records (e.g. 120) is greater than the number of Permutations (N=100)? In this case, Forceea

  • will generate the values of Permutations for the first N=100 records and

  • will set a "blank" value for the rest 20 records (expected, isn't it?).

This scenario is something that we normally want to avoid.


Some best practices and guidelines

  • As a rule of thumb, Permutations is the correct approach when we have questions like "How can I create a record <for each value of field A> AND <for each value of field B> AND ..."

  • The number of records generated using setNumberOfRecords('auto') can easily become quite big to handle in the limited CPU time. To avoid issues, try to reduce the number of values of the fields used in Permutations.

  • As always, use FObject.setGlobalVerbose('debug') in your Test methods during development (or even in non-test methods) to see the data generation details.

Conclusion: power to the people


This article was a concise introduction to Forceea Permutations. Permutations is one of the most important capabilities of Forceea and will certainly give you the right solution in tricky situations.

 




bottom of page