How to programmatically create a shipment from multiple orders? [closed] - acumatica

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
What is the easiest way to create a shipment and add multiple orders to it with all of their items?

The sample below utilize the CreateShipment method used on both the Sales Orders and Shipments screens. Basically what this sample is doing is looping through all SOShipmentPlan plan for the given Customer and the given Warehouse to select them in a way similar to how the Add Sales Orders popup works on the Shipment screen. The only difference is the execution of a single BQL-query to retrieve all SOShipmentPlan records, that can be added to the Shipment, instead of manipulating with the Add Sales Orders popup thought code.
string operation = SOOperation.Issue;
var graph = PXGraph.CreateInstance<SOShipmentEntry>();
var shipment = graph.Document.Insert();
var customer = (BAccountR)PXSelect<BAccountR,
Where<BAccountR.acctCD, Equal<Required<BAccountR.acctCD>>>>
.SelectSingleBound(graph, new object[] { }, "ABARTENDE");
shipment.CustomerID = customer.BAccountID;
shipment = graph.Document.Update(shipment);
var warehouse = (INSite)PXSelect<INSite,
Where<INSite.siteCD, Equal<Required<INSite.siteCD>>>>
.SelectSingleBound(graph, new object[] { }, "RETAIL");
shipment.SiteID = warehouse.SiteID;
graph.Document.Update(shipment);
SOOrder prevOrder = null;
foreach (PXResult<SOShipmentPlan, SOLineSplit, SOOrderShipment, SOOrder> res in
PXSelectJoin<SOShipmentPlan,
InnerJoin<SOLineSplit,
On<SOLineSplit.planID, Equal<SOShipmentPlan.planID>>,
LeftJoin<SOOrderShipment,
On<SOOrderShipment.orderType, Equal<SOShipmentPlan.orderType>,
And<SOOrderShipment.orderNbr, Equal<SOShipmentPlan.orderNbr>,
And<SOOrderShipment.operation, Equal<SOLineSplit.operation>,
And<SOOrderShipment.siteID, Equal<SOShipmentPlan.siteID>,
And<SOOrderShipment.confirmed, Equal<boolFalse>,
And<SOOrderShipment.shipmentNbr, NotEqual<Current<SOShipment.shipmentNbr>>>>>>>>,
InnerJoin<SOOrder,
On<SOOrder.orderType, Equal<SOShipmentPlan.orderType>,
And<SOOrder.orderNbr, Equal<SOShipmentPlan.orderNbr>,
And<SOOrder.customerID, Equal<Current<SOShipment.customerID>>,
And<SOOrder.cancelled, Equal<boolFalse>,
And<SOOrder.completed, Equal<boolFalse>,
And<SOOrder.hold, Equal<False>,
And<SOOrder.creditHold, Equal<False>>>>>>>>>>>,
Where<SOShipmentPlan.orderType, Equal<Required<SOShipmentPlan.orderType>>,
And<SOShipmentPlan.siteID, Equal<Current<SOShipment.siteID>>,
And<SOOrderShipment.shipmentNbr, IsNull,
And<SOLineSplit.operation, Equal<Required<SOLineSplit.operation>>,
And2<
Where<Current<SOShipment.destinationSiteID>, IsNull,
Or<SOShipmentPlan.destinationSiteID, Equal<Current<SOShipment.destinationSiteID>>>>,
And<
Where<SOShipmentPlan.inclQtySOShipping, Equal<True>,
Or<SOShipmentPlan.inclQtySOShipped, Equal<True>,
Or<SOShipmentPlan.requireAllocation, Equal<False>,
Or<SOLineSplit.lineType, Equal<SOLineType.nonInventory>>>>>>>>>>>>
.Select(graph, "SO", operation))
{
var plan = (SOShipmentPlan)res;
plan.Selected = true;
graph.soshipmentplan.Update(plan);
var order = (SOOrder)res;
prevOrder = prevOrder ?? order;
if (order.OrderNbr == prevOrder.OrderNbr) continue;
graph.CreateShipment(prevOrder, shipment.SiteID, shipment.ShipDate, false, operation, null);
graph.soshipmentplan.Cache.Clear();
prevOrder = order;
}
if (prevOrder != null)
{
graph.CreateShipment(prevOrder, shipment.SiteID, shipment.ShipDate, false, operation, null);
graph.soshipmentplan.Cache.Clear();
}
graph.Actions.PressSave();

Related

