Acumatica change Shipping Terms on Sales Order creation - acumatica

I'm using Acumatica's contract based API to create sales order from an ASP.net application. I need to update the "Shipping Terms" field under the "Shipping Settings" tab on a Sales Order when I create it (see below), but I can not find the property to use on the ASP.net objects that are provided through the contract based API. How would I accomplish this?
Here is my current code for how I create the sales order:
using (DefaultSoapClient client = new DefaultSoapClient(binding, address))
{
//Sales order data
string customerID = "CUST1234;
string orderDescription = "Automated Order";
string customerOrder = "TEST";
var orderDetails = new List<SalesOrderDetail>();
foreach(var lineItem in order.line_items)
{
orderDetails.Add(new SalesOrderDetail {
InventoryID = new StringValue { Value = lineItem.sku },
Quantity = new DecimalValue { Value = lineItem.quantity },
UnitPrice = new DecimalValue { Value = Decimal.Parse(lineItem.price) }, //TODO this should only be done for MHR owned sites
UOM = new StringValue { Value = "EACH" },
});
}
//Specify the values of a new sales order
SalesOrder orderToBeCreated = new SalesOrder
{
OrderType = new StringValue { Value = "SO" },
CustomerID = new StringValue { Value = customerID },
Description = new StringValue { Value = orderDescription },
CustomerOrder = new StringValue { Value = customerOrder },
ExternalReference = new StringValue { Value = order.order_number.ToString() },
Details = orderDetails.ToArray<SalesOrderDetail>(),
ShippingAddressOverride = new BooleanValue { Value = true },
ShippingContactOverride = new BooleanValue { Value = true },
ShippingContact = new Contact()
{
DisplayName = new StringValue { Value = order.shipping_address.first_name + " " + order.shipping_address.last_name },
FirstName = new StringValue { Value = order.shipping_address.first_name },
LastName = new StringValue { Value = order.shipping_address.last_name },
Address = new Address()
{
AddressLine1 = new StringValue { Value = order.shipping_address.address_1 },
AddressLine2 = new StringValue { Value = order.shipping_address.address_2 },
City = new StringValue { Value = order.shipping_address.city },
State = new StringValue { Value = order.shipping_address.state },
Country = new StringValue { Value = order.shipping_address.country },
PostalCode = new StringValue { Value = order.shipping_address.postcode }
}
},
};
client.Login(_acumaticaUid, _acumaticaPwd, _acumaticaCompany, null, null);
//Create a sales order with the specified values
try
{
SalesOrder newOrder = (SalesOrder)await client.PutAsync(orderToBeCreated);
client.Logout();
return newOrder;
}
catch (Exception e)
{
//order addition to Acumatica failed, update the order status in Woo Commerce
client.Logout();
Console.WriteLine("Acumatica could not add specified entity: " + e);
return null;
}
}
UPDATE:
Based on PatrickChen's comment, I created a new web service endpoint in Acumatica "SalesOrderCustom", where I used all of the default fields and then added "ShippingTerms" to the list as well. I then imported that web service into my .net project (with some headache due to this issue) and was able to use the service to GET the sales order I wanted to add shipping terms to, and try to update it. The code executes ok, but after the PUT operation is done, the object is NOT updated in Acumatica and the ShippingTerms property is returned as NULL. What am I doing wrong? Code below:
public async Task<SalesOrderCustom> UpdateShippingTerms(string customerOrder, string originStore, string shippingSpeed)
{
var binding = CreateNewBinding(true, 655360000, 655360000);
var address = new EndpointAddress(ConfigurationManager.AppSettings["AcumaticaCustomUrl"]);
var soToBeFound = new SalesOrderCustom()
{
OrderType = new StringSearch { Value = "SO" },
CustomerOrder = new StringSearch { Value = customerOrder }
};
using (DefaultSoapClient client = new DefaultSoapClient(binding, address))
{
client.Login(_acumaticaUid, _acumaticaPwd, _acumaticaCompany, null, null);
try
{
var soToBeUpdated = (SalesOrderCustom) await client.GetAsync(soToBeFound);
soToBeUpdated.ShippingTerms = new StringValue { Value = "USPS 1 CLS" };
var updatedOrder = (SalesOrderCustom)await client.PutAsync(soToBeUpdated);
//ShippingTerms is still NULL on returned object even after updating the object!!! WHY???
client.Logout();
return updatedOrder;
}
catch (Exception e)
{
client.Logout();
Console.WriteLine("Acumatica could not find specified entity: " + e);
return null;
}
}
}

