How to block column in Acumatica grid or one value in column

Hello,

I want to share with you how to block some columns in Acumatica.

You can do it with the PXUIFieldAttribute.SetEnabled method.

Let's say you have DAC PRTran with column earningType and values of PRTran you get from PaySlipDetails view. Then you can block whole column with the following call:

PXUIFieldAttribute.SetEnabled<PRTran.earningType>(PaySlipDetails.Cache, null, isEnabled);

Another question which sometime appears is how to block single record value in column.

The solution is the following:

row = .... here goes your logic which will get PRTran for which you need to make blocking

PXUIFieldAttribute.SetEnabled<PRTran.earningType>(PaySlipDetails.Cache,  row, false);

Current items in View

Hello everybody,

today I want to share with everybody how to find all items in view in Acumatica.

Suppose you have View declared in the following way:

public PXSelectJoin<PRPayrollDetails,

InnerJoin<EPEmployee, On<EPEmployee.bAccountID, Equal<PRPayrollDetails.employeeID>>,

InnerJoin<PRPayroll, On<PRPayroll.refNbr, Equal<Current<PRPayrollDetails.payrollRefNbr>>>,

LeftJoin<APInvoice, On<APInvoice.refNbr, Equal<PRPayrollDetails.aPRefNbr>, And<APInvoice.docType, Equal<PRPayrollDetails.aPDocType>>>>>>,

Where<PRPayrollDetails.payrollRefNbr, Equal<Current<PRPayroll.refNbr>>>, OrderBy<Asc<PRPayrollDetails.description>>> PayRollsDetails;

 

and now you made some changes to that view in one of your functions. How to get current situation of view?

If you answered PayRollsDetails.Cache.Cached then you are wrong. You should get them as PayRollsDetails.Select() and only in that way. Then you'll get current situation with items in grid

An object reference is required for the non-static field, method, or property PX.Data.PXSelectBase Acumatica DAC Select in Acumatica

Hello everybody,

today I want to share how to fight with error like 

Error 22 An object reference is required for the non-static field, method, or property 'PX.Data.PXSelectBase<Acumatica DAC>.Select(params object[])' bla bla bla

As usually it means that you try to use this in selector of Extension class. Just replace this at Base or Base2 and your problem will go away.

for example 

CR.Location customerLoc = PXSelect<CR.Location, Where<CR.Location.bAccountID, Equal<Required<CR.Location.bAccountID>>, 

                            And<CR.Location.locationID, Equal<Required<CR.Location.locationID>>>>>.Select(this, customer.BAccountID, customer.DefLocationID);

should be 

CR.Location customerLoc = PXSelect<CR.Location, Where<CR.Location.bAccountID, Equal<Required<CR.Location.bAccountID>>, 

                            And<CR.Location.locationID, Equal<Required<CR.Location.locationID>>>>>.Select(Base, customer.BAccountID, customer.DefLocationID);

and your code will be compiled again

Create new record in Acumatica or which insert works faster

Hello everybody,

today I want to share results of my investigations of two similar pieces of functionality in Acumatica.

Have you ever wondered which Insert in cache works faster this:

a) var temp = (PRPayrollDetails)PayRollsDetails.Cache.Insert();

or this:

b)          var temp = new PRPayrollDetails();

             temp = (PRPayrollDetails)PayRollsDetails.Cache.Insert(temp);

If to believe to results of Stopwatch, the second part of code works faster. For my set of data, the first one took 5.5 seconds, while the second option took 4.3 seconds. And this is difference for 300 records. If you have any ideas why it can be, you are welcome to share them.

And if I had 250 records then the difference between option a and b is ~4 seconds

How to read from stored procedure in Acumatica

Hello readers,

today I want to share hwo it is possible to read from stored procedure in Acumatica. Keep in mind, that reading from sp is against best practices of Acumatica, because if you read from sp, then you'll reading will not be cached and other side effects, but sometime you don't have a choice. So, for such cases you can try following approach:

 

create procedure uspWow

@invnbr nvarchar(6),

@money decimal(19,4) OUTPUT

AS

       SELECT @money = ARInvoice.CuryLineTotal

       FROM ARInvoice

       WHERE ARInvoice.RefNbr = @invnbr;

       RETURN

GO

 

 

var invNbr = new PXSPInParameter("invnbr""000595");

var money = new PXSPOutParameter("money"PXDbType.Decimal, 19, 4, null);

var results = PXDatabase.Execute("uspWow"new PXSPParameter[] { invNbr, money});

 

var sb = new System.Text.StringBuilder("PROC RESULT:\n");

foreach(var r in results)

{

    sb.AppendLine(r.ToString());

}

throw new PXException(sb.ToString());

Get extension of basic DAC class in Acumatica

Helllo,

today I want to share how to get extension of basic DAC class iin Acumatica. Lets say you have class ARTran, and extenstion for it ARTranExt and you want to get it in the code of ARTran_RowUpdated event

Then you can get extenstion in the following way:

 

 

   protected virtual void ARTran_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)

        {

            var newRow = (ARTran)e.Row;

            var newRowE = PXCache<ARTran>.GetExtension<ARTranExt>(newRow);

            .

            .

            .

       }

How to get companyid in Acumatica

Hello everybody,

today I want to share how to find current company id in Acumatica:

Here it is:

int? companyid = PX.Common.PXContext.GetSlot<Int32?>("singleCompanyID")

 

