Solved

How to pass values into a static processing delegate


Userlevel 6
Badge +3

I have created a screen to change items in a sales order using a processing screen

The top of the form has two fields, the “From” item and the “To” item.

When you kick off the PROCESS ALL, I need to have the values in those fields available to the process delegate.

 

 

Since the UpdateOrders delegate is static, I don’t know how to get the from and to item numbers.  I’ve tried creating public properties and setting the values of the properties on the rowselected event.  But when UpdateOrders fires, and ultimately fires the UpdateOrder method, the properties are null.  

In the code below, I hard coded the inventoryID’s just to verify the code actually changes the sales order and it works great.  I just don’t know how to access the values in the top of the screen in the code. 

ItemNumberToChangeFilter filterValues = Filter.Select();  returns nulls.

 

Other than that, I’m almost done!  :-)

        public PXFilter<ItemNumberToChangeFilter> Filter;

        public PXFilteredProcessingJoin<SOOrder, ItemNumberToChangeFilter,
            LeftJoin<SOLine, On<SOLine.orderNbr.IsEqual<SOOrder.orderNbr>>>,
            Where<SOOrder.status.IsEqual<SOOrderStatus.open>
                .And<SOOrder.completed.IsEqual<False>>
                .And<SOOrder.orderType.IsEqual<SOOrderTypeConstants.salesOrder>>
                .And<SOLine.inventoryID.IsEqual<ItemNumberToChangeFilter.inventoryOld.FromCurrent>>>,
            OrderBy<SOOrder.orderNbr.Desc>> OrdersToProcess;

        [Serializable]
        //[PXHidden]
        [PXCacheName("Filtering Fields")]
        public class ItemNumberToChangeFilter : IBqlTable
        {
            #region InventoryOld
            [Inventory]
            [PXUIField(DisplayName = "Original Item ID")]
            public virtual int? InventoryOld { get; set; }
            public abstract class inventoryOld : PX.Data.BQL.BqlInt.Field<inventoryOld> { }
            #endregion

            #region InventoryNew
            [Inventory]
            [PXUIField(DisplayName = "New Item ID")]
            public virtual int? InventoryNew { get; set; }
            public abstract class inventoryNew : PX.Data.BQL.BqlInt.Field<inventoryNew> { }
            #endregion

        }
 

        public ICSSalesOrderItemChange()
        {
            OrdersToProcess.SetProcessDelegate(UpdateOrders);
        }

        public static void UpdateOrders(List<SOOrder> ordersToProcess)
        {
            using (var ts = new PXTransactionScope())
            {
                ICSSalesOrderItemChange graph = PXGraph.CreateInstance<ICSSalesOrderItemChange>();
                PXLongOperation.StartOperation(graph, delegate ()
                {
                    foreach (SOOrder order in ordersToProcess)
                    {
                        try
                        {
                            graph.UpdateOrder(order, true);
                        }
                        catch (Exception e)
                        {
                            PXProcessing<SOOrder>.SetError(ordersToProcess.IndexOf(order), e);
                        }
                    }
                });
                ts.Complete();
            }
        }

        public void UpdateOrder(SOOrder order, bool isMassProcess = false)
        {
            SOOrderEntry graph = PXGraph.CreateInstance<SOOrderEntry>();
            graph.Clear();
            graph.Document.Select(order);

            ItemNumberToChangeFilter filterValues = Filter.Select();

            foreach(SOLine line in graph.Transactions.Select())
            {
                decimal? quantity = line.OrderQty;
                //if (line.InventoryID == filterValues.InventoryOld)
                if (line.InventoryID == 691)
                {
                    graph.Transactions.Delete(line);

                    var doc = new SOLine()
                    {
                        OrderType = order.OrderType,
                        OrderNbr = order.OrderNbr
                    };
                    doc = graph.Transactions.Insert(doc);
                    //doc.InventoryID = filterValues.InventoryNew;
                    doc.InventoryID = 693;
                    doc.OrderQty = quantity;
                    graph.Transactions.Update(doc);
                }
            }
        
            graph.Actions.PressSave();

            if (isMassProcess)
            {
                PXProcessing.SetInfo(string.Format("Updated", order.OrderNbr));
            }
        }
 

icon

Best answer by Naveen Boga 6 May 2021, 03:21

View original

3 replies

Userlevel 7
Badge +17

Hi @joe21 

