Monday, 27 February 2017

Hide Action from Datasource

Hi All,

When you new create action in the PXGraphExtensions, it is automatically getting visible in in the data-source actions bar, even if you have not customized ASPX.
public class JournalEntry_Extension:PXGraphExtension<JournalEntry>
    public PXAction<PX.Objects.GL.BatchNewAction;  
    [PXButton(CommitChanges true)]
    [PXUIField(DisplayName "New Action")]
    protected void newAction()
It looks like here:
new action acumatica

But if you want to hide that button, it is very easy to do it with Customization Browser. Just drag and drop button to the data-source in page editor:
new action acumatica

Than just set the Name to your action name and Visible to false.
new action name acumatica

That is all. Now Action is not visible anymore.

Have a nice development!

Thursday, 23 February 2017

Customization and Source Control

Hi All,

I'm sure you know that Acumatica customization project is just a big XML file that has some links on external files. You can easily export ZIP archive with all linked files and store it on the file system. Unfortunately is not really good for tracking changes.

But do you know that Acumatica has very easy-to-use integration with source control where you can export project as set of text files? Let me show you how to use it:
source control acumatica

As I said customization project is big zip file, but it can be split by items, that you can see using File -Edit Project Items menu:
Edit Project Items menu acumatica

All of these items we can export to some folder as a separate files, so it will be much easier to store them and track changes.
To export them click on Source Control -> Save To Folder
Save To Folder acumatica

Monday, 20 February 2017

Override Static Method

Hi All,

Unfortunately sometimes during customization you may need to override some logic in static methods and that is really bad task, as it requires to copy a lot of code.
customization acumatica
Here I will show you few examples that can give you idea how you can fix it.

In general there is no way to really override static method, the only one way how you can replace it's logic is just define a new one and replace all places where it is called.

3 different scenarios will be based on Acumatica Fixed Assets module:
  • Not so good - static method on event
    • AssetMaint.LiveUpdateMaskedSubs(PXGraph graph, PXCache facache, FALocationHistory lochist);
  • Bad - static method on dynamically subscribed event
    • AssetMaint.MakeSubID<MaskField, SubIDField>(PXCache sender, FixedAsset asset);
  • Very Bad - static method on Persist
    • AssetProces.TransferAsset(PXGraph graph, FixedAsset asset, FALocationHistory location, ref FARegister register);
Lets start:

Thursday, 9 February 2017

Multi-Company Reports

Hi All,

Today I want to share with you a way how you can print multi-company (multi-tenancy) reports.
You know that Acumatica tenants are completely separated and there is no way to make a report or generic inquiry for multiple tenants.
Acumatica tenants

So first of all want to share with you the technical details - Acumatica stores all tenants in one database, but separate it by CompanyID column, that is a part of primary key. You can read more about it here.

Acumatica Framework automatically detects CompanyID column in the table and adds "WHERE CompanyID = {Something}" to every query. Unfortunately you cannot change anything here.
But good thing is - if you have table without CompanyID column, it will be also supported and Acumatica will work with that table as a global for all tenants.

So if we create a view without CompanyID column, we can use it for global reporting. The only one thing that lefts is to create a DAC for that view and use it in Acumatica.

However views and DACs are not really protected from updates - if you update Acumatica and there are changes in database, you have to recreate views and DACs.
So here I want to show you few tricks, how you can keep it update protected with minimum changes.

Welcome in the article for more details.

Monday, 6 February 2017

Dynamically Activate Extensions

Hi All,

Today I want to share with the way how you can enable and disable extensions dynamically.

You know that when you have published extension as a DLL or a Code file it will be automatically discovered by Acumatica Framework and used.
However there is a hidden way to stop Acumatica from usage of that extension. Do do that you just need add static method IsActive() to your extension.
  public class GL_Batch_Ext PXCacheExtension<PX.Objects.GL.Batch>
      public static bool IsActive()
        return false;
Acumatica will automatically call that method by signature (you need to have correct name, public, static and return bool) and if it returns False, extensions will be ignored.
That works the same way for Graph and Cache extensions.
Also note, that if method rise an exception extension will be loaded any way.

Good thing about it that you really can decide dynamically what extension should be loaded based on database value or current company.So that is a way how you can have different business logic customization for different companies.

So in that example I have renamed one of fields on Journal Entry screen based on current company id:
Have a nice development!

Wednesday, 1 February 2017

Approval Workflow Customization

Hi Everyone,

Today I want to share with you one important point about customization of automation approval workflow.

Firs of all please read this article on Stack Overflow to understand how Acumatica Approval works.
But here I would take Purchase Orders screen as example, because there we already have automation workflow configured.

In the article below, you may notices that all approval logic is encapsulated into the special Data View - EPApprovalAutomation. On the Purchase Orders form it is designed like this:
public EPApprovalAutomation<POOrder, POOrder.approved, POOrder.rejected, POOrder.hold, POSetupApproval> Approval;

EPApprovalAutomation is just a class with multiple virtual methods that you can override and customize. 
So we can create our own approval workflow and define it in the graph or graph extension.
public class MyAppprovalAutomation
: EPApprovalAutomation<POOrder, POOrder.approved, POOrder.rejected, POOrder.hold,
{ }

public class POOrderEntry_Extension : PXGraphExtension<POOrderEntry>
       #region DataViews
       public MyApprovalAutomation Approval;

However, here we have one issue.