Updating existing activity with attachments - acumatica

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
}
);

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()]

AdaptiveCards with PostBack button

I am trying to replace a HeroCard that has multiple CardAction buttons. I would like to use AdaptiveCards, however, I don't see any documentation that states how to enable postBack from an AdaptiveCard button. I see open browser, and what not, but no postBack.
Is this supported yet?
var cardButtons = new List<CardAction>();
var yesAction = new CardAction()
{
Value = "Yes",
Type = "postBack",
Title = "Yes"
};
cardButtons.Add(yesAction);
var noAction = new CardAction()
{
Value = "Nope",
Type = "postBack",
Title = "No, I'll try it"
};
cardButtons.Add(noAction);
var plCard = new HeroCard()
{
Title = $"Are you sure?",
Buttons = cardButtons
};
Have you tried SubmitAction?
var noAction = new CardAction()
{
Value = "Nope",
Type = SubmitAction.TYPE,
Title = "No, I'll try it"
};
This code renders correctly, even seems to send information back to the bot. But still cannot figure out how to read the data back on the resuming function:
var card = new AdaptiveCard();
card.Body.Add(
new ColumnSet() {
Columns = new List<Column>() {
new Column() {
SelectAction = new SubmitAction() { Data = 3, Title = "Good" },
Items = new List<CardElement>() { new Image() { Url = GeneralStrings.Feedback03 } }
},
new Column() {
SelectAction = new SubmitAction() { Data = 2, Title = "Average" },
Items = new List<CardElement>() { new Image() { Url = GeneralStrings.Feedback02 } }
},
new Column() {
SelectAction = new SubmitAction() { Data = 1, Title = "Bad" },
Items = new List<CardElement>() { new Image() { Url = GeneralStrings.Feedback01 } }
}
}
});
var attachemnt = new Attachment() { ContentType = AdaptiveCard.ContentType, Content = card };
var message = context.MakeMessage();
message.Attachments.Add(attachemnt);
await context.PostAsync(message);
context.Wait<Activity>(this.AfterAskFeedback);

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

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);

Enter Physical Inventory Count Through Acumatica API

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

Resources