Enter Physical Inventory Count Through Acumatica API - acumatica

Can someone please provide me with an example on how to enter a PI Count through the API. I used the following code which worked fine at the beginning, but I cannot enter a count for an Item/Location combination which does not figure in the initial PI Count list released directly from Acumatica.
IN305010Content IN305010 = oScreen.IN305010GetSchema();
oScreen.IN305010Clear();
List<Command> oCmds = new List<Command>();
oCmds.Clear();
oCmds.Add(new Key { Value = StocktakeRef, FieldName = IN305010.DocumentSummary.ReferenceNbr.FieldName, ObjectName = IN305010.DocumentSummary.ReferenceNbr.ObjectName, Commit = true });
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
oCmds.Add(new Key { Value = "='" + ds.Tables[0].Rows[i].ItemArray[2].ToString() + "'", FieldName = IN305010.PhysicalInventoryDetails.InventoryID.FieldName, ObjectName = IN305010.PhysicalInventoryDetails.InventoryID.ObjectName });
oCmds.Add(new Value { Value = "='" + ds.Tables[0].Rows[i].ItemArray[5].ToString() + "'", FieldName = IN305010.PhysicalInventoryDetails.Location.FieldName, ObjectName = IN305010.PhysicalInventoryDetails.Location.ObjectName, Commit = true });
oCmds.Add(new Value { Value = ds.Tables[0].Rows[i].ItemArray[3].ToString(), LinkedCommand = IN305010.PhysicalInventoryDetails.PhysicalQuantity, Commit = true});
}
oCmds.Add(IN305010.Actions.Save);
oScreen.IN305010Submit(oCmds.ToArray());
Thanks,
G

I'm not following your code and actually have no idea what it should do.
But as i see you need to call Popup window, i haven't exact example for that screen but i will provide similar.
Also, please follow our old forum where you can find some useful things.
http://forum.acumatica.com/forum/acumatica-reseller-and-isv-community/development-and-customization/844-t210-acumatica-web-services-basic?p=3003#post3003
SO301000result = context.SO301000Submit(
new Command[]
{
new Value { Value = "SO", LinkedCommand = SO301000.OrderSummary.OrderType },
new Value { Value = ordNum, LinkedCommand = SO301000.OrderSummary.OrderNbr },
//popup window
new Value { Value = "OK", LinkedCommand = SO301000.InventoryLookup.ServiceCommands.DialogAnswer, Commit = true },
new Value { Value = "OK", LinkedCommand = SO301000.InventoryLookupInventory.ServiceCommands.DialogAnswer, Commit = true },
new Value { Value = "RETAIL", LinkedCommand = SO301000.InventoryLookupInventory.SiteID },
new Value { Value = "CPU000", LinkedCommand = SO301000.InventoryLookupInventory.Inventory, Commit = true },
new Key { Value = "='CPU00004'", FieldName = SO301000.InventoryLookup.InventoryCD.FieldName, ObjectName = SO301000.InventoryLookup.InventoryCD.ObjectName },
new Value { Value = "True", LinkedCommand = SO301000.InventoryLookup.Selected, Commit = true },
SO301000.Actions.Save
}
);

This is the code that fixed my issue if anyone needs it
IN305010Content IN305010 = oScreen.IN305010GetSchema();
oScreen.IN305010Clear();
List<Command> oCmds = new List<Command>();
oCmds.Clear();
oCmds.Add(new Key { Value = StocktakeRef, FieldName = IN305010.DocumentSummary.ReferenceNbr.FieldName, ObjectName = IN305010.DocumentSummary.ReferenceNbr.ObjectName, Commit = true });
oCmds.Add(new Value { Value = "OK", LinkedCommand = IN305010.AddLine.ServiceCommands.DialogAnswer, Commit = true });
oCmds.Add(new Value { Value = "True" , FieldName = IN305010.AddLine.AutoAddLine.FieldName, ObjectName = IN305010.AddLine.AutoAddLine.ObjectName, Commit = true });
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
oCmds.Add(new Value { Value = "OK", LinkedCommand = IN305010.AddLine.ServiceCommands.DialogAnswer, Commit = true });
oCmds.Add(new Value { Value = <<"Qty">>, FieldName = IN305010.AddLine.Qty.FieldName, ObjectName = IN305010.AddLine.Qty.ObjectName });
oCmds.Add(new Value { Value = <<"Item">>, FieldName = IN305010.AddLine.InventoryID.FieldName, ObjectName = IN305010.AddLine.InventoryID.ObjectName, Commit = true });
oCmds.Add(new Value { Value = <<"Location">>, FieldName = IN305010.AddLine.LocationID.FieldName, ObjectName = IN305010.AddLine.LocationID.ObjectName, Commit = true });
oCmds.Add(new Value { Value = "True", LinkedCommand = IN305010.Actions.AddLine2, Commit = true });
}
oCmds.Add(IN305010.Actions.Save);
oScreen.IN305010Submit(oCmds.ToArray());
Cheers,
G

Related

Tabulator: How to create a dynamic custom editor based on another cell's value

