Acumatica Rest API to get sales order with line item detail - rest

I was doing a demo and could easily create and retrieve orders but was not able to get the expand parameter to work
For example
I created order SO003615 with:
URI http://localhost/Acumatica6/entity/Default/6.00.001/SalesOrder
{
"OrderType": { value: "SO" },
"CustomerID" : { value : "ACTIVESTAF" } ,
"LocationID" : { value : "MAIN" },
"Description" : { value : "Sample Order"},
"Details" :
[
{
"InventoryID" : {value: "AACOMPUT01"},
"Quantity" : {value: 2},
"UOM" : {value: "EA"},
"UnitPrice" : {value: 1000.99}
},
{
"InventoryID" : {value: "AALEGO500"},
"Quantity" : {value: 1}
}
]
}
Then I tried to get order with
URI http://localhost/Acumatica6/entity/Default/6.00.001/SalesOrder/SO/SO003615?expand=Details
But the line items are not in the result. What am I missing?
{
"id": "37c15980-f71d-4496-882d-6e05e4a50061",
"rowNumber": 1,
"note": "",
"BillingAddressOverride": {
"value": false
},
"BillingContactOverride": {
"value": false
},
"CreditHold": {
"value": false
},
"Currency": {
"value": "USD"
},
"CustomerID": {
"value": "ACTIVESTAF"
},
"CustomerOrder": {},
"Date": {
"value": "2017-03-16T00:00:00-04:00"
},
"Description": {
"value": "Sample Order 6"
},
"DestinationWarehouseID": {},
"ExternalReference": {},
"Hold": {
"value": false
},
"IsTaxValid": {
"value": false
},
"LastModified": {
"value": "2017-03-17T01:05:56.74-04:00"
},
"LocationID": {
"value": "MAIN"
},
"NewCard": {
"value": false
},
"OrderedQty": {
"value": 3
},
"OrderNbr": {
"value": "SO003615"
},
"OrderTotal": {
"value": 2101.98
},
"OrderType": {
"value": "SO"
},
"PaymentCardIdentifier": {},
"PaymentMethod": {
"value": "CHECK"
},
"PaymentRef": {},
"PreferredWarehouseID": {},
"Project": {
"value": "X"
},
"RequestedOn": {
"value": "2017-03-16T00:00:00-04:00"
},
"ShippingAddressOverride": {
"value": false
},
"ShippingContactOverride": {
"value": false
},
"ShipVia": {},
"Status": {
"value": "Open"
},
"TaxTotal": {
"value": 0
},
"custom": {},
"files": []
}

It is $expand, not expand. Try using the following
http://localhost/Acumatica6/entity/Default/6.00.001/SalesOrder/SO/003615?$expand=Details

Related

Updating array list in Mongo DB

I want to update the Status field inside array list of Slots where id = "".
Sample data
{
"_id": ObjectId("621e816e7a938400016c5c64"),
"Resource": "abc#gmail.com",
"School": {
"Class": [
{
"Type": "ABC",
"Slots": [
{
"id": "",
"Duration": "1 week",
"Status": "Released",
"Selected": true
},
{
"id": "123",
"Duration": "1 week",
"Status": "Released",
"Selected": true
}
]
}
]
}
}
This is how I am approaching:
db.getCollection("XYZ").update({
"Resource": "abc#gmail.com",
"School.Class": {
"$elemMatch": {
"Type": "ABC",
"Slots.Status": "Released",
"Slots.id": "",
"Slots.Duration": "1 week"
}
}
},
{
$set: {
"School.Class.$[outer].Slots.$[inner].Status": "Confirmed"
}
},
{
"arrayFilters": [
{
"outer.Type": "ABC"
},
{
"inner.Duration": "1 week"
}
]
})
But it is updating the status as confirmed for the both the array list.How can I update the particular field where "Slots.id" : "" . Please forgive me in case of any misalignment or brackets missing in data
If I've understood correctly you are almost there, since you want to update only values where id is "" you have to add that condition into arrayFilters: "inner.id": "".
db.collection.update({
"Resource": "abc#gmail.com",
"School.Class": {
"$elemMatch": {
"Type": "ABC",
"Slots.Status": "Released",
"Slots.id": "",
"Slots.Duration": "1 week"
}
}
},
{
$set: {
"School.Class.$[outer].Slots.$[inner].Status": "Confirmed"
}
},
{
"arrayFilters": [
{
"outer.Type": "ABC"
},
{
"inner.Duration": "1 week",
"inner.id": "" // <--- This line
}
]
})
Example here

