Skip to main content
Answer

Edit Scan Message in Screen Pick, Pack, and Ship (SO302020)

  • July 25, 2023
  • 12 replies
  • 213 views

RaphaelPfaff12
Semi-Pro III

As a user, I would like to see not only the item ID in the scan message, but also the description. Does anyone know how to extend this?

 

Unfortunately, I did not find anything in the attributes of the Message field.

 

Best answer by darylbowman

 This code defines new local variables for the messages with a placeholder for an additional parameter ‘{5}’. The method responsible for displaying messages is overridden to use the local variables. Then, inventory.Descr is passed as a fifth parameter.

// Acuminator disable once PX1016 ExtensionDoesNotDeclareIsActiveMethod extension should be constantly active
public class DXPaperlessPickingExt : PXGraphExtension<PaperlessPicking, PickPackShip.Host>
{
public const string PickItemNoLotSerial = "Pick {2}-{5}, quantity: {0} {1} left.";
public const string PickItemWithLotSerial = "Pick {2}-{5}, lot/serial: {3}, quantity: {0} {1} left.";
public const string PickItemFromLocationNoLotSerial = "Go to {4} and pick {2}-{5}, quantity: {0} {1} left.";
public const string PickItemFromLocationWithLotSerial = "Go to {4} and pick {2}-{5}, lot/serial: {3}, quantity: {0} {1} left.";


// Replaces 'PromptWantedItem()' method from PaperlessPicking.cs
public delegate string PromptWantedItemDelegate();
[PXOverride]
public string PromptWantedItem(PromptWantedItemDelegate baseMethod)
{
SOPickerListEntry wantedSplit = Base1.GetWantedSplit();
if (wantedSplit != null)
{
var similarSplits = Base1.GetWantedSplitsForIncrease();

var inventory = InventoryItem.PK.Find(Base1.Basis, wantedSplit.InventoryID);
var lotSerialClass = Base1.Basis.GetLotSerialClassOf(inventory);
bool noCertainLotSerial =
lotSerialClass == null ||
lotSerialClass.LotSerTrack == INLotSerTrack.NotNumbered ||
lotSerialClass.LotSerAssign == INLotSerAssign.WhenUsed ||
lotSerialClass.LotSerIssueMethod == INLotSerIssueMethod.UserEnterable;
string msg = Base1.Basis.DefaultLocation
? noCertainLotSerial
? PickItemFromLocationNoLotSerial // Changed line to use local variable
: PickItemFromLocationWithLotSerial // Changed line to use local variable
: noCertainLotSerial
? PickItemNoLotSerial // Changed line to use local variable
: PickItemWithLotSerial; // Changed line to use local variable
return Base1.Basis.Localize(
msg,
similarSplits.Sum(s => s.Qty - s.PickedQty),
wantedSplit.UOM,
Base1.Basis.SightOf<SOPickerListEntry.inventoryID>(wantedSplit),
wantedSplit.LotSerialNbr,
Base1.Basis.SightOf<SOPickerListEntry.locationID>(wantedSplit),
// Start added lines
inventory.Descr);
// End added lines);
}

return null;
}
}

 

12 replies

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

Is a simple code customization an option?


Chris Hackett
Community Manager
Forum|alt.badge.img
  • Acumatica Community Manager
  • August 22, 2023

Hi @RaphaelPfaff12 were you able to find a solution? Thank you!


Forum|alt.badge.img
  • Freshman I
  • November 28, 2024

Is a simple code customization an option?

Hi Daryl,
how to customize the field? for example, how to add the description of the item after the InventoryID?


Forum|alt.badge.img+1
  • Jr Varsity III
  • November 29, 2024

Hi ​@hmzamr ,
  For displaying message you can write code on field updated event.


Forum|alt.badge.img
  • Freshman I
  • November 29, 2024

Hi ​@hmzamr ,
  For displaying message you can write code on field updated event.

the problem is with the necessary logic to get the InventoryID from the message and update it with the InventoryID+Description

 


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

@hmzamr - This took me a while to figure out. I’ll send you a private message.


  • Freshman I
  • May 29, 2025

@darylbowman How did you end up solving this?


darylbowman
Captain II
Forum|alt.badge.img+15
  • Answer
  • May 30, 2025

 This code defines new local variables for the messages with a placeholder for an additional parameter ‘{5}’. The method responsible for displaying messages is overridden to use the local variables. Then, inventory.Descr is passed as a fifth parameter.