Why am I getting an blank character at the end of an element when randomly selecting an element from a word list [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 11 months ago.
Improve this question
I have to hard code my selectedWord to avoid the blank character
Future<String> getData() async {
try {
return await rootBundle.loadString('text_file/four_words.txt');
} catch (e) {
throw (e.toString());
}
}
Future<String> val = getData();
val.then((value) {
setState(() {
dataString = value;
var elements = dataString.split("\n");
elements.forEach((element) {
wordList.add(element);
//debugPrint(element);
});
_selectNewWord() {
setState(() {
selectedWord = wordList[_random.nextInt(wordList.length)];
selectedWord=selectedWord[0]+selectedWord[1]+selectedWord[2]+selectedWord[3];
var elements2 = selectedWord.split("");
myList.clear();
for (var element in elements2) {
if (element.isNotEmpty) {
myList.add(element);
}
}
});
}
I implemented dataString.replaceAll("\r\n", "\n").split("\n") and it solved the problem by removing the \r that was causing the extra item in the split list

How to update Cost for a stock item

Is possible to call Update Cost process, in the stock item maintenance screen? In my case, my custom code creates BOM records, then executes BOM cost roll. Last step is to execute Update Cost, in order to push the pending cost data. I notice the Update Cost process is actually a method in the base graph, not the stock item maintenance graph. I am unsure how to execute the action button in this case.
Because the Update Cost action on Stock Items takes an additional parameter we need to figure out how to access an action with the following:
public PXAction<InventoryItem> action;
[PXUIField(DisplayName = "Actions", MapEnableRights = PXCacheRights.Select)]
[PXButton(SpecialType = PXSpecialButtonType.ActionsFolder)]
protected virtual IEnumerable Action(PXAdapter adapter,
[PXInt]
[PXIntList(new int[] { 1, 2, 3 }, new string[]
{
"Update Price",
"Update Cost",
"View Restriction Group"
})]
int? actionID
)
{
// button action code here...
}
Looking at examples in Acumatica I was able to find out how to provide parameters to a PXAction that takes more than just the adapter. In our case we need to provide actionID a value.
To get this working we need to work with a new PXAdapter instance and pass this to the action. Here is a working sample:
var itemMaint = CreateInstance<InventoryItemMaint>();
var inventoryID = 151;
itemMaint.Item.Current = itemMaint.Item.Search<InventoryItem.inventoryID>(inventoryID);
// Must use this dummy view - actual view will not work
var view = PXView.Dummy.For<InventoryItem>(itemMaint);
var itemAdapter = new PXAdapter(view)
{
Arguments = new Dictionary<string, object> { { "actionID", 2 } }
};
itemMaint.action.PressButton(itemAdapter);
Putting it all together which is what I used to test the example we end up with something like this...
Coll BOM Cost (cost roll)
Update pending cost (cost roll)
Update Cost (stock item)
Working Example:
PXLongOperation.StartOperation(this, () =>
{
var costRoll = CreateInstance<BOMCostRoll>();
costRoll.Settings.Current.SnglMlti = RollupSettings.SelectOptSM.Multi;
costRoll.Settings.Current.BOMID = "00000000000041";
costRoll.Settings.Current.RevisionID = "A";
// ROLL COSTS
costRoll.start.Press();
var inventoryIds = new HashSet<int>();
foreach (AMBomCost costRollRec in costRoll.BomCostRecs.Select())
{
inventoryIds.Add(costRollRec.InventoryID.GetValueOrDefault());
}
// UPDATE PENDING
costRoll.updpnd.Press();
var itemMaint = CreateInstance<InventoryItemMaint>();
foreach (var inventoryId in inventoryIds)
{
itemMaint.Clear();
itemMaint.Item.Current = itemMaint.Item.Search<InventoryItem.inventoryID>(inventoryId);
if (itemMaint.Item.Current == null)
{
continue;
}
// Must use this dummy view - actual view will not work
var view = PXView.Dummy.For<InventoryItem>(itemMaint);
var itemAdapter = new PXAdapter(view)
{
Arguments = new Dictionary<string, object> {{"actionID", 2}}
};
// UPDATE COST
itemMaint.action.PressButton(itemAdapter);
}
});

How to programmatically create and confirm shipment for an order using ADD Order popup?

I am trying to create and confirm shipment programmatically for a single order. But I am stuck on how to select all the lines that are displayed on ADD Order popup for adding SOLines on Shipments screen. Any help on this?
string operation = SOOperation.Issue;
SOShipmentEntry shipmentGraph = PXGraph.CreateInstance<SOShipmentEntry>();
BAccountR customer = null;
INSite warehouse = null;
PXResultset<SOOrder> objSOOrder = PXSelect<SOOrder, Where<SOOrder.customerRefNbr, Equal<Required<SOImportFilter.referenceID>>>>.Select(this, currentFilter.ReferenceID);
foreach(SOOrder order in objSOOrder)
{
shipmentGraph.Clear();
var shipment = shipmentGraph.Document.Insert();
customer = (BAccountR)PXSelect<BAccountR,
Where<BAccountR.bAccountID, Equal<Required<BAccountR.bAccountID>>>>
.SelectSingleBound(shipmentGraph, new object[] { }, order.CustomerID);
shipment.CustomerID = customer.BAccountID;
shipment = shipmentGraph.Document.Update(shipment);
warehouse = (INSite)PXSelect<INSite,
Where<INSite.siteID, Equal<Required<INSite.siteID>>>>
.SelectSingleBound(shipmentGraph, new object[] { }, "159");
shipment.SiteID = warehouse.SiteID;
shipment = shipmentGraph.Document.Update(shipment);
var addorder = shipmentGraph.addsofilter.Insert();
addorder.Operation = operation;
addorder = shipmentGraph.addsofilter.Update(addorder);
addorder.OrderType = order.OrderType;
addorder = shipmentGraph.addsofilter.Update(addorder);
addorder.OrderNbr = order.OrderNbr;
addorder = shipmentGraph.addsofilter.Update(addorder);
foreach (PXResult<SOShipmentPlan, SOLineSplit, SOLine> plan in
shipmentGraph.soshipmentplan.Select())
{
SOShipmentPlan shipmentPlan = (SOShipmentPlan)plan;
shipmentPlan.Selected = true;
shipmentGraph.soshipmentplan.Update(plan);
shipmentGraph.Actions.PressSave();
}
shipmentGraph.Actions.PressSave();
}
I have difficulty understanding the feature you are trying to implement from the description. Usually you would automate CreateShipment and ConfirmShipment actions to do this.
Perhaps you have to handle a special case, if all that is blocking you is selecting the data from the grid inside the "Add Order" smart panel:
Using Inspect Element feature, determine the name of the DataView you target by clicking on the grid:
Use View Business Logic Source to look up the DataView source code:
From the source code for that DataView, we see that it returns 3 DAC (SOShipmentPlan, SOLineSplit and SOLine):
PXSelectJoinOrderBy<SOShipmentPlan,
InnerJoin<SOLineSplit, On<SOLineSplit.planID, Equal<SOShipmentPlan.planID>>,
InnerJoin<SOLine, On<SOLine.orderType, Equal<SOLineSplit.orderType>, And<SOLine.orderNbr, Equal<SOLineSplit.orderNbr>, And<SOLine.lineNbr, Equal<SOLineSplit.lineNbr>>>>>>,
OrderBy<Asc<SOLine.sortOrder, Asc<SOLine.lineNbr, Asc<SOLineSplit.lineNbr>>>>> soshipmentplan;
With that information we can now iterate the DataView using the Select method:
foreach (PXResult<SOShipmentPlan, SOLineSplit, SOLine> plan in Base.soshipmentplan.Select())
{
SOShipmentPlan shipmentPlan = (SOShipmentPlan)plan;
SOLineSplit lineSplit = (SOLineSplit)plan;
SOLine line = (SOLine)plan;
}
I used Base member to reference SOShipmentEntry graph in order to get the DataView. This should be used when you are in the context of a SOShipmentEntry graph extension:
Base.soshipmentplan.Select()
If you have a direct reference to SOShipmentEntry graph instead you can use that directly:
SOShipmentEntry shipmentEntry = PXGraph.CreateInstance<SOShipmentEntry>();
shipmentEntry.soshipmentplan.Select()
EDIT
Code for automating the Add Order dialog:
shipmentEntry.addsofilter.Current.OrderType = SOOrderTypeConstants.SalesOrder;
shipmentEntry.addsofilter.Current.OrderNbr = "000001";
shipmentEntry.addsofilter.Update(shipmentEntry.addsofilter.Current);
foreach (SOShipmentPlan line in shipmentEntry.soshipmentplan.Select())
{
line.Selected = true;
shipmentEntry.soshipmentplan.Update(line);
}
shipmentEntry.addSO.Press();

save the value of the array list to a spinner [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a spinner in my app and I want to save the state of the array list to so if the user chooses an option and closed the app, I want the spinner to save it value if the user reopen my app.
My Main Activity:
t1.typeface = Typeface.createFromAsset(assets, "andlso.ttf")
val fonts = arrayOf("الخط الديواني", "الخط الأندلسي")
spinner.adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fonts)
spinner.onItemSelectedListener = object :AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val SelectedItem = parent!!.getItemAtPosition(position).toString()
val sharedPreferences = getSharedPreferences("savefile", Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.putString("savefile", fonts.toString())
editor.apply()
if (SelectedItem == "الخط الديواني"){
t.typeface = Typeface.createFromAsset(assets, "andlso.ttf")
}else if (SelectedItem == "الخط الأندلسي"){
t.typeface = Typeface.createFromAsset(assets, "frsspbl.TTF")
}
just write the following code in your mainActivity,
val preferences = applicationContext.getSharedPreferences("MyPrefs", Context.MODE_PRIVATE)
val prefEditor = preferences.edit()
val fonts = arrayOf("Data1", "Data2", "Data3", "Data4")
var adapterCountry = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fonts)
val spinner = findViewById<Spinner>(R.id.spinner)
spinner.adapter = adapterCountry;
spinner.setSelection(preferences.getInt("position", 0))
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
spinner.setSelection(position)
prefEditor.putInt("position", position)
prefEditor.apply()
}
override fun onNothingSelected(parent: AdapterView<*>) {
}
}
this will do your work. I hope this is helpful for you.

How to pass line item custom field value to sales order from opportunity?

I have a custom line number field in opportunity product tab for customer to re-sequence the selected products and the grid is sorted on custom field value.
I am trying to pass the value from opportunity to sales order which also having a similar field.
the following code i have tried and it did not work
PXGraph.InstanceCreated.AddHandler<SOOrderEntry>((graph) =>
{
graph.RowUpdated.AddHandler<SOLine>((cache, args) =>
{
CROpportunityProducts product = (adapter.View.Graph as OpportunityMaint).Products.Current;
CROpportunityProductsExtNV productext = PXCache<CROpportunityProducts>.GetExtension<CROpportunityProductsExtNV>(product);
SOLine soline = (SOLine)args.Row;
SOLineExtNV solineext = PXCache<SOLine>.GetExtension<SOLineExtNV>(soline);
solineext.UsrLineNo = productext.UsrLineNo;
});
});
The following piece of code returns same value for all line numbers
You can implement RowInserting Event handler as below:
graph.RowInserting.AddHandler<SOLine>((cache, args) =>
{
var soLine = (SOLine)args.Row;
CROpportunityProducts opProduct = PXResult<CROpportunityProducts>.Current;
SOLineExtNV soLineExt = PXCache<SOLine>.GetExtension<SOLineExtNV>(soLine);
CROpportunityProductsExtNV opProductExt = PXCache<CROpportunityProducts>.GetExtension<CROpportunityProductsExtNV>(opProduct);
soLineExt.UsrLineNo = opProductExt.UsrLineNo;
});
wish they could split up the call to create the order and the call to insert the lines to make it easier to customize. We have done something similar. Here is a sample from what I tested using a graph extension and overriding the DoCreateSalesOrder call in the opportunitymaint graph. (This assumes the select on products is the same order the transaction on the sales order were inserted. I am sure there could be a better answer, but this is an example I have handy.)
public class CROpportunityMaintExtNV : PXGraphExtension<OpportunityMaint>
{
[PXOverride]
public virtual void DoCreateSalesOrder(Action del)
{
try
{
del();
}
catch (PXRedirectRequiredException redirect)
{
var products = this.Products.Select().ToArray();
int rowCntr = 0;
foreach (SOLine soLine in ((SOOrderEntry)redirect.Graph).Transactions.Select())
{
// Assumes inserted rows in same order as products listed (default should be the key)
//Current product
CROpportunityProducts currentProduct = products[rowCntr];
var productExtension = currentProduct.GetExtension<CROpportunityProductsExtNV>();
((SOOrderEntry) redirect.Graph).Transactions.Cache.SetValueExt<SOLineExtNV.usrLineNo>(soLine, productExtension.UsrLineNo);
rowCntr++;
}
throw redirect;
}
}
}
The problem you had with your code is the Current product was always the same which resulted in the same value.

Resources