How to sum values using unwind in MongoDB with Spring Data

When using unwind("items") each item produces a duplicate line. This leads to revenue being counted as many times as there are items.
Example: Someone buys 1 item of A and 1 item of B, resulting in a cummulative value of 10. Unwind now inserts a row for each item, leading to a sum(cummulative) of 20.
I tried grouping the elements directly after unwind but have not managed to get it to work properly.
How can I sum each array element without duplication every other value?
I have this data structure
{
"_id": {
"$binary": "VEE6CsjHPvjzS2JYso7mnQ==",
"$type": "3"
},
"sequentialId": {
"$numberLong": "1"
},
"date": "2022-02-04",
"invoiceTotal": {
"$numberDecimal": "9.85"
},
"vatTotal": {
"$numberDecimal": "0"
},
"vatPercentage": {
"$numberDecimal": "19.00"
},
"invoiceNumber": "1111111",
"type": "ELEKTRONISCH",
"aktivkonto": 2800,
"passivkonto": 5200,
"buyerEmail": "",
"username": "",
"shop": "",
"externalId": "",
"shipped": false,
"actualShippingCost": {
"$numberDecimal": "1"
},
"filename": "",
"isReported": false,
"deliveryCostTotal": {
"$numberDecimal": "4.35"
},
"items": [
{
"lineItemId": "",
"amount": "1",
"sku": "A123123",
"title": "",
"priceTotal": {
"$numberDecimal": "4.50"
},
"vatTotal": {
"$numberDecimal": "0"
},
"hardwareCostPerPiece": {
"$numberDecimal": "0.22"
},
"hardwareCostTotal": {
"$numberDecimal": "0.22"
}
},
{
"lineItemId": "",
"amount": "1",
"sku": "B212312",
"title": "",
"priceTotal": {
"$numberDecimal": "1.00"
},
"vatTotal": {
"$numberDecimal": "0"
},
"hardwareCostPerPiece": {
"$numberDecimal": "0.22"
},
"hardwareCostTotal": {
"$numberDecimal": "0.22"
}
}
],
"packagingCost": {
"$numberDecimal": "0.15"
},
"hasInvoiceSent": false,
"tenant": "you!",
"createdAt": {
"$date": "2022-02-04T15:23:40.716Z"
},
"modifiedAt": {
"$date": "2022-02-04T15:23:40.716Z"
},
"_class": "_.RevenueEntity"
}
and this query
fun sumAllByWeeklyAndTenant(tenant: String): Flux<DashboardRevenue> {
val aggregation = newAggregation(
match(findByTenant(tenant)),
unwind("items"),
group("invoiceNumber")
.sum("items.hardwareCostTotal").`as`("hardwareCostTotal"),
project()
.andExpression("year(createdAt)").`as`("year")
.andExpression("week(createdAt)").`as`("week")
.andInclude(bind("hardwareCostTotal", "items.hardwareCostTotal"))
.andInclude(
"invoiceTotal",
"vatTotal",
"actualShippingCost",
"packagingCost",
"marketplaceFeesTotal",
"tenant"
),
group("year", "week", "tenant")
.sum("invoiceTotal").`as`("umsatz")
.sum("actualShippingCost").`as`("portokosten")
.sum("packagingCost").`as`("verpackung")
.sum("marketplaceFeesTotal").`as`("marketplaceFees")
.sum("hardwareCostTotal").`as`("hardwareCost")
.sum("vatTotal").`as`("vatTotal")
.count().`as`("numberOfInvoices"),
sort(Sort.Direction.DESC, "year", "week"),
limit(8),
sort(Sort.Direction.ASC, "year", "week")
)
return reactiveMongoTemplate
.aggregate(aggregation, "revenue", DashboardRevenue::class.java)
.toFlux()
}
Using the data above the query results in
[
{
"_id": {
"year": 2022,
"month": 2,
"week": 0,
"tenant": "einsupershop"
},
"umsatz": 19.70,
"portokosten": 2,
"verpackung": 0.30,
"marketplaceFees": 3.42,
"hardwareCost": 0.22,
"vatTotal": 0,
"numberOfInvoices": 2
}
]
Where the expected value is "invoiceTotal": { "$numberDecimal": "9.85" }

Is it possible to filter a MongoDB on the value of a field whose value is a list of dictionaries?

