Acumatica: Refresh the UI elements

In order to get the best performance, Acumatica  has optimizations on which UI items it refreshes.

For example, if you capture the delete event of a grid, and you want to update another row in the same grid, you will find that your changes are not reflected in the UI. So let’s say that you have Rows with a Title Field. And the Title Field of your three rows is ‘one’, ‘two’, ‘three’.

Let’s say that row ‘two’ is deleted and you want to update row ‘three’ to set the title as ‘two’.

If you do this in the graph you will find that the UI is not updated to reflect the change. This is because of an Acumatica optimization that would only refresh the deleted row and remove it but does not refresh the other rows.

The fix is simple just call the View.RequestRefresh() operation of your data view and it will updated accordingly. Voila!

Posted in Acumatica | Tagged | Leave a comment

Acumatica: Copy DAC

There could be situations where you need to insert a new DAC which is the same or very similar to another DAC.

Acumatica has a function that meets this exact requirement. Meet the CreateCopy function of the PXCache object.

What’s important to keep in mind is that the CreateCopy creates an exact copy of the DAC, including the IDs. Therefore, if you want to insert  a new entry, you have to null the IDs, such as the following example.

 


MyDAC myDAC = PXCache<MyDAC>.CreateCopy(sourceDAC);
myDAC.ID = null; // null the ID
myDAC.Title = "A new DAC"; //update any fields
myGraph.Entries.Insert(myDAC); //update the Graph

Posted in Acumatica | Tagged | Leave a comment

Acumatica: Capturing command events in Javascript

Disclaimer: Today’s blog describes how you can extend Acumatica through Javascript. Using Javascript may not fully supported by Acumatica and may cause additional work during upgrades.

A typical scenario that an Acumatica developer may encounter, is the need to add some particular logic on the client-side when a specific command completes. For example, after the user has clicked on a grid button and the action has completed.

In order to support this, we can use the ClientEvents functionality of the DataSource. An example where this is used in Acumatica, is in the page SM208000.

As can be seen below, the ClientEvents element of the PXDataSource has a CommandPerformed property which takes the name of a Javascript function.


<px:PXDataSource ID="ds" runat="server" Visible="True"
PrimaryView="Designs"
TypeName="PX.Data.Maintenance.GI.GenericInquiryDesigner">
<ClientEvents CommandPerformed="commandResult" />

 

The Javascript function takes 2 parameters: the datasource and the context. In this case of the SM208000, this page uses the context.command property to identify which of the grid button was clicked. It then highlights the next/previous row depending on whether the user has clicked on the move up or the move down button.

 


function commandResult(ds, context)

{

// grdFilterID and grdResultsID is registered by server

var grid = null;

var row = null;

if (context.command == "MoveDownFilter" || context.command == "MoveUpFilter")

grid = px_all[grdFilterID];

else if (context.command == "MoveDownResults" || context.command == "MoveUpResults")

grid = px_all[grdResultsID];

else if (context.command == "MoveDownSortings" || context.command == "MoveUpSortings")

grid = px_all[grdSortsID];

else if (context.command == "MoveDownCondition" || context.command == "MoveUpCondition")

grid = px_all[grdWheresID];

else if (context.command == "MoveDownRelations" || context.command == "MoveUpRelations")

grid = px_all[grdJoinsID];

else if (context.command == "MoveDownOn" || context.command == "MoveUpOn")

grid = px_all[grdOnsID];

else if (context.command == "MoveDownGroupBy" || context.command == "MoveUpGroupBy")

grid = px_all[grdGroupByID];

&nbsp;

&nbsp;

if (context.command == "MoveDownFilter" || context.command == "MoveDownResults" || context.command == "MoveDownSortings"

|| context.command == "MoveDownCondition" || context.command == "MoveDownRelations" || context.command == "MoveDownOn" || context.command == "MoveDownGroupBy")

row = grid.activeRow.nextRow();

else if (context.command == "MoveUpFilter" || context.command == "MoveUpResults" || context.command == "MoveUpSortings"

|| context.command == "MoveUpCondition" || context.command == "MoveUpRelations" || context.command == "MoveUpOn" || context.command == "MoveUpGroupBy")

row = grid.activeRow.prevRow();

if (row)

row.activate();

}

</script>

 

The above represents just one application of the CommandPerformed property. This can be used in other circumstances, typically whenever client side logic needs to be added after a command has completed.

 

Posted in Uncategorized | Tagged | Leave a comment

SQL Basics: the order of logical query processing

Syntax vs Processing order

An important aspect is that the order of keywords in the syntax is different from the order in which it is processed.

The Syntax order is as follows:

  1. SELECT
  2. FROM
  3. WHERE
  4. GROUP BY
  5. HAVING
  6. ORDER BY

However, the processing order is different

  1. FROM
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT
  6. ORDER BY

This means that the processing engine starts executing from 1 to 6, and  it can only refer to elements in previous steps. For example, if the engine is at “stage 2 WHERE”, it cannot refer to fields created by the SELECT. The following would throw an error Invalid column name ”Fullname”.


Select age, name + surname as FullName
from dbo.tblPeople
where FullName = 'Joseph Caruana'

Although Fullname is a valid column, the WHERE clause does not know about it yet and that it is why the error is “Invalid column name”.

This basic ordering concept explains several other things. For example, it describes why you cannot filter a GROUP by value (such as SUM) based on the WHERE clause.

Posted in Uncategorized | Leave a comment