Files
vinlottis/api/virtualRegistration.js

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