Imagine having a document structured like this
{
"_id" : "PQ8GUYYB7IERPNE9NX-CombQQD7F",
"combId" : 5,
"alignToOffer" : true,
"product" : "TwBuYJZquKeKTmtwr",
"price" : 85,
}
Now, the goal is to calculate the average price for each combination of the same product when aligned (if the align option is checked). This can be achieved by using Meteor observe handle. By aggregating the average price values for related documents, we are able to track changes effectively.
Offers.find({}).observe({
changed: function(offer, fields) {
var result = Offers.aggregate(
[
{
$match:
{
product: offer.product,
status: true,
combId: Number(offer.combId)
}
},
{
$group:
{
_id: "$product",
priceAlign: { $avg: "$price" },
minPrice: { $min: "$price" }
}
}
]
);
if (result.length){
var averageValue = parseFloat(Math.round(result[0].priceAlign * 100) / 100).toFixed(2),
bestOffer = parseFloat(Math.round(result[0].minPrice * 100) / 100).toFixed(2);
var updateValues = { $set: {
avgOffer: averageValue,
bestOffer: bestOffer
}};
var updatePrice = { $set: {
price : averageValue
}};
Offers.update({
product: offer.product,
combId: offer.combId,
status: true
}, updateValues, {multi: true});
Offers.update({
product: offer.product,
combId: offer.combId,
alignToOffer: true,
status: true
}, updatePrice, {multi: true});
}
}
});
While the above approach works flawlessly, there is a significant issue when saving the average price. To elaborate, let's assume we have three documents with the same product, where two are aligned (align to offer key checked) and one isn't. When the fixed value document's price (which is not aligned) is updated, the other two will save with an increment or decrement of decimal places instead of the exact price. For instance, updating the fixed price to 96 may result in the other prices being saved as 95.99999999999996 or 96.00000000000001 rather than just 96. Achieving a whole number without any decimals seems challenging even with methods like toFixed() in vanilla JS. Any guidance on resolving this enigma would be highly appreciated.
The most recent change still yields 96.01 or 95.99