Building velo query function to sum total values from multiple datasets - javascript

Thank you for looking at thus question. It's driving me crazy.
I have 2 databases with various fields which are:
dataset = projectproducts
field ID = product // matching ID in products dataset
field ID = productQuantity // returns number
dataset = products
field ID = _id // matching product field value in projectproducts
field ID = productPrice // returns number
I am trying to query the projectproducts dataset and retrieve the items from the product field (several hundred of them) and the quantity from the productQuantity field.
Then based on the product field (which is the ID of the item/row in the products dataset) query the products dataset and retrieve the result from productPrice field.
Then I'd like to multiply the
productQuantity result x productPrice result
and add all the values together to retrieve a final amount.

I'm not sure about how it's different when datasets are involved but here is an approach which uses wixData directly
import wixData from 'wix-data';
$w.onReady(async function () {
const {items: projectproducts} = await wixData.query('projectproducts').find();
const projectproductsQuery = wixData.query('products');
projectproducts.forEach(pp => {
projectproductsQuery.eq('_id', pp.product)
})
const {items: products} = await projectproductsQuery.find();
const productsPrices = products.reduce((acc, current) => ({
...acc,
[current._id]: current.price
}), {});
console.log({products, productsPrices, projectproducts});
const sum = projectproducts.reduce((acc, current) => {
return acc + productsPrices[current.product] * current.productQuantity;
}, 0);
console.log(sum);
});
Demo: https://moshef9.wixsite.com/agg-collections (Open the console for more information about the collections)

Related

I need to export field "unit" in another json file, if they have a equal "name"

I have a script that compares 2 JSON files, It takes a name from the first JSON and comparing to another JSON file, and if they don't have an equal "name", the object will be deleted.
Here is a code:
const fs = require('fs');
// Read the goods JSON file
const goods = JSON.parse(fs.readFileSync('good.json', 'utf-8'));
// Read the products JSON file
const products = JSON.parse(fs.readFileSync('products.json', 'utf-8'));
// Create an array of the names of objects in goods
const goodsNames = goods.map(obj => obj.name);
// Filter objects from products that don't have a matching name in goods
const filteredProducts = products.filter(obj => goodsNames.includes(obj.name));
// Write the filtered and sorted products back to the products file with formatting for readability
fs.writeFileSync('products.json', JSON.stringify(filteredProducts, null, 4), 'utf-8');
I need to export a field "unit" from good.json, another JSON, and put the field in objects with equals "name".
Try to add this above the last line in your code:
filteredProducts.forEach(product => {
const matchingGood = goods.find(good => good.name === product.name);
product.unit = matchingGood.unit;
});

I want to get multiple types as query parameters by using .split(',') in WHERE IN()

I want to get multiple types as query parameters by using type.split(',') in WHERE IN().
I have service.js and DAO.js files. And I tried this like below.
service.js
const productTypeSort = async (name, type, productSort, page) => {
const sort = orderBy(productSort);
const categoryType = getCategoryType(name, type);
return await productsDao.productTypeSort(categoryType, sort, page);
};
const getCategoryType = (name, type) => {
const filter = type.toString().split(',')
const FilterType = {
category: `WHERE c.name = "${name}"`,
categoryType: `WHERE c.name = "${name}" AND t.name IN ("${filter}")`,
};
if (name && type) {
return FilterType.categoryType;
} else if (name) {
return FilterType.category;
}
return '';
};
DAO.js
const productTypeSort = async (categoryType, sort, page) => {
const products = await myDataSource.query(
`SELECT
c.name AS category,
t.name AS type,
pr.name,
pr.description,
price_origin,
pr.created_at,
count(*) OVER() AS totalCount
FROM products pr
JOIN category c ON c.id = pr.category_id
JOIN product_types t ON t.id = pr.type_id
${categoryType}
GROUP BY pr.id
${sort}
LIMIT ?, 9`,
[(page - 1) * 9]
);
return products;
};
and the query I sent is as follows.
?name=abc&type=aaa,bbb&sort=review&page=1
But this returns an empty data column.
{
"data": []
}
What am I doing wrong? Maybe the location of .split(',') is wrong? I need help.
Your problem is that your filter array is ["aaa,bbb"] and that ends up making a query string which looks like:
WHERE t.name IN ("aaa,bbb")
What you need is to map each value in filter to a single-quote enclosed string, and remove the double-quotes from the query:
filter = type.split(',').map(s => `'${s}'`)
// ...
categoryType: `WHERE c.name = "${name}" AND t.name IN (${filter})`,
This will give you something that looks like:
WHERE t.name IN ('aaa','bbb')
which should give you your desired result.
You should take note of what #Andreas referred to in their comment; you should preferably be using prepared statements rather than injecting user input directly into your query. If someone sent type="); DROP table products --
you would get a nasty surprise.

how to get the sum of data numbers inside an array

