201 lines
5.6 KiB
JavaScript
201 lines
5.6 KiB
JavaScript
const path = require("path");
|
|
|
|
const _wineFunctions = require(path.join(__dirname, "/wine"));
|
|
const _personFunctions = require(path.join(__dirname, "/person"));
|
|
const Message = require(path.join(__dirname, "/message"));
|
|
const VirtualWinner = require(path.join(
|
|
__dirname, "/schemas/VirtualWinner"
|
|
));
|
|
const PreLotteryWine = require(path.join(
|
|
__dirname, "/schemas/PreLotteryWine"
|
|
));
|
|
|
|
|
|
const getWinesToWinnerById = async (req, res) => {
|
|
let id = req.params.id;
|
|
let foundWinner = await VirtualWinner.findOne({ id: id });
|
|
|
|
if (!foundWinner) {
|
|
return res.json({
|
|
success: false,
|
|
message: "No winner with this id.",
|
|
existing: false,
|
|
turn: false
|
|
});
|
|
}
|
|
|
|
let allWinners = await VirtualWinner.find().sort({ timestamp_drawn: 1 });
|
|
if (
|
|
allWinners[0].id != foundWinner.id ||
|
|
foundWinner.timestamp_limit == undefined ||
|
|
foundWinner.timestamp_sent == undefined
|
|
) {
|
|
return res.json({
|
|
success: false,
|
|
message: "Not the winner next in line!",
|
|
existing: true,
|
|
turn: false
|
|
});
|
|
}
|
|
|
|
return res.json({
|
|
success: true,
|
|
existing: true,
|
|
turn: true,
|
|
name: foundWinner.name,
|
|
color: foundWinner.color
|
|
});
|
|
};
|
|
|
|
const registerWinnerSelection = async (req, res) => {
|
|
let id = req.params.id;
|
|
let wineName = req.body.wineName;
|
|
let foundWinner = await VirtualWinner.findOne({ id: id });
|
|
|
|
if (!foundWinner) {
|
|
return res.json({
|
|
success: false,
|
|
message: "No winner with this id."
|
|
})
|
|
} else if (foundWinner.timestamp_limit < new Date().getTime()) {
|
|
return res.json({
|
|
success: false,
|
|
message: "Timelimit expired, you will receive a wine after other users have chosen.",
|
|
limit: true
|
|
})
|
|
}
|
|
|
|
let date = new Date();
|
|
date.setHours(5, 0, 0, 0);
|
|
let prelotteryWine = await PreLotteryWine.findOne({ name: wineName });
|
|
|
|
if (!prelotteryWine) {
|
|
return res.json({
|
|
success: false,
|
|
message: "No wine with this name.",
|
|
wine: false
|
|
});
|
|
}
|
|
|
|
let wonWine = await _wineFunctions.findSaveWine(prelotteryWine);
|
|
await prelotteryWine.delete();
|
|
await _personFunctions.findSavePerson(foundWinner, wonWine, date);
|
|
await Message.sendWineConfirmation(foundWinner, wonWine, date);
|
|
|
|
await foundWinner.delete();
|
|
console.info("Saved winners choice.");
|
|
|
|
return findAndNotifyNextWinner()
|
|
.then(() => res.json({
|
|
message: "Choice saved and next in line notified.",
|
|
success: true
|
|
}))
|
|
.catch(error => res.json({
|
|
message: error["message"] || "Error when notifing next winner.",
|
|
success: false
|
|
}))
|
|
};
|
|
|
|
const chooseLastWineForUser = (winner, preLotteryWine) => {
|
|
let date = new Date();
|
|
date.setHours(5, 0, 0, 0);
|
|
|
|
return _wineFunctions.findSaveWine(preLotteryWine)
|
|
.then(wonWine => _personFunctions.findSavePerson(winner, wonWine, date))
|
|
.then(() => preLotteryWine.delete())
|
|
.then(() => Message.sendLastWinnerMessage(winner, preLotteryWine))
|
|
.then(() => winner.delete())
|
|
.catch(err => {
|
|
console.log("Error thrown from chooseLastWineForUser: " + err);
|
|
throw err;
|
|
})
|
|
}
|
|
|
|
const findAndNotifyNextWinner = async () => {
|
|
let nextWinner = undefined;
|
|
|
|
let winnersLeft = await VirtualWinner.find().sort({ timestamp_drawn: 1 });
|
|
let winesLeft = await PreLotteryWine.find();
|
|
|
|
if (winnersLeft.length > 1) {
|
|
console.log("multiple winners left, choose next in line")
|
|
nextWinner = winnersLeft[0]; // multiple winners left, choose next in line
|
|
} else if (winnersLeft.length == 1 && winesLeft.length > 1) {
|
|
console.log("one winner left, but multiple wines")
|
|
nextWinner = winnersLeft[0] // one winner left, but multiple wines
|
|
} else if (winnersLeft.length == 1 && winesLeft.length == 1) {
|
|
console.log("one winner and one wine left, choose for user")
|
|
nextWinner = winnersLeft[0] // one winner and one wine left, choose for user
|
|
wine = winesLeft[0]
|
|
return chooseLastWineForUser(nextWinner, wine);
|
|
}
|
|
|
|
if (nextWinner) {
|
|
return Message.sendWineSelectMessage(nextWinner)
|
|
.then(messageResponse => startTimeout(nextWinner.id))
|
|
} else {
|
|
console.info("All winners notified. Could start cleanup here.");
|
|
return Promise.resolve({
|
|
message: "All winners notified."
|
|
})
|
|
}
|
|
};
|
|
|
|
const sendNotificationToWinnerById = async (req, res) => {
|
|
const { id } = req.params;
|
|
let winner = await VirtualWinner.findOne({ id: id });
|
|
|
|
if (!winner) {
|
|
return res.json({
|
|
message: "No winner with this id.",
|
|
success: false
|
|
})
|
|
}
|
|
|
|
return Message.sendWineSelectMessage(winner)
|
|
.then(success => res.json({
|
|
success: success,
|
|
message: `Message sent to winner ${id} successfully!`
|
|
}))
|
|
.catch(err => res.json({
|
|
success: false,
|
|
message: "Error while trying to send sms.",
|
|
error: err
|
|
}))
|
|
}
|
|
|
|
function startTimeout(id) {
|
|
const minute = 60000;
|
|
const minutesForTimeout = 10;
|
|
|
|
console.log(`Starting timeout for user ${id}.`);
|
|
console.log(`Timeout duration: ${ minutesForTimeout * minute }`)
|
|
setTimeout(async () => {
|
|
let virtualWinner = await VirtualWinner.findOne({ id: id });
|
|
if (!virtualWinner) {
|
|
console.log(`Timeout done for user ${id}, but user has already sent data.`);
|
|
return;
|
|
}
|
|
console.log(`Timeout done for user ${id}, sending update to user.`);
|
|
|
|
Message.sendWineSelectMessageTooLate(virtualWinner);
|
|
|
|
virtualWinner.timestamp_drawn = new Date().getTime();
|
|
virtualWinner.timestamp_limit = null;
|
|
virtualWinner.timestamp_sent = null;
|
|
await virtualWinner.save();
|
|
|
|
findAndNotifyNextWinner();
|
|
}, minutesForTimeout * minute);
|
|
|
|
return Promise.resolve()
|
|
}
|
|
|
|
module.exports = {
|
|
getWinesToWinnerById,
|
|
registerWinnerSelection,
|
|
findAndNotifyNextWinner,
|
|
|
|
sendNotificationToWinnerById
|
|
};
|