// Acuminator disable once PX1016 ExtensionDoesNotDeclareIsActiveMethod extension should be constantly active
public class DXPaperlessPickingExt : PXGraphExtension<PaperlessPicking, PickPackShip.Host>
{
public const string PickItemNoLotSerial = "Pick {2}-{5}, quantity: {0} {1} left.";
public const string PickItemWithLotSerial = "Pick {2}-{5}, lot/serial: {3}, quantity: {0} {1} left.";
public const string PickItemFromLocationNoLotSerial = "Go to {4} and pick {2}-{5}, quantity: {0} {1} left.";
public const string PickItemFromLocationWithLotSerial = "Go to {4} and pick {2}-{5}, lot/serial: {3}, quantity: {0} {1} left.";


// Replaces 'PromptWantedItem()' method from PaperlessPicking.cs
public delegate string PromptWantedItemDelegate();
[PXOverride]
public string PromptWantedItem(PromptWantedItemDelegate baseMethod)
{
SOPickerListEntry wantedSplit = Base1.GetWantedSplit();
if (wantedSplit != null)
{
var similarSplits = Base1.GetWantedSplitsForIncrease();

var inventory = InventoryItem.PK.Find(Base1.Basis, wantedSplit.InventoryID);
var lotSerialClass = Base1.Basis.GetLotSerialClassOf(inventory);
bool noCertainLotSerial =
lotSerialClass == null ||
lotSerialClass.LotSerTrack == INLotSerTrack.NotNumbered ||
lotSerialClass.LotSerAssign == INLotSerAssign.WhenUsed ||
lotSerialClass.LotSerIssueMethod == INLotSerIssueMethod.UserEnterable;
string msg = Base1.Basis.DefaultLocation
? noCertainLotSerial
? PickItemFromLocationNoLotSerial // Changed line to use local variable
: PickItemFromLocationWithLotSerial // Changed line to use local variable
: noCertainLotSerial
? PickItemNoLotSerial // Changed line to use local variable
: PickItemWithLotSerial; // Changed line to use local variable
return Base1.Basis.Localize(
msg,
similarSplits.Sum(s => s.Qty - s.PickedQty),
wantedSplit.UOM,
Base1.Basis.SightOf<SOPickerListEntry.inventoryID>(wantedSplit),
wantedSplit.LotSerialNbr,
Base1.Basis.SightOf<SOPickerListEntry.locationID>(wantedSplit),
// Start added lines
inventory.Descr);
// End added lines);
}

return null;
}
}

 


Forum|alt.badge.img+1
  • Semi-Pro I
  • May 30, 2025

Our VAR struggled with this quite a bit; they were never able to make any kind of change to what displays on this screen.  I’m going to come back to this after we upgrade and give it another shot.


  • Freshman I
  • May 30, 2025

@darylbowman Thank you!!!! that was the pointer I needed!!!!
Ill make sure to share my full working graph here when complete. 


  • Freshman I
  • May 30, 2025

Thanks to ​@darylbowman 

Here is the full working graph extension using the exampled code that got it working where I can start dialing it in to our clients needs. 

 

 

using System;
using System.Linq;
using System.Diagnostics;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using PX.Common;
using PX.Data;
using PX.Data.BQL;
using PX.Data.BQL.Fluent;
using PX.BarcodeProcessing;
using PX.Objects.AR;
using PX.Objects.CS;
using PX.Objects.IN;
using PX.Objects.IN.WMS;
using PX.Objects.Common.Extensions;
using PX.Objects;
using PX.Objects.SO.WMS;

namespace PX.Objects.SO.WMS
{
public class ItemCodeDesc_Ext: PXGraphExtension<PaperlessPicking,PickPackShip.Host>
{
#region Event Handlers
public const string PickItemNoLotSerial = "Pick {2}-{5}, quantity: {0} {1} left.";
public const string PickItemWithLotSerial = "Pick {2}-{5}, lot/serial: {3}, quantity: {0} {1} left.";
public const string PickItemFromLocationNoLotSerial = "Go to {4} and pick {2}-{5}, quantity: {0} {1} left.";
public const string PickItemFromLocationWithLotSerial = "Go to {4} and pick {2}-{5}, lot/serial: {3}, quantity: {0} {1} left.";

// Replaces 'PromptWantedItem()' method from PaperlessPicking.cs
public delegate string PromptWantedItemDelegate();
[PXOverride]
public string PromptWantedItem(PromptWantedItemDelegate baseMethod)
{
SOPickerListEntry wantedSplit = Base1.GetWantedSplit();

if (wantedSplit != null)
{
var similarSplits = Base1.GetWantedSplitsForIncrease();

var inventory = InventoryItem.PK.Find(Base1.Basis, wantedSplit.InventoryID);
var lotSerialClass = Base1.Basis.GetLotSerialClassOf(inventory);

bool noCertainLotSerial =
lotSerialClass == null ||
lotSerialClass.LotSerTrack == INLotSerTrack.NotNumbered ||
lotSerialClass.LotSerAssign == INLotSerAssign.WhenUsed ||
lotSerialClass.LotSerIssueMethod == INLotSerIssueMethod.UserEnterable;

string msg = Base1.Basis.DefaultLocation
? noCertainLotSerial
? PickItemFromLocationNoLotSerial
: PickItemFromLocationWithLotSerial
: noCertainLotSerial
? PickItemNoLotSerial
: PickItemWithLotSerial;

return Base1.Basis.Localize(
msg,
similarSplits.Sum(s => s.Qty - s.PickedQty), // {0}
wantedSplit.UOM, // {1}
Base1.Basis.SightOf<SOPickerListEntry.inventoryID>(wantedSplit), // {2}
wantedSplit.LotSerialNbr, // {3}
Base1.Basis.SightOf<SOPickerListEntry.locationID>(wantedSplit), // {4}
inventory?.Descr // {5}
);
}

return null;
}
#endregion
}
}

 


  • Freshman I
  • May 30, 2025

Side note, it also covers the web version.