UNPKG

@gameroom/cli

Version:

A command line tool for Gameroom

161 lines (151 loc) 5.5 kB
const cosmetic = require('cosmetic'), Table = require('tabley'), { enums: { timecard_status }, models: { User, Timecard } } = require('@gameroom/kit'), { join, resolve } = require('path'), { correctionStatus, dateAddDays, dateLocaleString, dateString, getAll, grGreen, printTable, writeCSVFile } = require('../../helpers'), { spinner } = require('../../refs') module.exports = async({ start_at, end_at, days, weeks, id, email, first, last, write }) => { spinner.start() spinner.info(`generating ${grGreen('timecards')} report`) spinner.info(`from ${grGreen(start_at.toLocaleString())} to ${grGreen(end_at.toLocaleString())}`) const filters = [{ key: 'locked', value: false }] if (id) filters.push({ key: 'id', value: id }) if (email) filters.push({ key: 'email', value: email }) if (first) filters.push({ key: 'first_name', value: first }) if (last) filters.push({ key: 'last_name', value: last }) spinner.text = `getting ${grGreen('users')}` const users = await getAll(User, { filter: { and: filters }, sort : [{ last_name: 1 }] }) spinner.succeed(`got ${users.length} ${grGreen('users')}`) spinner.text = `getting ${grGreen('timecards')}` let timecards = await getAll(Timecard, { filter: { and: [ { key: 'started_at', comparison: '>=', value: start_at }, { key: 'ended_at', comparison: '<=', value: end_at }, { key: 'status', comparison: '!=', value: 3 } ] } }) const corrected_timecards = await getAll(Timecard, { filter: { and: [ { key: 'started_correction', comparison: '>=', value: start_at }, { key: 'ended_correction', comparison: '<=', value: end_at }, { key: 'status', value: 3 } ] } }) const all_timecards = [ ...timecards, ...corrected_timecards ].filter(t => users.find(u => u.id === t.user_id)).sort((a, b) => (a.status === 3 ? a.started_correction : a. started_at) < (b.status === 3 ? b.started_correction : b. started_at) ? -1 : 1) spinner.succeed(`got ${all_timecards.length} total ${grGreen('timecards')}`) const csv_data = [] for (const user of users) { const user_timecards = all_timecards.filter(t => t.user_id === user.id) if (user_timecards.length === 0) continue // meta const total = { first: user.first_name, last: user.last_name, email: user.email, week: 'total', in: start_at, out: dateAddDays(end_at, -1), hours: 0, status: null, error: null } const week_totals = [] if (!weeks) weeks = [] for (let [index, week] of weeks.entries()) week_totals.push({ first: user.first_name, last: user.last_name, email: user.email, week: `week ${index + 1}`, in: (dateAddDays(start_at, index * 7)), out: dateAddDays(week, -1), hours: 0, status: null, error: null }) let previous // timecards const rows = [] for (let [index, timecard] of user_timecards.entries()) { const started_at = timecard.status === 3 ? timecard.started_correction : timecard.started_at const ended_at = timecard.status === 3 ? timecard.ended_correction : timecard.ended_at // row const row = { first: user.first_name, last: user.last_name, email: user.email, in: started_at, out: ended_at, hours: (ended_at - started_at) / 36e2, status: timecard_status[timecard.status], error: null } // week meta hours for (let [index, week] of week_totals.entries()) { const end = new Date(ended_at * 1000) if (end > week.in && end <= dateAddDays(week.out, 1)) { week.hours += row.hours row.week = week.week break } } // total hours total.hours += row.hours // Error Checking if (row.hours > 11) row.error = ('>11') if (previous && row.in < previous.out) { if (row.error) { row.error += ' overlap' } else { row.error = 'overlap' } } previous = row rows.push(row) } const meta = [ ...week_totals, total ] for (const m of meta) { m.in = m.in.toLocaleDateString() m.out = m.out.toLocaleDateString() } for (const r of rows) { r.in = r.in.toLocaleString() r.out = r.out.toLocaleString() r.hours = r.hours.toFixed ? r.hours.toFixed(2) : r.hours } // table const columns = [ { key: 'first', hidden: true }, { key: 'last', hidden: true }, { key: 'email', hidden: true }, { key: 'in', title: 'In' }, { key: 'out', title: 'Out' }, { key: 'hours', title: 'Hours' }, { key: 'status', title: 'Status', value: v => correctionStatus(v) }, { key: 'error', title: 'Error', value: v => cosmetic.red(v) } ] if (weeks.length) columns.splice(1, 0, { key: 'week', title: 'Week' }) const table = new Table(rows, { title: grGreen(user.last_name && user.first_name ? `${user.last_name}, ${user.first_name}` : user.email), align: 'center', meta, columns, margin: 4, }) csv_data.push(...rows, ...meta) spinner.stop() table.print() console.log() spinner.start() } if (write) { const path = await writeCSVFile(join(resolve(write === true ? '.' : write), 'gameroom-timecards-report.csv'), csv_data) spinner.succeed(`wrote data to ${path}`) } spinner.succeed(`generated ${grGreen('timecards')} report `).stop() }