I want to know if it is possible to get all the documents from a MongoDB database by querying on the elements of a field whose value is a list. For example here q2.Results has a list of comments and I would like to get all the documents where the UserNickname of the person who wrote the comment is Jackobear :
{
"_id": {
"$oid": "5fd5e617260828c7646000aa"
},
"q2": {
"Id": "q2",
"Locale": "fr_FR",
"Results": [
{
"Id": "163069310",
"CID": "eb523c23-980d-5661-b9d0-c6dc1028fa42",
"SourceClient": "sephora-fr",
"Badges": {
"loyaltyYes--Im-a-VIB-Rouge": {
"ContentType": "REVIEW",
"Id": "loyaltyYes--Im-a-VIB-Rouge",
"BadgeType": "Custom"
}
},
"BadgesOrder": [
"loyaltyYes--Im-a-VIB-Rouge"
],
"LastModeratedTime": "2020-09-22T12:00:18.000+00:00",
"LastModificationTime": "2020-12-10T14:36:16.000+00:00",
"ProductId": "P3742199",
"CampaignId": "BV_PIE_ONLINE",
"ContextDataValuesOrder": [
"Gender",
"Eyes",
"Skin"
],
"UserLocation": "Paris",
"AuthorId": "78948942",
"ContentLocale": "fr_FR",
"IsFeatured": false,
"TotalInappropriateFeedbackCount": {
"$numberInt": "0"
},
"TotalClientResponseCount": {
"$numberInt": "0"
},
"TotalCommentCount": {
"$numberInt": "0"
},
"Rating": {
"$numberInt": "5"
},
"IsRatingsOnly": false,
"IsRecommended": true,
"Helpfulness": {
"$numberDouble": "1.0"
},
"TotalFeedbackCount": {
"$numberInt": "2"
},
"TotalNegativeFeedbackCount": {
"$numberInt": "0"
},
"TotalPositiveFeedbackCount": {
"$numberInt": "2"
},
"ModerationStatus": "APPROVED",
"SubmissionId": "r23232-fr__16007743UA3Zr3O9L5",
"SubmissionTime": "2020-09-22T11:32:57.000+00:00",
"ReviewText": "J’adore, il sent le bord de mer une ressemblance avec le parfum Kenzo",
"Title": "Très bon parfum",
"UserNickname": "Jackobear",
"ContextDataValues": {
"Gender": {
"Value": "Male",
"Id": "Gender"
},
"Skin": {
"Value": "Normale",
"Id": "Skin"
},
"Eyes": {
"Value": "Marrons",
"Id": "Eyes"
}
},
"Videos": [],
"Pros": null,
"InappropriateFeedbackList": [],
"SecondaryRatings": {},
"ClientResponses": [],
"Photos": [],
"Cons": null,
"IsSyndicated": false,
"SecondaryRatingsOrder": [],
"AdditionalFields": {},
"RatingRange": {
"$numberInt": "5"
},
"TagDimensions": {},
"AdditionalFieldsOrder": [],
"ProductRecommendationIds": [],
"CommentIds": [],
"TagDimensionsOrder": []
},
{
"Id": "129228166",
"CID": "66aec0c2-04b0-57d2-aa9f-ac3b7ecb91df",
"SourceClient": "sephora-fr",
"Badges": {
"loyaltyYes--Im-a-beauty-insider": {
"ContentType": "REVIEW",
"Id": "loyaltyYes--Im-a-beauty-insider",
"BadgeType": "Custom"
}
},
"BadgesOrder": [
"loyaltyYes--Im-a-beauty-insider"
],
"LastModeratedTime": "2019-06-12T00:15:07.000+00:00",
"LastModificationTime": "2020-02-07T10:11:38.000+00:00",
"ProductId": "P3742199",
"CampaignId": "BV_REVIEW_DISPLAY",
"ContextDataValuesOrder": [
"Gender",
"Age",
"Eyes",
"Skin"
],
"UserLocation": "Bayeux",
"AuthorId": "78051240",
"ContentLocale": "fr_FR",
"IsFeatured": false,
"InappropriateFeedbackList": [
{
"AuthorId": "ztn5x2jvnf5u8llq2jagt7j4mp",
"SubmissionTime": "2019-06-11T23:12:44.000+00:00"
},
{
"AuthorId": "zpebdw7hh48w5zpr3778nx2hgg",
"SubmissionTime": "2019-06-06T23:20:57.000+00:00"
},
{
"AuthorId": "zkvy1qeaaz8s2znk6kesfg3dnb",
"SubmissionTime": "2019-06-03T20:01:34.000+00:00"
}
],
"TotalInappropriateFeedbackCount": {
"$numberInt": "3"
},
"TotalClientResponseCount": {
"$numberInt": "0"
},
"TotalCommentCount": {
"$numberInt": "0"
},
"Rating": {
"$numberInt": "5"
},
"IsRatingsOnly": false,
"IsRecommended": true,
"Helpfulness": {
"$numberDouble": "0.8999999761581421"
},
"TotalFeedbackCount": {
"$numberInt": "40"
},
"TotalNegativeFeedbackCount": {
"$numberInt": "4"
},
"TotalPositiveFeedbackCount": {
"$numberInt": "36"
},
"ModerationStatus": "APPROVED",
"SubmissionId": "halilss25hcanccb0yj6nxvpk",
"SubmissionTime": "2019-06-03T11:43:04.000+00:00",
"ReviewText": "Un parfum enivrant mais pas entêtant, la note de tête est exquise et très fraîche, parfaite pour l'été. Vous devriez vendre ce parfum dans plus de sephora et avec plus de stock!!",
"Title": "Parfait pour l'été",
"UserNickname": "Abraxas",
"ContextDataValues": {
"Age": {
"Value": "18to24",
"Id": "Age"
},
"Gender": {
"Value": "Female",
"Id": "Gender"
},
"Skin": {
"Value": "Grasse",
"Id": "Skin"
},
"Eyes": {
"Value": "Bleus",
"Id": "Eyes"
}
},
"Videos": [],
"Pros": null,
"SecondaryRatings": {},
"ClientResponses": [],
"Photos": [],
"Cons": null,
"IsSyndicated": false,
"SecondaryRatingsOrder": [],
"AdditionalFields": {},
"RatingRange": {
"$numberInt": "5"
},
"TagDimensions": {},
"AdditionalFieldsOrder": [],
"ProductRecommendationIds": [],
"CommentIds": [],
"TagDimensionsOrder": []
}
],
"HasErrors": false,
"Errors": []
},
"name": "L'Atelier des Subtils Eau d'Océan - Eau de toilette",
}
I was thinking of a cause like doing a find_all with:
users = ['Jackobear']
collection.findall({'q2.Results.x.UserNickname' : {'$in': users}})
If it is not possible, I suppose I have to make a new database with the perfumes appreciated by each person? How can I make the script that could retrieve this information from the database by searching these documents for each user?
$match to filter the records 1st so that $unwind will have fewer records to deal with.
$unwind to break into individual documents.
Now perform match on individual documents.
You can use $group to group documents.
db.collection.aggregate([
{ $match: { "q2.Results.UserNickname": { $in: [ "Jackobear", "ABC" ] } } },
{ $unwind: "$q2.Results" },
{ $match: { "q2.Results.UserNickname": { $in: [ "Jackobear", "ABC" ] } } }
])
Demo - https://mongoplayground.net/p/g04J8f4-TjY

