const { ObjectId } = require('mongodb'); const connectDb = require("./db"); const { LotDb } = require("./lotDb"); const lotDb = new LotDb(); const SaleDb = class { constructor() { this.getCollection(); } async getCollection() { const db = await connectDb(); if (!db) { throw new Error('Database not connected'); } this.collection = db.collection("Sales"); } // CRUD async get(id) { let result = await this.collection.findOne({_id: new ObjectId(id)}); return result; } async post(newDocument) { delete newDocument._id; let result = await this.collection.insertOne(newDocument); return result; } async put(id, data) { let result = await this.collection.updateOne({_id: new ObjectId(id)}, {$set: data}); return result; } async remove(id) { let result = await this.collection.deleteOne({_id: new ObjectId(id)}); return result; } // Fucntions async getAll() { let result = await this.collection.find({}).toArray(); return result; } async getByUrl(url) { let result = await this.collection.findOne({url: url}); return result; } async getByIDPlatform(idSalePlatform, platformName) { let result = await this.collection.findOne({idPlatform: String(idSalePlatform), platform: String(platformName)}); return result; } async processStats(id) { let Sale = await this.get(id); if(!Sale){ console.error("Sale not found"); throw new Error("Sale not found"); } console.log(Sale); let Lots = await lotDb.getBySaleId(Sale._id.toString(),Sale.platform); let TimestampInSecond = (timestamp) => { const stringTimestamp = String(timestamp); if (stringTimestamp.length === 13) { return timestamp / 1000; } else if (stringTimestamp.length === 10) { return timestamp; } else { return 0; } } // Create an array to hold the updated lots let updatedLots = []; let bidsDuration = 0; // process each lot for (let lot of Lots) { let highestBid, duration, percentageAboveUnderLow, percentageAboveUnderHigh = 0; // if bid let nbrBids = 0; if (Array.isArray(lot.Bids)) { nbrBids = lot.Bids.length; highestBid = lot.Bids.reduce((prev, current) => (prev.amount > current.amount) ? prev : current).amount; let startTime = TimestampInSecond(lot.Bids[0].timestamp); let endTime = TimestampInSecond(lot.Bids[lot.Bids.length-1].timestamp); duration = endTime - startTime; // total time of bids bidsDuration += duration; duration = duration.toFixed(0); } // if auctioned percentageAboveUnderLow = 0; percentageAboveUnderHigh = 0; if (lot.auctioned) { if(lot.EstimateLow){ percentageAboveUnderLow = ((lot.auctioned.amount - lot.EstimateLow) / lot.EstimateLow) * 100; } if(lot.EstimateHigh){ percentageAboveUnderHigh = ((lot.auctioned.amount - lot.EstimateHigh) / lot.EstimateHigh) * 100; } } let lotPostProcessing = { nbrBids: nbrBids, highestBid: highestBid, duration: duration, percentageAboveUnderLow: percentageAboveUnderLow.toFixed(0), percentageAboveUnderHigh: percentageAboveUnderHigh.toFixed(0) } lot.postProcessing = lotPostProcessing; await lotDb.put(lot._id, lot); // Add the updated lot to the array updatedLots.push(lot); } // refresh with postprocess datas Lots = updatedLots; let startTime = 0; if (Array.isArray(Lots[0].Bids)) { startTime = TimestampInSecond(Lots[0].Bids[0].timestamp); }else{ startTime = TimestampInSecond(Lots[0].timestamp); } let LastBid = [...Lots].reverse().find(lot => lot.auctioned !== undefined); let endTime = 0; if (Array.isArray(LastBid.Bids)) { endTime = TimestampInSecond(LastBid.Bids[LastBid.Bids.length-1].timestamp); }else{ endTime = TimestampInSecond(LastBid.timestamp); } console.log("Start Time: "+startTime); console.log("End Time: "+endTime); let duration = (endTime-startTime).toFixed(0); let totalAmount = 0; let unsoldLots = 0; for (let lot of Lots) { if (lot.auctioned) { totalAmount += lot.auctioned.amount; } else { unsoldLots++; } } function calculateMedian(array) { array.sort((a, b) => a - b); let middleIndex = Math.floor(array.length / 2); if (array.length % 2 === 0) { // array has an even length return (array[middleIndex - 1] + array[middleIndex]) / 2; } else { // array has an odd length return array[middleIndex]; } } const amounts = Lots.map(lot => lot.auctioned?.amount).filter(Boolean); //console.error(Lots); let postProcessing = { nbrLots: Lots.length, duration: duration, bidsDuration: bidsDuration.toFixed(0), durationPerLots: (duration/Lots.length).toFixed(0), totalAmount: totalAmount, averageAmount: (totalAmount/Lots.length).toFixed(2), medianAmount: calculateMedian(amounts).toFixed(2), minAmount: Math.min(...amounts).toFixed(2), maxAmount: Math.max(...amounts).toFixed(2), unsoldLots: unsoldLots, unsoldPercentage: ((unsoldLots/Lots.length)*100).toFixed(2) } console.log(postProcessing); Sale.postProcessing = postProcessing; await this.put(Sale._id, Sale); } } module.exports = { SaleDb };