When I call the Acumatica REST API to update a PO Receipt, the PO Number field on the detail line is not updating. I'm just doing a PUT to the Default/17.200.001 endpoint, including a detail line. The PUT is successful, but the response returns an empty PONbr and POType on the detail line, and those fields are not updated. Are these fields read-only for some reason? How can I resolve this or override it so that these PO fields will update?
Update #1 3/22:
Per the response below, I tried putting these values in the insert instead of the update, but now I get a different error: "PO Error: Quantity must be greater than 0", and "PurchaseReceipt.Details[0].ReceiptQty: Quantity must be greater than 0". However, the ReceiptQty is there and is greater than 0.
Update #2 3/22:
You should be able to duplicate it with very simple steps:
Create a PO with Vendor, which defaults Location.
Add a PO Line with InventoryID, which defaults the line type and Warehouse
Enter the Order Qty
Save PO
In Postman, PUT similar JSON to what I supplied below for a PO Receipt, specifying a detail line with the referenced Inventory ID, PO Order Nbr, PO Order Type, Line Nbr, PO Line Nbr, Receipt Qty, Warehouse
The response is an error “PO Error: Quantity must be greater than 0”, “PurchaseReceipt.Details[0].ReceiptQty: Quantity must be greater than 0”
Here is sample json for the insert:
{
"Date": {
"value": "2019-03-22T00:00:00-04:00"
},
"Details": [
{
"InventoryID": {
"value": "0010006"
},
"LineNbr": {
"value": 1
},
"Location": {
"value": "01P"
},
"POLineNbr": {
"value": 1
},
"POOrderNbr": {
"value": "005554"
},
"POOrderType": {
"value": "RO"
},
"ReceiptQty": {
"value": 5
},
"Warehouse": {
"value": "002"
}
}
],
"PostPeriod": {
"value": "032019"
},
"VendorID": {
"value": "CVS TRADE"
}
}
Update #3 3/24:
To try to get around Acumatica forcing ReceiptQty to 0, I tried adding a POReceiptLine_ReceiptQty_CacheAttached handler, without the PXDBQuantity, PXDefault, and PXFormula attributes to try to prevent it from getting zeroed out. That gives me a SQL error: "Incorrect syntax near 'INTranInTransit_INTransitLineStatus'" - whatever that means.
The logic there is that when you insert a Purchase Receipt detail line, if you specify the information about the Purchase order then the line will be added with a reference to original Purchase Order in the form of the PONbr and POType.
After the line is inserted the behavior through the web services is the same as the one on the screen, the PONbr and POType are read only field and cannot be modified.
During the insertion the parameter that are required to insert the Purchase Order Line properly are the PONbr, the POType and the POLineNbr.
Update
In certain case due to the complexity of an operation a special adapter was created in order to cover a specific scenario.
In this case the adding of a detail line to a purchase receipt is one of these scenarios.
So only some specific values are required and the rest will be taken from the record in the system.
I think in your case that since the Purchase Order Line is/are already present on another Purchase Receipt, they have a Open quantity of 0 which is then put as the value for the Receipt quantity. Unfortunately this then trigger an error since the receipt quantity in a purchase receipt cannot be 0.
Related
I've introduced a new DAC and a new field on the Sales Order associated to the new DAC key. When trying to retrieve the information through OpenAPI it comes back empty. I'd like to know why and how I can adjust my code to return the information. I've tried both PXSelect and PXSelectReadOnly
Declaring Statement on SOOrderEntry(extension):
public PXSelect<IOCSCompanyBrand, Where<IOCSCompanyBrand.companyBrandNbr,
Equal<Current<SOOrderExt.usrCompanyBrand>>>> CompanyBranding;
When I hit the URL: http://localhost/Acumatica21/entity/AcumaticaExtended21R1/20.200.001/SalesOrder?$select=OrderNbr,CompanyBranding,OrderType,CompanyBrand&$expand=CompanyBranding&$filter=OrderNbr%20eq%20'SO-030003'
This is the data that is returned:
[
{
"id": "f827cb43-9b8a-ec11-a481-747827c044c8",
"rowNumber": 1,
"note": {
"value": ""
},
"CompanyBrand": {
"value": "IO"
},
"CompanyBranding": null,
"OrderNbr": {
"value": "SO-030003"
},
"OrderType": {
"value": "SO"
},
"custom": {}
}
]
Acumatica Version: 21.205.0063
Here's the definition for SalesOrder in the endpoint (which was populated via the GUI)
I ended up opening a Acumatica Developer case and here is their response.
Hi Kyle,
Thanks for your time yesterday.
Endpoint mapping is valid but the fields in the view isn't fetch due the limitation of the filter parameter in the request. Filter parameter optimizes the data that are being fetch. In the case, the customer view isn't fetched. To workaround the limitation, instead of using filter, you can try something like below,
http://localhost/Acumatica/entity/AcumaticaExtended21R1/20.200.001/SalesOrder/SO/SO-030007?$expand=CompanyBranding
You can fetch the record and use expand to get the detail level fields. This way you can avoid the limitation of the filter.
Please check and let me know if you have any questions.
Regards,
Vignesh
Two Requirements are needed:
Get item path of the document in a BIM360 document management.
Get all custom attributes for that item.
For Req. 1, an api exists to fetch and for getting custom attributes, another api exists and data can be retrived.
Is there a way to get both the requirements in a single api call instead of using two.
In case of large number of records, api to retrieve item path is taking more than an hour for fetching 19000+ records and token gets expired though refesh token is used, while custom attribute api processes data in batches of 50, which completes it in 5 minutes only.
Please suggest.
Batch-Get Custom Attributes is for the additional attributes of Document Management specific. While path in project is a general information with Data Management.
The Data Management API provides some endpoints in a format of command, which can ask the backend to process the data for bunch of items.
https://forge.autodesk.com/en/docs/data/v2/reference/http/ListItems/
This command will retrieve metadata for up to 50 specified items one time. It also supports the flag includePathInProject, but the usage is tricky and API document does not indicate it. In the response, it will tell the pathInProject of these items. It may save more time than iteration.
{
"jsonapi": {
"version": "1.0"
},
"data": {
"type": "commands",
"attributes": {
"extension": {
"type": "commands:autodesk.core:ListItems",
"version": "1.0.0" ,
"data":{
"includePathInProject":true
}
}
},
"relationships": {
"resources": {
"data": [
{
"type": "items",
"id": "urn:adsk.wipprod:dm.lineage:vkLfPabPTealtEYoXU6m7w"
},
{
"type": "items",
"id": "urn:adsk.wipprod:dm.lineage:bcg7gqZ6RfG4BoipBe3VEQ"
}
]
}
}
}
}
Get item path of the document in a BIM360 document management.
Is this question about getting the hiarchy of the item? e.g. rootfolder>>subfolder>>item ? With the endpoint, by specifying the query param includePathInProject=true, it will return the relative path of the item (pathInProject) in the folder structure.
https://forge.autodesk.com/en/docs/data/v2/reference/http/projects-project_id-items-item_id-GET/
"data": {
"type": "items",
"id": "urn:adsk.wipprod:dm.lineage:xxx",
"attributes": {
"displayName": "my-issue-att.png",
"createTime": "2021-03-12T04:51:01.0000000Z",
"createUserId": "xxx",
"createUserName": "Xiaodong Liang",
"lastModifiedTime": "2021-03-12T04:51:02.0000000Z",
"lastModifiedUserId": "200902260532621",
"lastModifiedUserName": "Xiaodong Liang",
"hidden": false,
"reserved": false,
"extension": {
"type": "items:autodesk.bim360:File",
"version": "1.0",
"schema": {
"href": "https://developer.api.autodesk.com/schema/v1/versions/items:autodesk.bim360:File-1.0"
},
"data": {
"sourceFileName": "my-issue-att.png"
}
},
"pathInProject": "/Project Files"
}
or if you may iterate by the data of parent
"parent": {
"data": {
"type": "folders",
"id": "urn:adsk.wipprod:fs.folder:co.sdfedf8wef"
},
"links": {
"related": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.project.id.xyz/items/urn:adsk.wipprod:dm.lineage:hC6k4hndRWaeIVhIjvHu8w/parent"
}
}
},
Get all custom attributes for that item. For Req. 1, an api exists to fetch and for getting custom attributes, another api exists and data can be retrived. Is there a way to get both the requirements in a single api call instead of using two. In case of large number of records, api to retrieve item path is taking more than an hour for fetching 19000+ records and token gets expired though refesh token is used, while custom attribute api processes data in batches of 50, which completes it in 5 minutes only. Please suggest.*
Let me try to understand the question better. Firstly, two things: Custom Attributes Definitions, and Custom Attributes Values(with the documents). Could you clarify what are they with 19000+ records?
If Custom Attributes Definitions, the API to fetch them is
https://forge.autodesk.com/en/docs/bim360/v1/reference/http/document-management-custom-attribute-definitions-GET/
It supports to set limit of each call. i.e. the max limit of one call is 200, which means you can fetch 19000+ records by 95 times, while each time calling should be quick (with my experience < 10 seconds). Totally around 15 minutes, instead of more than 1 hour..
Or at your side, each call with 200 records will take much time?
If Custom Attributes Values, the API to fetch them is
https://forge.autodesk.com/en/docs/bim360/v1/reference/http/document-management-versionsbatch-get-POST/
as you know, 50 records each time. And it seems it is pretty quick at your side with 5 minutes only if fetch the values of 19000+ records?
In Acumatica REST API - StockItem
I am using the url https://sandbox.kimballinc.com/AcumaticaERP/entity/Default/18.200.001/StockItem?$filter=InventoryID eq '12345' & $expand=UOMConversions
In the response i am getting UOMConversions object as
"UOMConversions": [
{
"rowNumber": 1,
"note": null,
"ConversionFactor": {
"value": 1
},
"FromUOM": {
"value": "EACH"
},
"MultiplyDivide": {
"value": "Multiply"
},
"ToUOM": {
"value": "FOOT"
}
}
]
I want to know how ConversionFactor, FromUOM, MultiplyDivide, ToUOM is used and possible values for these fields.
can you please help me in understand these fields. Thanks
In order to find more information on that , I would recommend that you connect to the Acumatica site in the browser, Navigate to the Stock Item screen and go to the help page for that screen(Tools -> Help).
Once on the help screen, search for the "Unit Conversion Table" you will then find more information about these fields.
For the values that are available, I would recommend once again to go to the browser and the screen itself. Open the selector for the "From Unit" field and the drop-down for the "Multiply/Divid" field. The "Conversion" being just a decimal number and the "To Unit" being a read only field that take for value the base unit of the Stock Item.
I have an Excel sheet with a column containing IDs of items I want to retrieve
||ID||
|123|
|124|
|125|
The API I am calling can take an array of IDs as input (e.g. https://API.com/rest/items?ID=123&ID=124&ID=125....(up to 50))
and returns one JSON.
"data": [
{
"id": 123,
"fields": {
"name": "blah blah",
"description": "some description",
}
},
{
"id": 124,
"fields": {
"name": "blah bli",
"description": "some description",
}
},
{
"id": 125,
"fields": {
"name": "blah blo",
"description": "some description",
}
},...
]
}
I would like to load data from this JSON in another table or sheet.
||ID||Name||
|123|blah blah|
|124|blahblo|
|125|blahbli|
I would know how to parameterise the query by referencing single cells, but if I am retrieving 100+ items, that's a lot of work.
Can't I somehow build a query that gets each value (ID) from the table or range in one simple move?
--edit1--
Found another API endpoint where I can provide an array of IDs. (before I thought it was only possible to send one ID per request to retrieve one JSON at a time)
--edit2--
Maybe I can concatenate all IDs into the request URL already in an Excel cell and parameterise just based on that one cell. (still experimenting)
If you've got the JSON for each ID, then you just need to pull out the name part.
For example, if you have a column [JSON] with the JSON for each ID, then you can create a custom column using Json.Document([JSON])[data][name] as the formula.
You can likely combine pulling the JSON and parsing it into a single step if you'd like.
I'm trying to get a collection of list items from a SharePoint through Microsoft Graph, which I want to filter by CreatedBy.
Requesting: https://graph.microsoft.com/v1.0/sites/{siteid}/lists/TeamRequests/items
Returns:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('{url}')/lists('TeamRequests')/items",
"value": [
{
"#odata.etag": "\"56ad787e-bd69-464a-b5da-dd953e40d7c4,13\"",
"createdDateTime": "2018-02-26T08:34:26Z",
"eTag": "\"56ad787e-bd69-464a-b5da-dd953e40d7c4,13\"",
"id": "11",
"lastModifiedDateTime": "2018-03-22T13:20:03Z",
"webUrl": "{url}/Lists/TeamRequests/11_.000",
"createdBy": {
"user": {
"email": "{email}",
"id": "9c9cbb67-c049-4a2d-845d-6c5ca2300041",
"displayName": "{Name}"
}
},
"lastModifiedBy": {
"user": {
"email": "{email}",
"id": "9c9cbb67-c049-4a2d-845d-6c5ca2300041",
"displayName": "{Name}"
}
},
"parentReference": {},
"contentType": {
"id": "0x01005F15F8133495554D834FF82F187AD0630002133A9CCDE4494D8CB2206D7D6453D6"
}
},
Now I'd like to filter this request for createdBy, either Id, displayName or email address. I tried ?$filter=createdBy/user/email eq '{email}' and similar requests for id or displayName. They all return
{
"error": {
"code": "generalException",
"message": "An unspecified error has occurred.",
"innerError": {
"request-id": "492e3bde-05fe-4484-a475-435ff0aa70b6",
"date": "2018-07-23T07:41:46"
}
}
}
So how to accomplish this filter? Is it even supported?
Even though it sounds like a straightforward query, i have not come up to anything more simple then the following solution:
It seems filtering by user field is not supported except the case when user id is provided, that's the reason why the solution consists of two steps:
1) First, we need to determine user Id by Email , for that purpose the following query could be utilized:
https://graph.microsoft.com/v1.0/sites/root/lists('User Information List')/items?expand=fields(select=Id,Email)
*where User Information List system list stores user properties including Id and Email properties *
2) Once the user Id is resolved, the final query to filter items by user id could be applied:
https://graph.microsoft.com/v1.0/sites/{site-id}/lists('list-name')/items?filter=fields/<user-field-name>LookupId eq '<user-id>'
where
<user-field-name>LookupId is a field which is getting exposed in addition to user field, in case of Created field the name should be AuthorLookupId
Example:
https://graph.microsoft.com/v1.0/sites/root/lists('TeamRequests')/items?filter=fields/AuthorLookupId eq '10'
Note
In some cases the following error is returned Field ''
cannot be referenced in filter or orderby as it is not indexed.
Provide the 'Prefer: HonorNonIndexedQueriesWarningMayFailRandomly'
header to allow this, but be warned that such queries may fail on
large lists.
In that case the following request header needs to be applied:
Prefer: HonorNonIndexedQueriesWarningMayFailRandomly
When I tried to access User Information List list. There is an error with list not found.
So since in my case, first I filtered list data based on status value and next step got the logged in user display name and filtered listitems based on display name.
I'm using #pnp/graph
Filter list data with status filter
let resultsList = await listItemsQuery.filter("fields/RequestStatus eq 'Approval Pending'").expand("fields").get<MicrosoftGraph.ListItem[]>();
Get Logged-In Profile:
const profileQueryEndPoint = new GraphQueryableCollection(graph.me, "/");
Select displayName property from above result
let profileData : User = await profileQueryEndPoint.select("displayName").get <User>();
console.log('displayName : ' + profileData['displayName']);
Filter ListItems with createdby Field by passing profileData['displayName']
let filterUserCreatedRequests: MicrosoftGraph.ListItem[] = resultsList.filter(ListItem => ListItem["createdBy"].user.displayName === profileData['displayName']);
Display filtered results
console.log('filterUserCreatedRequests : ' + JSON.stringify(filterUserCreatedRequests));
I'm giving all the steps for your reference. But above code can simplified more.
Hope this helps someone :)