Skip to main content
Solved

Modifying Inventory Lookup grid in Transfer screen


Hello,

I am trying to modify the projection on INSiteStatusSelected for the Inventory Lookup grid in Transfer screen. I have tried inheriting from INSiteStatusLookupExt in INTransferEntry extension, as well as extending INRegisterEntryBase. Below is the example extending INTransferEntry. I am not able to pass the new DAC into Inventory Lookup grid. Any ideas what am I doing wrong?

 public class CFINTransferEntryExt: PXGraphExtension<INTransferEntry>
 {
     public class SiteStatusLookupExt : INSiteStatusLookupExt<INTransferEntry, INSiteStatusSelectedNew>
     {

         protected override bool IsAddItemEnabled(INRegister doc) => Transactions.AllowInsert;

         protected override INTran InitTran(INTran newTran, INSiteStatusSelectedNew selected)
         {
             newTran.ToSiteID = Document.Current.ToSiteID;

             newTran.SiteID = selected.SiteID ?? newTran.SiteID;
             newTran.InventoryID = selected.InventoryID;
             newTran.SubItemID = selected.SubItemID;
             newTran.UOM = selected.BaseUnit;
             newTran = PXCache<INTran>.CreateCopy(Transactions.Update(newTran));
             if (selected.LocationID != null)
             {
                 newTran.LocationID = selected.LocationID;
                 newTran = PXCache<INTran>.CreateCopy(Transactions.Update(newTran));
             }
             return newTran;
         }

         #region DAC overrides
         [PXCustomizeBaseAttribute(typeof(PXDefaultAttribute), nameof(PXDefaultAttribute.PersistingCheck), PXPersistingCheck.Null)]
         protected virtual void _(Events.CacheAttached<INSiteStatusFilter.siteID> e) { }

         [PXMergeAttributes(Method = MergeMethod.Replace)]
         [Location(typeof(INSiteStatusFilter.siteID))]
         protected virtual void _(Events.CacheAttached<INSiteStatusFilter.locationID> e) { }
         #endregion

         #region DACs
         public sealed class INTransferStatusFilter : PXCacheExtension<INSiteStatusFilter>
         {
             #region ReceiptNbr
             [PXDBString(15, IsUnicode = true, InputMask = ">CCCCCCCCCCCCCCC")]
             [PXUIField(DisplayName = "Receipt Nbr.", Visibility = PXUIVisibility.SelectorVisible)]
             [PXSelector(typeof(
                 Search2<POReceipt.receiptNbr,
                 InnerJoin<Vendor, On<POReceipt.vendorID, Equal<Vendor.bAccountID>>>,
                 Where<POReceipt.receiptType, Equal<POReceiptType.poreceipt>,
                 And<Match<Vendor, Current<AccessInfo.userName>>>>>), Filterable = true)]
             public String ReceiptNbr { get; set; }
             public abstract class receiptNbr : BqlString.Field<receiptNbr> { }
             #endregion
         }

         [PXHidden, PXProjection(typeof(
     Select2<InventoryItem,
     LeftJoin<INLocationStatusByCostCenter,
         On<INLocationStatusByCostCenter.FK.InventoryItem>,
     LeftJoin<INLocation,
         On<INLocationStatusByCostCenter.locationID, Equal<INLocation.locationID>>,
     LeftJoin<INSubItem,
         On<INLocationStatusByCostCenter.FK.SubItem>,
     LeftJoin<INSite,
         On<INLocationStatusByCostCenter.FK.Site>,
     LeftJoin<INItemXRef,
         On2<INItemXRef.FK.InventoryItem,
             And<INItemXRef.alternateType, In3<INAlternateType.barcode, INAlternateType.gIN>,
             And2<Where<INItemXRef.subItemID, Equal<INLocationStatusByCostCenter.subItemID>,
                 Or<INLocationStatusByCostCenter.subItemID, IsNull>>,
             And<CurrentValue<INSiteStatusFilter.barCode>, IsNotNull>>>>,
     LeftJoin<INItemClass,
         On<InventoryItem.FK.ItemClass>,
     LeftJoin<INPriceClass,
         On<InventoryItem.FK.PriceClass>,
     LeftJoin<POReceiptLine,
         On<POReceiptLine.receiptType, Equal<POReceiptType.poreceipt>,
             And<POReceiptLine.receiptNbr, Equal<CurrentValue<INTransferStatusFilter.receiptNbr>>,
             And<POReceiptLine.siteID, Equal<CurrentValue<INRegister.siteID>>,
             And<POReceiptLine.inventoryID, Equal<InventoryItem.inventoryID>>>>>>>>>>>>>,
     Where2<CurrentMatch<InventoryItem, AccessInfo.userName>,
         And2<Where<INLocationStatusByCostCenter.siteID, IsNull, Or<INSite.branchID, IsNotNull, And2<CurrentMatch<INSite, AccessInfo.userName>,
             And<Where2<FeatureInstalled<FeaturesSet.interBranch>,
                 Or<SameOrganizationBranch<INSite.branchID, Current<INRegister.branchID>>>>>>>>,
         And2<Where<INLocationStatusByCostCenter.subItemID, IsNull,
             Or<CurrentMatch<INSubItem, AccessInfo.userName>>>,
         And2<Where<CurrentValue<INSiteStatusFilter.onlyAvailable>, Equal<boolFalse>,
             Or<INLocationStatusByCostCenter.qtyOnHand, Greater<decimal0>>>,
         And2<Where<CurrentValue<INTransferStatusFilter.receiptNbr>, IsNull,
             Or<POReceiptLine.lineNbr, IsNotNull>>,
         And<InventoryItem.stkItem, Equal<boolTrue>,
         And<InventoryItem.isTemplate, Equal<False>,
         And<InventoryItem.itemStatus, NotIn3<InventoryItemStatus.unknown, InventoryItemStatus.inactive, InventoryItemStatus.markedForDeletion>>>>>>>>>>),
     Persistent = false)]

         public class INSiteStatusSelectedNew : PXBqlTable, IPXSelectable, IQtySelectable, IBqlTable
         {
             #region Selected
             [PXBool]
             [PXUnboundDefault(false)]
             [PXUIField(DisplayName = "Selected")]
             public virtual bool? Selected { get; set; }
             public abstract class selected : BqlBool.Field<selected> { }
             #endregion
             #region InventoryID
             [Inventory(BqlField = typeof(InventoryItem.inventoryID), IsKey = true)]
             [PXDefault]
             public virtual Int32? InventoryID { get; set; }
             public abstract class inventoryID : BqlInt.Field<inventoryID> { }
             #endregion
             #region InventoryCD
             [PXDefault]
             [InventoryRaw(BqlField = typeof(InventoryItem.inventoryCD))]
             public virtual String InventoryCD { get; set; }
             public abstract class inventoryCD : BqlString.Field<inventoryCD> { }
             #endregion
             #region Descr
             [PXDBLocalizableString(PX.Objects.Common.Constants.TranDescLength, IsUnicode = true, BqlField = typeof(InventoryItem.descr), IsProjection = true)]
             [PXUIField(DisplayName = "Description", Visibility = PXUIVisibility.SelectorVisible)]
             public virtual String Descr { get; set; }
             public abstract class descr : BqlString.Field<descr> { }
             #endregion
             #region ItemClassID
             [PXDBInt(BqlField = typeof(InventoryItem.itemClassID))]
             [PXUIField(DisplayName = "Item Class ID", Visible = false)]
             [PXDimensionSelector(INItemClass.Dimension, typeof(INItemClass.itemClassID), typeof(INItemClass.itemClassCD), ValidComboRequired = true)]
             public virtual int? ItemClassID { get; set; }
             public abstract class itemClassID : BqlInt.Field<itemClassID> { }
             #endregion
             #region ItemClassCD
             [PXDBString(30, IsUnicode = true, BqlField = typeof(INItemClass.itemClassCD))]
             public virtual string ItemClassCD { get; set; }
             public abstract class itemClassCD : BqlString.Field<itemClassCD> { }
             #endregion
             #region ItemClassDescription
             [PXDBLocalizableString(PX.Objects.Common.Constants.TranDescLength, IsUnicode = true, BqlField = typeof(INItemClass.descr), IsProjection = true)]
             [PXUIField(DisplayName = "Item Class Description", Visible = false)]
             public virtual String ItemClassDescription { get; set; }
             public abstract class itemClassDescription : BqlString.Field<itemClassDescription> { }
             #endregion
             #region PriceClassID
             [PXDBString(10, IsUnicode = true, BqlField = typeof(InventoryItem.priceClassID))]
             [PXUIField(DisplayName = "Price Class ID", Visible = false)]
             public virtual String PriceClassID { get; set; }
             public abstract class priceClassID : BqlString.Field<priceClassID> { }
             #endregion
             #region PriceClassDescription
             [PXDBString(PX.Objects.Common.Constants.TranDescLength, IsUnicode = true, BqlField = typeof(INPriceClass.description))]
             [PXUIField(DisplayName = "Price Class Description", Visible = false)]
             public virtual String PriceClassDescription { get; set; }
             public abstract class priceClassDescription : BqlString.Field<priceClassDescription> { }
             #endregion
             #region BarCode
             [PXDBString(255, BqlField = typeof(INItemXRef.alternateID), IsUnicode = true)]
             public virtual String BarCode { get; set; }
             public abstract class barCode : BqlString.Field<barCode> { }
             #endregion
             #region SiteID
             [PXUIField(DisplayName = "Warehouse")]
             [Site(BqlField = typeof(INLocationStatusByCostCenter.siteID), IsKey = true)]
             public virtual Int32? SiteID { get; set; }
             public abstract class siteID : BqlInt.Field<siteID> { }
             #endregion
             #region SiteCD
             [PXDBString(IsUnicode = true, BqlField = typeof(INSite.siteCD))]
             [PXDimension(SiteAttribute.DimensionName)]
             public virtual String SiteCD { get; set; }
             public abstract class siteCD : BqlString.Field<siteCD> { }
             #endregion
             #region LocationID
             [Location(typeof(siteID), BqlField = typeof(INLocationStatusByCostCenter.locationID), IsKey = true)]
             [PXDefault]
             public virtual Int32? LocationID { get; set; }
             public abstract class locationID : BqlInt.Field<locationID> { }
             #endregion
             #region LocationCD
             [PXDBString(BqlField = typeof(INLocation.locationCD), IsUnicode = true)]
             [PXDimension(LocationAttribute.DimensionName)]
             [PXDefault]
             public virtual String LocationCD { get; set; }
             public abstract class locationCD : BqlString.Field<locationCD> { }
             #endregion
             #region SubItemID
             [SubItem(typeof(inventoryID), BqlField = typeof(INSubItem.subItemID), IsKey = true)]
             public virtual Int32? SubItemID { get; set; }
             public abstract class subItemID : BqlInt.Field<subItemID> { }
             #endregion
             #region SubItemCD
             [PXDBString(IsUnicode = true, BqlField = typeof(INSubItem.subItemCD))]
             [PXDimension(SubItemAttribute.DimensionName)]
             public virtual String SubItemCD { get; set; }
             public abstract class subItemCD : BqlString.Field<subItemCD> { }
             #endregion
             #region BaseUnit
             [PXDefault(typeof(Search<INItemClass.baseUnit, Where<INItemClass.itemClassID, Equal<Current<InventoryItem.itemClassID>>>>))]
             [INUnit(DisplayName = "Base Unit", Visibility = PXUIVisibility.Visible, BqlField = typeof(InventoryItem.baseUnit))]
             public virtual String BaseUnit { get; set; }
             public abstract class baseUnit : BqlString.Field<baseUnit> { }
             #endregion
             #region QtySelected
             [PXQuantity]
             [PXUnboundDefault(TypeCode.Decimal, "0.0")]
             [PXUIField(DisplayName = "Qty. Selected")]
             public virtual Decimal? QtySelected
             {
                 get => this._QtySelected ?? 0m;
                 set
                 {
                     if (value != null && value != 0m)
                         this.Selected = true;
                     this._QtySelected = value;
                 }
             }
             protected Decimal? _QtySelected;
             public abstract class qtySelected : BqlDecimal.Field<qtySelected> { }
             #endregion
             #region QtyOnHand
             [PXDBQuantity(BqlField = typeof(INLocationStatusByCostCenter.qtyOnHand))]
             [PXDefault(TypeCode.Decimal, "0.0")]
             [PXUIField(DisplayName = "Qty. On Hand")]
             public virtual Decimal? QtyOnHand { get; set; }
             public abstract class qtyOnHand : BqlDecimal.Field<qtyOnHand> { }
             #endregion
             #region QtyAvail
             [PXDBQuantity(BqlField = typeof(INLocationStatusByCostCenter.qtyAvail))]
             [PXDefault(TypeCode.Decimal, "0.0")]
             [PXUIField(DisplayName = "Qty. Available")]
             public virtual Decimal? QtyAvail { get; set; }
             public abstract class qtyAvail : BqlDecimal.Field<qtyAvail> { }
             #endregion
             #region NoteID
             [PXNote(BqlField = typeof(InventoryItem.noteID))]
             public virtual Guid? NoteID { get; set; }
             public abstract class noteID : BqlGuid.Field<noteID> { }
             #endregion
         }
     }

 

Best answer by Samvel Petrosov

@stanaistov Your changes are not applied because of the data view definition still referring to the original Projection.

You need to “overwrite/swap” the data view definition in your TransferEntryExt.

 

The data view originally is defined in AddItemLookupBaseExt<TGraph, TDocument, TItemInfo, TItemFilter> abstract class.

 

[PXFilterable(new Type[]
        {

        })]
[PXCopyPasteHiddenView]
public FbqlSelect<SelectFromBase<TItemInfo, TypeArrayOf<IFbqlJoin>.Empty>, TItemInfo>.View ItemInfo;

 

View original
Did this topic help you find an answer to your question?

8 replies

Forum|alt.badge.img+8
  • Captain II
  • 366 replies
  • February 4, 2025

Hi ​@stanaistov 

 

Not quite sure I understand what you are trying to accomplish but hope the below helps.

 

You need to add a view for the DAC into the graph.

 

Something similar to:

public SelectFrom<INSiteStatusSelectedNew>.View YourViewName;

the name you give it will appear in the view selector in the customisation project editor.

 

I have re-read your question, you shouldn’t need to make a new PXProjection DAC. You can add custom fields to it, however you need to add the respective fields to the original DAC the field will be derived from, the table in your ‘BqlField =’ expression.

 

Aleks


  • Author
  • Freshman I
  • 5 replies
  • February 4, 2025

The original Acumatica view has a view delegate assigned, so I would lose all of that logic if I go that route.


Forum|alt.badge.img+8
  • Captain II
  • 366 replies
  • February 5, 2025

@stanaistov 

 

I can see you have essentially copied and pasted Acumatica’s source code for this, could you please explain what you are trying to do.


darylbowman
Captain II
Forum|alt.badge.img+13

You can write a cache extension on a projection just like any other DAC. Do you need to change the included tables?


  • Author
  • Freshman I
  • 5 replies
  • February 5, 2025
aiwan wrote:

@stanaistov 

 

I can see you have essentially copied and pasted Acumatica’s source code for this, could you please explain what you are trying to do.

Inventory Lookup in the Transfer screen does not include items received to a project and task. Acumatica has acknowledged the issue but it might take a while for fix to come out and the client is going live very soon. I found the issue with the original query with the join:

				LeftJoin<INLocationStatusByCostCenter,
					On2<INLocationStatusByCostCenter.FK.InventoryItem,
						And<INLocationStatusByCostCenter.costCenterID, 
                   Equal<CostCenter.freeStock>>>,

CostCenterID is always 0. Items are received into CostCenterID other than 0 if a receipt include project and task. Running an equivalent SQL query from profiler without CostCenterID = 0 displays the correct records. So I am implementing a workaround until Acumatica properly fixes the issue. 


Samvel Petrosov
Jr Varsity II
Forum|alt.badge.img+5

@stanaistov Your changes are not applied because of the data view definition still referring to the original Projection.

You need to “overwrite/swap” the data view definition in your TransferEntryExt.

 

The data view originally is defined in AddItemLookupBaseExt<TGraph, TDocument, TItemInfo, TItemFilter> abstract class.

 

[PXFilterable(new Type[]
        {

        })]
[PXCopyPasteHiddenView]
public FbqlSelect<SelectFromBase<TItemInfo, TypeArrayOf<IFbqlJoin>.Empty>, TItemInfo>.View ItemInfo;

 


  • Author
  • Freshman I
  • 5 replies
  • February 6, 2025
Samvel Petrosov wrote:

@stanaistov Your changes are not applied because of the data view definition still referring to the original Projection.

You need to “overwrite/swap” the data view definition in your TransferEntryExt.

 

The data view originally is defined in AddItemLookupBaseExt<TGraph, TDocument, TItemInfo, TItemFilter> abstract class.

 

[PXFilterable(new Type[]
        {

        })]
[PXCopyPasteHiddenView]
public FbqlSelect<SelectFromBase<TItemInfo, TypeArrayOf<IFbqlJoin>.Empty>, TItemInfo>.View ItemInfo;

 

Swapping view entirely is a last resort since that same extension contains a view delegate.


  • Author
  • Freshman I
  • 5 replies
  • February 7, 2025
Samvel Petrosov wrote:

@stanaistov Your changes are not applied because of the data view definition still referring to the original Projection.

You need to “overwrite/swap” the data view definition in your TransferEntryExt.

 

The data view originally is defined in AddItemLookupBaseExt<TGraph, TDocument, TItemInfo, TItemFilter> abstract class.

 

[PXFilterable(new Type[]
        {

        })]
[PXCopyPasteHiddenView]
public FbqlSelect<SelectFromBase<TItemInfo, TypeArrayOf<IFbqlJoin>.Empty>, TItemInfo>.View ItemInfo;

 

This has worked but with mixed results. Some receipts received to project are showing up, while others do not. Those that do have their qty on hand/availability numbers seriously screwed up and in the negatives. We decided to go with a custom inquiry screen and an action to create Transfers.

 

Thanks for all your responses.


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings