Solved

Blanket PO No in code: CS0120 issue

  • 13 October 2021
  • 1 reply
  • 73 views

Good day.

I am trying to set a custom field in my header to true if my purchase order detail line contains a blanket PO Nr.
I have created the custom field, and am currently trying to change the field in the row updated event.
I am currently getting a An object reference is required for the non-static field, method, or property 'POLine.PONbr'An object reference is required for the non-static field, method, or property 'POLine.PONbr' error.

Any help would be greatly appreciated.
Please see my code attached here

        #region UsrContainsBlanketPONo
[PXDBBool]
[PXUIField(DisplayName = "Contains Blanket No")]

public virtual bool? UsrContainsBlanketPONo { get; set; }
public abstract class usrContainsBlanketPONo : PX.Data.BQL.BqlBool.Field<usrContainsBlanketPONo> { }
#endregion
 protected void POLine_RowUpdated(PXCache cache, PXRowUpdatedEventArgs e)
{

var row = (POLine)e.Row;

foreach (POLine line in Base.Transactions.Select().RowCast<POLine>().Where(POLine.PONbr != null))
{
POOrderExt extdata = cache.GetExtension<POOrder>(line);
extdata.UsrContainsBlanketPONo = true;
break;
}

}

 

icon

Best answer by mvolshteyn 20 October 2021, 10:28

View original

1 reply

Userlevel 5
Badge +3

@charlbester34 , this particular error is caused by the incorrect syntax of the Where method. It requires a lambda expression and non-static object reference (see https://docs.microsoft.com/ru-ru/dotnet/api/system.linq.enumerable.where?view=net-5.0), such as:

foreach (POLine line in Base.Transactions.Select().RowCast<POLine>().Where(line => ((POLine)line).PONbr != null))

but there are other issues with this code:

  1. On the following line, the GetExtension method is applied to incorrect cache reference (lines cache). Should be POOrder cache:
    POOrderExt extdata = Base.Document.Cache.GetExtension<POOrderExt >(Base.Document.Current);
  2. Also, there should be the logic setting this field to false when there are no more lines with PONbr  field filled (POLine_RowDeleted)
  3. foreach cycle seems redundant here, since you can use the .any method to check presence ot lines satisfying the condition. Coupled with (2), it suggests the following code:

    extdata.UsrContainsBlanketPONo = Base.Transactions.Select().RowCast<POLine>().Any(line => ((POLine)line).PONbr != null);
     
  4. since the PONbr  field is filled on line creation and cannot be edited for existing line, the appropriate place for this logic seems to be the POLine_RowInserted

Given all this, I would implemented the requested check on the BLC level as follows:

public class POOrderEntryCommCust147Ext : PXGraphExtension<POOrderEntry>
    {

        private void RecalcUsrContainsBlanketPONo()
        {
            POOrderCommCust147Ext extdata = Base.Document.Cache.GetExtension<POOrderCommCust147Ext>(Base.Document.Current);
            extdata.UsrContainsBlanketPONo = Base.Transactions.Select().RowCast<POLine>().Any(line => ((POLine) line).PONbr != null);
        }

        [PXOverride]
        public virtual void POLine_RowInserted(PXCache cache, PXRowInsertedEventArgs e, PXRowInserted baseMethod)
        {

            baseMethod(cache, e);
            //foreach (POLine line in Base.Transactions.Select().RowCast<POLine>().Where(line => line.PONbr != null))
            if (Base.Document.Current.OrderType == POOrderType.RegularOrder)
            {
                RecalcUsrContainsBlanketPONo();
            }
            
        }

        [PXOverride]
        public virtual void POLine_RowDeleted(PXCache cache, PXRowDeletedEventArgs e, PXRowDeleted baseMethod)
        {

            baseMethod(cache, e);
            //foreach (POLine line in Base.Transactions.Select().RowCast<POLine>().Where(line => line.PONbr != null))
            if (Base.Document.Current.OrderType == POOrderType.RegularOrder)
            {
                RecalcUsrContainsBlanketPONo();
            }
        }
    }

 

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved