What is the proper way to update values of DAC's retrieved via PXResultset?

≡放荡痞女 提交于 2021-01-16 04:25:44

问题


We have a business requirement to set the SO return COST to the original cost issued without invoicing if possible. We determined that Sales Orders are necessary to track issuing materials to our client, and we are cost driven rather than price driven. We use FIFO costing, but SO return orders do not seem to return at the original COST unless invoiced (which we also don't do in a traditional manner).

I found that setting the unit/ext cost on the SO Shipment Line directly in the database before Confirm Shipment and Update IN appears to provide the results desired. Applying a custom menu option to streamline and strongly control the return, I cloned nearby code as a base. The section between the === is where I set the unit/ext cost. The PXTrace shows the expected value, but it is coming out as $0 on the shipment record. I thought I might need "docgraph.Update(sOShipmentLine)" to save it, but that's not accessible in this scope.

using (var ts = new PXTransactionScope())
{
    PXTimeStampScope.SetRecordComesFirst(typeof(SOOrder), true);
    //Reminder - SOShipmentEntry docgraph = PXGraph.CreateInstance<SOShipmentEntry>();
    docgraph.CreateShipment(order, SiteID, filter.ShipDate, adapter.MassProcess, SOOperation.Receipt, created, adapter.QuickProcessFlow);


    PXTrace.WriteError("Setting Cost");
    //Set Cost on Shipment to Cost On SO Line
    PXResultset<SOShipment> results =
                            PXSelectJoin<SOShipment,
                            InnerJoin <SOShipLine, On<SOShipLine.shipmentNbr, Equal<SOShipment.shipmentNbr>>,
                            InnerJoin <SOLine, On<SOLine.orderType, Equal<SOShipLine.origOrderType>,
                                            And<SOLine.orderNbr, Equal<SOShipLine.origOrderNbr>, And<SOLine.lineNbr, Equal<SOShipLine.origLineNbr>>>>
                            >>,
                                Where<SOShipment.shipmentNbr, Equal<Required<SOShipment.shipmentNbr>>>>
                            .Select(docgraph, docgraph.Document.Current.ShipmentNbr);

    PXTrace.WriteError("Shipment {0} - Records {1}", docgraph.Document.Current.ShipmentNbr, results.Count);

    foreach (PXResult<SOShipment, SOShipLine, SOLine> record in results)
    {
        SOShipment shipment = (SOShipment)record;
        SOShipLine shipmentLine = (SOShipLine)record;
        SOLine sOLine = (SOLine)record;
        ==============================================
        shipmentLine.UnitCost = GetReturnUnitCost(sOLine.OrigOrderType, sOLine.OrigOrderNbr, sOLine.OrigLineNbr, sOLine.CuryInfoID);
        shipmentLine.ExtCost = shipmentLine.Qty * shipmentLine.UnitCost;
        PXTrace.WriteError(string.Format("{0} {1}-{2} = {3} / {4}", shipmentLine.LineType, shipmentLine.ShipmentNbr, shipmentLine.LineNbr, shipmentLine.Qty, shipmentLine.UnitCost));
        ==============================================
    }

    PXAutomation.CompleteSimple(docgraph.Document.View);
    var items = new List<object> { order };
    PXAutomation.RemovePersisted(docgraph, typeof(SOOrder), items);
    PXAutomation.RemoveProcessing(docgraph, typeof(SOOrder), items);
    ts.Complete();
}

Still on the learning curve so I'm expecting the solution is likely simple and obvious to someone more experienced.


回答1:


There's three phase to it:

  1. Changing the value
  2. Updating the cache
  3. Persisting the cache

I think you are changing the value but not persisting it. The reason why it works after invoking Confirm Shipment or Update IN action is probably that these actions will persist all changes by calling the graph Save action.

To change a field value in a data view you would do:

DACRecord.Field = value;
DataView.Update(DACRecord);    

The particularity of your example is that the request is not bound to a data view. When you have a loose BQL request you can do the same operation with a cache object. In your example the Caches context is available from docGraph:

DACRecord.Field = value;
graph.Caches[typeof(DACType)].Update(DACRecord);
graph.Caches[typeof(DACType)].Persist(DACRecord, PXDBOperation.Update);

Update and Persist are often omitted because in many scenarios they will be called later on by other framework mechanism. For example if you were to do only Update on a UI field, the record won't be persisted until the user clicks on the save button.

Updating value on UI is a bit different than updating in cache.

The recommended approach for UI fields is to use SetValue:

cache.SetValue<DAC.DacField>(DACRecord, fieldValue);

Or use SetValueExt when you want to trigger the framework events like FieldUpdated when changing the field value:

cache.SetValueExt<DAC.DacField>(DACRecord, fieldValue);

You'll still have to update and persist the changes in cache for these too if you want the changes to stick without requiring the user to manually save the document.



来源:https://stackoverflow.com/questions/53070800/what-is-the-proper-way-to-update-values-of-dacs-retrieved-via-pxresultset

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!