| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- const _ = require('lodash')
- const moment = require('moment-immutable')
- const { getWeeks, formatDate, parseDate } = require('../dates')
- const { Retailer, Workday, Terminal, Service, sequelize } = require('../database')
- const { Op } = require('sequelize')
- const list = async (req, res) => {
- const terminalKey = req.params.terminal
- const terminal = await Terminal.findOne({where: {key: terminalKey}})
- if (!terminal) return res.status(404).end()
- const workdays = await Workday.findAll({where: { terminalId: terminal.id }})
- let workweeks = _.groupBy(workdays, d => formatDate(moment(d.date).startOf('week')))
-
- // fill workweeks
- getWeeks(10).forEach(week => {
- const w = formatDate(week)
- if (!workweeks[w]) workweeks[w] = []
- })
- // fill workdays
- workweeks = _.chain(workweeks)
- .toPairs()
- .map(([w, days]) => {
- days = _.chain(days)
- .map(d => [moment(d.date).weekday(), d])
- .fromPairs()
- .value()
-
- days = _.range(0, 7).map(d => days[d] || null)
- .map(day => day && {
- cartons: day.cartons
- })
- return {
- workweek: w,
- workdays: days
- }
- })
- .sortBy(x => x.workweek)
- .reverse()
- .value()
- res.status(200).send(workweeks)
- }
- const get = async (req, res) => {
- const terminalKey = req.params.terminal
- const terminal = await Terminal.findOne({where: {key: terminalKey}})
- const week = parseDate(req.params.week)
- const workdays = await Workday.findAll({
- where: {
- terminalId: terminal.id,
- date: {
- [Op.gte]: week,
- [Op.lt]: moment(week).endOf('week')
- }
- },
- order: [ 'date' ]
- })
- const services = await Service.findAll({
- where: {
- workdayId: {
- [Op.in]: workdays.map(x => x.id)
- }
- }
- })
- const servicesByWorkday = _.groupBy(services, x => x.workdayId)
- const extraRetailers = _.chain(services)
- .map(x => x.retailerId)
- .filter(x => x)
- .uniq()
- .value()
- const retailers = await Retailer.findAll({
- where: {
- [Op.or]: [
- { terminalId: terminal.id },
- {
- id: {
- [Op.in]: extraRetailers
- }
- }
- ]
- },
- order: [ 'name' ]
- })
- const retailersById = _.chain(retailers).map(x => [x.id, x]).fromPairs().value()
- // Fill in empty days
- const workdaysByKey = _.chain(workdays).map(wd => [formatDate(wd.date), wd]).fromPairs().value()
- const allWorkdays = []
- for (let day = week, i = 0; i < 7; i++, day = day.add(1, 'day')) {
- const wd = workdaysByKey[formatDate(day)]
- allWorkdays[i] = wd ? wd.toJSON() : {}
- }
- const workdaysWithServices = allWorkdays.map(wd => {
- const services = servicesByWorkday[wd.id] || []
- const serviceByRetailer = _.chain(services).map(l => [l.retailerId, l]).fromPairs().value()
- // Map from staffMembers to preserve sorting
- wd.services = retailers
- .map(sm => serviceByRetailer[sm.id] || {retailerId: sm.id})
- .map(sm => ({
- retailerId: sm.retailerId,
- cartons: sm.cartons || null
- }))
- // Restore any staffMembers that are no longer assigned this terminal
- services.forEach(l => {
- if (!serviceByRetailer[l.retailerId]) {
- wd.services.push(l)
- }
- })
- return wd
- })
- res.status(200).send({
- workdays: allWorkdays
- })
- }
- const patch = async (req, res) => {
- const transaction = await sequelize.transaction()
- try {
- const terminalKey = req.params.terminal
- const terminal = await Terminal.findOne({where: {key: terminalKey}})
- const week = parseDate(req.params.week)
- const workdays = await Workday.findAll({
- where: {
- terminalId: terminal.id,
- date: {
- [Op.gte]: week,
- [Op.lte]: moment(week).endOf('week')
- }
- },
- order: [ 'date' ]
- })
- const services = await Service.findAll({
- where: {
- workdayId: {
- [Op.in]: workdays.map(x => x.id)
- }
- }
- })
- const servicesByWorkday = _.groupBy(services, x => x.workdayId)
- const extraRetailers = _.chain(services)
- .map(x => x.retailerId)
- .filter(x => x)
- .uniq()
- .value()
- const retailers = await Retailer.findAll({
- where: {
- [Op.or]: [
- { terminalId: terminal.id },
- {
- id: {
- [Op.in]: extraRetailers
- }
- }
- ]
- },
- order: [ 'name' ]
- })
- const retailersById = _.chain(retailers).map(x => [x.id, x]).fromPairs().value()
- // Fill in empty days
- const workdaysByKey = _.chain(workdays).map(wd => [formatDate(wd.date), wd]).fromPairs().value()
- const allWorkdays = []
- for (let day = week, i = 0; i < 7; i++, day = day.add(1, 'day')) {
- const wd = workdaysByKey[formatDate(day)]
- allWorkdays[i] = wd || Workday.build({
- terminalId: terminal.id,
- date: week.add(i, 'day')
- })
- }
- const workdaysWithServices = allWorkdays.map(wd => {
- const services = servicesByWorkday[wd.id] || []
- const servicesByRetailer = _.chain(services).map(l => [l.retailerId, l]).fromPairs().value()
- // Map from staffMembers to preserve sorting
- wd.services = retailers.map(sm => servicesByRetailer[sm.id] || Service.build({retailerId: sm.id, workdayId: wd.id}))
- // Restore any staffMembers that are no longer assigned this terminal
- services.forEach(l => {
- if (!retailersById[l.retailerId]) {
- wd.services.push(l)
- }
- })
- return wd
- })
- // Update with model
- const model = req.body
- await Promise.all(model.workdays.map(async (modelWorkday, i) => {
- const modelServicesById = _.chain(modelWorkday.services).map(l => [l.retailerId, l]).fromPairs().value()
- const workday = allWorkdays[i]
- workday.services.forEach(service => {
- const modelService = modelServicesById[service.retailerId]
- service.cartons = modelService.cartons || 0
- })
- workday.cartons = workday.services.map(l => l.cartons).reduce((a, b) => a + b, 0)
-
- if (workday.cartons || !workday.isNewRecord) {
- await workday.save({ transaction })
- }
- await Promise.all(workday.services.map(async service => {
- if (service.cartons || !service.isNewRecord) {
- await service.save({ transaction })
- }
- }))
- }))
- await transaction.commit()
-
- res.status(200).end()
- } catch (err) {
- await transaction.rollback()
- console.log(err.message)
- console.log(err.sql)
- throw err
- }
- }
- module.exports = {
- list,
- get,
- patch
- }
|