Jucundus/backend/services/saleDb.js

212 lines
6.3 KiB
JavaScript

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 };