for me it was long way to find it

Enumerate Cached objects

Hello everybody,

today I want to share how to enumerate cahed objects according to some type. 

Imagine you have following declaration:

public PXSelectJoin<PRTran> PaySlipDetails;

And that you need to enumerate them as list of PRTran's in some special way.

In my case I used following instruction:

 

var prTrans = PaySlipDetails.Cache.Cached.Cast<PRTran>().ToList().Where(a => a.IsDeleted.HasValue && !a.IsDeleted.Value).ToList();// we have list of all undeleted pr trans

var sumOtherAdj = prTrans.Where(a => a.EarningType == EarningType.OA.GetEnumDescription() || a.EarningType == EarningType.OD.GetEnumDescription()).Sum(a => a.TotalAmount);

Rename column at screen in Acumatica

Hello everybody,

today I want to share answer at simple question how to change the caption at some screen. 

For example you want to change caption at screen AR202000 for Inventory ID to caption INVENTORY ID.

For this purpose we need to understand which DAC is responsible for Grid. For this puprose we can open page AR202000.

There we can see the following line:

<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%" PrimaryView="Filter" TypeName="PX.Objects.AR.ARSalesPriceMaint">

So it means that for Graph or controller we will check ARSalesPriceMaint.

For field inventory id responsible code 

<px:PXSegmentMask ID="edInventoryID" runat="server" DataField="InventoryID" AllowEdit="True">

and view which we need is named 

 <px:PXGridLevel DataMember="Records">

Lets navigate to class PX.Objects.AR.ARSalesPriceMaint with help of reflector ( one of my favorite tools ).

Find there member Records which is declared in the following way:

public SalesPriceProcessing<ARSalesPrice, InnerJoin<InventoryItem, On<InventoryItem.inventoryID, Equal<ARSalesPrice.inventoryID>>, LeftJoin<INItemCost, On<INItemCost.inventoryID, Equal<InventoryItem.inventoryID>>>>, Where<ARSalesPrice.custPriceClassID, Equal<Current<ARSalesPriceFilter.custPriceClassID>>, And2<Where<Current<ARSalesPriceFilter.curyID>, IsNull, Or<ARSalesPrice.curyID, Equal<Current<ARSalesPriceFilter.curyID>>>>, And<ARSalesPrice.isPromotionalPrice, Equal<Current<ARSalesPriceFilter.promotionalPrice>>, And<InventoryItem.itemStatus, NotEqual<INItemStatus.inactive>, And<InventoryItem.itemStatus, NotEqual<INItemStatus.toDelete>, And<Where2<Where<Current<ARSalesPriceFilter.itemClassID>, IsNull, Or<Current<ARSalesPriceFilter.itemClassID>, Equal<InventoryItem.itemClassID>>>, And2<Where<Current<ARSalesPriceFilter.inventoryPriceClassID>, IsNull, Or<Current<ARSalesPriceFilter.inventoryPriceClassID>, Equal<InventoryItem.priceClassID>>>, And2<Where<Current<ARSalesPriceFilter.ownerID>, IsNull, Or<Current<ARSalesPriceFilter.ownerID>, Equal<InventoryItem.priceManagerID>>>, And2<Where<Current<ARSalesPriceFilter.myWorkGroup>, Equal<boolFalse>, Or<InventoryItem.priceWorkgroupID, InMember<CurrentValue<ARSalesPriceFilter.currentOwnerID>>>>, And<Where<Current<ARSalesPriceFilter.workGroupID>, IsNull, Or<Current<ARSalesPriceFilter.workGroupID>, Equal<InventoryItem.priceWorkgroupID>>>>>>>>>>>>>>, OrderBy<Asc<ARSalesPrice.inventoryID, Asc<ARSalesPrice.uOM, Asc<ARSalesPrice.lastDate>>>>> Records;

Looks scarry, huh? For me in the begining of my way also. But lets continue. 

DataField="InventoryID" means that this field is declared in class ARSalesPrice.

Just for example lets say that DataField looked in the following way:

DataField="InventoryItem__InventoryID". That mean that we need to search for class InventoryItem.

Lets navigate with reflector to class ARSalesPrice and find there field InventoryID.

It's declared in the following way:

        [Inventory(DisplayName="Inventory ID"), PXDefault, PXParent(typeof(Select<InventoryItem, Where<InventoryItem.inventoryID, Equal<Current<inventoryID>>>>))]
        public virtual int? InventoryID
        {
            get
            {
                return this._InventoryID;
            }
            set
            {
                this._InventoryID = value;
            }
        }

Then do the following:

1. create class ARSalesPriceExt like this:

 public class  ARSalesPriceExt : PXCacheExtension< ARSalesPrice>
    {

2. In the class declare the following member:

        [Inventory(DisplayName="INVENTORY ID"), PXDefault, PXParent(typeof(Select<InventoryItem, Where<InventoryItem.inventoryID, Equal<Current<inventoryID>>>>))]
        public virtual int? InventoryID
        {
            get
            {
                return this._InventoryID;
            }
            set
            {
                this._InventoryID = value;
            }
        }

3. Build class library and reference it in your Acumatica web site and congratulations, you have changed caption in grid

 

FieldUpdated behaviour

Hello everybody,

today  I want to share one interesting feature of Acumatica. 

I revelaed that after inserting of new row executes FieldUpdated even if field wasn't updated. After reading documentation I found that it is gotcha and inteded to be so.