Related
I am trying to create a new array with children from my database result. I've tried something and actually it worked a bit but where am i missing, can you help me?
This is my data coming from database:
[
{
"nodeId": "1",
"label": "Applications"
},
{
"nodeId": "2",
"label": "Calendar",
"parentId": "1"
},
{
"nodeId": "3",
"label": "Documents"
},
{
"nodeId": "4",
"label": "OSS",
"parentId": "3"
},
{
"nodeId": "5",
"label": "MUI",
"parentId": "3"
},
{
"nodeId": "6",
"label": "index.js",
"parentId": "5"
}
]
And this is what i want to convert the data coming from database to:
[
{
"nodeId": "1",
"label": "Applications",
"children": [
{
"nodeId": "2",
"label": "Calendar"
}
]
},
{
"nodeId": "3",
"label": "Documents",
"children": [
{
"nodeId": "4",
"label": "OSS"
},
{
"nodeId": "5",
"label": "MUI",
"children": [
{
"nodeId": "6",
"label": "index.js"
}
]
}
]
}
]
I've tried this code below.
interface TreeData {
nodeId: string;
label: string;
parentId?: string;
}
interface RealTreeData {
nodeId: string;
label: string;
children?: RealTreeData[];
}
const treeData: TreeData[] = [
{
nodeId: '1',
label: 'Applications'
},
{
nodeId: '2',
label: 'Calendar',
parentId: '1'
},
{
nodeId: '3',
label: 'Documents'
},
{
nodeId: '4',
label: 'OSS',
parentId: '3'
},
{
nodeId: '5',
label: 'MUI',
parentId: '3'
},
{
nodeId: '6',
label: 'index.js',
parentId: '5'
}
];
function test(data: TreeData[]) {
const realData: RealTreeData[] = [];
const ignore: string[] = [];
for (const treeData of data) {
const children = data.filter(x => x.parentId === treeData.nodeId);
if (children.length) {
const childrenData = test(children);
for (const child of childrenData) {
ignore.push(child.nodeId);
}
realData.push({
label: treeData.label,
nodeId: treeData.nodeId,
children: childrenData
});
} else {
if (!ignore.includes(treeData.nodeId)) {
realData.push({
label: treeData.label,
nodeId: treeData.nodeId
});
}
}
}
return realData;
}
console.log(JSON.stringify(test(treeData), undefined, 4));
And I got this output:
[
{
"label": "Applications",
"nodeId": "1",
"children": [
{
"label": "Calendar",
"nodeId": "2"
}
]
},
{
"label": "Documents",
"nodeId": "3",
"children": [
{
"label": "OSS",
"nodeId": "4"
},
{
"label": "MUI",
"nodeId": "5"
}
]
},
{
"label": "MUI",
"nodeId": "5",
"children": [
{
"label": "index.js",
"nodeId": "6"
}
]
}
]
Mertcan Yüzer (from a discord server) found a solution. Thanks!
function test(treeItems: TreeData[]): RealTreeData[] {
const result: RealTreeData[] = [];
for (const item of treeItems) {
const newItem: RealTreeData = item;
if (!newItem.parentId) {
result.push(newItem);
}
const children = treeItems.filter(
treeItem => treeItem.parentId === newItem.nodeId
);
if (children.length) {
newItem.children = children;
}
delete newItem.parentId;
}
return result;
}
I’m sending a Sales Order with Pre-Authorized Payment thru REST API in Acumatica. This works perfect in my local Acumatica instance. However, I can’t get it worked when switching to Acumatica.com and I’m getting this error “The order cannot be applied, the specified combination of the order type and order number cannot be found in the system.”. It works well when I remove the payment details.
<pre><code>
{
"BillToAddress": {
"AddressLine1": {
"value": "3153 Doctors Drive"
},
"AddressLine2": {
"value": ""
},
"City": {
"value": "Los Angeles"
},
"Country": {
"value": "US"
},
"PostalCode": {
"value": "90017"
},
"State": {
"value": "CA"
},
"custom": {}
},
"BillToAddressOverride": {
"value": false
},
"BillToContact": {
"Attention": {
"value": "Mr."
},
"BusinessName": {
"value": "Gregory Luton"
},
"Email": {
"value": "gluton#hotmeal.com"
},
"Phone1": {
"value": "(310) 341-3975"
},
"custom": {}
},
"CreditHold": {
"value": false
},
"CustomerID": {
"value": "S000000001"
},
"CustomerOrder": {},
"Date": {
"value": "2021-06-02T13:42:02.22Z"
},
"Description": {
"value": ""
},
"Details": [
{
"ManualPrice": {
"value": true
},
"Amount": {
"value": 79.99
},
"DiscountAmount": {
"value": 0
},
"DiscountCode": {},
"DiscountPercent": {
"value": 0
},
"ExtendedPrice": {
"value": 79.99
},
"FreeItem": {
"value": false
},
"InventoryID": {
"value": "ELEHDD1"
},
"LineDescription": {
"value": "Lego 500 piece set"
},
"LineNbr": {
"value": 1
},
"ManualDiscount": {
"value": false
},
"OpenQty": {
"value": 1
},
"OrderQty": {
"value": 1
},
"RequestedOn": {
"value": "2021-06-02T13:42:02.22Z"
},
"Subitem": {
"value": ""
},
"UnbilledAmount": {
"value": 79.99
},
"UnitPrice": {
"value": 79.99
},
"UOM": {
"value": "EA"
},
"WarehouseID": {
"value": "WHOLESALE"
},
"rowNumber": 1,
"custom": {}
}
],
"Hold": {
"value": false
},
"OrderedQty": {
"value": 1
},
"OrderTotal": {
"value": 79.99
},
"OrderType": {
"value": "SO"
},
"Payments": [
{
"CardAccountNbr": {
"value": "CUSTOMPAYMC:S000000001"
},
"CashAccount": {
"value": "10600"
},
"CreditCardTransactionInfo": [
{
"AuthNbr": {
"value": "23456"
},
"NeedValidation": {
"value": false
},
"TranDate": {
"value": "2021-06-02T16:13:01.22Z"
},
"TranNbr": {
"value": "12345"
},
"TranType": {
"value": "Authorize Only"
},
"custom": {}
}
],
"Description": {
"value": "Payment for 006024"
},
"PaymentAmount": {
"value": 79.99
},
"PaymentMethod": {
"value": "CUSTOMPAYMC"
},
"ProcessingCenterID": {
"value": "CUSTOMPAY"
},
"Status": {
"value": "Pre-Authorized"
},
"custom": {}
}
],
"RequestedOn": {
"value": "2021-06-02T13:42:02.22Z"
},
"ShipToAddress": {
"AddressLine1": {},
"AddressLine2": {},
"City": {},
"Country": {},
"PostalCode": {},
"State": {},
"custom": {}
},
"ShipToAddressOverride": {
"value": false
},
"ShipToContact": {
"Attention": {},
"BusinessName": {},
"Email": {},
"Phone1": {},
"custom": {}
},
"ShipVia": {
"value": ""
},
"Status": {},
"TaxTotal": {
"value": 0
},
"Totals": {
"FreightCost": {
"value": 0
},
"DiscountTotal": {
"value": 0
},
"LineTotalAmount": {
"value": 79.99
},
"custom": {}
},
"custom": {
"Document": {
"AttributeAMT": {
"value": "79.99",
"type": "CustomStringField"
},
"AttributeAUTHID": {
"value": "23456",
"type": "CustomStringField"
},
"AttributeCUR": {
"value": "USD",
"type": "CustomStringField"
},
"AttributeDT": {
"value": "6/2/2021 4:13:01 PM",
"type": "CustomStringField"
},
"AttributeEXPDATE": {
"value": "2025-05",
"type": "CustomStringField"
},
"AttributeRC": {
"value": "0",
"type": "CustomStringField"
},
"AttributeTOKEN": {
"value": "Gmg9niiBqh8B8FXH",
"type": "CustomStringField"
},
"AttributeTRANID": {
"value": "12345",
"type": "CustomStringField"
},
"AttributeCID": {
"value": "B",
"type": "CustomStringField"
},
"AttributeSTATUS": {
"value": "Pending",
"type": "CustomStringField"
}
}
}
}
</code></pre>
public async Task Upsert(BusinessModel.Order
order)
{
// Map BusinessModel to DTO
var request = _mapper.Map(order);
//Add Payment record
DataModel.SalesOrderPayment payment = new
DataModel.SalesOrderPayment();
payment.Description = new StringValue { Value =
string.Format("Payment for {0}", order.OrderNumber)};
payment.PaymentMethod = new StringValue { Value =
"CUSTOMPAYMC" };
payment.CardAccountNbr = new StringValue { Value =
string.Concat(order.PaymentDetails.CardID) };
payment.CashAccount = new StringValue { Value = "10600" };
payment.ProcessingCenterID = new StringValue { Value =
"CUSTOMPAY"};
payment.Hold = new BooleanValue { Value = false };
payment.PaymentAmount = new DecimalValue { Value =
order.Header.TotalAmount };
payment.AppliedToOrder = new DecimalValue { Value =
order.Header.TotalAmount };
payment.Custom = new Dictionary>();
payment.Status = new StringValue { Value = "Pre-Authorized"
};
DataModel.SalesOrderCreditCardTransactionDetail detail = new
DataModel.SalesOrderCreditCardTransactionDetail();
detail.AuthNbr = new StringValue { Value =
order.PaymentDetails.AuthorizationNumber };
detail.NeedValidation = new BooleanValue { Value = false };
detail.TranDate = new DateTimeValue { Value =
order.PaymentDetails.AuthorizationDateTime };
detail.TranNbr = new StringValue { Value =
order.PaymentDetails.TransactionID };
detail.TranType = new StringValue { Value = "Authorize Only"
};
detail.Custom = new Dictionary>();
payment.CreditCardTransactionInfo = new
List();
//payment.CreditCardTransactionInfo.Add(detail);
request.Payments = new List();
request.Payments.Add(payment);
// Invoke API
SalesOrder salesOrderResponse = await
api.PutEntityAsync(request, null, null, null, null));
// Map response DTO to BusinessModel
var response = _mapper.Map
(salesOrderResponse);
return Ok(response);
}
Here is the data representation in mongodb :
{
"_id": {
"$oid": "60754054fa887e14c4569a94"
},
"details": [{
"label": "Asset title",
"type": "text",
"id": "text-1617189723969",
"value": "S1",
"rawValue": "S1"
}, {
"label": "Total Cost",
"type": "number",
"id": "number-1618296818377",
"value": "1500",
"rawValue": "1500"
}, {
"label": "Possession Status",
"type": "radio",
"id": "radio-1617189728809",
"value": "Available",
"rawValue": "available"
}, {
"label": "Estimated Monthly Rent",
"type": "number",
"id": "number-1617189737553",
"value": "200",
"rawValue": "200"
}],
"status": "Approved",
"createdAt": {
"$date": "2021-04-13T06:55:16.843Z"
},
"__v": 0
},
{
"_id": {
"$oid": "60756c279cdd25019c6c3707"
},
"details": [{
"label": "Asset title",
"type": "text",
"id": "text-1617189723969",
"value": "S2",
"rawValue": "S2"
}, {
"label": "Total Cost",
"type": "number",
"id": "number-1618296818377",
"value": "280",
"rawValue": "280"
}, {
"label": "Possession Status",
"type": "radio",
"id": "radio-1617189728809",
"value": "Available",
"rawValue": "available"
}, {
"label": "Estimated Monthly Rent",
"type": "number",
"id": "number-1617189737553",
"value": "500",
"rawValue": "500"
}],
"status": "Approved",
"createdAt": {
"$date": "2021-04-13T10:02:15.701Z"
},
"__v": 0
},
{
"_id": {
"$oid": "60756d33af10052394f24e5c"
},
"details": [{
"label": "Asset title",
"type": "text",
"id": "text-1617189723969",
"value": "S3",
"rawValue": "S3"
}, {
"label": "Total Cost",
"type": "number",
"id": "number-1618296818377",
"value": "100",
"rawValue": "100"
}, {
"label": "Possession Status",
"type": "radio",
"id": "radio-1617189728809",
"value": "Available",
"rawValue": "available"
}, {
"label": "Estimated Monthly Rent",
"type": "number",
"id": "number-1617189737553",
"value": "300",
"rawValue": "300"
}],
"status": "Approved",
"createdAt": {
"$date": "2021-04-13T10:06:43.560Z"
},
"__v": 0
}
For example : I am trying to sort the documents where I have to pick the value of that object from details array whose label is "Total Cost" and apply sorting based on "Total cost" value.
MY CODE IMPLEMENTATION :
assetCtrl.getApprovedAsset = async (req, res) => {
try {
let { sorting, sortingtype } = req.query;
let perPage = Number(req.query.perpage ? req.query.perpage : 0);
let page = Number(req.query.page ? req.query.page : 0);
if (typeof perPage !== 'undefined' && perPage !== '' && perPage > 0 &&
typeof page !== 'undefined' && page !== '' && page > 0) {
let skippage = (perPage * page) - perPage;
let filter = {
status: "Approved",
}
let sortObj = {}
let sorttype = (sortingtype === 'asc') ? 1 : -1;
if (sorting !== '') {
switch (sorting) {
case 'cost' :
sortObj.details.value = sorttype;
break;
case 'monthly_rent' :
sortObj.details.value = sorttype;
break;
case 'createdAt':
sortObj.createdAt = sorttype;
break;
}
} else {
sortObj.details.value = 1;
}
AddAssets.aggregate([
{
"$project": {
createdAt: 1,
userid: 1,
details: 1,
status: 1
}
},
{
"$match": filter
},
// {
// "$match": {
// details: {
// "$elemMatch": {
// label: "Total Cost"
// }
// }
// }
// },
// ]).sort({ "details.value": 1 }).skip(skippage).limit(perPage)
]).sort({ sortObj}).skip(skippage).limit(perPage)
.exec((err, assetList) => {
if (err) {
res.status(400).json({ status: false, message: err.message })
} else {
res.status(200).json({
status: true,
message: "success",
assetList: assetList,
current: page,
})
}
})
}
} catch (error) {
res.status(500).json({ status: false, message: "Internal Server Error" })
}
}
Note: I also tried excluding sortObj and implemented commented code .
Use $set with https://docs.mongodb.com/manual/reference/operator/aggregation/filter/ to reduce the array to the single document with the total cost field, then $sort on this field.
I have a collection with the following data:
{ "id": 1,
"name": "abc",
"age" : "12"
"quizzes": [
{
"id": "1",
"time": "10"
},
{
"id": "2",
"time": "20"
}
]
},
{ "id": 2,
"name": "efg",
"age" : "20"
"quizzes": [
{
"id": "3",
"time": "11"
},
{
"id": "4",
"time": "25"
}
]
},
...
I would like to perform the MongoDB Aggregation for a sum of quizzes for each document.and set it to totalTimes field
And this is the result that I would like to get after the querying:
{ "id": 1,
"name": "abc",
"age" : "12",
"totalTimes": "30"
"quizzes": [
{
"id": "1",
"time": "10"
},
{
"id": "2",
"time": "20"
}
]
},
{ "id": 2,
"name": "efg",
"age" : "20",
"totalTimes": "36"
"quizzes": [
{
"id": "3",
"time": "11"
},
{
"id": "4",
"time": "25"
}
]
},
...
How can I query to get the sum of quizzes time?
Quite simple using $reduce
db.collection.aggregate([
{
$addFields: {
totalTimes: {
$reduce: {
input: "$quizzes",
initialValue: 0,
in: {
$sum: [
{
$toInt: "$$this.time"
},
"$$value"
]
}
}
}
}
}
])
Mongo Playground
The problem: I have 2 identical in terms of settings and mappings indexes.
The first index contains only 1 document.
The second index contains the same document + 16M of others.
When I'm running the query on the first index it returns the document, but when I do the same query on the second — I receive nothing.
Indexes settings:
{
"tasks_test": {
"settings": {
"index": {
"analysis": {
"analyzer": {
"tag_analyzer": {
"filter": [
"lowercase",
"tag_filter"
],
"tokenizer": "whitespace",
"type": "custom"
}
},
"filter": {
"tag_filter": {
"type": "word_delimiter",
"type_table": "# => ALPHA"
}
}
},
"creation_date": "1444127141035",
"number_of_replicas": "2",
"number_of_shards": "5",
"uuid": "wTe6WVtLRTq0XwmaLb7BLg",
"version": {
"created": "1050199"
}
}
}
}
}
Mappings:
{
"tasks_test": {
"mappings": {
"Task": {
"dynamic": "false",
"properties": {
"format": "dateOptionalTime",
"include_in_all": false,
"type": "date"
},
"is_private": {
"type": "boolean"
},
"last_timestamp": {
"type": "integer"
},
"name": {
"analyzer": "tag_analyzer",
"type": "string"
},
"project_id": {
"include_in_all": false,
"type": "integer"
},
"user_id": {
"include_in_all": false,
"type": "integer"
}
}
}
}
}
The document:
{
"_index": "tasks_test",
"_type": "Task",
"_id": "1",
"_source": {
"is_private": false,
"name": "135548- test with number",
"project_id": 2,
"user_id": 1
}
}
The query:
{
"query": {
"filtered": {
"query": {
"bool": {
"must": [
[
{
"match": {
"_all": {
"query": "135548",
"type": "phrase_prefix"
}
}
}
]
]
}
},
"filter": {
"bool": {
"must": [
{
"term": {
"is_private": false
}
},
{
"terms": {
"project_id": [
2
]
}
},
{
"terms": {
"user_id": [
1
]
}
}
]
}
}
}
}
}
Also, some findings:
if I replace _all with name everything works
if I replace match_phrase_prefix with match_phrase works too
ES version: 1.5.1
So, the question is: how to make the query work for the second index without mentioned hacks?