| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- const app = require('../app')
- const moment = require('moment-immutable')
- const { editIcon, calculatedIcon, dollarIcon } = require('../assets')
- const _ = require('lodash')
- app.component('appLaborEntryPage', {
- template: html`
- <app-user-area title-text="{{ctrl.terminalKey}} Labor Entry">
- <app-breadcrumb links="[
- { text: 'Home', link: '/dashboard' },
- { text: ctrl.terminalKey + ' Labor', link: '/labor/' + ctrl.terminalKey },
- { text: ctrl.startDate.format('L') + ' - ' + ctrl.endDate.format('L'), link: '/labor/' + ctrl.terminalKey + '/' + ctrl.startDate.format('YYYY-MM-DD') }
- ]"></app-breadcrumb>
- <p>For week of {{ctrl.startDate.format('LL')}} to {{ctrl.endDate.format('LL')}}</p>
- <div>
- <md-input-container class="md-margin">
- <label>Labor Cost</label>
- <input type="text" readonly value="{{ctrl.model.workweek.laborCost | currency}}" />
- <md-icon md-svg-src="${calculatedIcon}">
- <md-tooltip md-direction="down" style="height: 7em">
- This field is calculated, <br/>
- and cannot be edited directly. <br />
- Save your changes to update.
- </md-tooltip>
- </md-icon>
- </md-input-container>
- <md-input-container class="md-margin">
- <label>Labor Charge</label>
- <input type="number" min="0" step="0.01" ng-model="ctrl.model.workweek.laborCharge" />
- <md-icon md-svg-src="${dollarIcon}"></md-icon>
- </md-input-container>
- <md-input-container class="md-margin" ng-if="ctrl.model.workweek.laborCharge && ctrl.model.workweek.laborCost">
- <label>Difference</label>
- <input type="text" readonly value="{{(ctrl.model.workweek.laborCost - ctrl.model.workweek.laborCharge) | currency}} or {{(ctrl.model.workweek.laborCharge / ctrl.model.workweek.laborCost) * 100 | number : 1}}%" />
- <md-icon md-svg-src="${calculatedIcon}">
- <md-tooltip md-direction="down" style="height: 7em">
- This field is calculated, <br/>
- and cannot be edited directly. <br />
- Save your changes to update.
- </md-tooltip>
- </md-icon>
- </md-input-container>
- </div>
- <form name="form" ng-submit="ctrl.submit()">
- <table md-table md-progress="ctrl.promise">
- <colgroup>
- <col style="width: 15%" />
- <col ng-repeat="weekday in ctrl.model.weekdays" style="width: 12%" />
- </colgroup>
- <thead md-head>
- <tr md-row>
- <th md-column>Staff Member</th>
- <th md-column ng-repeat="weekday in ::ctrl.weekdays">
- <span hide show-xs>{{::weekday.min}} {{::weekday.date.format('M/DD')}}</span>
- <span hide show-sm>{{::weekday.short}} {{::weekday.date.format('M/DD')}}</span>
- <span hide show-gt-sm>{{::weekday.name}}<br />{{::weekday.date.format('L')}}</span>
- </th>
- </tr>
- </thead>
- <tbody md-body>
- <tr md-row ng-repeat="sfl in ctrl.staffMemberLabor track by sfl.id" ng-init="$sflIndex = $index">
- <td md-cell>
- {{ctrl.staffMembers[sfl.id].name}}
- </td>
- <td md-cell ng-repeat="day in sfl.days track by $index" ng-init="$dayIndex = $index">
- <input
- class="hour-input md-button "
- tabindex="{{$index * ctrl.staffMemberLabor.length + ($parent.$index) + 1}}"
- ng-model="day.hours"
- type="number" min="0" step="0.01"
- ng-keypress="ctrl.keypress($event)"
- md-whiteframe="{{(day.hours == ctrl.saved[$sflIndex].days[$dayIndex].hours) ? 1 : 8}}">
- </td>
- </tr>
- </tbody>
- </table>
- <div>
- <md-button type="submit" class="md-raised md-primary">Submit</md-button>
- </div>
- </form>
- </app-user-area>
- `,
- controllerAs: 'ctrl',
- controller: function(api, $routeParams, weekdays, $mdToast) {
- this.terminalKey = $routeParams.terminal
- const week = moment($routeParams.week)
- if (!week.isSame(week.startOf('week'))) throw new Error('Date is not start of week')
- this.startDate = week
- this.endDate = week.endOf('week')
- this.weekdays = weekdays.map(d => Object.assign({}, d, {date: week.add(d.value, 'days')}))
- api.staffMemberDictionary().then(staffMembers => {
- this.staffMembers = staffMembers
- })
- const load = () => {
- this.promise = api.get(`/api/labor/${$routeParams.terminal}/${$routeParams.week}`).then((model) => {
- this.model = model
- const staffMemberIds = this.model.workdays[0].labor.map(x => x.staffMemberId)
- this.staffMemberLabor = staffMemberIds.map((id, i) => ({
- id,
- days: this.model.workdays.map(wd => wd.labor[i])
- }))
- this.saved = _.cloneDeep(this.staffMemberLabor)
- })
- }
- load()
- let saveTimer = null
- this.save = async (delay, then) => {
- if (saveTimer) {
- clearTimeout(saveTimer)
- }
- const model = {
- workweek: this.model.workweek,
- workdays: this.model.workdays.map(workday => ({
- labor: workday.labor.map(labor => ({
- staffMemberId: labor.staffMemberId,
- hours: labor.hours || null
- }))
- }))
- }
- const saved = _.cloneDeep(this.staffMemberLabor)
- saveTimer = setTimeout(async () => {
- saveTimer = null
- try {
- await api.patch(`/api/labor/${$routeParams.terminal}/${$routeParams.week}`, model)
- $mdToast.showSimple('Labor saved.')
- this.saved = saved
- if (then) {
- then()
- }
- } catch (err) {
- window.err = err
- console.error(err)
- $mdToast.showSimple(`Could not save Labor: ${err.message || err.statusText || err}`)
- }
- }, delay || 0)
- }
- this.submit = () => this.save(0, load)
- this.keypress = async ($event) => {
- if ($event.key === 'Enter') {
- const tabIndex = +$event.srcElement.getAttribute('tabindex') + 1
- const nextElement = document.querySelector(`[tabindex="${tabIndex}"]`)
- if (nextElement) {
- $event.returnValue = false
- nextElement.focus()
- nextElement.select && nextElement.select()
- }
- await this.save(2000)
- }
- }
- }
- })
|