Monday, 8 August 2016

Cool ways to use PXFormula

Hi All,

Acumatica platform continuously evolving and includes more and more new cool features to optimize your code and save time on development and testing.

Today i want to share with you some really cool features of PXFormula attribute and how to use it to significantly simplify your code.
Here I want to cover following parameters:
  • Validate - Validate<field>
  • Current - Current<TRecord.field>
  • Parent - Parent<TParent.field>
  • IsTableEmpty - IsTableEmpty<TRecord>
  • Selector - Selector<KeyField, ForeignOperand> 
Welcome in details if you need examples.

Validate
The Validate<field> formula will raise dependentField's FieldVerifying event each time the RelatedField is updated.

Example:
public class DacClass: PX.Data.IBqlTable
{
    public abstract class field : IBqlField { }
    public virtual int? Field { get; set; }

    public abstract class dependentField : IBqlField { } 
    [PXFormula(typeof(Validate<field>))]
    public virtual int? DependentField { get; set; }   
}

Of course there you can do the same with graph/attribute events, but with formula it is much more stable and easier.

Current
Current<TRecord.field> and Current2<TRecord.field> fetches the field value from the record stored in the Current property of the TRecord cache.

If the cache's Current property or the field itself contains null:
  • Current<> forces field defaulting and returns the default field value.
  • Current2<> returns null
Example:
[PXFormula(typeof(Switch<
    Case<Where<
        ARAdjust.adjgDocType, Equal<Current<ARPayment.docType>>,
        And<ARAdjust.adjgRefNbr, Equal<Current<ARPayment.refNbr>>>>,
        ARAdjust.classIcon.outgoing>,
    ARAdjust.classIcon.incoming>))]
protected virtual void ARAdjust_ClassIcon_CacheAttached(PXCache sender)

Parent
Parent<TParent.field> fetches the field value from the parent data record as defined by PXParentAttribute residing on the current DAC.

Example:
public class INTran : IBqlTable
{
    [PXParent(typeof(Select<
        INRegister, 
        Where<
            INRegister.docType, Equal<Current<INTran.docType>>,
            And<INRegister.refNbr,Equal<Current<INTran.refNbr>>>>>))]
    public virtual String RefNbr { ... }

    [PXFormula(typeof(Parent<INRegister.origModule>))]
    public virtual String OrigModule { ... }
}

IsTableEmpty
IsTableEmpty<TRecord> returns true if the DB table corresponding to the specified DAC contains no records.

Example:
public class APRegister : IBqlTable
{
    [PXFormula(typeof(Switch<
        Case<Where<
            IsTableEmpty<APSetupApproval>, Equal<True>>,
            True,
        Case<Where<
            APRegister.requestApproval, Equal<True>>,
            False>>,
        True>))]
    public virtual bool? DontApprove { get; set; }
}

Selector
Selector<KeyField, ForeignOperand> does following:
  1. Fetches a PXSelectorAttribute defined on the foreign key field (KeyField) of the current DAC. 
  2. Fetches the foreign data record currently referenced by the selector. 
  3. Using calculates and returns an expression on that data record as defined by ForeignOperand.
Example:
public class APVendorPrice : IBqlTable
{
    // Inventory attribute is an aggregate containing a PXSelectorAttribute
    // inside, which is also valid for Selector<>.
    [Inventory(DisplayName = "Inventory ID")]
    public virtual int? InventoryID

    [PXFormula(typeof(Selector<
        APVendorPrice.inventoryID, 
        InventoryItem.purchaseUnit>))]
    public virtual string UOM { get; set; }
}

Big thanks to Acumatica Development team for this example.
Have a nice development!

1 comment:

Sol Sam said...

I was not aware that there are different ways to use PXFormula. Now that I know, I can share this new knowledge to my students taking up trust my paper review. Glad I came across your blog and learned something.