Using Tabulator, I want to dynamically create a cell's editor, either input or select, based on another cell's value.
Declaring:
var valueEditor = function(cell, onRendered, success, cancel, editorParams)
I seem to be able to declare the correct editor and I have the list of values are available in the editorParams the is passed to the function API, but for theselect I can't get the drop-down to display the values.
Here's a code snippet:
var valueEditor = function(cell, onRendered, success, cancel, editorParams) {
const item = cell.getRow().getData();
var editor = null;
// Use a combobox when the type is Choice, or regular input cell otherwise
if (item.type === "Choice") {
editor = document.createElement("select");
editor.setAttribute("values", editorParams.values ); // <-- This is probably incorrect, but I'm unable to assign the right attribute
} else {
editor = document.createElement("input");
editor.setAttribute("type", "text");
}
//create and style input
editor.style.padding = "3px";
editor.style.width = "100%";
editor.style.boxSizing = "border-box";
editor.value = item.value;
//when the value has been set, trigger the cell to update
function successFunc(){
success(editor.value );
}
editor.addEventListener("change", successFunc);
editor.addEventListener("blur", successFunc);
//return the editor element
return editor;
};
{title: 'Name', field: 'name', width: 130},
{title: 'Type', field: 'type', width: 95},
{title: 'Value', field: 'value', width: 260, editor: valueEditor }];
When my row's type column is "Choice", I would like to show a combobox with, say Choice1, Choice2, Choice3, Choice4. Otherwise, I want to have a regular Input cell where the user can enter any values.
It took much time and I found this way to create custom select editor of Tabulator for showing NAME base on KEY value. Hope this post helps someone.
var cboData = [
{
"key": "",
"name": ""
},
{
"key": "01",
"name": "OPTION 1"
},
{
"key": "02",
"name": "OPTION 2"
}];
var comboEditor = function (cell, onRendered, success, cancel, editorParams) {
var editor = document.createElement("select");
for (var i = 0; i < editorParams.length; i++) {
var opt = document.createElement('option');
opt.value = editorParams[i].key;
opt.innerHTML = editorParams[i].name;
editor.appendChild(opt);
}
editor.style.padding = "3px";
editor.style.width = "100%";
editor.style.boxSizing = "border-box";
editor.value = cell.getValue();
onRendered(function () {
editor.focus();
editor.style.css = "100%";
});
function successFunc() {
success(editor.value);
}
editor.addEventListener("change", successFunc);
editor.addEventListener("blur", successFunc);
return editor;
};
In columns setting like this:
{
title: "SELECTION",
field: 'select_key',
headerHozAlign: 'center',
hozAlign: 'center',
editor: comboEditor,
editorParams: cboData,
formatter: function (cell, formatterParams) {
for (var i = 0; i < formatterParams.length; i++) {
if (formatterParams[i].key == cell.getValue()) {
return formatterParams[i].name;
}
}
},
formatterParams: cboData,
},
Edited:
If you want to load dropdown value based on another cell value, you can change as bellow:
var cboData = []; //Store last values based on another cell value
var comboEditor = function (cell, onRendered, success, cancel, editorParams) {
var editor = document.createElement("select");
//GET DATA FOR THIS HERE. NOTE THAT THIS CALL EVERY TIME YOU SELECT THIS DROPDOWN
let otherCellValue = cell.getData().OtherColName;
$.ajax({
type: 'POST',
url: [URL TO GET VALUE],
contentType: "application/json; charset=utf-8",
data: '{ key:' + JSON.stringify(otherCellValue ) + '}',
async: false, //wait ultil get data done
processData: false,
success: function (result) {
//assume that result is an array of data with VALUE/TEXT fields
for (var i = 0; i < result.length; i++) {
var item = {};
item.key = result[i].Value;
item.name = result[i].Text;
cboData.push(item);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
for (var i = 0; i < cboData.length; i++) {
var opt = document.createElement('option');
opt.value = cboData[i].key;
opt.innerHTML = cboData[i].name;
editor.appendChild(opt);
}
editor.style.padding = "3px";
editor.style.width = "100%";
editor.style.boxSizing = "border-box";
editor.value = cell.getValue();
onRendered(function () {
editor.focus();
editor.style.css = "100%";
});
function successFunc() {
success(editor.value);
}
editor.addEventListener("change", successFunc);
editor.addEventListener("blur", successFunc);
return editor;
};
item, I think, is an object, so you would need to find your property value for your cell, like :
editor.value = item[cell.getField()]

Update Existing Line Item Values in Netsuite SuiteScript 2.0

No matter what I do, I can't update the line item values in an inbound shipment record. I have a ton of debug statements, and I know that I technically am at the correct line, but when I try to get or set values, they are empty.
I am working in dynamic mode, and so in order to loop, I found something online that said I needed to stringify the record. I see all the correct data, but any time I try to manipulate the values, it doesn't do anything, or the values are empty. I also keep getting asked to provide the required fields, but for this particular line, they are already there.
Here is my code:
function doPost(restletBody){
log.debug('Called from POST', restletBody);
var success = [],
errors = [];
restletBody.data.forEach(function(e)
{
try
{
//Inbound Shipment Stuff
var ibsID = e.ibShipments.inboundShipmentRecordID;
var containerNumber = e.ibShipments.containerNumber;
var memo = e.ibShipments.memo;
var cargoReturnDate = e.ibShipments.cargoReturnDate;
var billoflading = e.ibShipments.billoflading;
var quantityexpected = e.ibShipments.quantityexpected;
var destCountry = e.ibShipments.destCountry;
var actualdeliverydate = e.ibShipments.actualdeliverydate;
var expecteddeliverydate = e.ibShipments.expecteddeliverydate;
var poDueDate = e.ibShipments.poDueDate;
var shipmentstatus = e.ibShipments.shipmentstatus;
var factory = e.ibShipments.factory;
var vesselNumber = e.ibShipments.vesselNumber;
var actualshippingdate = e.ibShipments.actualshippingdate;
var expectedshippingdate = e.ibShipments.expectedshippingdate;
var vesselBookingNumber = e.ibShipments.vesselBookingNumber;
var bookingDate = e.ibShipments.bookingDate;
var recID = null;
if((ibsID == "" || ibsID == null) && (containerNumber != "" || memo != "" || cargoReturnDate != "" ||
billoflading != "" || quantityexpected != "" || destCountry != "" || actualdeliverydate != "" ||
expecteddeliverydate != "" || poDueDate != "" || shipmentstatus != "" || factory != "" || vesselNumber != "" ||
actualshippingdate != "" || expectedshippingdate != "" || vesselBookingNumber != "" || bookingDate != ""))
{
//Create a new record
log.debug('Create Record', "");
var rec =
r.create({
type: "inboundshipment",
isDynamic: true,
defaultValues: null
});
//Might need to save the record, then add the fields
recID = rec.save();
var i = 1;
}
else
{
log.debug('Update Record Instead', ibsID);
recID = ibsID;
}
var inboundShipmentUpdate = r.load({
type: 'inboundshipment',
id: recID,
isDynamic: true
});
//Get Values from purchase order
var poID = e.poID;
var poName = e.poName;
var poShipDate = e.poShipDate;
var poShipWindowStart = e.poShipWindowStart;
if(poShipWindowStart != "")
poShipWindowStart = new Date(poShipWindowStart);
else
poShipWindowStart = "";
var poShipWindowEnd = e.poShipWindowEnd;
if(poShipWindowEnd != "")
poShipWindowEnd = new Date(poShipWindowEnd);
else
poShipWindowEnd = "";
//Item Fields
var itemID = e.items.itemID;
var itemDisplayName = e.items.displayName;
var itemName = e.items.name;
//Get Values from inbound shipment entry
var shipmentnumber = e.ibShipments.shipmentnumber;
var bookingDate = e.ibShipments.bookingDate;
if(bookingDate != "")
bookingDate = new Date(bookingDate);
else
bookingDate = "";
var vesselBookingNumber = e.ibShipments.vesselBookingNumber;
var expectedshippingdate = e.ibShipments.expectedshippingdate;
if(expectedshippingdate != "")
expectedshippingdate = new Date(expectedshippingdate);
else
expectedshippingdate = "";
var actualshippingdate = e.ibShipments.actualshippingdate;
if(actualshippingdate != "")
actualshippingdate = new Date(actualshippingdate);
else
actualshippingdate = "";
var vesselNumber = e.ibShipments.vesselNumber;
var containerNumber = e.ibShipments.containerNumber;
var factory = e.ibShipments.factory;
var shipmentStatus = e.ibShipments.shipmentstatus;
var poDueDate = e.ibShipments.poDueDate;
var expecteddeliverydate = e.ibShipments.expecteddeliverydate;
if(expecteddeliverydate != "")
expecteddeliverydate = new Date(expecteddeliverydate);
else
expecteddeliverydate = "";
var actualdeliverydate = e.ibShipments.actualdeliverydate;
if(actualdeliverydate != "")
actualdeliverydate = new Date(actualdeliverydate);
else
actualdeliverydate = "";
var destCountry = e.ibShipments.destCountry;
var quantityexpected = e.ibShipments.quantityexpected;
var quantityreceived = e.ibShipments.quantityreceived;
var billoflading = e.ibShipments.billoflading;
var cargoReturnDate = e.ibShipments.cargoReturnDate;
if(cargoReturnDate != "")
cargoReturnDate = new Date(cargoReturnDate);
else
cargoReturnDate = "";
var memo = e.ibShipments.memo;
//Set Field Values
inboundShipmentUpdate.setValue('actualshippingdate', actualshippingdate);
inboundShipmentUpdate.setValue('actualdeliverydate',actualdeliverydate);
inboundShipmentUpdate.setValue('custrecord_kk_booking_date', bookingDate);
inboundShipmentUpdate.setValue('custrecord_kk_cargo_return_dt',cargoReturnDate);
inboundShipmentUpdate.setValue('expectedshippingdate',expectedshippingdate);
inboundShipmentUpdate.setValue('expecteddeliverydate',expecteddeliverydate);
inboundShipmentUpdate.setValue('shipmentmemo', memo);
inboundShipmentUpdate.setValue('externaldocumentnumber',containerNumber);
//inboundShipmentUpdate.setValue('shipmentstatus',shipmentStatus);
inboundShipmentUpdate.setValue('billoflading',billoflading);
inboundShipmentUpdate.setValue('custrecord_kk_vesselbooking_number',vesselBookingNumber);
inboundShipmentUpdate.setValue('vesselnumber',vesselNumber);
inboundShipmentUpdate.setValue('custrecord_kk_destination',destCountry);
log.debug("Inside Line Items", e.items.itemID + " " + poID);
//The item must be unique, so it cannot already be on the inbound shipment. Do not set the current sublist value to the item
//if it already exists
var objCurRecIBS = JSON.parse(JSON.stringify(inboundShipmentUpdate));
log.debug("objCurRecIBS", objCurRecIBS );
var objSublistsIBS = objCurRecIBS.sublists ? objCurRecIBS.sublists : '';
log.debug("objSublistsIBS", objSublistsIBS );
var objIBSItems = objSublistsIBS.items ? objSublistsIBS.items : '';
log.debug("objIBSItems", objIBSItems );
var itemLineCountIBS = Object.keys(objSublistsIBS.items).length; //First Item is an empty item
var itemPresent = false;
//First Item is an empty item, so start at 1
for (var k = 1; k < itemLineCountIBS; k++)
{
//This keeps coming back empty
var currentQuantity = inboundShipmentUpdate.getCurrentSublistValue({
sublistId: "items",
fieldId: "quantityexpected"
});
log.debug("Current Quantity", currentQuantity + "Line " + k );
//So does this
var currentItem = inboundShipmentUpdate.getCurrentSublistValue({
sublistId: "items",
fieldId: "shipmentitem"
});
log.debug("Current Item", currentItem + "Line " + k );
var currItemIDIBS = objIBSItems[Object.keys(objSublistsIBS.items)[k]].itemid;
log.debug("Current Line Item Id", currItemIDIBS);
var currentLineIBS = objIBSItems[Object.keys(objSublistsIBS.items)[k]];
log.debug("cURRENT iTEM IBS Line", currentLineIBS);
if(currItemIDIBS == itemID)
{
//Update the existing line, since it is already present
itemPresent = true;
log.debug("Current Item Exists in the IBS", itemPresent);
//This is empty, too
var linePO = inboundShipmentUpdate.getCurrentSublistValue({
sublistId: "items",
fieldId: "purchaseorder"
});
log.debug("Line PO: ", linePO);
var currentQuantity = inboundShipmentUpdate.getCurrentSublistValue({
sublistId: "items",
fieldId: "quantityexpected"
});
log.debug("Current Quantity", currentQuantity + "Line " + k );
var newQuantity = currentQuantity + 2;
log.debug("New Quantity", newQuantity );
inboundShipmentUpdate.selectLine({
sublistId: 'items',
line: k
});
inboundShipmentUpdate.setCurrentSublistValue({
sublistId: "items",
fieldId: "quantityexpected",
value: newQuantity
//quantityexpected
});
inboundShipmentUpdate.commitLine({sublistId:"items"});
log.debug("Inside SELECT Line Items", "Line Committed" );
}
}
if(!itemPresent)
{
log.debug("Inside Item Present Check", itemPresent);
inboundShipmentUpdate.setCurrentSublistValue({
sublistId: "items",
fieldId: "shipmentitem",
value: shipmentitem
});
inboundShipmentUpdate.setCurrentSublistValue({
sublistId: "items",
fieldId: "quantityexpected",
value: quantityexpected
});
log.debug("Inside Line Items", "Shipment ITEM Added " + shipmentitem );
inboundShipmentUpdate.commitLine({sublistId:"items"});
log.debug("Inside Line Items", "Line Committed" );
}
++i;
inboundShipmentUpdate.save();
}
catch(err)
{
var msg = '';
log.debug("There was an error", err);
}
})
return "";
}
Does anyone have any idea why everything is coming back empty for me when I try to use NetSuite's methods, but showing correctly when I read the actual record's JSON?
I made this much more difficult than I needed to. I used the findSublistLineWithValue function, and was able to get the correct line value (it WAS 0, for whatever reason the json of the object was coming back with two entries, the first being empty values, so I incorrectly assumed that was line 0). I also had to compare against an actual string instead of a value, or I would get -1.
var lineNumber = inboundShipmentUpdate.findSublistLineWithValue({
sublistId: 'items',
fieldId: 'itemid',
value: itemID.toString()
});
Once I did this, I was able to get the correct values using my other methods. I just really dumbed down my api calls, and that helped me figure out what was going on.

Create Purchase receipt from Purchase order through web service

We are trying to create a PO receipt document that is linked to a PO document. Below is the code, but after submitting the selection of PO lines, the webservice not returning any results. Later it gives an execution time out exception.
apitest.Screen context = BuisnessLogicACU.context;
PO302000Content PORcptSchema;
try
{
PORcptSchema = context.PO302000GetSchema();
}
catch
{
BuisnessLogicACU.contextLogin();
PORcptSchema = context.PO302000GetSchema();
}
PORcptSchema.Actions.AddPOOrderLine2.Commit = true;
//header
AcumaticaInterface.apitest.Command[] Document = new AcumaticaInterface.apitest.Command[]
{
PORcptSchema.Actions.Insert,
new Value
{
Value = BPCode,
LinkedCommand = PORcptSchema.DocumentSummary.Vendor,
Commit = true
},
new Value
{
Value = BPRefNbr ,
LinkedCommand = PORcptSchema.DocumentSummary.VendorRef
},
new Value
{
Value = PostDate.HasValue ? ((DateTime)PostDate.Value).ToLongDateString() : "",
LinkedCommand = PORcptSchema.DocumentSummary.Date
},
new Value
{
Value = DocDate.HasValue ? ((DateTime)DocDate.Value).ToLongDateString() : "",
LinkedCommand = PORcptSchema.DocumentSummary.Date
},
new Value
{
Value = Description,
LinkedCommand = PORcptSchema.DocumentSummary.NoteText
},
new Value
{
Value = "POS Doc " + DocNum,
LinkedCommand = PORcptSchema.DocumentSummary.VendorRef
},
};
//set the dialog answer
var dgAnswer = new Command[]
{ new Value
{
Value = "OK",
LinkedCommand = PORcptSchema.AddPurchaseOrderLine.ServiceCommands.DialogAnswer,
Commit = true
}
};
Document = Document.Concat(dgAnswer).ToArray();
//select lines
foreach (POReceiptLine line in POReceiptlines.OrderBy(x => x.LineNum))
{
AcumaticaInterface.apitest.Command[] Docline = new AcumaticaInterface.apitest.Command[]
{
new Key
{
ObjectName = PORcptSchema.AddPurchaseOrderLine.OrderNbr.ObjectName,
FieldName = PORcptSchema.AddPurchaseOrderLine.OrderNbr.FieldName,
Value = "='" + line.BaseDocNum + "'"
},
new Key
{
ObjectName = PORcptSchema.AddPurchaseOrderLine.LineNbr.ObjectName,
FieldName = PORcptSchema.AddPurchaseOrderLine.LineNbr.FieldName,
Value = "='" + line.BaseLineNum + "'"
},
new Value
{
Value = "True",
LinkedCommand = PORcptSchema.AddPurchaseOrderLine.Selected,
Commit = true
}
};
Document = Document.Concat(Docline).ToArray();
}
//Add PO line.
var addPOLine = new Command[]
{
PORcptSchema.Actions.AddPOOrderLine2,
////get back the added lines in the grid
PORcptSchema.DocumentDetails.POOrderNbr,
PORcptSchema.DocumentDetails.POLineNbr
};
Document = Document.Concat(addPOLine).ToArray();
var receiptLines = context.PO302000Submit(Document);
//update quantity..
//check CreateShipment() in webservice demo
List<Command> commandList = new List<Command>();
for (int index = 0; index < receiptLines.Length; index++)
{
commandList.Add(new Value
{
Value = index.ToString(),
LinkedCommand = PORcptSchema.DocumentDetails.ServiceCommands.RowNumber
});
POReceiptLine line = POReceiptlines.Where(x => x.BaseDocNum == receiptLines[index].DocumentDetails.POOrderNbr.Value && x.BaseLineNum.ToString() == receiptLines[index].DocumentDetails.POLineNbr.Value).FirstOrDefault();
if (line != null)
{
commandList.Add(new Value
{
Value = line.Qty.ToString(),
LinkedCommand = PORcptSchema.DocumentDetails.ReceiptQty,
Commit = index < receiptLines.Length - 1
});
}
else
throw new Exception("Matching POS Rcpt line not found.");
}
//save
AcumaticaInterface.apitest.Command[] save = new AcumaticaInterface.apitest.Command[] {
PORcptSchema.Actions.Save
};
Document = Document.Concat(save).ToArray();
//SAVING And get the document nbr
AcumaticaInterface.apitest.Command[] Output = new AcumaticaInterface.apitest.Command[] {
PORcptSchema.DocumentSummary.Type,
PORcptSchema.DocumentSummary.ReceiptNbr
};
Document = Document.Concat(Output).ToArray();
var POReceipt = context.PO302000Submit(Document)[0];
After this particular line, web service is not returning any results. Anyone can assist on this?
var receiptLines = context.PO302000Submit(Document);
This solution was tested using Acumatica version 6.00.1596.
I found that to return the value of the Purchase Order Lines, you do not need to do a foreach.
After setting the value for the summary and removing the deuplicate here is what I use to get back the POLines.
var selectPOLine = new Command[]
{
new Value
{
Value = "OK",
LinkedCommand = PORcptSchema.AddPurchaseOrderLine.ServiceCommands.DialogAnswer,
Commit = true
},
addPOLineWithCommit,
new Value
{
LinkedCommand = PORcptSchema.AddPurchaseOrderLinePOSelection.OrderNbr,
Value = "PO000451"
},
new Value
{
Value = "True",
LinkedCommand = PORcptSchema.AddPurchaseOrderLine.Selected,
},
PORcptSchema.AddPurchaseOrderLine.InventoryID,
PORcptSchema.AddPurchaseOrderLine.LineDescription,
PORcptSchema.AddPurchaseOrderLine.LineType,
};
With "addPOLineWithCommit" define as
var addPOLineWithCommit = PORcptSchema.Actions.AddPOOrderLine;
addPOLineWithCommit.Commit = true;
Using these the line :
var receiptLines = context.PO302000Submit(Document);
was returning me some information on available lines.
#samol518's sample assisted me to resolve. I am posting the full code, if anyone later needs it
the below code will add lines from PO, change quantity and save the PO receipt.
public void createAcuPR()
{
apitest.Screen context = BuisnessLogicACU.context;
PO302000Content PORcptSchema;
try
{
PORcptSchema = context.PO302000GetSchema();
}
catch
{
BuisnessLogicACU.contextLogin();
PORcptSchema = context.PO302000GetSchema();
}
var addPOLineWithCommit = PORcptSchema.Actions.AddPOOrderLine;
addPOLineWithCommit.Commit = true;
//somehow if there is a second document then it goes to update mode
context.PO302000Submit(new Command[] { PORcptSchema.Actions.Insert });
//header
AcumaticaInterface.apitest.Command[] Document = new AcumaticaInterface.apitest.Command[]
{
PORcptSchema.Actions.Insert,
new Value
{
Value = BPCode,
LinkedCommand = PORcptSchema.DocumentSummary.Vendor,
Commit = true
},
new Value
{
Value = BPRefNbr ,
LinkedCommand = PORcptSchema.DocumentSummary.VendorRef
},
new Value
{
Value = PostDate.HasValue ? ((DateTime)PostDate.Value).ToLongDateString() : "",
LinkedCommand = PORcptSchema.DocumentSummary.Date
},
new Value
{
Value = "POS Doc " + DocNum + "-" + Description,
LinkedCommand = PORcptSchema.DocumentSummary.NoteText
}
};
//set the dialog answer
var dgAnswer = new Command[]
{ new Value
{
Value = "OK",
LinkedCommand = PORcptSchema.AddPurchaseOrderLine.ServiceCommands.DialogAnswer,
Commit = true
}
};
Document = Document.Concat(dgAnswer).ToArray();
//select lines from smart panel
foreach (POReceiptLine line in POReceiptlines.OrderBy(x => x.LineNum))
{
AcumaticaInterface.apitest.Command[] Docline = new AcumaticaInterface.apitest.Command[]
{
new Key
{
ObjectName = PORcptSchema.AddPurchaseOrderLine.OrderNbr.ObjectName,
FieldName = PORcptSchema.AddPurchaseOrderLine.OrderNbr.FieldName,
Value = "='" + line.BaseDocNum + "'"
},
new Key
{
ObjectName = PORcptSchema.AddPurchaseOrderLine.LineNbr.ObjectName,
FieldName = PORcptSchema.AddPurchaseOrderLine.LineNbr.FieldName,
Value = "='" + line.BaseLineNum + "'"
},
new Value
{
Value = "True",
LinkedCommand = PORcptSchema.AddPurchaseOrderLine.Selected,
Commit = true
}
};
Document = Document.Concat(Docline).ToArray();
}
//Add PO line and retrive back the added lines.
var addPOLine = new Command[]
{
addPOLineWithCommit,
////get back the added lines in the grid
PORcptSchema.DocumentDetails.POOrderNbr,
PORcptSchema.DocumentDetails.POLineNbr
};
Document = Document.Concat(addPOLine).ToArray();
var receiptLines = context.PO302000Submit(Document);
//update quantity..
List<Command> commandList = new List<Command>();
for (int index = 0; index < receiptLines.Length; index++)
{
commandList.Add(new Value
{
Value = index.ToString(),
LinkedCommand = PORcptSchema.DocumentDetails.ServiceCommands.RowNumber
});
POReceiptLine line = POReceiptlines.Where(x => x.BaseDocNum == receiptLines[index].DocumentDetails.POOrderNbr.Value && x.BaseLineNum.ToString() == receiptLines[index].DocumentDetails.POLineNbr.Value).FirstOrDefault();
if (line != null)
{
commandList.Add(new Value
{
Value = line.Qty.ToString(),
LinkedCommand = PORcptSchema.DocumentDetails.ReceiptQty,
Commit = index < receiptLines.Length - 1
});
}
else
throw new Exception("Matching POS Rcpt line not found.");
}
//save
commandList.AddRange(
//SAVING And get the document nbr
new AcumaticaInterface.apitest.Command[] {
PORcptSchema.Actions.Save,
PORcptSchema.DocumentSummary.Type,
PORcptSchema.DocumentSummary.ReceiptNbr
});
var POReceipt = context.PO302000Submit(commandList.ToArray())[0];
}
This code is working, Receipt is creating but new created receipt is not generated for newley generated Purchase order, this receipt is generated for old any PO

Updating existing activity with attachments

I need to update an attachment to an existing activity using Web API from my application to an existing case in Acumatica Partner's Portal.
I have already written a code to this but it is updating to first activity always instead of for the activity I am passing the noteid.
I am doing this by retrieving the noteid of the activity created and then sending the same noteid along with caseid to update an attachment.
Below is the code which is updating the existing activity with attachment, please suggest.
var origActivities = context1.Export
(
new SP203010WS.Command[]
{
new SP203010WS.Value
{
Value = currentAcumaticaCaseNo,
LinkedCommand = content.Case.CaseID
},
content.Activities.Type,
content.Activities.Summary,
new SP203010WS.Field
{
FieldName = "NoteID",
ObjectName = content.Activities.Summary.ObjectName
},
content.Activities.CreatedAt,
},
null, 0, false, false
);
Guid?[] origActivityNoteID = null;
DateTime?[] origActivityCreatedDate = null;
if (origActivities != null && origActivities.Count() > 0)
{
origActivityNoteID = new Guid?[origActivities.Count()];
origActivityCreatedDate = new DateTime?[origActivities.Count()];
int i = 0;
foreach (string[] activity in origActivities)
{
origActivityNoteID[i] = new Guid(activity[2].ToString());
origActivityCreatedDate[i] = Convert.ToDateTime(activity[3]);
i++;
}
}
*****Adding new activity*****
var newActivities = context.Export
(
new SP203010WS.Command[]
{
new SP203010WS.Value
{
Value = currentAcumaticaCaseNo,
LinkedCommand = content.Case.CaseID
},
content.Activities.Type,
content.Activities.Summary,
new SP203010WS.Field
{
FieldName = "NoteID",
ObjectName = content.Activities.Summary.ObjectName
},
content.Activities.CreatedAt,
},
null, 0, false, false
);
Guid? newActivityNoteID = null;
for (var i = 1; i <= newActivities.GetUpperBound(0); i++)
{
if(origActivityNoteID != null && origActivityCreatedDate != null)
{
if((Array.IndexOf<Guid?>(origActivityNoteID, new Guid(newActivities[i][2])) <= 0) &&
(Array.IndexOf<DateTime?>(origActivityCreatedDate, Convert.ToDateTime(newActivities[i][3])) <= 0))
{
newActivityNoteID = new Guid(newActivities[i][2]);
break;
}
}
}
*****getting a list of all attachments*****
foreach (FileInfo fi in fileInfo)
{
SP203010WS.Content[] content1 = context.Submit
(
new SP203010WS.Command[]
{
new SP203010WS.Value
{
//Value = actiPartner.AcumaticaCaseID,
Value = currentAcumaticaCaseNo,
LinkedCommand = CR306000.Case.CaseID
},
new SP203010WS.Value
{
Value = newActivityNoteID.ToString(),
LinkedCommand = new SP203010WS.Field { FieldName="NoteID", ObjectName="Activities" }
},
new SP203010WS.Value
{
FieldName = fi.Name,
Value = Convert.ToBase64String(fi.BinData),
LinkedCommand = CR306000.Activities.ServiceCommands.Attachment
},
CR306000.Actions.Save
}
);
}
Looks like search in Screen-Based API has no support for GUIDs. You will have to locate necessary Attachment by other fields values, for instance: Type, Summary and CreatedAt:
Screen context = new Screen();
context.CookieContainer = new System.Net.CookieContainer();
context.Url = "http://localhost/ActivityAttachments/Soap/CR306000.asmx";
context.Login("admin", "123");
var content = context.GetSchema();
var newActivities = context.Export
(
new Command[]
{
new Value
{
Value = "000110",
LinkedCommand = content.CaseSummary.CaseID
},
content.Activities.Type,
content.Activities.Summary,
content.Activities.CreatedAt,
},
null, 0, false, false
);
byte[] filedata;
using (FileStream file = File.Open("EP507011.txt", FileMode.Open))
{
filedata = new byte[file.Length];
file.Read(filedata, 0, filedata.Length);
}
Content[] content1 = context.Submit
(
new Command[]
{
new Value
{
Value = "000110",
LinkedCommand = content.CaseSummary.CaseID
},
new Key
{
ObjectName = content.Activities.Type.ObjectName,
FieldName = content.Activities.Type.FieldName,
Value = string.Format("='{0}'", newActivities[newActivities.Length - 2][0])
},
new Key
{
ObjectName = content.Activities.Summary.ObjectName,
FieldName = content.Activities.Summary.FieldName,
Value = string.Format("='{0}'", newActivities[newActivities.Length - 2][1])
},
new Key
{
ObjectName = content.Activities.CreatedAt.ObjectName,
FieldName = content.Activities.CreatedAt.FieldName,
Value = newActivities[newActivities.Length - 2][2]
},
new Value
{
FieldName = "EP507011.txt",
Value = Convert.ToBase64String(filedata),
LinkedCommand = content.Activities.ServiceCommands.Attachment
},
content.Actions.Save
}
);

Error#285 The button Save is disabled, when Creating Payment and Applications Document in Acumatica 4.20.2115

We are getting an error 'save button is disabled' while we try to create a new payment. we tried the same values and steps in UI which doesnt seems to have any issue. please support.
The webservice code is as below
Note: we have our class variables inside the code.
foreach (Payment currPayment in order.InvPayments)
{
try
{
try
{
paymentSchema = context.AR302000GetSchema();
}
catch
{
BuisnessLogic.contextLogin();
paymentSchema = context.AR302000GetSchema();
}
Command[] cmdPayment;
paymentSchema.Actions.Insert.Commit = true;
cmdPayment = new Command[]
{
paymentSchema.Actions.Insert,
new Value
{
Value = order.CreatedOn.Value.ToLongDateString(),
LinkedCommand = paymentSchema.PaymentSummary.ApplicationDate,
Commit = true
},
new Value
{
Value = order.interfaceStatus.InvoiceNbr,
LinkedCommand = paymentSchema.PaymentSummary.PaymentRef
}
};
Command[] cmdBP = new Command[]
{
new Value
{
Value = FirstOrder.CustomerID,
LinkedCommand = paymentSchema.PaymentSummary.Customer
},
};
cmdPayment = cmdPayment.Concat(cmdBP).ToArray();
Command[] cmdHeader = new Command[]
{
new Value
{
Value = currPayment.PayMethod,
LinkedCommand = paymentSchema.PaymentSummary.PaymentMethod
},
new Value
{
Value = currPayment.CashAccount,
LinkedCommand = paymentSchema.PaymentSummary.CashAccount
},
new Value
{
Value = "false",
LinkedCommand = paymentSchema.PaymentSummary.Hold
}
};
cmdPayment = cmdPayment.Concat(cmdHeader).ToArray();
Command[] cmdINVDoc = new Command[]
{
new Value
{
Value = currPayment.PayAmount.ToString(),
LinkedCommand = paymentSchema.PaymentSummary.PaymentAmount,
Commit = true
},
paymentSchema.DocumentsToApply.ServiceCommands.NewRow,
new Value
{
Value = order.interfaceStatus.InvoiceNbr,
LinkedCommand = paymentSchema.DocumentsToApply.ReferenceNbr,
Commit = true
},
paymentSchema.PaymentSummary.AppliedToDocuments,
paymentSchema.Actions.Save,
paymentSchema.PaymentSummary.Type,
paymentSchema.PaymentSummary.ReferenceNbr
};
cmdPayment = cmdPayment.Concat(cmdINVDoc).ToArray();
// var pay = context.AR302000Submit(cmdPayment)[0];
// Command[] cmdSave = new Command[]
//{
// paymentSchema.Actions.Save,
// paymentSchema.PaymentSummary.Type,
// paymentSchema.PaymentSummary.ReferenceNbr
//};
//var payment2 = context.AR302000Submit(cmdSave)[0];
var payment2 = context.AR302000Submit(cmdPayment)[0];
string paymentType = payment2.PaymentSummary.Type.Value;
currPayment.PaymentNbr = payment2.PaymentSummary.ReferenceNbr.Value;
//release payment
ReleasePayments(paymentType, currPayment.PaymentNbr);
currPayment.Exported = true;
currPayment.updateAsExported(BuisnessLogic.Reporter);
BuisnessLogic.Reporter.writeLog("Invoice payment " + currPayment.PaymentNbr + " added.");
//clear screen
// cmdSave = new Command[]
//{
// paymentSchema.Actions.Insert
//};
// context.AR302000Submit(cmdSave);
}
catch (Exception ex)
{
retval = false;
ErrorMsg += "Invoice payment creation failed: " + //BuisnessLogic.getFriendlyError(ex.Message.ToString()) + Environment.NewLine;
}
}
DETAILED EXCEPTION
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> PX.Data.PXException: Error #285: The button Save is disabled.
at PX.Data.PXAction1.<Press>d__c.MoveNext()
at PX.Api.SyImportProcessor.SyStep.CommitChanges(Object itemToBypass, PXFilterRow[] targetConditions)
at PX.Api.SyImportProcessor.ExportTableHelper.ExportTable()
at PX.Api.ScreenUtils.Submit(String screenId, Command[] commands, SchemaMode schemaMode, PXGraph graph)
at PX.Api.Services.ScreenService.Submit(String id, IEnumerable1 commands, SchemaMode schemaMode)
at PX.Api.Soap.Screen.ScreenGate.Submit(Command[] commands)
--- End of inner exception stack trace ---
Focusing on your observation that this works for one, single threaded, use case but not for multiple threads, I would be interested in seeing the code behind the management (creation and login, etc) for the "context" object (context.getschema() and
context.AR302000Submit(cmdPayment)
Each thread needs its own context!
I've prepared template for you based on our demo data and version 4.20.2063, see below, it works fine on my side.
context.Url = "http://localhost/AcumaticaDB_4_20_2063/Soap/AR302000.asmx";
context.Login("admin", "123");
Content AR302000 = context.GetSchema();
context.Clear();
AR302000.DocumentsToApply.DocumentType.Commit = false;
try
{
Content[] AR302000Content = context.Submit(
new Command[]
{
new Value { Value = "Payment", LinkedCommand = AR302000.PaymentSummary.Type },
new Value { Value = "='new'", LinkedCommand = AR302000.PaymentSummary.ReferenceNbr },
new Value { Value = "ABARTENDE", LinkedCommand = AR302000.PaymentSummary.Customer, Commit = true },
//new Value { Value = "DME", LinkedCommand = AR302000.FinancialDetailsLinkToGL.Branch, Commit = true },
new Value { Value = "CASH", LinkedCommand = AR302000.PaymentSummary.PaymentMethod, Commit = true },
new Value { Value = "01/01/14", LinkedCommand = AR302000.PaymentSummary.ApplicationDate },
new Value { Value = "101000", LinkedCommand = AR302000.PaymentSummary.CashAccount },
new Value { Value = "false", LinkedCommand = AR302000.PaymentSummary.Hold },
new Value { Value = "001", LinkedCommand = AR302000.PaymentSummary.PaymentRef },
new Value { Value = "10496", LinkedCommand = AR302000.PaymentSummary.PaymentAmount },
new Value { Value = "test", LinkedCommand = AR302000.PaymentSummary.Description },
AR302000.DocumentsToApply.ServiceCommands.NewRow,
new Value {Value = "Invoice", LinkedCommand = AR302000.DocumentsToApply.DocumentType },
new Value {Value = "000709", LinkedCommand = AR302000.DocumentsToApply.ReferenceNbr },
AR302000.Actions.Save,
AR302000.PaymentSummary.ReferenceNbr
}
);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("RefNbr:" + AR302000.PaymentSummary.ReferenceNbr.Value);

Resources