Querying a map (<String, Object>) in JSON through MongoDB

How to query a map of type Map<String, List> in JSON form, in MongoDB?
Sample JSON:
{
"WIDTH": 810,
"HEIGHT": 465,
"MODULES": {
"23": {
"XNAME": "COMP1",
"PARAMS": {
"_Klockers": {
"TYPE": "text",
"VALUE": "Klocker#3"
},
"SUBSYS": {
"TYPE": "text",
"VALUE": "2"
},
"EP": {
"TYPE": "integer",
"VALUE": "2"
}
}
},
"24": {
"XNAME": "COMP2",
"PARAMS": {
"_Rockers": {
"TYPE": "text",
"VALUE": "Rocker#3"
},
"Driver": {
"TYPE": "binary",
"VALUE": 1
},
"EP": {
"TYPE": "long",
"VALUE": "233"
}
}
},
"25": {
"XNAME": "COMP3",
"PARAMS": {
"_Mockers": {
"TYPE": "text",
"VALUE": "Mocker#3"
},
"SYSMain": {
"TYPE": "text",
"VALUE": "2342"
},
"TLP": {
"TYPE": "double",
"VALUE": "2.3"
}
}
}
}
}
Basically I want to :
List all the "XNAME" field values of all keys in "MODULES".
Expected output : {"COMP1", "COMP2", "COMP3"}
List all the "TYPE" in "PARAMS" object within each key of "MODULES".
Expected output : {"text", "text", "integer", "text", "binary", "long", "text", "text", "double"}
I am new to MongoDB and any help or redirection is appreciated.
You can use this
db.collection.aggregate([
{
$project: {//You require this as your data is dynamic
"modules": {
"$objectToArray": "$MODULES"
}
}
},
{//Destruct the array
"$unwind": "$modules"
},
{
"$project": {//Again, requires the same as keys are dynamic
"types": {
"$objectToArray": "$modules.v.PARAMS"
},
xname: "$modules.v.XNAME"
}
},
{//Destruct the types
$unwind: "$types"
},
{//Get the distinct values
$group: {
"_id": null,
"xname": {
"$addToSet": "$xname"
},
"types": {
"$addToSet": "$types.v.TYPE"
},
}
}
])

