0
votes

How can I add an Attribute column from "Stock Items" screen to "Add Item" dialog box of Purchase Order screen. I want to add the following attribute from Stock Items screen to the "Add Item" Dialog box of Purchase Order Screen. Please review the images below for Stock Item and Purchase Order Screens.

Stock Items Attribute Tab Image

Purchase Order Inventory Status Dialog Image

I am able to get the field in the inventory lookup of PO, the values did not populated.

here goes my code....

namespace PX.Objects.PO
{
    [PXProjection(typeof(Select<CSAnswers, Where<CSAnswers.refNoteID, Equal<POSiteStatusSelected.noteID>, 
                                And<CSAnswers.attributeID, Equal<AttribMyAttribute>>>>), Persistent = false)]
  
    public class POSiteStatusSelectedExt : PXCacheExtension<PX.Objects.PO.POSiteStatusSelected>
    {
    #region UsrItemType
    [PXDBString(10, IsFixed = true, BqlField = typeof(CSAnswers.value))]
    [PXUIField(DisplayName = "Item Type")]
    //[PXDBScalar(typeof(Search<CSAnswers.value, Where<CSAnswers.refNoteID, Equal<POSiteStatusSelected.noteID>,
    //                            And<CSAnswers.attributeID, Equal<AttribMyAttribute>>>>))]
 
      public virtual string UsrItemType { get; set; }
      public abstract class usrItemType : IBqlField { }
        #endregion
        
    }
    public class AttribMyAttribute : Constant<string>
    {
        public AttribMyAttribute() : base("ITEMTYPE") { }
    }
}

I have created a DAC extension of POSiteStatusSeleted view and added my custom field which is a non-persisted field. There is noteId field in the POSiteStatusSeleted which is of type InventoryItem.noteID, i tried to use the same in the PXDBScalar attribute(the code line is commented), this also didn't work out, it was showing an error for "Unable to convert System.Int32 to System.String".

enter image description here

1

1 Answers

0
votes

Updated Answer: Because of the projection, we have to create a new class that inherits the DAC and uses the [PXSubstitute] attribute. The nature of PXSubstitute means that this will not be a DAC extension or even part of a Graph Extension. In my testing, I tried encapsulating this in a graph extension on POOrderEntry, and it did not work. By following the instructions of the stack overflow post below, I was able to create an Attribute called ITEMTYPE, assign it to one of my Item Classes, replace the PXProjection with an enhanced version that includes a left join back to the attribute table (CSAnswers) and then add it to the screen's smart panel grid.

Extend Acumatica Projection Based DAC Query

In the code sample below, the magic is in PXSubstitute, which will take the new class that you create and inherit from the base DAC and replace that base DAC with your new one. If you specify a graph, it will perform the substitution in only that graph (or each graph you specify - 1 per PXSubstitute attribute used). If you do not specify a graph, it will override the base DAC in every case it is used within the xRP Framework.

Code to perform the stated modification:

using PX.Data;
using PX.Objects.AP;
using PX.Objects.Common.Bql;
using PX.Objects.CS;
using PX.Objects.IN;
using System;

namespace PX.Objects.PO
{
    [System.SerializableAttribute()]
    [PXProjection(typeof(Select2<InventoryItem,
        LeftJoin<CSAnswers,
            On<CSAnswers.refNoteID, Equal<InventoryItem.noteID>,
            And<CSAnswers.attributeID, Equal<AttribItemType>>>,
        LeftJoin<INSiteStatus,
                        On<INSiteStatus.inventoryID, Equal<InventoryItem.inventoryID>, And<INSiteStatus.siteID, NotEqual<SiteAttribute.transitSiteID>>>,
        LeftJoin<INSubItem,
                        On<INSiteStatus.FK.SubItem>,
        LeftJoin<INSite,
                        On<INSiteStatus.FK.Site>,
        LeftJoin<INItemXRef,
                        On<INItemXRef.inventoryID, Equal<InventoryItem.inventoryID>,
                        And2<Where<INItemXRef.subItemID, Equal<INSiteStatus.subItemID>,
                                Or<INSiteStatus.subItemID, IsNull>>,
                        And<Where<CurrentValue<POSiteStatusFilter.barCode>, IsNotNull,
                        And<INItemXRef.alternateType, Equal<INAlternateType.barcode>>>>>>,
        LeftJoin<INItemPartNumber,
                        On<INItemPartNumber.inventoryID, Equal<InventoryItem.inventoryID>,
                        And<INItemPartNumber.alternateID, Like<CurrentValue<POSiteStatusFilter.inventory_Wildcard>>,
                        And2<Where<INItemPartNumber.bAccountID, Equal<Zero>,
                            Or<INItemPartNumber.bAccountID, Equal<CurrentValue<POOrder.vendorID>>,
                            Or<INItemPartNumber.alternateType, Equal<INAlternateType.cPN>>>>,
                        And<Where<INItemPartNumber.subItemID, Equal<INSiteStatus.subItemID>,
                            Or<INSiteStatus.subItemID, IsNull>>>>>>,
        LeftJoin<INItemClass,
                        On<InventoryItem.FK.ItemClass>,
        LeftJoin<INPriceClass,
                        On<INPriceClass.priceClassID, Equal<InventoryItem.priceClassID>>,
        LeftJoin<Vendor,
                        On<Vendor.bAccountID, Equal<InventoryItem.preferredVendorID>>,
        LeftJoin<INUnit,
                        On<INUnit.inventoryID, Equal<InventoryItem.inventoryID>,
                        And<INUnit.unitType, Equal<INUnitType.inventoryItem>,
                        And<INUnit.fromUnit, Equal<InventoryItem.purchaseUnit>,
                        And<INUnit.toUnit, Equal<InventoryItem.baseUnit>>>>>>>>>>>>>>>,
        Where2<CurrentMatch<InventoryItem, AccessInfo.userName>,
             And2<Where<INSiteStatus.siteID, IsNull, Or<INSite.branchID, IsNotNull, And2<CurrentMatch<INSite, AccessInfo.userName>,
                And<Where2<FeatureInstalled<FeaturesSet.interBranch>,
                    Or2<SameOrganizationBranch<INSite.branchID, Current<POOrder.branchID>>,
                    Or<CurrentValue<POOrder.orderType>, Equal<POOrderType.standardBlanket>>>>>>>>,
             And2<Where<INSiteStatus.subItemID, IsNull,
                Or<CurrentMatch<INSubItem, AccessInfo.userName>>>,
             And<InventoryItem.stkItem, Equal<boolTrue>,
             And<InventoryItem.itemStatus, NotEqual<InventoryItemStatus.inactive>,
             And<InventoryItem.itemStatus, NotEqual<InventoryItemStatus.unknown>,
             And<InventoryItem.itemStatus, NotEqual<InventoryItemStatus.markedForDeletion>,
             And<InventoryItem.itemStatus, NotEqual<InventoryItemStatus.noPurchases>>>>>>>>>>), Persistent = false)]

    //[PXSubstitute(GraphType = typeof(POOrderEntry))]
    [PXSubstitute]

    public partial class POSiteStatusSelectedCst : POSiteStatusSelected
    {
        #region UsrItemType
        [PXDBString(10, BqlField = typeof(CSAnswers.value))]
        [PXUIField(DisplayName = "Item Type")]
        public string UsrItemType { get; set; }
        public abstract class usrItemType : PX.Data.BQL.BqlString.Field<usrItemType> { }
        #endregion
    }

    public class AttribItemType : PX.Data.BQL.BqlString.Constant<AttribItemType>
    {
        public AttribItemType() : base("ITEMTYPE") { }
    }
}