Starting Acumatica 6, it's possible to update any field, not included into the Default endpoint. This feature is only available for endpoints implementing system contract of the 2nd version:
Below is the sample showing how to change Shipping Terms for a Sales Order with the Default Contract-Based endpoint by working with the CustomFields collection:
using (var client = new DefaultSoapClient())
{
client.Login("admin", "123", null, null, null);
try
{
var order = new SalesOrder()
{
OrderType = new StringSearch { Value = "SO" },
OrderNbr = new StringSearch { Value = "SO003729" }
};
order = client.Get(order) as SalesOrder;
order.CustomFields = new CustomField[]
{
new CustomStringField
{
fieldName = "ShipTermsID",
viewName = "CurrentDocument",
Value = new StringValue { Value = "FLATRATE2" }
}
};
client.Put(order);
}
finally
{
client.Logout();
}
}
No issues also noticed on my end when updating Sales Order Shipping Terms with the extended Default Contract-Based endpoint on a brand new Acumatica ERP 6.1 instance:
using (var client = new DefaultSoapClient())
{
client.Login("admin", "123", null, null, null);
try
{
var order = new SalesOrder()
{
OrderType = new StringSearch { Value = "SO" },
OrderNbr = new StringSearch { Value = "SO003729" }
};
order = client.Get(order) as SalesOrder;
order.ShippingTerms = new StringValue { Value = "FLATRATE1" };
client.Put(order);
}
finally
{
client.Logout();
}
}
For reference, adding screenshot of my extended Default endpoint used to update Shipping Terms in the SalesOrder entity:

I was able to add Shipping Terms when I created a new 6.0 endpoint. The default endpoint that ships with Acumatica is not extendable.

Related

Acumatica API Error when creating a Inventory Receipts API calls

Good day
I am creating a SOAP contract base connection to Acumatica.
I am getting an error: "System.ArgumentNullException: Value cannot be null."
I am not sure why I am getting the error.
Here is my code
using (var soapClient = new DefaultSoapClient())
{
try
{
soapClient.Login();
InventoryReceipt NewinventoryReceipt = new InventoryReceipt
{
ReferenceNbr = new StringValue { Value = "<NEW>" },
Hold = new BooleanValue { Value = true },
Date = new DateTimeValue { Value = DateTime.Now },
PostPeriod = new StringValue { Value = DateTime.Now.ToString("DD-yyyy") },
TransferNbr = new StringValue { Value = "" },
//External Ref
Description = new StringValue { Value = "" },
Details = new InventoryReceiptDetail[]
{
new InventoryReceiptDetail
{
//branch
InventoryID = new StringValue{Value = "NIS777"},
WarehouseID = new StringValue{Value = "FBTZEST"},
Location = new StringValue {Value = "BULK"},
Qty = new DecimalValue{Value = 1},
UOM = new StringValue{Value = "PALLET"},
UnitCost = new DecimalValue{Value = 91},
ExtCost = new DecimalValue{Value = 91},
LotSerialNbr = new StringValue{Value = "PLN12345"},
ExpirationDate = new DateTimeValue{Value = DateTime.Now},
// ReasonCode
Description = new StringValue{Value = ""}
}
},
};
InventoryReceipt putInventoryReceipt = (InventoryReceipt)soapClient.Put(NewinventoryReceipt);
}
catch (Exception ex)
{
soapClient.Logout();
throw;
}
finally
{
soapClient.Logout();
}
soapClient.Logout();
}
Console.ReadLine();
}
Is there any way to see what is null or what I am missing to post this data?
Have you tried manually entering the data into the UI? The Validation on the web service should be the same as the UI, so you might get more info from the UI. You have a lot of dependent values here since you're referencing a specific Lot perhaps a value is missing. Other than that, you might try adding Project = X.

How to create attributes on a Service Order through Web Services