Mongo Aggregation using $Max

I have a collection that stores history, i.e. a new document is created every time a change is made to the data, I need to extract fields based on the max value of a date field, however my query keeps returning either all of the dates or requires me to push the fields into an array which make the data hard to analyze for an end-user.
Expected output as CSV:
MAX(DATE), docID, url, type
1579719200216, 12371, www.foodnetwork.com, food
1579719200216, 12371, www.cnn.com, news,
1579719200216, 12371, www.wikipedia.com, info
Sample Doc:
{
"document": {
"revenueGroup": "fn",
"metaDescription": "",
"metaData": {
"audit": {
"lastModified": 1312414124,
"clientId": ""
},
"entities": [],
"docId": 1313943,
"url": ""
},
"rootUrl": "",
"taggedImages": {
"totalSize": 1,
"list": [
{
"image": {
"objectId": "woman-reaching-for-basket",
"caption": "",
"url": "",
"height": 3840,
"width": 5760,
"owner": "Facebook",
"alt": "Woman reaching for basket"
},
"tags": {
"totalSize": 4,
"list": []
}
}
]
},
"title": "The 8 Best Food Items of 2020",
"socialTitle": "The 8 Best Food Items of 2020",
"primaryImage": {
"objectId": "woman-reaching-for-basket.jpg",
"caption": "",
"url": "",
"height": 3840,
"width": 5760,
"owner": "Hero Images / Getty Images",
"alt": "Woman reaching for basket in laundry room"
},
"subheading": "Reduce your footprint with these top-performing diets",
"citations": {
"list": []
},
"docId": 1313943,
"revisionId": "1313943_1579719200216",
"templateType": "LIST",
"documentState": {
"activeDate": 579719200166,
"state": "ACTIVE"
}
},
"url": "",
"items": {
"totalSize": "",
"list": [
{
"type": "recipe",
"data": {
"comInfo": {
"list": [
{
"type": "food",
"id": "https://www.foodnetwork.com"
}
]
},
"type": ""
},
"id": 4,
"uuid": "1313ida-qdad3-42c3-b41d-223q2eq2j"
},
{
"type": "recipe",
"data": {
"comInfo": {
"list": [
{
"type": "news",
"id": "https://www.cnn.com"
},
{
"type": "info",
"id": "https://www.wikipedia.com"
}
]
},
"type": "PRODUCT"
},
"id": 11,
"uuid": "318231jc-da12-4475-8994-283u130d32"
}
]
},
"vertical": "food"
}
Below query:
db.collection.aggregate([
{
$match: {
vertical: "food",
"document.documentState.state": "ACTIVE",
"document.templateType": "LIST"
}
},
{
$unwind: "$document.items"
},
{
$unwind: "$document.items.list"
},
{
$unwind: "$document.items.list.contents"
},
{
$unwind: "$document.items.list.contents.list"
},
{
$match: {
"document.items.list.contents.list.type": "recipe",
"document.revenueGroup": "fn"
}
},
{
$sort: {
"document.revisionId": -1
}
},
{
$group: {
_id: {
_id: {
docId: "$document.docId",
date: {$max: "$document.revisionId"}
},
url: "$document.items.list.contents.list.data.comInfo.list.id",
type: "$document.items.list.contents.list.data.comInfo.list.type"
}
}
},
{
$project: {
_id: 1
}
},
{
$sort: {
"document.items.list.contents.list.id": 1, "document.revisionId": -1
}
}
], {
allowDiskUse: true
})
First of all, you need to go through the documentation of the $group aggregation here.
you should be doing this instead:
{
$group: {
"_id": "$document.docId"
"date": {
$max: "$document.revisionId"
},
"url": {
$first: "$document.items.list.contents.list.data.comInfo.list.id"
},
"type": {
$first:"$document.items.list.contents.list.data.comInfo.list.type"
}
}
}
This will give you the required output.