Replaced for clearer project structure & new ctrls.
These files where directly called from the api endpoints. Now all functoins have been replaced with a controller interfacing to the endpoint and a repository file for each of the functions.
This commit is contained in:
		
							
								
								
									
										154
									
								
								api/retrieve.js
									
									
									
									
									
								
							
							
						
						
									
										154
									
								
								api/retrieve.js
									
									
									
									
									
								
							@@ -1,154 +0,0 @@
 | 
			
		||||
const path = require("path");
 | 
			
		||||
 | 
			
		||||
const Purchase = require(path.join(__dirname, "/schemas/Purchase"));
 | 
			
		||||
const Wine = require(path.join(__dirname, "/schemas/Wine"));
 | 
			
		||||
const Highscore = require(path.join(__dirname, "/schemas/Highscore"));
 | 
			
		||||
const PreLotteryWine = require(path.join(
 | 
			
		||||
  __dirname, "/schemas/PreLotteryWine"
 | 
			
		||||
));
 | 
			
		||||
 | 
			
		||||
const prelotteryWines = async (req, res) => {
 | 
			
		||||
  let wines = await PreLotteryWine.find();
 | 
			
		||||
  return res.json(wines);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const allPurchase = async (req, res) => {
 | 
			
		||||
  let purchases = await Purchase.find()
 | 
			
		||||
    .populate("wines")
 | 
			
		||||
    .sort({ date: 1 });
 | 
			
		||||
  return res.json(purchases);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const purchaseByColor = async (req, res) => {
 | 
			
		||||
  const countColor = await Purchase.find();
 | 
			
		||||
  let red = 0;
 | 
			
		||||
  let blue = 0;
 | 
			
		||||
  let yellow = 0;
 | 
			
		||||
  let green = 0;
 | 
			
		||||
  let stolen = 0;
 | 
			
		||||
  for (let i = 0; i < countColor.length; i++) {
 | 
			
		||||
    let element = countColor[i];
 | 
			
		||||
    red += element.red;
 | 
			
		||||
    blue += element.blue;
 | 
			
		||||
    yellow += element.yellow;
 | 
			
		||||
    green += element.green;
 | 
			
		||||
    if (element.stolen != undefined) {
 | 
			
		||||
      stolen += element.stolen;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const highscore = await Highscore.find();
 | 
			
		||||
  let redWin = 0;
 | 
			
		||||
  let blueWin = 0;
 | 
			
		||||
  let yellowWin = 0;
 | 
			
		||||
  let greenWin = 0;
 | 
			
		||||
  for (let i = 0; i < highscore.length; i++) {
 | 
			
		||||
    let element = highscore[i];
 | 
			
		||||
    for (let y = 0; y < element.wins.length; y++) {
 | 
			
		||||
      let currentWin = element.wins[y];
 | 
			
		||||
      switch (currentWin.color) {
 | 
			
		||||
        case "blue":
 | 
			
		||||
          blueWin += 1;
 | 
			
		||||
          break;
 | 
			
		||||
        case "red":
 | 
			
		||||
          redWin += 1;
 | 
			
		||||
          break;
 | 
			
		||||
        case "yellow":
 | 
			
		||||
          yellowWin += 1;
 | 
			
		||||
          break;
 | 
			
		||||
        case "green":
 | 
			
		||||
          greenWin += 1;
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const total = red + yellow + blue + green;
 | 
			
		||||
 | 
			
		||||
  return res.json({
 | 
			
		||||
    red: {
 | 
			
		||||
      total: red,
 | 
			
		||||
      win: redWin
 | 
			
		||||
    },
 | 
			
		||||
    blue: {
 | 
			
		||||
      total: blue,
 | 
			
		||||
      win: blueWin
 | 
			
		||||
    },
 | 
			
		||||
    green: {
 | 
			
		||||
      total: green,
 | 
			
		||||
      win: greenWin
 | 
			
		||||
    },
 | 
			
		||||
    yellow: {
 | 
			
		||||
      total: yellow,
 | 
			
		||||
      win: yellowWin
 | 
			
		||||
    },
 | 
			
		||||
    stolen: stolen,
 | 
			
		||||
    total: total
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const highscore = async (req, res) => {
 | 
			
		||||
  const highscore = await Highscore.find().populate("wins.wine");
 | 
			
		||||
 | 
			
		||||
  return res.json(highscore);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const allWines = async (req, res) => {
 | 
			
		||||
  const wines = await Wine.find();
 | 
			
		||||
 | 
			
		||||
  return res.json(wines);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const allWinesSummary = async (req, res) => {
 | 
			
		||||
  const highscore = await Highscore.find().populate("wins.wine");
 | 
			
		||||
  let wines = {};
 | 
			
		||||
 | 
			
		||||
  for (let i = 0; i < highscore.length; i++) {
 | 
			
		||||
    let person = highscore[i];
 | 
			
		||||
    for (let y = 0; y < person.wins.length; y++) {
 | 
			
		||||
      let wine = person.wins[y].wine;
 | 
			
		||||
      let date = person.wins[y].date;
 | 
			
		||||
      let color = person.wins[y].color;
 | 
			
		||||
 | 
			
		||||
      if (wines[wine._id] == undefined) {
 | 
			
		||||
        wines[wine._id] = {
 | 
			
		||||
          name: wine.name,
 | 
			
		||||
          occurences: wine.occurences,
 | 
			
		||||
          vivinoLink: wine.vivinoLink,
 | 
			
		||||
          rating: wine.rating,
 | 
			
		||||
          image: wine.image,
 | 
			
		||||
          id: wine.id,
 | 
			
		||||
          _id: wine._id,
 | 
			
		||||
          dates: [date],
 | 
			
		||||
          winners: [person.name],
 | 
			
		||||
          red: 0,
 | 
			
		||||
          blue: 0,
 | 
			
		||||
          green: 0,
 | 
			
		||||
          yellow: 0
 | 
			
		||||
        };
 | 
			
		||||
        wines[wine._id][color] += 1;
 | 
			
		||||
      } else {
 | 
			
		||||
        wines[wine._id].dates.push(date);
 | 
			
		||||
        wines[wine._id].winners.push(person.name);
 | 
			
		||||
        if (wines[wine._id][color] == undefined) {
 | 
			
		||||
          wines[wine._id][color] = 1;
 | 
			
		||||
        } else {
 | 
			
		||||
          wines[wine._id][color] += 1;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  wines = Object.values(wines).reverse()
 | 
			
		||||
 | 
			
		||||
  return res.json(wines);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  prelotteryWines,
 | 
			
		||||
  allPurchase,
 | 
			
		||||
  purchaseByColor,
 | 
			
		||||
  highscore,
 | 
			
		||||
  allWines,
 | 
			
		||||
  allWinesSummary
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										142
									
								
								api/update.js
									
									
									
									
									
								
							
							
						
						
									
										142
									
								
								api/update.js
									
									
									
									
									
								
							@@ -1,142 +0,0 @@
 | 
			
		||||
const express = require("express");
 | 
			
		||||
const path = require("path");
 | 
			
		||||
 | 
			
		||||
const sub = require(path.join(__dirname, "/subscriptions"));
 | 
			
		||||
 | 
			
		||||
const _wineFunctions = require(path.join(__dirname, "/wine"));
 | 
			
		||||
const _personFunctions = require(path.join(__dirname, "/person"));
 | 
			
		||||
const Subscription = require(path.join(__dirname, "/schemas/Subscription"));
 | 
			
		||||
const Lottery = require(path.join(__dirname, "/schemas/Purchase"));
 | 
			
		||||
const PreLotteryWine = require(path.join(
 | 
			
		||||
  __dirname, "/schemas/PreLotteryWine"
 | 
			
		||||
));
 | 
			
		||||
 | 
			
		||||
const submitWines = async (req, res) => {
 | 
			
		||||
  const wines = req.body;
 | 
			
		||||
  for (let i = 0; i < wines.length; i++) {
 | 
			
		||||
    let wine = wines[i];
 | 
			
		||||
    let newWonWine = new PreLotteryWine({
 | 
			
		||||
      name: wine.name,
 | 
			
		||||
      vivinoLink: wine.vivinoLink,
 | 
			
		||||
      rating: wine.rating,
 | 
			
		||||
      image: wine.image,
 | 
			
		||||
      price: wine.price,
 | 
			
		||||
      country: wine.country,
 | 
			
		||||
      id: wine.id
 | 
			
		||||
    });
 | 
			
		||||
    await newWonWine.save();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let subs = await Subscription.find();
 | 
			
		||||
  console.log("Sending new wines w/ push notification to all subscribers.")
 | 
			
		||||
  for (let i = 0; i < subs.length; i++) {
 | 
			
		||||
    let subscription = subs[i]; //get subscription from your databse here.
 | 
			
		||||
 | 
			
		||||
    const message = JSON.stringify({
 | 
			
		||||
      message: "Dagens vin er lagt til, se den på lottis.vin/dagens!",
 | 
			
		||||
      title: "Ny vin!",
 | 
			
		||||
      link: "/#/dagens"
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      sub.sendNotification(subscription, message);
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      console.error("Error when trying to send push notification to subscriber.");
 | 
			
		||||
      console.error(error);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return res.send({
 | 
			
		||||
    message: "Submitted and notified push subscribers of new wines!",
 | 
			
		||||
    success: true
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const schema = async (req, res) => {
 | 
			
		||||
  let schema = { ...PreLotteryWine.schema.obj };
 | 
			
		||||
  let nulledSchema = Object.keys(schema).reduce((accumulator, current) => {
 | 
			
		||||
    accumulator[current] = "";
 | 
			
		||||
    return accumulator
 | 
			
		||||
  }, {});
 | 
			
		||||
 | 
			
		||||
  return res.send(nulledSchema);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO IMPLEMENT WITH FRONTEND (unused)
 | 
			
		||||
const submitWinesToLottery = async (req, res) => {
 | 
			
		||||
  const { lottery } = req.body;
 | 
			
		||||
  const { date, wines } = lottery;
 | 
			
		||||
  const wineObjects = await Promise.all(wines.map(async (wine) => await _wineFunctions.findSaveWine(wine)))
 | 
			
		||||
 | 
			
		||||
  return Lottery.findOneAndUpdate({ date: date }, {
 | 
			
		||||
      date: date,
 | 
			
		||||
      wines: wineObjects
 | 
			
		||||
    }, {
 | 
			
		||||
      upsert: true
 | 
			
		||||
    }).then(_ => res.send(true))
 | 
			
		||||
      .catch(err => res.status(500).send({ message: 'Unexpected error while updating/saving wine to lottery.',
 | 
			
		||||
                                           success: false,
 | 
			
		||||
                                           exception: err.message }));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 /**
 | 
			
		||||
  * @apiParam (Request body) {Array} winners List of winners
 | 
			
		||||
  */
 | 
			
		||||
const submitWinnersToLottery = async (req, res) => {
 | 
			
		||||
  const { lottery } = req.body;
 | 
			
		||||
  const { winners, date } = lottery;
 | 
			
		||||
 | 
			
		||||
  for (let i = 0; i < winners.length; i++) {
 | 
			
		||||
    let currentWinner = winners[i];
 | 
			
		||||
    let wonWine = await _wineFunctions.findSaveWine(currentWinner.wine); // TODO rename to findAndSaveWineToLottery
 | 
			
		||||
    await _personFunctions.findSavePerson(currentWinner, wonWine, date); // TODO rename to findAndSaveWineToPerson
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return res.json(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 /**
 | 
			
		||||
  * @apiParam (Request body) {Date} date Date of lottery
 | 
			
		||||
  * @apiParam (Request body) {Number} blue Number of blue tickets
 | 
			
		||||
  * @apiParam (Request body) {Number} red Number of red tickets
 | 
			
		||||
  * @apiParam (Request body) {Number} green Number of green tickets
 | 
			
		||||
  * @apiParam (Request body) {Number} yellow Number of yellow tickets
 | 
			
		||||
  * @apiParam (Request body) {Number} bought Number of tickets bought
 | 
			
		||||
  * @apiParam (Request body) {Number} stolen Number of tickets stolen
 | 
			
		||||
  */
 | 
			
		||||
const submitLottery = async (req, res) => {
 | 
			
		||||
  const { lottery } = req.body
 | 
			
		||||
 | 
			
		||||
  const { date,
 | 
			
		||||
          blue,
 | 
			
		||||
          red,
 | 
			
		||||
          yellow,
 | 
			
		||||
          green,
 | 
			
		||||
          bought,
 | 
			
		||||
          stolen } = lottery;
 | 
			
		||||
 | 
			
		||||
  return Lottery.findOneAndUpdate({ date: date }, {
 | 
			
		||||
      date: date,
 | 
			
		||||
      blue: blue,
 | 
			
		||||
      yellow: yellow,
 | 
			
		||||
      red: red,
 | 
			
		||||
      green: green,
 | 
			
		||||
      bought: bought,
 | 
			
		||||
      stolen: stolen
 | 
			
		||||
    }, {
 | 
			
		||||
      upsert: true
 | 
			
		||||
    }).then(_ => res.send(true))
 | 
			
		||||
      .catch(err => res.status(500).send({ message: 'Unexpected error while updating/saving lottery.',
 | 
			
		||||
                                           success: false,
 | 
			
		||||
                                           exception: err.message }));
 | 
			
		||||
 | 
			
		||||
  return res.send(true);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  submitWines,
 | 
			
		||||
  schema,
 | 
			
		||||
  submitLottery,
 | 
			
		||||
  submitWinnersToLottery,
 | 
			
		||||
  submitWinesToLottery
 | 
			
		||||
};
 | 
			
		||||
@@ -1,281 +0,0 @@
 | 
			
		||||
const path = require("path");
 | 
			
		||||
const crypto = require("crypto");
 | 
			
		||||
 | 
			
		||||
const config = require(path.join(__dirname, "/../config/defaults/lottery"));
 | 
			
		||||
const Message = require(path.join(__dirname, "/message"));
 | 
			
		||||
const { findAndNotifyNextWinner } = require(path.join(__dirname, "/virtualRegistration"));
 | 
			
		||||
 | 
			
		||||
const Attendee = require(path.join(__dirname, "/schemas/Attendee"));
 | 
			
		||||
const VirtualWinner = require(path.join(__dirname, "/schemas/VirtualWinner"));
 | 
			
		||||
const PreLotteryWine = require(path.join(__dirname, "/schemas/PreLotteryWine"));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const winners = async (req, res) => {
 | 
			
		||||
  let winners = await VirtualWinner.find();
 | 
			
		||||
  let winnersRedacted = [];
 | 
			
		||||
  let winner;
 | 
			
		||||
  for (let i = 0; i < winners.length; i++) {
 | 
			
		||||
    winner = winners[i];
 | 
			
		||||
    winnersRedacted.push({
 | 
			
		||||
      name: winner.name,
 | 
			
		||||
      color: winner.color
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  res.json(winnersRedacted);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const winnersSecure = async (req, res) => {
 | 
			
		||||
  let winners = await VirtualWinner.find();
 | 
			
		||||
 | 
			
		||||
  return res.json(winners);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const deleteWinners = async (req, res) => {
 | 
			
		||||
  await VirtualWinner.deleteMany();
 | 
			
		||||
  var io = req.app.get('socketio');
 | 
			
		||||
  io.emit("refresh_data", {});
 | 
			
		||||
  return res.json(true);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const attendees = async (req, res) => {
 | 
			
		||||
  let attendees = await Attendee.find();
 | 
			
		||||
  let attendeesRedacted = [];
 | 
			
		||||
  let attendee;
 | 
			
		||||
  for (let i = 0; i < attendees.length; i++) {
 | 
			
		||||
    attendee = attendees[i];
 | 
			
		||||
    attendeesRedacted.push({
 | 
			
		||||
      name: attendee.name,
 | 
			
		||||
      raffles: attendee.red + attendee.blue + attendee.yellow + attendee.green,
 | 
			
		||||
      red: attendee.red,
 | 
			
		||||
      blue: attendee.blue,
 | 
			
		||||
      green: attendee.green,
 | 
			
		||||
      yellow: attendee.yellow
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  return res.json(attendeesRedacted);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const attendeesSecure = async (req, res) => {
 | 
			
		||||
  let attendees = await Attendee.find();
 | 
			
		||||
 | 
			
		||||
  return res.json(attendees);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const addAttendee = async (req, res) => {
 | 
			
		||||
  const attendee = req.body;
 | 
			
		||||
  const { red, blue, yellow, green } = attendee;
 | 
			
		||||
 | 
			
		||||
  let newAttendee = new Attendee({
 | 
			
		||||
    name: attendee.name,
 | 
			
		||||
    red,
 | 
			
		||||
    blue,
 | 
			
		||||
    green,
 | 
			
		||||
    yellow,
 | 
			
		||||
    phoneNumber: attendee.phoneNumber,
 | 
			
		||||
    winner: false
 | 
			
		||||
  });
 | 
			
		||||
  await newAttendee.save();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  var io = req.app.get('socketio');
 | 
			
		||||
  io.emit("new_attendee", {});
 | 
			
		||||
 | 
			
		||||
  return res.send(true);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const deleteAttendees = async (req, res) => {
 | 
			
		||||
  await Attendee.deleteMany();
 | 
			
		||||
  var io = req.app.get('socketio');
 | 
			
		||||
  io.emit("refresh_data", {});
 | 
			
		||||
  return res.json(true);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const drawWinner = async (req, res) => {
 | 
			
		||||
  let allContestants = await Attendee.find({ winner: false });
 | 
			
		||||
 | 
			
		||||
  if (allContestants.length == 0) {
 | 
			
		||||
    return res.json({
 | 
			
		||||
      success: false,
 | 
			
		||||
      message: "No attendees left that have not won."
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  let raffleColors = [];
 | 
			
		||||
  for (let i = 0; i < allContestants.length; i++) {
 | 
			
		||||
    let currentContestant = allContestants[i];
 | 
			
		||||
    for (let blue = 0; blue < currentContestant.blue; blue++) {
 | 
			
		||||
      raffleColors.push("blue");
 | 
			
		||||
    }
 | 
			
		||||
    for (let red = 0; red < currentContestant.red; red++) {
 | 
			
		||||
      raffleColors.push("red");
 | 
			
		||||
    }
 | 
			
		||||
    for (let green = 0; green < currentContestant.green; green++) {
 | 
			
		||||
      raffleColors.push("green");
 | 
			
		||||
    }
 | 
			
		||||
    for (let yellow = 0; yellow < currentContestant.yellow; yellow++) {
 | 
			
		||||
      raffleColors.push("yellow");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  raffleColors = shuffle(raffleColors);
 | 
			
		||||
 | 
			
		||||
  let colorToChooseFrom =
 | 
			
		||||
    raffleColors[Math.floor(Math.random() * raffleColors.length)];
 | 
			
		||||
  let findObject = { winner: false };
 | 
			
		||||
 | 
			
		||||
  findObject[colorToChooseFrom] = { $gt: 0 };
 | 
			
		||||
 | 
			
		||||
  let tries = 0;
 | 
			
		||||
  const maxTries = 3;
 | 
			
		||||
  let contestantsToChooseFrom = undefined;
 | 
			
		||||
  while (contestantsToChooseFrom == undefined && tries < maxTries) {
 | 
			
		||||
    const hit = await Attendee.find(findObject);
 | 
			
		||||
    if (hit && hit.length) {
 | 
			
		||||
      contestantsToChooseFrom = hit;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    tries++;
 | 
			
		||||
  }
 | 
			
		||||
  if (contestantsToChooseFrom == undefined) {
 | 
			
		||||
    return res.status(404).send({
 | 
			
		||||
      success: false,
 | 
			
		||||
      message: `Klarte ikke trekke en vinner etter ${maxTries} forsøk.`
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let attendeeListDemocratic = [];
 | 
			
		||||
 | 
			
		||||
  let currentContestant;
 | 
			
		||||
  for (let i = 0; i < contestantsToChooseFrom.length; i++) {
 | 
			
		||||
    currentContestant = contestantsToChooseFrom[i];
 | 
			
		||||
    for (let y = 0; y < currentContestant[colorToChooseFrom]; y++) {
 | 
			
		||||
      attendeeListDemocratic.push({
 | 
			
		||||
        name: currentContestant.name,
 | 
			
		||||
        phoneNumber: currentContestant.phoneNumber,
 | 
			
		||||
        red: currentContestant.red,
 | 
			
		||||
        blue: currentContestant.blue,
 | 
			
		||||
        green: currentContestant.green,
 | 
			
		||||
        yellow: currentContestant.yellow
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  attendeeListDemocratic = shuffle(attendeeListDemocratic);
 | 
			
		||||
 | 
			
		||||
  let winner =
 | 
			
		||||
    attendeeListDemocratic[
 | 
			
		||||
      Math.floor(Math.random() * attendeeListDemocratic.length)
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
  let winners = await VirtualWinner.find({ timestamp_sent: undefined }).sort({
 | 
			
		||||
    timestamp_drawn: 1
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  var io = req.app.get('socketio');
 | 
			
		||||
  io.emit("winner", {
 | 
			
		||||
    color: colorToChooseFrom,
 | 
			
		||||
    name: winner.name,
 | 
			
		||||
    winner_count: winners.length + 1
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  let newWinnerElement = new VirtualWinner({
 | 
			
		||||
    name: winner.name,
 | 
			
		||||
    phoneNumber: winner.phoneNumber,
 | 
			
		||||
    color: colorToChooseFrom,
 | 
			
		||||
    red: winner.red,
 | 
			
		||||
    blue: winner.blue,
 | 
			
		||||
    green: winner.green,
 | 
			
		||||
    yellow: winner.yellow,
 | 
			
		||||
    id: sha512(winner.phoneNumber, genRandomString(10)),
 | 
			
		||||
    timestamp_drawn: new Date().getTime()
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  await Attendee.update(
 | 
			
		||||
    { name: winner.name, phoneNumber: winner.phoneNumber },
 | 
			
		||||
    { $set: { winner: true } }
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  await newWinnerElement.save();
 | 
			
		||||
  return res.json({
 | 
			
		||||
    success: true,
 | 
			
		||||
    winner
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const finish = async (req, res) => {
 | 
			
		||||
  if (!config.gatewayToken) {
 | 
			
		||||
    return res.json({
 | 
			
		||||
      message: "Missing api token for sms gateway.",
 | 
			
		||||
      success: false
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let winners = await VirtualWinner.find({ timestamp_sent: undefined }).sort({
 | 
			
		||||
    timestamp_drawn: 1
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (winners.length == 0) {
 | 
			
		||||
    return res.json({
 | 
			
		||||
      message: "No winners to draw from.",
 | 
			
		||||
      success: false
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Message.sendInitialMessageToWinners(winners.slice(1));
 | 
			
		||||
 | 
			
		||||
  return findAndNotifyNextWinner()
 | 
			
		||||
    .then(() => res.json({
 | 
			
		||||
      success: true,
 | 
			
		||||
      message: "Sent wine select message to first winner and update message to rest of winners."
 | 
			
		||||
    }))
 | 
			
		||||
    .catch(error => res.json({
 | 
			
		||||
      message: error["message"] || "Unable to send message to first winner.",
 | 
			
		||||
      success: false
 | 
			
		||||
    }))
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const genRandomString = function(length) {
 | 
			
		||||
  return crypto
 | 
			
		||||
    .randomBytes(Math.ceil(length / 2))
 | 
			
		||||
    .toString("hex") /** convert to hexadecimal format */
 | 
			
		||||
    .slice(0, length); /** return required number of characters */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const sha512 = function(password, salt) {
 | 
			
		||||
  var hash = crypto.createHmac("md5", salt); /** Hashing algorithm sha512 */
 | 
			
		||||
  hash.update(password);
 | 
			
		||||
  var value = hash.digest("hex");
 | 
			
		||||
  return value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function shuffle(array) {
 | 
			
		||||
  let currentIndex = array.length,
 | 
			
		||||
    temporaryValue,
 | 
			
		||||
    randomIndex;
 | 
			
		||||
 | 
			
		||||
  // While there remain elements to shuffle...
 | 
			
		||||
  while (0 !== currentIndex) {
 | 
			
		||||
    // Pick a remaining element...
 | 
			
		||||
    randomIndex = Math.floor(Math.random() * currentIndex);
 | 
			
		||||
    currentIndex -= 1;
 | 
			
		||||
 | 
			
		||||
    // And swap it with the current element.
 | 
			
		||||
    temporaryValue = array[currentIndex];
 | 
			
		||||
    array[currentIndex] = array[randomIndex];
 | 
			
		||||
    array[randomIndex] = temporaryValue;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return array;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  deleteWinners,
 | 
			
		||||
  deleteAttendees,
 | 
			
		||||
  winners,
 | 
			
		||||
  winnersSecure,
 | 
			
		||||
  drawWinner,
 | 
			
		||||
  finish,
 | 
			
		||||
  attendees,
 | 
			
		||||
  attendeesSecure,
 | 
			
		||||
  addAttendee
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,200 +0,0 @@
 | 
			
		||||
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
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user