I had to create my own Web Service Endpoint for Service Orders. Here is the WSDL: https://imagineersllc.acumatica.com/(W(7))/entity/PileraAPI/19.100.0122?wsdl&company=Imagineers%20LLC%20-%20Prototype I added Attributes to it following an example I found under Stock Items in the Default Endpoint.
I added attributes to the Service Order type and when I try to populate the attributes in my API they remain blank. The Service Order gets created just fine it just does not populate the attributes.
I've tried renaming the attributes and using the code vs the description in my code.
string sServiceOrderType = "MRO"; // Only type supported
string sCustomer = "1003";
string sBranchLocation = "PROPMGMT"; // Only location available
string sWorkflowStage = "ACKNOWLEDGED";
DateTime dDate = DateTime.Parse("7/1/2019");
string sExternalReference = "WO-2345";
string sDescription = "Service Order from Pilera API";
bool bOverride = true; // Used to make Contact and Address editable
string sCompanyName = "DSD Business Systems";
string sAttention = "John Wiles";
string sPhone = "(858) 550-5900";
string sEmail = "johnw#dsdinc.com";
string sAddressLine1 = "1225 Rosemarie Way";
string sAddressLine2 = "";
string sCity = "Chesapeake";
string sState = "VA";
string sPostalCode = "23322";
DateTime dPromisedDate = DateTime.Parse("7/21/2019");
string sSeverity = "Low";
string sPriority = "High";
string sComment = "Comment created by API";
bool bHold = true;
string sCategory = "GENERALREPAIR";
string sCommunity = "Deerfield Condominium Assoc.";
string sContact = "Annamma George";
string sContactPhone = "860-656-6603";
string sContactLocation = "268 Richard Street #1 Newington, CT 06111";
ServiceOrders ServiceOrdersToBeCreated = new ServiceOrders
{
ServiceOrderType = new StringValue { Value = sServiceOrderType },
Customer = new StringValue { Value = sCustomer },
BranchLocation = new StringValue { Value = sBranchLocation },
WorkflowStage = new StringValue { Value = sWorkflowStage },
Date = new DateTimeValue { Value = dDate },
ExternalReference = new StringValue { Value = sExternalReference },
Description = new StringValue { Value = sDescription },
Hold = new BooleanValue { Value = bHold },
PromisedDate = new DateTimeValue { Value = dPromisedDate },
Severity = new StringValue { Value = sSeverity },
Priority = new StringValue { Value = sPriority },
Category = new StringValue { Value = sCategory },
Override = new BooleanValue { Value = bOverride },
CompanyName = new StringValue { Value = sCompanyName },
Attention = new StringValue { Value = sAttention },
Phone = new StringValue { Value = sPhone },
Email = new StringValue { Value = sEmail },
AddressLine1 = new StringValue { Value = sAddressLine1 },
AddressLine2 = new StringValue { Value = sAddressLine2 },
City = new StringValue { Value = sCity },
State = new StringValue { Value = sState },
PostalCode = new StringValue { Value = sPostalCode },
Comment = new StringValue { Value = sComment },
Attributes = new[]
{
new AttributeValue
{
AttributeID = new StringValue { Value = "Community" },
Value = new StringValue { Value = sCommunity }
},
new AttributeValue
{
AttributeID = new StringValue { Value = "Contact" },
Value = new StringValue { Value = sContact }
},
new AttributeValue
{
AttributeID = new StringValue { Value = "Phone" },
Value = new StringValue { Value = sContactPhone }
},
new AttributeValue
{
AttributeID = new StringValue { Value = "Location" },
Value = new StringValue { Value = sContactLocation }
}
}
};
ServiceOrders newServiceOrder = (ServiceOrders)soapClient.Put(ServiceOrdersToBeCreated);
Service Order is created without attributes. No error messages received.
Here is what Support provided:
try
{
ServiceOrders newServiceOrder = (ServiceOrders)client.Put(ServiceOrdersToBeCreated);
List<AttributeValue> attrList = new List<AttributeValue>();
foreach (AttributeValue attrVal in newServiceOrder.Attributes)
{
AttributeValue attr = new AttributeValue();
attr.ID = attrVal.ID;
switch(attrVal.AttributeID.Value)
{
case "Community":
attr.Value = new StringValue { Value = sCommunity };
break;
case "Contact":
attr.Value = new StringValue { Value = sContact };
break;
case "Phone":
attr.Value = new StringValue { Value = sContactPhone };
break;
case "Location":
attr.Value = new StringValue { Value = sContactLocation };
break;
default:
Console.WriteLine("Attribute Not Found!");
break;
}
attrList.Add(attr);
}
newServiceOrder.Attributes = attrList.ToArray();
newServiceOrder = (ServiceOrders)client.Put(newServiceOrder);
}

How to specify fields for detail records with Acumatica ReturnBehavior