I have modified your code and attached the new code here. Please verify.

 

 public class ICSSalesOrderItemChange : PXGraph<ICSSalesOrderItemChange>
{
public PXCancel<ItemNumberToChangeFilter> Cancel;
public PXFilter<ItemNumberToChangeFilter> Filter;

[PXFilterable]
public PXFilteredProcessingJoin<SOOrder, ItemNumberToChangeFilter,
InnerJoin<SOLine, On<SOLine.orderType.IsEqual<SOOrder.orderType>.And<SOLine.orderNbr.IsEqual<SOOrder.orderNbr>>>>,
Where<SOOrder.status.IsEqual<SOOrderStatus.open>
.And<SOOrder.orderType.IsEqual<SOOrderTypeConstants.salesOrder>>
.And<SOLine.inventoryID.IsEqual<ItemNumberToChangeFilter.inventoryOld.FromCurrent>>>,
OrderBy<SOOrder.orderNbr.Desc>> OrdersToProcess;

[Serializable]
//[PXHidden]
[PXCacheName("Filtering Fields")]
public class ItemNumberToChangeFilter : IBqlTable
{
#region InventoryOld
[Inventory]
[PXUIField(DisplayName = "Original Item ID")]
public virtual int? InventoryOld { get; set; }
public abstract class inventoryOld : PX.Data.BQL.BqlInt.Field<inventoryOld> { }
#endregion

#region InventoryNew
[Inventory]
[PXUIField(DisplayName = "New Item ID")]
public virtual int? InventoryNew { get; set; }
public abstract class inventoryNew : PX.Data.BQL.BqlInt.Field<inventoryNew> { }
#endregion

}

#region Constructor

public ICSSalesOrderItemChange()
{
ItemNumberToChangeFilter currentFilter = this.Filter.Current;
OrdersToProcess.SetProcessDelegate(
delegate (List<SOOrder> list)
{
UpdateOrders(list, currentFilter);
});
}
#endregion



//public ICSSalesOrderItemChange()
//{
// OrdersToProcess.SetProcessDelegate(UpdateOrders);
//}

public static void UpdateOrders(List<SOOrder> list, ItemNumberToChangeFilter currentFilter)
{
ICSSalesOrderItemChange graph = PXGraph.CreateInstance<ICSSalesOrderItemChange>();
graph.ReplaceItemsInSO(list, currentFilter);
}

public virtual void ReplaceItemsInSO(List<SOOrder> ordersToProcess, ItemNumberToChangeFilter currentFilter)
{
if (ordersToProcess.Count <= 0) return;

SOOrderEntry SOOrderEntryGraph = PXGraph.CreateInstance<SOOrderEntry>();
foreach (SOOrder currentOrder in ordersToProcess)
{
try
{
using (var ts = new PXTransactionScope())
{
SOOrderEntryGraph.Clear();
SOOrderEntryGraph.Document.Current = SOOrderEntryGraph.Document.Search<SOOrder.orderNbr>(currentOrder.OrderNbr, currentOrder.OrderType);
SOOrderEntryGraph.CurrentDocument.Current = SOOrderEntryGraph.CurrentDocument.Search<SOOrder.orderNbr>(currentOrder.OrderNbr, currentOrder.OrderType);


foreach (SOLine line in SOOrderEntryGraph.Transactions.Select().FirstTableItems.ToList().Where(x => x.InventoryID == currentFilter.InventoryOld))
{
decimal? quantity = line.OrderQty;
decimal? UnitPrice = line.CuryUnitPrice;


SOOrderEntryGraph.Transactions.Delete(line);

SOLine newitem = (SOLine)SOOrderEntryGraph.Transactions.Cache.Insert();
newitem.InventoryID = currentFilter.InventoryNew;
SOOrderEntryGraph.Transactions.Cache.Update(newitem);
newitem.Qty = quantity;
newitem.ManualPrice = true;
newitem.CuryUnitPrice = UnitPrice;
SOOrderEntryGraph.Transactions.Cache.Update(newitem);

}
SOOrderEntryGraph.Save.Press();
ts.Complete();
PXProcessing<SOOrder>.SetInfo(ordersToProcess.IndexOf(currentOrder), "Inventory ID successfully replaced.");
}
}
catch (Exception ex)
{
PXProcessing<SOOrder>.SetError(ordersToProcess.IndexOf(currentOrder), ex.Message);
}
}


}

/*
public static void UpdateOrders(List<SOOrder> ordersToProcess, ItemNumberToChangeFilter currentFilter)
{
using (var ts = new PXTransactionScope())
{
ICSSalesOrderItemChange graph = PXGraph.CreateInstance<ICSSalesOrderItemChange>();

foreach (SOOrder order in ordersToProcess)
{
try
{
graph.UpdateOrder(order, true);
}
catch (Exception e)
{
PXProcessing<SOOrder>.SetError(ordersToProcess.IndexOf(order), e);
}
}

ts.Complete();
}
}

public void UpdateOrder(SOOrder order, bool isMassProcess = false)
{
SOOrderEntry graph = PXGraph.CreateInstance<SOOrderEntry>();
graph.Clear();
graph.Document.Select(order);

ItemNumberToChangeFilter filterValues = Filter.Select();

foreach (SOLine line in graph.Transactions.Select())
{
decimal? quantity = line.OrderQty;
//if (line.InventoryID == filterValues.InventoryOld)
if (line.InventoryID == 691)
{
graph.Transactions.Delete(line);


var doc = new SOLine()
{
OrderType = order.OrderType,
OrderNbr = order.OrderNbr
};
doc = graph.Transactions.Insert(doc);
//doc.InventoryID = filterValues.InventoryNew;
doc.InventoryID = 693;
doc.OrderQty = quantity;
graph.Transactions.Update(doc);
}
}

graph.Actions.PressSave();

if (isMassProcess)
{
PXProcessing.SetInfo(string.Format("Updated", order.OrderNbr));
}
}
*/
}

 

Userlevel 6
Badge +3

Naveen, your re-write is priceless.  I can learn so much from the way you did this!  The only thing I have to use as a reference is the training course and I tried to follow the training class as it was the only code available for me to look at and “modify”.  

I did not know that you could do this!

delegate (List<SOOrder> list)

{ UpdateOrders(list, currentFilter); });

This is more help than a noob could hope for.  WOW!  Am I missing some training that is available?  Or did you learn this by looking through the Acumatica code?  This is awesome.

Userlevel 7
Badge +17

Joe, In the initial stage, I also faced the same kind of problems in the coding.

I got the project, where I can directly work with Acumatica, there I learned many techniques from them. :) 
You may find these techniques in training courses as well but I’m NOT sure.
 

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved