0

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 Answers1

0

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") { }
    }
}
Brian Stevens
  • 1,826
  • 1
  • 7
  • 16
  • Hi Brian, thanks for your prompt reply, I have tried exactly the way you told me to do using the PXProjection, I have customized the POSiteStatusSeleted view by creating a DAC extension of the view and using the projection there. The required data does not appear in the column, I will share my work by editing the question above – SD Netsense Jul 31 '20 at 04:04
  • The actual view used by the grid is siteStatus. It looked like it worked through that projection, but I ran out of time digging up the exact details. I had hoped the things I shared would point you in the right direction. If you don’t get it sorted before I can can back to it, I will try to take a look over the weekend. – Brian Stevens Jul 31 '20 at 04:06
  • See the revised answer above for the complete code that I used to complete the stated objective. Assuming your attribute name is ITEMTYPE, you simply need to ensure it is assigned to the Item Class(es) where applicable and then add the new column to the smart panel's grid. My previous guidance was based on simple DAC's and did not take into account the projection, but I tested the code above within a fresh SalesDemo instance before posting. – Brian Stevens Aug 03 '20 at 05:33