I'm trying to use the Acumatica API to return a list of Sales Order and Sales Order Details, while limiting the fields returned.
So far, I have :
SalesOrder filter = new SalesOrder
{
//Filter the SOs returned
OrderType = new AcumaticaOpticsExt.StringValue { Value = salesOrder.Split('/').First() },
OrderNbr = new AcumaticaOpticsExt.StringValue { Value = salesOrder.Split('/').Last() },
//Specify return behavior
ReturnBehavior = ReturnBehavior.OnlySpecified,
//Specify the fields to be returned on the SO
Hold = new BooleanReturn(),
CustomerName = new StringReturn(),
SchedShipment = new DateTimeReturn(),
QtyAllocatedM = new DecimalReturn(),
QtyAllocatedNotCompletedM = new DecimalReturn(),
//And from the SO Line Detail
};
It's not clear how I can specify the fields from the Details and I haven't found any multi-level uses in the documentation.
Does anyone have an example?
Here is an example that works for me :
SalesOrder so = new SalesOrder
{
ReturnBehavior = ReturnBehavior.OnlySpecified,
OrderType = new StringSearch { Value = "SO", Condition = StringCondition.Equal },
OrderNbr = new StringSearch { Value = "001253", Condition = StringCondition.Equal },
Details = new SalesOrderDetail[]
{
new SalesOrderDetail
{
ReturnBehavior = ReturnBehavior.OnlySpecified,
InventoryID = new StringReturn(),
LineNbr = new IntReturn(),
UOM = new StringReturn(),
UnitPrice = new DecimalReturn(),
Quantity = new DecimalReturn()
}
}
};
You just have to define the array of detail items, in the first one define the return behavior level that you want and if it applies the field(s) that you want to be returned.

How To Retrieve An Attribute Field In StockItems In Acumatica API?

