Files
vinlottis/api/history.js
Kasper Rynning-Tønnesen 59b4366ed5 fix: Archive but save set winners as winners
If archiving a lottery, let archive-functionality circumvent SMS-service if the winners have been set on the archive page.
- Also remove unused file
2021-03-25 20:15:38 +01:00

349 lines
6.5 KiB
JavaScript

const path = require("path");
const Winner = require(path.join(__dirname, "/schemas/Highscore"));
const wineRepository = require(path.join(__dirname, "/wine"));
class HistoryByDateNotFound extends Error {
constructor(message = "History for given date not found.") {
super(message);
this.name = "HistoryByDateNotFound";
this.statusCode = 404;
}
}
class HistoryForUserNotFound extends Error {
constructor(message = "History for given user not found.") {
super(message);
this.name = "HistoryForUserNotFound";
this.statusCode = 404;
}
}
// highscore
const addWinnerWithWine = async (winner, wine) => {
const exisitingWinner = await Winner.findOne({
name: winner.name
});
const savedWine = await wineRepository.addWine(wine);
const date = new Date();
date.setHours(5, 0, 0, 0);
const winObject = {
date: date,
wine: savedWine,
color: winner.color
};
if (exisitingWinner == undefined) {
const newWinner = new Winner({
name: winner.name,
wins: [winObject]
});
await newWinner.save();
} else {
exisitingWinner.wins.push(winObject);
exisitingWinner.markModified("wins");
await exisitingWinner.save();
}
return exisitingWinner;
};
// lottery
const all = (includeWines = false) => {
if (includeWines === false) {
return Winner.find().sort("-wins.date");
} else {
return Winner.find()
.sort("-wins.date")
.populate("wins.wine");
}
};
// lottery
const byDate = date => {
const startQueryDate = new Date(date.setHours(0, 0, 0, 0));
const endQueryDate = new Date(date.setHours(24, 59, 59, 99));
const query = [
{
$match: {
"wins.date": {
$gte: startQueryDate,
$lte: endQueryDate
}
}
},
{ $unwind: "$wins" },
{
$match: {
"wins.date": {
$gte: startQueryDate,
$lte: endQueryDate
}
}
},
{
$lookup: {
from: "wines",
localField: "wins.wine",
foreignField: "_id",
as: "wins.wine"
}
},
{ $unwind: "$wins.wine" },
{
$project: {
name: "$name",
date: "$wins.date",
color: "$wins.color",
wine: "$wins.wine"
}
}
];
return Winner.aggregate(query).then(winners => {
if (winners.length == 0) {
throw new HistoryByDateNotFound();
}
return winners;
});
};
// highscore
const byName = (name, sort = "desc") => {
return Winner.findOne({ name }, ["name", "wins"])
.sort("-wins.date")
.populate("wins.wine")
.then(winner => {
if (winner) {
winner.wins = sort !== "asc" ? winner.wins.reverse() : winner.wins;
return winner;
} else {
throw new HistoryForUserNotFound();
}
});
};
// highscore
const search = (query, sort = "desc") => {
return Winner.find({ name: { $regex: query, $options: "i" } }, ["name"]).then(winners => {
if (winners) {
winners = sort === "desc" ? winners.reverse() : winners;
return winners;
} else {
throw new HistoryForUserNotFound();
}
});
};
// lottery
const latest = () => {
const query = [
{
$unwind: "$wins"
},
{
$lookup: {
from: "wines",
localField: "wins.wine",
foreignField: "_id",
as: "wins.wine"
}
},
{
$group: {
_id: "$wins.date",
winners: {
$push: {
_id: "$_id",
name: "$name",
color: "$wins.color",
wine: "$wins.wine"
}
}
}
},
{
$project: {
date: "$_id",
winners: "$winners"
}
},
{
$sort: {
_id: -1
}
},
{
$limit: 1
}
];
return Winner.aggregate(query).then(winners => winners[0]);
};
// lottery - byDate
const groupByDate = (includeWines = false, sort = "asc") => {
const sortDirection = sort == "asc" ? -1 : 1;
const query = [
{
$unwind: "$wins"
},
{
$group: {
_id: "$wins.date",
winners: {
$push: {
_id: "$_id",
name: "$name",
color: "$wins.color",
wine: "$wins.wine"
}
}
}
},
{
$project: {
date: "$_id",
winners: "$winners"
}
},
{
$sort: {
date: sortDirection
}
}
];
if (includeWines) {
query.splice(1, 0, {
$lookup: {
from: "wines",
localField: "wins.wine",
foreignField: "_id",
as: "wins.wine"
}
});
}
return Winner.aggregate(query);
};
// highscore - byColor
const groupByColor = (includeWines = false) => {
const query = [
{
$unwind: "$wins"
},
{
$group: {
_id: "$wins.color",
winners: {
$push: {
_id: "$_id",
name: "$name",
date: "$wins.date",
wine: "$wins.wine"
}
},
count: { $sum: 1 }
}
},
{
$project: {
color: "$_id",
count: "$count",
winners: "$winners"
}
},
{
$sort: {
_id: -1
}
}
];
if (includeWines) {
query.splice(1, 0, {
$lookup: {
from: "wines",
localField: "wins.wine",
foreignField: "_id",
as: "wins.wine"
}
});
}
return Winner.aggregate(query);
};
// highscore - byWineOccurences
// highscore - byWinCount
const orderByWins = (includeWines = false, limit = undefined) => {
let query = [
{
$project: {
name: "$name",
wins: "$wins",
totalWins: { $size: "$wins" }
}
},
{
$sort: {
totalWins: -1,
"wins.date": -1
}
}
];
if (includeWines) {
const includeWinesSubQuery = [
{
$unwind: "$wins"
},
{
$lookup: {
from: "wines",
localField: "wins.wine",
foreignField: "_id",
as: "wins.wine"
}
},
{
$unwind: "$wins._id"
},
{
$group: {
_id: "$_id",
name: { $first: "$name" },
totalWins: { $first: "$totalWins" },
wins: { $push: "$wins" }
}
}
];
query = includeWinesSubQuery.concat(query);
}
return Winner.aggregate(query).then(winners => {
if (limit == null) {
return winners;
}
return winners.slice(0, limit);
});
};
module.exports = {
addWinnerWithWine,
all,
byDate,
byName,
search,
latest,
groupByDate,
groupByColor,
orderByWins
};