1. To get salesorders based items available physical qty
internal final class SNSalesOrderItemQty extends SysOperationServiceBase
{
//M Vinodkumar - to get salesorders based items available physical qty - 15 oct 2025
/// <summary>
/// Gets today's sales order items with positive physical inventory (grouped by ItemId, Site, Location).
/// </summary>
public void getTodaysSalesOrderItemsGroupedInventory()
{
SalesTable salesTable;
SalesLine salesLine;
InventSum inventSum;
utcdatetime endDate, fromDate;
endDate = DateTimeUtil::utcNow(); // Current UTC datetime
fromDate = DateTimeUtil::addHours(endDate, -1); // Subtract 1 hour
Map resultMap = new Map(Types::String, Types::Real); // Key: ItemId
Set processedKeys = new Set(Types::String);
str mapKey;
real physicalQty;
// Step 1: Loop through Sales Orders created today with Open or Invoiced status
while select SalesId
from salesTable
where (salesTable.CreatedDateTime >= fromDate && salesTable.CreatedDateTime <= endDate) &&
(salesTable.SalesStatus == SalesStatus::Backorder ||
salesTable.SalesStatus == SalesStatus::Invoiced)
{
// Step 2: Loop through SalesLines on that order
while select ItemId
from salesLine
where salesLine.SalesId == salesTable.SalesId
{
// Composite key using ItemId
mapKey = strFmt("%1", salesLine.ItemId);
// Only process each (ItemId ) once
if (!processedKeys.in(mapKey))
{
processedKeys.add(mapKey);
// Step 3: Check InventSum for this Item
select sum(AvailPhysical) from inventSum
where inventSum.ItemId == salesLine.ItemId &&
inventSum.AvailPhysical > 0;
if (inventSum.AvailPhysical > 0)
{
resultMap.insert(mapKey, inventSum.AvailPhysical);
}
}
}
}
// Step 4: Display results
MapEnumerator enumerator = resultMap.getEnumerator();
while (enumerator.moveNext())
{
mapKey = enumerator.currentKey();
physicalQty = enumerator.currentValue();
container keyParts = str2con(mapKey, "|");
info(strFmt("Item: %1, AvailPhysical: %2",
conPeek(keyParts, 1),
physicalQty));
}
}
}
internal final class SNSalesOrderItemQtyController extends SysOperationServiceController
{
/// <summary>
///
/// </summary>
public void new()
{
super();
this.parmClassName(classStr(SNSalesOrderItemQty));
this.parmMethodName(methodStr(SNSalesOrderItemQty, getTodaysSalesOrderItemsGroupedInventory));
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public ClassDescription caption()
{
return "Sales order items qty.";
}
/// <summary>
///
/// </summary>
/// <param name = "args"></param>
public static void main(Args args)
{
SNSalesOrderItemQtyController controller;
controller = new SNSalesOrderItemQtyController();
controller.parmExecutionMode(SysOperationExecutionMode::Synchronous);
controller.startOperation();
}
}
---------------------------------------------------------------------------------------------------------------------
2. Addproducts hierarchy and inserting in form level of ecoresproductdetailsextended form of product
[ExtensionOf(formControlStr(EcoResProductDetailsExtended,AddRetailProductsButton))]
final class SNEcoResProductDetailsExtendedFormControl_Extension
{
void clicked()
{
//super();
xFormRun formRun;
RetailIAddItems formAddItems;
Args args;
MenuFunction menuFunction;
InventTable inventTableLoc;
EcoResProduct ecoResProductLoc;
SNSimilarProducts SNSimilarProducts;
inventTableLoc = this.formrun().datasource(formDataSourceStr(EcoResProductDetailsExtended,InventTable)).cursor();
ecoResProductLoc = this.formrun().datasource(formDataSourceStr(EcoResProductDetailsExtended,EcoResProduct)).cursor();
SNSimilarProducts = this.formrun().datasource(formDataSourceStr(EcoResProductDetailsExtended,SNSimilarProducts)).cursor();
args = new Args();
args.caller(element);
args.record(SNSimilarProducts);
args.parm(inventTableLoc.ItemId);
menuFunction = new MenuFunction(menuitemDisplayStr(RetailAddProductsVariants), MenuItemType::Display);
formRun = menuFunction.create(args);
formRun.run();
formRun.wait();
next clicked();
}
}
[ExtensionOf(formStr(RetailAddItems))]
final class SNRetailAddItemsForm_Extension
{
public InventTable callerInventTable;
/// <summary>
/// Creates records in caller table when <c>RetailAddItems</c> form is closed.
/// </summary>
/// <param name = "_callerTableId">
/// The caller tableId.
/// </param>
/// <param name = "_tmpInventTable">
/// The table buffer of <c>TmpRetailProductsToAdd</c> temporary table.
/// </param>
public void createCallerTableRecords(TableId _callerTableId, TmpRetailProductsToAdd _tmpInventTable)
{
ItemId callerItemId;
SNSimilarProducts simProd;
next createCallerTableRecords(_callerTableId, _tmpInventTable);
switch (_callerTableId)
{
case tableNum(SNSimilarProducts):
callerItemId = this.args().parm();
InventTable inventTable = InventTable::find(callerItemId);
if (callerItemId && inventTable)
{
TmpRetailProductsToAdd tmpProd;
// Loop through the temp table directly
while select _tmpInventTable //M Vinodkumar - select query directly parameter added where buffer not worked - 14 oct 2025
//where tmpProd.TableId == _tmpInventTable.TableId
{
// Prevent duplicates
select firstonly simProd
where simProd.ProItemNum == callerItemId
&& simProd.SimItemId == _tmpInventTable.ItemId;//tmpProd.ItemId;
if (!simProd)
{
simProd.clear();
simProd.ProItemNum = callerItemId;
simProd.SimItemId = _tmpInventTable.ItemId;//tmpProd.ItemId;
simProd.insert(); // Will auto-handle reverse relation if you coded insert()
}
}
//M Vinodkumar - deleting unwanted itemids which are null - 14 oct 2025 - start
ttsbegin;
delete_from simProd where simProd.SimItemId == '';
ttscommit;
//M Vinodkumar - deleting unwanted itemids which are null - 14 oct 2025 - end
}
break;
}
}
}
------------------------------------------------------------------------------------------------------------------
3. To insert one field value when creating record based on form level itemid
[FormControlEventHandler(formControlStr(EcoResProductDetailsExtended, ProductAdd), FormControlEventType::Clicked)]
public static void ProductAdd_OnClicked(FormControl sender, FormControlEventArgs e)
{
// InventTable inventTable = sender.formRun().dataSource(formDataSourceStr(EcoResProductDetailsExtended, InventTable)).cursor();
FormDataSource sNSimilarProducts_ds = sender.formRun().dataSource(formDataSourceStr(EcoResProductDetailsExtended, SNSimilarProducts));
// Create new record buffer
SNSimilarProducts newLine = sNSimilarProducts_ds.cursor() as SNSimilarProducts;
//Info(strFmt("%1",newLine.ProItemNum));
newLine.ProItemRecid = InventTable::find(newLine.ProItemNum).Product;
sNSimilarProducts_ds.create(true);
sNSimilarProducts_ds.refresh();
}
--------------------------------------------------------------------------------------------------------------------
4. Category hierarchy lookup, product lookup based on category, default size lookup based on product
EcoResCategoryHierarchy ecoResCategoryHierarchy;
[DataField]
class Category
{
/// <summary>
/// Lookup Category
/// </summary>
/// <param name = "_formReferenceControl">formControl</param>
/// <returns></returns>
public Common lookupReference(FormReferenceControl _formReferenceControl)
{
Common ret;
ret = RetailGroupMemberLine::channelNavigationCategoryLookup(_formReferenceControl, ecoResCategoryHierarchy.RecId);
return ret;
}
}
[DataField]
class ProductId
{
/// <summary>
/// Lookup Product
/// </summary>
/// <param name = "_formControl">formControl</param>
/// <param name = "_filterStr">Str</param>
public void lookup(FormControl _formControl, str _filterStr)
{
SysTableLookup sysTableLookup;
Query query = new Query();
QueryBuildDataSource qbdsProduct, qbdsCategory;
QueryBuildLink qbLink;
sysTableLookup = SysTableLookup::newParameters(tableNum(EcoResProduct), _formControl);
qbdsProduct = query.addDataSource(tableNum(EcoResProduct));
qbdsCategory = qbdsProduct.addDataSource(tableNum(EcoResProductCategory));
qbdsCategory.relations(true);
qbLink = qbdsCategory.addLink(fieldNum(EcoResProduct, RecId), fieldNum(EcoResProductCategory, Product));
if(Grid_Category.valueStr() != '')
{
qbdsCategory.addRange(fieldNum(EcoResProductCategory, Category)).value(queryValue(Grid_Category.valueStr()));
}
sysTableLookup.addLookupfield(fieldNum(EcoResProduct, RecId));
sysTableLookup.addLookupfield(fieldNum(EcoResProduct, DisplayProductNumber));
sysTableLookup.addLookupfield(fieldNum(EcoResProduct, SearchName));
sysTableLookup.addSelectionField(fieldNum(EcoResProduct, RecId));
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}
[DataField]
class DefaultSize
{
/// <summary>
/// Lookup Size
/// </summary>
/// <param name = "_formControl">formControl</param>
/// <param name = "_filterStr">Str</param>
public void lookup(FormControl _formControl, str _filterStr)
{
SysTableLookup sysTableLookup;
Query query = new Query();
QueryBuildDataSource qbdsSize, qbdsInventDim;
QueryBuildLink qbLink;
sysTableLookup = SysTableLookup::newParameters(tableNum(InventDim), _formControl);
qbdsSize = query.addDataSource(tableNum(InventDim));
qbdsInventDim = qbdsSize.addDataSource(tableNum(InventDimCombination));
qbdsInventDim.relations(true);
qbLink = qbdsInventDim.addLink(fieldNum(InventDim, inventDimId), fieldNum(InventDimCombination, InventDimId));
if(Grid_DisplayProductNumber.valueStr() != '')
{
qbdsInventDim.addRange(fieldNum(InventDimCombination, ItemId)).value(queryValue(Grid_DisplayProductNumber.valueStr()));
}
sysTableLookup.addLookupfield(fieldNum(InventDim, InventSizeId));
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}
}
--------------------------------------------------------------------------------------------------------------------------