I am wondering if a specific attribute can be retrieved in the Web Service API?
I have tried IN202500.AttributesAttributes.Value when exporting but that listed all attributes of the inventory. I also noticed the attributes are saved in the table as [AttributeName]_Attributes in the Inventory table, is there any way of retrieving this?
This is the code I am using (expecting it would retrieve the Attributes)
IN202500Content IN202500 = context.IN202500GetSchema();
context.IN202500Clear();
Command[] oCmd = new Command[] {
IN202500.StockItemSummary.ServiceCommands.EveryInventoryID,
IN202500.StockItemSummary.InventoryID,
IN202500.StockItemSummary.Description,
IN202500.StockItemSummary.ItemStatus,
IN202500.GeneralSettingsItemDefaults.ItemClass,
IN202500.GeneralSettingsItemDefaults.LotSerialClass,
new Field {
ObjectName = IN202500.StockItemSummary.InventoryID.ObjectName,
FieldName = "BARCODE_Attributes"},
new Field {
ObjectName = IN202500.StockItemSummary.InventoryID.ObjectName,
FieldName = "DfltReceiptLocationID"},
new Field {
ObjectName = IN202500.StockItemSummary.InventoryID.ObjectName,
FieldName = "LastModifiedDateTime"}
};
Filter[] oFilter = new Filter[] {
new Filter
{
Field = new Field {
ObjectName = IN202500.StockItemSummary.InventoryID.ObjectName,
FieldName = "LastModifiedDateTime"},
Condition = FilterCondition.Greater,
Value = SyncDate
}
};
String[][] sReturn = context.IN202500Export(oCmd, oFilter, 0, true, false);
But the Attribute field returned is an empty string.
Thanks,
G
You can leverage the dynamic fields that are added to the primary view of the screen to retrieve specific attribute values. These fields don't show up in the WSDL schema, so you have to create a Field object and pass it to the Export function.
I looked up the field name and object name from an Export scenario by displaying the Native Object / Native Field name columns. Resulting Export call looks like this:
var result = screen.Export(new IN202500.Command[] {
new IN202500.Value() { LinkedCommand = schema.StockItemSummary.InventoryID, Value = "Z730P00073"},
schema.StockItemSummary.InventoryID,
schema.StockItemSummary.Description,
new IN202500.Field { FieldName = "COLOR_Attributes", ObjectName = "Item"},
new IN202500.Field { FieldName = "HWMAN_Attributes", ObjectName = "Item"},
}, null, 0, true, true);
This code will retrieve the two attributes value (COLOR and HWMAN Attributes) for a specific inventory item (Z730P00073). The result variable contains a two-dimensional array, let me know if you need help getting results from the array.
This example shows how to add an item and set attributes and image:
byte[] filedata;
using (System.IO.FileStream file = System.IO.File.Open(#"C:\1.jpg", System.IO.FileMode.Open))
{
filedata = new byte[file.Length];
file.Read(filedata, 0, filedata.Length);
}
Random rnd = new Random();
string inventoryID = "CPU0000" + rnd.Next(100).ToString();
context.IN202500Clear();
IN202500result = context.IN202500Submit(
new Command[]
{
IN202500.Actions.Insert,
new Value { Value = inventoryID, LinkedCommand = IN202500.StockItemSummary.InventoryID },
new Value { Value = inventoryID, LinkedCommand = IN202500.StockItemSummary.Description },
new Value { Value = "CPU", LinkedCommand = IN202500.GeneralSettingsItemDefaults.ItemClass, Commit = true },
new Value { Value = "TAXABLE", LinkedCommand = IN202500.GeneralSettingsItemDefaults.TaxCategory, Commit = true },
//attributes - pairs
new Value { Value = "FREQUENCY", LinkedCommand = IN202500.AttributesAttributes.Attribute },
new Value { Value = "1400", LinkedCommand = IN202500.AttributesAttributes.Value, Commit = true },
new Value { Value = "CORE", LinkedCommand = IN202500.AttributesAttributes.Attribute },
new Value { Value = "2 CORES", LinkedCommand = IN202500.AttributesAttributes.Value, Commit = true },
new Value { Value = "INTGRAPH", LinkedCommand = IN202500.AttributesAttributes.Attribute },
new Value { Value = "True", LinkedCommand = IN202500.AttributesAttributes.Value, Commit = true },
//image
new Value { Value = Convert.ToBase64String(filedata), FieldName = "1.jpg", LinkedCommand = IN202500.StockItemSummary.ServiceCommands.Attachment }, //uploads
new Value { Value = "1.jpg", LinkedCommand = IN202500.Attributes.ImageUrl }, //sets as an item picture
IN202500.Actions.Save,
//return the result
IN202500.StockItemSummary.InventoryID
});

Can't create invoice details with manual discount using OrganizationServiceClient in CRM 2011

I'm using OrganizationServiceClient with CRM 2011, When I create an invoicedetail with a manualdiscountamount, the discount doesn't appear in the CRM website.
Here's my code:
OrganizationServiceClient client = new OrganizationServiceClient("CustomBinding_IOrganizationService",new EndpointAddress(AuthenticationInfo.OrganizationServiceUrl))) { client.ConfigureCrmOnlineBinding(AuthenticationInfo.OrganizationPolicy.IssuerUri);
client.Token = AuthenticationInfo.OrganizationToken;
Entity entityDetails = = new Entity();
entityDetails.LogicalName = "invoicedetail";
entityDetails.Attributes = new AttributeCollection();
entityDetails.Attributes.Add(new KeyValuePairOfstringanyType() {
key = "productid",
value =
new EntityReference() {
LogicalName = "product",
Id = Guid.Parse("Some Product Id")
}
});
entityDetails.Attributes.Add(new KeyValuePairOfstringanyType() {
key = "uomid",
value =
new EntityReference() {
LogicalName = "uom",
Id = Guid.Parse("33B75DB8-8771-4B5A-875F-810CC0732C0C")
}
});
entityDetails.Attributes.Add(new KeyValuePairOfstringanyType() {
key = "invoiceid",
value = new EntityReference() {LogicalName = "invoice", Id = Guid.Parse("Some Invoice Id")}
});
entityDetails.Attributes.Add(new KeyValuePairOfstringanyType() {
key = "quantity",
value = 1
});
entityDetails.Attributes.Add(new KeyValuePairOfstringanyType() {
key = "createdon",
value = DateTime.Now
});
entityDetails.Attributes.Add(new KeyValuePairOfstringanyType() {
key = "manualdiscountamount",
value = 15
});
invoiceDetailsId = client.Create(entityDetails);
What may be the problem here?
Try to use following code to add manualdiscountamount field:
entityDetails.Attributes.Add(new KeyValuePairOfstringanyType() {
key = "manualdiscountamount",
value = new Money(Convert.ToDecimal(15))
});
Because manualdiscountamount field is of Money type. Recheck following article

Resources