Yuriy Zaletskyy
Yuriy Zaletskyy

Reputation: 5151

How to subscribe to User Defined fields in Acumatica

I've added on Acumatica User defined field:

enter image description here How can I add to those fields CommitChanges="true" and how it's possible to add RowUpdated, FieldUpdated functionality for those fields?

Upvotes: 3

Views: 950

Answers (2)

Nayan Mansinha
Nayan Mansinha

Reputation: 301

These UDF fields are attribute fields that are created at runtime as part of FieldSelecting event and so can be accessed using PXCache.GetValueExt/SetValueExt as shown in the example below. Note here that field name is prepended with a word "Attribute" followed by the attribute code.

        var row = Base.Opportunity.Current;
        var cache = Base.Opportunity.Cache;
        var udfREFOPP = (PXStringState)cache.GetValueExt(row, "AttributeREFOPP");
        var udfREFAPPT = (PXStringState)cache.GetValueExt(row, "AttributeREFAPPT");

        cache.SetValueExt(row, "AttributeREFOPP", udfREFAPPT.Value);
        cache.SetValueExt(row, "AttributeREFAPPT", udfREFOPP.Value);

Upvotes: 4

Samvel Petrosov
Samvel Petrosov

Reputation: 7706

The UDF fields are rendered as regular fields, so the Commit Changes can be turned on from JavaScript by setting the onValueChange to 1.

The tricky part is with capturing the event. Unfortunately, the event is not triggered on the UDF field itself. But from the way the field is rendered it is bound to the main Form of the page. For example, on SO301000 - Sales orders it is bound to the Header form - primary view. Which means that it will trigger SO Order row level events.

enter image description here

From JavaScript side you can access this fields by the following way:

px_all.ctl00_phF_form_t1_AttributeBURDEN

you just need to set the onValueChange to 1 to get the Commit Changes working

px_all.ctl00_phF_form_t1_AttributeBURDEN.onValueChange=1;

As I have already explained in my this answer the UDF's are handled via KvExt tables and to access them we need to create additional DAC.

[PXCacheName("SO Order Attributes")]
[Serializable]
public class SOOrderKvExt : IBqlTable
{
    public abstract class recordID : BqlGuid.Field<recordID> { }
    [PXDBGuid(IsKey = true)]
    public Guid? RecordID { get; set; }

    public abstract class fieldName : BqlString.Field<fieldName> { }
    [PXDBString(50, IsKey = true)]
    [PXUIField(DisplayName = "Name")]
    public string FieldName { get; set; }

    public abstract class valueNumeric : BqlDecimal.Field<valueNumeric> { }
    [PXDBDecimal(8)]
    [PXUIField(DisplayName = "Value Numeric")]
    public decimal? ValueNumeric { get; set; }

    public abstract class valueDate : BqlDateTime.Field<valueDate> { }
    [PXDBDate]
    [PXUIField(DisplayName = "Value Date")]
    public DateTime? ValueDate { get; set; }

    public abstract class valueString : BqlString.Field<valueString> { }
    [PXDBString(256)]
    [PXUIField(DisplayName = "Value String")]
    public string ValueString { get; set; }

    public abstract class valueText : BqlString.Field<valueText> { }
    [PXDBString]
    [PXUIField(DisplayName = "Value Text")]
    public string ValueText { get; set; }
}

After this we can catch the event in the SOOrder_RowUpdated handler like below:

protected virtual void SOOrder_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
{
    if(e.Row is SOOrder row)
    {
        PXResultset<SOOrder> orderWithUDFs = PXSelectJoin<SOOrder, 
            LeftJoin<SOOrderKvExt, On<SOOrder.noteID, Equal<SOOrderKvExt.recordID>>,
            LeftJoin<PX.CS.CSAttribute, On<SOOrderKvExt.fieldName, Contains<PX.CS.CSAttribute.attributeID>>>>, 
            Where<SOOrder.orderNbr, Equal<Required<SOOrder.orderNbr>>,
            And<SOOrder.orderType,Equal<Required<SOOrder.orderType>>>>>.Select(this.Base, row.OrderNbr,row.OrderType);
        foreach (PXResult<SOOrder,SOOrderKvExt,PX.CS.CSAttribute> orderWithUDF in orderWithUDFs)
        {
            var udfValue = (SOOrderKvExt)orderWithUDF;
            var attributeDef = (PX.CS.CSAttribute)orderWithUDF;
            if(attributeDef.FieldName=="BURDEN")
            {
                //do something
                var value = udfValue.ValueText;//depending on the Attribute.
            }
        }
    }
}

So the same way you can work with other Row level events. Unfortunately, I don't see any way to work with the field directly in the way we all used to do.

Upvotes: 1

Related Questions