0
votes

I have added a DAC Extension to ARTran with a field to provide the Discount Unit Price (displayed to the user on the Invoices screen)

public class ARTran_Extension : PXCacheExtension<ARTran>
{
    [PXDecimal]
    [PXUIField(DisplayName = "Disc Unit Price", Enabled = false)]
    [PXDefault(TypeCode.Decimal, "0")]
    [PXDBCalced(typeof(Div<Mult<IsNull<ARTran.curyUnitPrice, Zero>, Sub<_100Percents, IsNull<ARTran.discPct, Zero>>>, _100Percents>), typeof(decimal))]
    public virtual decimal UsrDiscUnitPrice { get; set; }
    public abstract class usrDiscUnitPrice : IBqlField { }
}

Now I'm trying to compose a simple Generic Inquiry that has SOOrder Inner Join SOLine and SOLine Left Join ARTran (and a couple parameters to specify a date range of orders). When I view the inquiry and select a date range that returns records it returns an error: "Error #111: An error occurred while processing the field Disc Unit Price : Object reference not set to an instance of an object."

The Results Grid does not currently reference any fields from the ARTran table. This occurs even when Inner joining ARTran (ensuring there are records from the table).

I systematically eliminated elements and identified when the PXDBCalced attribute is removed the Inquiry runs successfully. I then tried changing it to use a Custom attribute instead and found even when a custom attribute is added, even if it has no functional code within it, the inquiry again fails with that error. Even when there is FieldSelecting event code via the custom attribute, setting a breakpoint within it that event is never reached.

public class ARTranDiscUnitPriceAttribute : PXEventSubscriberAttribute, IPXFieldSelectingSubscriber
{
    public virtual void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
    {
        /*
        ARTran artran = (ARTran)e.Row;
        if (artran == null) return;
        e.ReturnValue = (artran.CuryUnitPrice ?? 0) * (100 - (artran.DiscPct ?? 0)) / 100;
        */
    }
}

public class ARTran_Extension : PXCacheExtension<ARTran>
{
    [PXDecimal]
    [PXUIField(DisplayName = "Disc Unit Price")]
    [PXDefault(TypeCode.Decimal, "0")]
    [ARTranDiscUnitPrice]
    public virtual decimal UsrDiscUnitPrice { get; set; }
    public abstract class usrDiscUnitPrice : IBqlField { }
}

Any details or suggestions how to resolve this would be greatly appreciated.

The Trace:

Error #111: An error occurred while processing the field Disc Unit Price : Object reference not set to an instance of an object..

System.NullReferenceException: Object reference not set to an instance of an object.

at _SetValueByOrdinal(ARTran , Int32 , Object , PXCacheExtension[] )

at PX.Data.PXCache`1.SetValueByOrdinal(TNode data, Int32 ordinal, Object value, PXCacheExtension[] extensions)

at PX.Data.PXCache`1.SetValue(Object data, Int32 ordinal, Object value)

at PX.Data.PXDBCalcedAttribute.RowSelecting(PXCache sender, PXRowSelectingEventArgs e)

at PX.Data.PXCache.OnRowSelecting(Object item, PXDataRecord record, Int32& position, Boolean isReadOnly)

at PX.Data.PXCache.OnRowSelecting(Object item, PXDataRecord record, Int32& position, Boolean isReadOnly)

at PX.Data.PXGenericInqGrph.d__9.MoveNext()

at _CustomMethod(Object , Object[] )

at PX.Data.PXView.InvokeDelegate(Object[] parameters)

at PX.Data.PXView.Select(Object[] currents, Object[] parameters, Object[] searches, String[] sortcolumns, Boolean[] descendings, PXFilterRow[] filters, Int32& startRow, Int32 maximumRows, Int32& totalRows)

at PX.Data.PXProcessingBase`1._SelectRecords(Int32 startRow, Int32 maxRows)

at PX.Data.Maintenance.GI.GIFilteredProcessing._List()

at _CustomMethod(Object , Object[] )

at PX.Data.PXView.InvokeDelegate(Object[] parameters)

at PX.Data.PXView.Select(Object[] currents, Object[] parameters, Object[] searches, String[] sortcolumns, Boolean[] descendings, PXFilterRow[] filters, Int32& startRow, Int32 maximumRows, Int32& totalRows)

at PX.Data.PXGraph.ExecuteSelect(String viewName, Object[] parameters, Object[] searches, String[] sortcolumns, Boolean[] descendings, PXFilterRow[] filters, Int32& startRow, Int32 maximumRows, Int32& totalRows)

1

1 Answers

1
votes

A super easy fix for this issue: in Acumatica all DAC fields must be of a nullable type, so once you declare your UsrDiscUnitPrice field of the Nullable<decimal> type or the decimal? type, you should be good to go:

public class ARTran_Extension : PXCacheExtension<ARTran>
{
    public abstract class usrDiscUnitPrice : IBqlField { }

    [PXDecimal]
    [PXUIField(DisplayName = "Disc Unit Price")]
    [PXDefault(TypeCode.Decimal, "0")]
    [ARTranDiscUnitPrice]
    public virtual decimal? UsrDiscUnitPrice { get; set; }
}