Skip to main content
Question

Modify Selector in Materials Screen (AM300000)

  • December 13, 2024
  • 10 replies
  • 130 views

Forum|alt.badge.img+2

Hi I want to modify the Parent Lot/ Serial Nbr to only show selector records where the value is greater than 0 in remaining quantity.

I’ve tried to modify the selector using this approach below and it does not filter as expected.

[PXSelector( typeof(Search<INLotSerialStatus.lotSerialNbr, Where<INLotSerialStatus.qtyOnHand, Greater<decimal0>>>),

Any help would be appreciated, thank you!

10 replies

Forum|alt.badge.img+1
  • Jr Varsity III
  • December 13, 2024

Hi ​@TharidhiP 
Override field on screen level try like below:
// In your DAC Extension
[PXSelector(
    typeof(Search<INLotSerialStatus.lotSerialNbr,
        Where<INLotSerialStatus.inventoryID, Equal<Current<INRegister.inventoryID>>,
            And<INLotSerialStatus.siteID, Equal<Current<INRegister.siteID>>,
            And<INLotSerialStatus.qtyOnHand, Greater<decimal0>>>>>),
    typeof(INLotSerialStatus.lotSerialNbr),
    typeof(INLotSerialStatus.qtyOnHand),
    typeof(INLotSerialStatus.expireDate),
    SubstituteKey = typeof(INLotSerialStatus.lotSerialNbr))]

If not work try with below approach:
 

public class YourGraphExtension : PXGraphExtension<YourBaseGraph>
{
    protected virtual void _(Events.FieldSelecting<YourDAC.parentLotSerialNbr> e)
    {
        var cache = e.Cache;
        var row = e.Row as YourDAC;
        if (row == null) return;

        PXSelector selector = PXSelectorAttribute.GetAttribute<PXSelectorAttribute>(cache, row, nameof(YourDAC.parentLotSerialNbr));
        if (selector == null) return;

        // Modify the selector's search to include quantity filtering
        selector.SetHandler(
            typeof(Search<INLotSerialStatus.lotSerialNbr,
                Where<INLotSerialStatus.inventoryID, Equal<Current<INRegister.inventoryID>>,
                    And<INLotSerialStatus.siteID, Equal<Current<INRegister.siteID>>,
                    And<INLotSerialStatus.qtyOnHand, Greater<decimal0>>>>>));
    }
}

Hope it will work.


Forum|alt.badge.img+2
  • Author
  • Pro III
  • December 16, 2024

Hi ​@noorula77 thank you for your suggestions! Can I also add logic to keep the parent/ lot serial nbr editable after release using the FieldSelecting event handler you have added? 


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

...Can I also add logic to keep the parent/ lot serial nbr editable after release using the FieldSelecting event handler you have added? 

Field control needs to be modified in the RowSelected event handler.


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

 But for the original problem, you should be able to add a PXRestrictor attribute to the DAC field on CacheAttached:

[PXMergeAttributes(Method = MergeMethod.Append)][PXRestrictor(typeof(Where<INLotSerialStatus.qtyOnHand.IsGreater<decimal0>>), "Qty On Hand is zero")]
protected virtual void _(Events.CacheAttached<INLotSerialStatus.parentLotSerialNbr> e) { }

This is a less heavy-handed approach and exactly what the PXRestrictor is for.


Forum|alt.badge.img+2
  • Author
  • Pro III
  • December 19, 2024

Thank you for the suggestion! ​@darylbowman 


Forum|alt.badge.img+2
  • Author
  • Pro III
  • December 20, 2024

Hi ​@darylbowman I tried using the restrictor for this as below 

[PXMergeAttributes(Method = MergeMethod.Append)][PXRestrictor(typeof(Where<AMProdItemSplit.qtyRemaining.IsGreater<decimal0>>), "Qty Remaining is zero")]
protected virtual void _(Events.CacheAttached<AMMTran.parentLotSerialNbr> e) { }

but the filtration doesn’t happen do I need to set any other properties on this field?

Thanks!


darylbowman
Captain II
Forum|alt.badge.img+15
  • December 20, 2024

Apologies. I didn’t do my research and assumed from the code in ​@noorula77’s answer that the selector was based on INLotSerialStatus, but it’s not. It’s based on AMProdItemSplit. A PXRestrictor can only use statements of tables already joined in the original selector. Furthermore, the actual selector is managed by the ParentLotSerialNbrAttribute which uses an ugly compose statement. I’ve tried to modify it to join the INLotSerialStatus table and only return QtyOnHand greater than zero:

using PX.Common;
using PX.Data;
using PX.Objects.AM;
using PX.Objects.CS;
using PX.Objects.IN;
using System;

namespace Test
{
public class DXTest : PXGraphExtension<MaterialEntry>
{
// Replaces the orignal ParentLotSerialNbrAttribute with the DXParentLotSerialNbrAttribute
[PXMergeAttributes(Method = MergeMethod.Append)]
[PXRemoveBaseAttribute(typeof(PX.Objects.AM.Attributes.ParentLotSerialNbrAttribute))]
[DXParentLotSerialNbr(typeof(AMMTran.orderType), typeof(AMMTran.prodOrdID), ValidateValue = false, PersistingCheck = PXPersistingCheck.Nothing)]
protected virtual void _(Events.CacheAttached<AMMTran.parentLotSerialNbr> e) { }
}

// The modified ParentLotSerialNbrAttribute
[PXDBString(100, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Parent Lot/Serial Nbr.", FieldClass = "LotSerial")]
[PXDefault("")]
public class DXParentLotSerialNbrAttribute : PXEntityAttribute
{
public DXParentLotSerialNbrAttribute(Type ProdOrderType, Type ProdOrdIDType)
{
Type itemType = BqlCommand.GetItemType(ProdOrderType);
if (!typeof(ILSMaster).IsAssignableFrom(itemType))
{
throw new PXArgumentException("itemType", "The specified type {0} must implement the {1} interface.", itemType.GetLongName(), typeof(ILSMaster).GetLongName());
}

PXSelectorAttribute item = new PXSelectorAttribute(
BqlCommand.Compose(typeof(Search2<,,>),
typeof(AMProdItemSplit.lotSerialNbr),
typeof(InnerJoin<,>), typeof(INLotSerialStatus),
typeof(On<,,>), typeof(INLotSerialStatus.inventoryID), typeof(Equal<>), typeof(AMProdItemSplit.inventoryID),
typeof(And<,,>), typeof(INLotSerialStatus.subItemID), typeof(Equal<>), typeof(AMProdItemSplit.subItemID),
typeof(And<,,>), typeof(INLotSerialStatus.siteID), typeof(Equal<>), typeof(AMProdItemSplit.siteID),
typeof(And<,,>), typeof(INLotSerialStatus.locationID), typeof(Equal<>), typeof(AMProdItemSplit.locationID),
typeof(And<,>), typeof(INLotSerialStatus.lotSerialNbr), typeof(Equal<>), typeof(AMProdItemSplit.lotSerialNbr),
typeof(Where<,,>),
typeof(AMProdItemSplit.orderType), typeof(Equal<>), typeof(Optional<>), ProdOrderType,
typeof(And<,,>),
typeof(AMProdItemSplit.prodOrdID), typeof(Equal<>), typeof(Optional<>), ProdOrdIDType,
typeof(And<,>),
typeof(INLotSerialStatus.qtyOnHand), typeof(GreaterEqual<>), typeof(decimal0)
),
typeof(AMProdItemSplit.lotSerialNbr),
typeof(AMProdItemSplit.qty),
typeof(AMProdItemSplit.qtyComplete),
typeof(AMProdItemSplit.qtyScrapped),
typeof(AMProdItemSplit.qtyRemaining));

_Attributes.Add(item);
_SelAttrIndex = _Attributes.Count - 1;
}
}
}

Unfortunately, I don’t have any instances using Lot / Serial tracking right now, so I can’t test if it actually works.


Forum|alt.badge.img+2
  • Author
  • Pro III
  • December 21, 2024

Hey ​@darylbowman thank you for letting me know regarding this logic, I tried this out but it still does not filter any records based on values greater than 0 but shows values where remaining qty is 0.00, please see below screenshot with the logic I changed as  typeof(INLotSerialStatus.qtyOnHand), typeof(Greater<>), typeof(decimal0). 

If I got to line details of the production order it shows these records where filtering is based on.

 


darylbowman
Captain II
Forum|alt.badge.img+15
  • December 21, 2024

Are you saying even with the changes you made it's still not working?


Forum|alt.badge.img+2
  • Author
  • Pro III
  • December 22, 2024

Hi ​@darylbowman yes even with my modification it does not filter