I am currently studying Vue and creating a personal account for the gazoline company.
I have an API IMG in console log
inside the data array there is also a transfer array, also u can see in below picture.
This data is output like this :
I want to get the amount of income in each tankfarme. How can I do it ?
somehow I was able to get the amount of the expense, but it receives the entire amount, and not in one tankfarm. Here is code
const getSumExpense = computed(() => {
let array = getTransfers.value.transfers.data;
let sum = 0;
array.forEach((element) => {
let arrayIncome = element.transfer;
arrayIncome.forEach((el) => {
sum = sum + el.expense;
});
});
return sum;
});
please help me, if you do not understand what I wrote, also tell me, I will try to write better
You can Array.prototype.reduce()
Code:
const arrayIncome = [{expense: 20}, {expense: 30}, {expense: 40}]
const sum = arrayIncome.reduce((a, { expense: e }) => a + e, 0)
console.log(sum)
If you want to get the sum of some specific tankfarm then you have to filter the array first and then with the help of reduce you can sum the records.
const data= [{tankfarm: 'cymma', transfer: [{expense: 10}, {expense: 20}]}]
const result = data.filter(element => element.tankfarm === 'cymma')[0].transfer.reduce((a, { expense: e }) => a + e, 0)
console.log("cymma expense", result)

Get cypress database query output objects in to variables

I have a cypress test which has been set up with mysql node module. When I run bellow mentioned test Its giving output as follows.
const executeQuery = (query) => {
cy.task('DBQuery', query).then(function (recordset) {
var rec = recordset
cy.log(rec)
})
}
Query:
select *
from Users
where email = 'sheeranlymited#lymitedtest.com'
OUTPUT: log [Object{23}]
Query:
select firstname
from Users
where email = 'sheeranlymited#lymitedtest.com'
OUTPUT: log [{firstname: Edward}]
instead of cy.log(rec) I want to get the output of 23 columns to assign in to different variables based on the column name.
Appreciate if someone can help me to resolve this...
You can use Object.values in js to retrieve values from your object
Let's say you need to extract the value of the 3rd column, so your code will look like,
cy.task('DBQuery', query).then(function (recordset) {
var rec = recordset
const results = Object.values(rec[0])
// results[index of the column] will output the results
cy.log(results[3])
})
We can do a small modification to make your task easier,
cy.task('DBQuery', query).then(function (recordset) {
var rec = recordset
const Values = Object.values(rec[0]);
const keys = Object.keys(rec[0]);
let result = {};
let index = 0;
keys.forEach(key => {
result[keys[index]] = Values[index];
i++
})
//result.firstName will give you your results
cy.log(result.firstName);
})
In this way, we are generating key-value pairs having the key as the column name. So you can use the column name to find the value.
Hope this helps.
cheers.

Generate combination of products given a total price limit

I have an array of products id, and 2 arrays with product id in key and price and unique flag in values.
I would like to have all unique combinations of products under a given total limit price :
a product could be several times in combination, except if it is flagged as unique
combination should be sorted by product id
a valid combination is one to the which we can't add product
Sample:
products = [1, 2, 3];
productPrices = {1:10, 2:15, 3:10};
productUnique = {1:true, 2:false, 3:false};
limitPrice = 40;
expected result = [[1,2,2],[1,2,3],[1,3,3,3],[2,2,3],[2,3,3],[3,3,3,3]];
How can I obtain this result in javascript if possible ?
Thanks for the help.
I would suggest another format for your input, so it is a single array of objects, where each of those objects has an id, price and unique property.
Then with that array of objects and the limit price, use recursion to select at each level of recursion a product to be added to a series of products until none can be added. At that time add the selected product list to a results array.
When selecting a product, determine which products can still be selected in the next level of recursion: when a unique product was selected, then don't pass that on as a selection possibility to the next level.
To avoid duplicates, once a product is no longer selected from, don't come back to it at deeper recursion levels; so pass on a shorter product list in recursion when it is decided not to pick the same product again. The recursion ends when the cheapest, still available product is more expensive than the amount that is still available.
Here is a snippet:
function intoOne(products, productPrices, productUnique) {
return products.map( (id) => ({
id,
price: productPrices[id],
unique: productUnique[id]
}));
}
function combinations(products, limitPrice) {
const results = [];
function recurse(sel, products, minPrice, maxPrice) {
products = products.filter(p => p.price <= maxPrice);
if (!products.length && minPrice > maxPrice) return results.push(sel);
products.forEach( (p, i) => {
recurse(sel.concat(p.id), products.slice(i+p.unique),
minPrice, maxPrice-p.price);
minPrice = Math.min(minPrice, p.price);
});
}
recurse([], products, limitPrice, limitPrice);
return results;
}
var products = [1, 2, 3],
productPrices = {1:10, 2:15, 3:10},
productUnique = {1:true, 2:false, 3:false},
limitPrice = 40;
// Combine product characteristics in more suitable structure
products = intoOne(products, productPrices, productUnique);
// Call main algorithm
var result = combinations(products, limitPrice);
console.log(JSON.stringify(result));
You could take an iterative and recursive approach by checking the sum, length and unique parameter for next call of the same function with changed index or temporary items.
If the sum is smaller than the limit, the temporary result is added to the result set.
function iter(index, temp) {
var product = products[index],
sum = temp.reduce((s, k) => s + prices[k], 0);
if (sum + prices[product] > limit) {
result.push(temp);
return;
}
if (!unique[product] || temp[temp.length - 1] !== product) {
iter(index, temp.concat(product));
}
if (index + 1 < products.length) {
iter(index + 1, temp);
}
}
var products = [1, 2, 3],
prices = { 1: 10, 2: 15, 3: 10 },
unique = { 1: true, 2: false, 3: false },
limit = 40,
result = [];
iter(0, []);
console.log(JSON.stringify(result));

Categories

Resources