Bladeren bron

Location -> Terminal

Alan Colon 7 jaren geleden
bovenliggende
commit
70c16cb4cb

+ 1 - 1
app/assets/index.js

@@ -4,7 +4,7 @@ module.exports = Object.assign(assets, {
   logo: require('./logo-simple.png'),
   staffingAgencyIcon: require('@alancnet/icomoon-svg/office.svg'),
   staffMemberIcon: require('@alancnet/icomoon-svg/user-tie.svg'),
-  locationIcon: require('@alancnet/icomoon-svg/location.svg'),
+  terminalIcon: require('@alancnet/icomoon-svg/location.svg'),
   laborIcon: require('./noun_constructor_593655.svg'),
   crumbIcon: require('@alancnet/material-design-icons/image_ic_navigate_next_48px.svg'),
   retailerIcon: require('@alancnet/material-design-icons/maps_ic_store_mall_directory_48px.svg'),

+ 6 - 6
app/components/labor-entry-page.js

@@ -4,11 +4,11 @@ const { editIcon } = require('../assets')
 
 app.component('appLaborEntryPage', {
   template: html`
-  <app-user-area title-text="{{ctrl.locationKey}} Labor Entry">
+  <app-user-area title-text="{{ctrl.terminalKey}} Labor Entry">
     <app-breadcrumb links="[
       { text: 'Home', link: '/dashboard' },
-      { text: ctrl.locationKey + ' Labor', link: '/labor/' + ctrl.locationKey },
-      { text: ctrl.startDate.format('L') + ' - ' + ctrl.endDate.format('L'), link: '/labor/' + ctrl.locationKey + '/' + ctrl.startDate.format('YYYY-MM-DD') }
+      { 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>
     <form name="form" ng-submit="ctrl.submit()">
@@ -47,7 +47,7 @@ app.component('appLaborEntryPage', {
   controllerAs: 'ctrl',
   controller: function(api, $routeParams, weekdays, $mdToast) {
     this.weekdays = weekdays
-    this.locationKey = $routeParams.location
+    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
@@ -55,7 +55,7 @@ app.component('appLaborEntryPage', {
     api.staffMemberDictionary().then(staffMembers => {
       this.staffMembers = staffMembers
     })
-    this.promise = api.get(`/api/labor/${$routeParams.location}/${$routeParams.week}`).then(({workdays}) => {
+    this.promise = api.get(`/api/labor/${$routeParams.terminal}/${$routeParams.week}`).then(({workdays}) => {
       this.model = workdays
       const staffMemberIds = workdays[0].labor.map(x => x.staffMemberId)
       this.staffMemberLabor = staffMemberIds.map((id, i) => ({
@@ -74,7 +74,7 @@ app.component('appLaborEntryPage', {
         }))
       }
       try {
-        await api.patch(`/api/labor/${$routeParams.location}/${$routeParams.week}`, model)
+        await api.patch(`/api/labor/${$routeParams.terminal}/${$routeParams.week}`, model)
         $mdToast.showSimple('Labor saved.')
       } catch (err) {
         window.err = err

+ 7 - 7
app/components/labor-page.js

@@ -3,10 +3,10 @@ const { editIcon } = require('../assets')
 
 app.component('appLaborPage', {
   template: html`
-    <app-user-area title-text="{{ctrl.locationKey}} Labor">
+    <app-user-area title-text="{{ctrl.terminalKey}} Labor">
       <app-breadcrumb links="[
         { text: 'Home', link: '/dashboard' },
-        { text: ctrl.locationKey + ' Labor', link: '/labor/' + ctrl.locationKey }
+        { text: ctrl.terminalKey + ' Labor', link: '/labor/' + ctrl.terminalKey }
       ]"></app-breadcrumb>
       <table md-table ng-model="ctrl.selected" md-progress="ctrl.promise">
         <thead md-head>
@@ -42,7 +42,7 @@ app.component('appLaborPage', {
               </div>
             </td>
             <td md-cell>
-              <md-button ng-href="labor/{{::ctrl.location.key}}/{{::week.workweek}}">
+              <md-button ng-href="labor/{{::ctrl.terminal.key}}/{{::week.workweek}}">
                 <md-icon md-svg-icon="${editIcon}"></md-icon>
                 Edit
               </md-button>
@@ -55,12 +55,12 @@ app.component('appLaborPage', {
   `,
   controllerAs: 'ctrl',
   controller: function(api, $routeParams, weekdays) {
-    this.locationKey = $routeParams.location
+    this.terminalKey = $routeParams.terminal
     this.weekdays = weekdays
-    api.location($routeParams.location).then(location => {
-      this.location = location
+    api.terminal($routeParams.terminal).then(terminal => {
+      this.terminal = terminal
     })
-    this.promise = api.get(`/api/labor/${$routeParams.location}`).then(labor => {
+    this.promise = api.get(`/api/labor/${$routeParams.terminal}`).then(labor => {
       this.labor = labor
     })
   }

+ 6 - 6
app/components/services-entry-page.js

@@ -4,11 +4,11 @@ const { editIcon } = require('../assets')
 
 app.component('appServicesEntryPage', {
   template: html`
-  <app-user-area title-text="{{ctrl.locationKey}} Service Entry">
+  <app-user-area title-text="{{ctrl.terminalKey}} Service Entry">
     <app-breadcrumb links="[
       { text: 'Home', link: '/dashboard' },
-      { text: ctrl.locationKey + ' Services', link: '/services/' + ctrl.locationKey },
-      { text: ctrl.startDate.format('L') + ' - ' + ctrl.endDate.format('L'), link: '/services/' + ctrl.locationKey + '/' + ctrl.startDate.format('YYYY-MM-DD') }
+      { text: ctrl.terminalKey + ' Services', link: '/services/' + ctrl.terminalKey },
+      { text: ctrl.startDate.format('L') + ' - ' + ctrl.endDate.format('L'), link: '/services/' + ctrl.terminalKey + '/' + ctrl.startDate.format('YYYY-MM-DD') }
     ]"></app-breadcrumb>
     <p>For week of {{::ctrl.startDate.format('LL')}} to {{::ctrl.endDate.format('LL')}}</p>
     <form name="form" ng-submit="ctrl.submit()">
@@ -47,7 +47,7 @@ app.component('appServicesEntryPage', {
   controllerAs: 'ctrl',
   controller: function(api, $routeParams, weekdays, $mdToast) {
     this.weekdays = weekdays
-    this.locationKey = $routeParams.location
+    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
@@ -55,7 +55,7 @@ app.component('appServicesEntryPage', {
     api.retailerDictionary().then(retailers => {
       this.retailers = retailers
     })
-    this.promise = api.get(`/api/services/${$routeParams.location}/${$routeParams.week}`).then(({workdays}) => {
+    this.promise = api.get(`/api/services/${$routeParams.terminal}/${$routeParams.week}`).then(({workdays}) => {
       this.model = workdays
       const retailerIds = workdays[0].services.map(x => x.retailerId)
       this.retailerServices = retailerIds.map((id, i) => ({
@@ -74,7 +74,7 @@ app.component('appServicesEntryPage', {
         }))
       }
       try {
-        await api.patch(`/api/services/${$routeParams.location}/${$routeParams.week}`, model)
+        await api.patch(`/api/services/${$routeParams.terminal}/${$routeParams.week}`, model)
         $mdToast.showSimple('Services saved.')
       } catch (err) {
         window.err = err

+ 7 - 7
app/components/services-page.js

@@ -3,10 +3,10 @@ const { editIcon } = require('../assets')
 
 app.component('appServicesPage', {
   template: html`
-    <app-user-area title-text="{{ctrl.locationKey}} Services">
+    <app-user-area title-text="{{ctrl.terminalKey}} Services">
       <app-breadcrumb links="[
         { text: 'Home', link: '/dashboard' },
-        { text: ctrl.locationKey + ' Services', link: '/services/' + ctrl.locationKey }
+        { text: ctrl.terminalKey + ' Services', link: '/services/' + ctrl.terminalKey }
       ]"></app-breadcrumb>
       <table md-table ng-model="ctrl.selected" md-progress="ctrl.promise">
         <thead md-head>
@@ -39,7 +39,7 @@ app.component('appServicesPage', {
               </div>
             </td>
             <td md-cell>
-              <md-button ng-href="services/{{::ctrl.location.key}}/{{::week.workweek}}">
+              <md-button ng-href="services/{{::ctrl.terminal.key}}/{{::week.workweek}}">
                 <md-icon md-svg-icon="${editIcon}"></md-icon>
                 Edit
               </md-button>
@@ -52,12 +52,12 @@ app.component('appServicesPage', {
   `,
   controllerAs: 'ctrl',
   controller: function(api, $routeParams, weekdays) {
-    this.locationKey = $routeParams.location
+    this.terminalKey = $routeParams.terminal
     this.weekdays = weekdays
-    api.location($routeParams.location).then(location => {
-      this.location = location
+    api.terminal($routeParams.terminal).then(terminal => {
+      this.terminal = terminal
     })
-    this.promise = api.get(`/api/services/${$routeParams.location}`).then(services => {
+    this.promise = api.get(`/api/services/${$routeParams.terminal}`).then(services => {
       this.services = services
     })
   }

+ 16 - 11
app/components/staff-member-pages.js

@@ -2,13 +2,13 @@ const { pages } = require('@alancnet/material-framework/app/crud')
 
 pages({
   camelName: 'staffMember',
-  apiPrefix: '/api/staff-members/:location',
-  appPrefix: '/staff-members/:location',
+  apiPrefix: '/api/staff-members/:terminal',
+  appPrefix: '/staff-members/:terminal',
   titles: {
     details: ctrl => ctrl.isNew
-    ? `New ${ctrl.$routeParams.location == 'all' ? '' : ctrl.$routeParams.location} Staff Member`
-    : `${ctrl.$routeParams.location == 'all' ? '' : ctrl.$routeParams.location} Staff Member Details`,
-    list: ctrl => `${ctrl.$routeParams.location == 'all' ? 'All' : ctrl.$routeParams.location} Staff Members`
+    ? `New ${ctrl.$routeParams.terminal == 'all' ? '' : ctrl.$routeParams.terminal} Staff Member`
+    : `${ctrl.$routeParams.terminal == 'all' ? '' : ctrl.$routeParams.terminal} Staff Member Details`,
+    list: ctrl => `${ctrl.$routeParams.terminal == 'all' ? 'All' : ctrl.$routeParams.terminal} Staff Members`
   },
   columns: [
     { camelName: 'name', row: 1 },
@@ -20,11 +20,11 @@ pages({
       apiPrefix: '/api/labor-categories'
     },
     {
-      titleName: 'Location',
-      camelName: 'locationId',
-      routeParam: 'location',
+      titleName: 'terminal',
+      camelName: 'terminalId',
+      routeParam: 'terminal',
       type: 'autocomplete',
-      apiPrefix: '/api/locations'
+      apiPrefix: '/api/terminals'
     },
     {
       titleName: 'Staffing Agency',
@@ -36,14 +36,19 @@ pages({
       inList: false,
       camelName: 'wage',
       type: 'currency'
+    },
+    {
+      inList: false,
+      camelName: 'salary',
+      type: 'currency'
     }
   ],
   layout: [
     {
       section: null,
       rows: [
-        [ 'name', 'title' ],
-        [ 'wage', 'locationId' ]
+        [ 'name', 'title', 'terminalId' ],
+        [ 'wage', 'salary' ]
       ]
     },
     {

+ 14 - 14
app/components/user-area-nav.js

@@ -17,35 +17,35 @@ app.component('appUserAreaNav', {
       </md-menu-item>
     </div>
 
-    <div ng-repeat="location in $ctrl.locations">
-      <h3>{{::location.name}}</h3>
+    <div ng-repeat="terminal in $ctrl.terminals">
+      <h3>{{::terminal.name}}</h3>
       <md-menu-item ng-if="$ctrl.api.claims.LABOR_VIEW">
-        <md-button ng-href="/labor/{{::location.key}}">
+        <md-button ng-href="/labor/{{::terminal.key}}">
           <md-icon md-svg-icon="${laborIcon}"></md-icon>
-          {{::location.key}} Labor
+          {{::terminal.key}} Labor
         </md-button>
       </md-menu-item>
       <md-menu-item ng-if="$ctrl.api.claims.SERVICES_VIEW">
-        <md-button ng-href="/services/{{::location.key}}">
+        <md-button ng-href="/services/{{::terminal.key}}">
           <md-icon md-svg-icon="${serviceIcon}"></md-icon>
-          {{::location.key}} Services
+          {{::terminal.key}} Services
         </md-button>
       </md-menu-item>
       <md-menu-item ng-if="$ctrl.api.claims.STAFF_MEMBER_READ">
-        <md-button ng-href="/staff-members/{{::location.key}}">
+        <md-button ng-href="/staff-members/{{::terminal.key}}">
           <md-icon md-svg-icon="${staffMemberIcon}"></md-icon>
-          {{::location.key}} Staff Members
+          {{::terminal.key}} Staff Members
         </md-button>
       </md-menu-item>
       <md-menu-item ng-if="$ctrl.api.claims.RETAILER_READ">
-        <md-button ng-href="/retailers/{{::location.key}}">
+        <md-button ng-href="/retailers/{{::terminal.key}}">
           <md-icon md-svg-icon="${retailerIcon}"></md-icon>
-          {{::location.key}} Clients
+          {{::terminal.key}} Clients
         </md-button>
       </md-menu-item>
     </div>
 
-    <div ng-if="$ctrl.api.claims.LOCATION_ALL_ACCESS">
+    <div ng-if="$ctrl.api.claims.TERMINAL_ALL_ACCESS">
       <h3>All</h3>
       <md-menu-item ng-if="$ctrl.api.claims.STAFF_MEMBER_READ">
         <md-button ng-href="/staff-members/all">
@@ -70,9 +70,9 @@ app.component('appUserAreaNav', {
   `,
   controller: function(api) {
     this.api = api
-    api.locations().then(locations => {
-      this.locations = _.sortBy(locations, 'key')
-        .filter(({key}) => api.claims[`LOCATION_${key}_ACCESS`])
+    api.terminals().then(terminals => {
+      this.terminals = _.sortBy(terminals, 'key')
+        .filter(({key}) => api.claims[`TERMINAL_${key}_ACCESS`])
     })
   }
 })

+ 5 - 5
app/routes.js

@@ -1,9 +1,9 @@
 module.exports = function($routeProvider) {
   $routeProvider.when('/dashboard', {template: '<app-dashboard-page />'})
-  $routeProvider.crudRoutes({ appPrefix: '/staff-members/:location', camelName: 'staffMember' })
+  $routeProvider.crudRoutes({ appPrefix: '/staff-members/:terminal', camelName: 'staffMember' })
   $routeProvider.crudRoutes({ camelName: 'staffingAgency' })
-  $routeProvider.when('/labor/:location', {template: '<app-labor-page />'})
-  $routeProvider.when('/labor/:location/:week', {template: '<app-labor-entry-page />'})
-  $routeProvider.when('/services/:location', {template: '<app-services-page />'})
-  $routeProvider.when('/services/:location/:week', {template: '<app-services-entry-page />'})
+  $routeProvider.when('/labor/:terminal', {template: '<app-labor-page />'})
+  $routeProvider.when('/labor/:terminal/:week', {template: '<app-labor-entry-page />'})
+  $routeProvider.when('/services/:terminal', {template: '<app-services-page />'})
+  $routeProvider.when('/services/:terminal/:week', {template: '<app-services-entry-page />'})
 }

+ 7 - 7
app/services/api.js

@@ -4,15 +4,15 @@ const _ = require('lodash')
 app.run(function(api) {
   api.statistics = () => api.get('/api/statistics')
 
-  let locations = null
-  api.locations = () => locations || (locations = api.get('/api/locations'))
+  let terminals = null
+  api.terminals = () => terminals || (terminals = api.get('/api/terminals'))
 
-  let locationsDictionary = null
-  api.locationsDictionary = () => locationsDictionary || (locationsDictionary = api.locations().then(locations => 
-    _.fromPairs(locations.map(loc => [loc.key, loc]))
+  let terminalsDictionary = null
+  api.terminalsDictionary = () => terminalsDictionary || (terminalsDictionary = api.terminals().then(terminals => 
+    _.fromPairs(terminals.map(loc => [loc.key, loc]))
   ))
-  api.location = (key) => api.locations().then(async locations =>
-    (await api.locationsDictionary())[key]
+  api.terminal = (key) => api.terminals().then(async terminals =>
+    (await api.terminalsDictionary())[key]
   )
   let staffMembers = null
   api.staffMembers = () => staffMembers || (staffMembers = api.get('/api/staff-members/all'))

+ 1 - 1
auto-crud/index.js

@@ -1,4 +1,4 @@
-require('./location')
+require('./terminal')
 require('./labor-category')
 require('./retailer')
 /* Example */

+ 8 - 8
auto-crud/retailer.js

@@ -3,13 +3,13 @@ const { register, Sequelize } = require('@alancnet/material-framework/auto-crud'
 register({
   camelName: 'retailer',
   iconAsset: 'userIcon',
-  appPrefix: '/retailers/:location',
-  apiPrefix: '/api/retailers/:location',
+  appPrefix: '/retailers/:terminal',
+  apiPrefix: '/api/retailers/:terminal',
   titles: {
     details: ctrl => ctrl.isNew
-    ? `New ${ctrl.$routeParams.location == 'all' ? '' : ctrl.$routeParams.location} Client`
-    : `${ctrl.$routeParams.location == 'all' ? '' : ctrl.$routeParams.location} Client Details`,
-    list: ctrl => `${ctrl.$routeParams.location == 'all' ? 'All' : ctrl.$routeParams.location} Clients`
+    ? `New ${ctrl.$routeParams.terminal == 'all' ? '' : ctrl.$routeParams.terminal} Client`
+    : `${ctrl.$routeParams.terminal == 'all' ? '' : ctrl.$routeParams.terminal} Client Details`,
+    list: ctrl => `${ctrl.$routeParams.terminal == 'all' ? 'All' : ctrl.$routeParams.terminal} Clients`
   },
   showNav: false,
   schema: {
@@ -24,7 +24,7 @@ register({
       unique: true
     },
     address: Sequelize.STRING,
-    locationId: Sequelize.UUID,
+    terminalId: Sequelize.UUID,
     distanceMiles: Sequelize.DOUBLE
   },
   options: {
@@ -40,7 +40,7 @@ register({
     { camelName: 'key' },
     { camelName: 'name' },
     { camelName: 'address', inList: false },
-    { camelName: 'locationId', titleName: 'Location', type: 'autocomplete', apiPrefix: '/api/locations', routeParam: 'location' },
+    { camelName: 'terminalId', titleName: 'terminal', type: 'autocomplete', apiPrefix: '/api/terminals', routeParam: 'terminal' },
     { camelName: 'distanceMiles', titleName: 'Distance in Miles', type: 'number' }
   ],
   layout: [
@@ -49,7 +49,7 @@ register({
       rows: [
         [ 'name', 'key' ],
         [ 'address' ],
-        [ 'locationId', 'distanceMiles' ]
+        [ 'terminalId', 'distanceMiles' ]
       ]
     }
   ]

+ 1 - 1
auto-crud/service.js

@@ -37,7 +37,7 @@ register({
       rows: [
         [ 'name', 'key' ],
         [ 'address' ]
-        [ 'locationId', 'distanceMiles' ]
+        [ 'terminalId', 'distanceMiles' ]
       ]
     }
   ]

+ 2 - 2
auto-crud/location.js → auto-crud/terminal.js

@@ -1,8 +1,8 @@
 const { register, Sequelize } = require('@alancnet/material-framework/auto-crud')
 
 register({
-  camelName: 'location',
-  iconAsset: 'locationIcon',
+  camelName: 'terminal',
+  iconAsset: 'terminalIcon',
   showNav: false,
   schema: {
     id: {

+ 16 - 16
lib/controllers/labor.js

@@ -1,14 +1,14 @@
 const _ = require('lodash')
 const moment = require('moment-immutable')
 const { getWeeks, formatDate, parseDate } = require('../dates')
-const { StaffMember, Workday, Location, Labor, sequelize } = require('../database')
+const { StaffMember, Workday, Terminal, Labor, sequelize } = require('../database')
 const { Op } = require('sequelize')
 
 const list = async (req, res) => {
-  const locationKey = req.params.location
-  const location = await Location.findOne({where: {key: locationKey}})
-  if (!location) return res.status(404).end()
-  const workdays = await Workday.findAll({where: { locationId: location.id }})
+  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')))
   
@@ -47,12 +47,12 @@ const list = async (req, res) => {
 }
 
 const get = async (req, res) => {
-  const locationKey = req.params.location
-  const location = await Location.findOne({where: {key: locationKey}})
+  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: {
-      locationId: location.id,
+      terminalId: terminal.id,
       date: {
         [Op.gte]: week,
         [Op.lte]: moment(week).endOf('week')
@@ -76,7 +76,7 @@ const get = async (req, res) => {
   const staffMembers = await StaffMember.findAll({
     where: {
       [Op.or]: [
-        { locationId: location.id },
+        { terminalId: terminal.id },
         {
           id: {
             [Op.in]: extraStaffMembers
@@ -107,7 +107,7 @@ const get = async (req, res) => {
         staffMemberId: sm.staffMemberId,
         hours: (sm.regularHours + sm.overtimeHours) || null
       }))
-    // Restore any staffMembers that are no longer assigned this location
+    // Restore any staffMembers that are no longer assigned this terminal
     labor.forEach(l => {
       if (!staffMembersById[l.staffMemberId]) {
         wd.labor.push(l)
@@ -124,12 +124,12 @@ const get = async (req, res) => {
 const patch = async (req, res) => {
   const transaction = await sequelize.transaction()
   try {
-    const locationKey = req.params.location
-    const location = await Location.findOne({where: {key: locationKey}})
+    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: {
-        locationId: location.id,
+        terminalId: terminal.id,
         date: {
           [Op.gte]: week,
           [Op.lt]: moment(week).endOf('week')
@@ -153,7 +153,7 @@ const patch = async (req, res) => {
     const staffMembers = await StaffMember.findAll({
       where: {
         [Op.or]: [
-          { locationId: location.id },
+          { terminalId: terminal.id },
           {
             id: {
               [Op.in]: extraStaffMembers
@@ -171,7 +171,7 @@ const patch = async (req, res) => {
     for (let day = week, i = 0; i < 7; i++, day = day.add(1, 'day')) {
       const wd = workdaysByKey[formatDate(day)]
       allWorkdays[i] = wd || Workday.build({
-        locationId: location.id,
+        terminalId: terminal.id,
         date: week.add(i, 'day')
       })
     }
@@ -181,7 +181,7 @@ const patch = async (req, res) => {
       const laborByStaffMember = _.chain(labor).map(l => [l.staffMemberId, l]).fromPairs().value()
       // Map from staffMembers to preserve sorting
       wd.labor = staffMembers.map(sm => laborByStaffMember[sm.id] || Labor.build({staffMemberId: sm.id, workdayId: wd.id}))
-      // Restore any staffMembers that are no longer assigned this location
+      // Restore any staffMembers that are no longer assigned this terminal
       labor.forEach(l => {
         if (!staffMembersById[l.staffMemberId]) {
           wd.labor.push(l)

+ 16 - 16
lib/controllers/services.js

@@ -1,14 +1,14 @@
 const _ = require('lodash')
 const moment = require('moment-immutable')
 const { getWeeks, formatDate, parseDate } = require('../dates')
-const { Retailer, Workday, Location, Service, sequelize } = require('../database')
+const { Retailer, Workday, Terminal, Service, sequelize } = require('../database')
 const { Op } = require('sequelize')
 
 const list = async (req, res) => {
-  const locationKey = req.params.location
-  const location = await Location.findOne({where: {key: locationKey}})
-  if (!location) return res.status(404).end()
-  const workdays = await Workday.findAll({where: { locationId: location.id }})
+  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')))
   
@@ -45,12 +45,12 @@ const list = async (req, res) => {
 }
 
 const get = async (req, res) => {
-  const locationKey = req.params.location
-  const location = await Location.findOne({where: {key: locationKey}})
+  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: {
-      locationId: location.id,
+      terminalId: terminal.id,
       date: {
         [Op.gte]: week,
         [Op.lt]: moment(week).endOf('week')
@@ -74,7 +74,7 @@ const get = async (req, res) => {
   const retailers = await Retailer.findAll({
     where: {
       [Op.or]: [
-        { locationId: location.id },
+        { terminalId: terminal.id },
         {
           id: {
             [Op.in]: extraRetailers
@@ -104,7 +104,7 @@ const get = async (req, res) => {
         retailerId: sm.retailerId,
         cartons: sm.cartons || null
       }))
-    // Restore any staffMembers that are no longer assigned this location
+    // Restore any staffMembers that are no longer assigned this terminal
     services.forEach(l => {
       if (!serviceByRetailer[l.retailerId]) {
         wd.services.push(l)
@@ -121,12 +121,12 @@ const get = async (req, res) => {
 const patch = async (req, res) => {
   const transaction = await sequelize.transaction()
   try {
-    const locationKey = req.params.location
-    const location = await Location.findOne({where: {key: locationKey}})
+    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: {
-        locationId: location.id,
+        terminalId: terminal.id,
         date: {
           [Op.gte]: week,
           [Op.lte]: moment(week).endOf('week')
@@ -150,7 +150,7 @@ const patch = async (req, res) => {
     const retailers = await Retailer.findAll({
       where: {
         [Op.or]: [
-          { locationId: location.id },
+          { terminalId: terminal.id },
           {
             id: {
               [Op.in]: extraRetailers
@@ -168,7 +168,7 @@ const patch = async (req, res) => {
     for (let day = week, i = 0; i < 7; i++, day = day.add(1, 'day')) {
       const wd = workdaysByKey[formatDate(day)]
       allWorkdays[i] = wd || Workday.build({
-        locationId: location.id,
+        terminalId: terminal.id,
         date: week.add(i, 'day')
       })
     }
@@ -178,7 +178,7 @@ const patch = async (req, res) => {
       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 location
+      // Restore any staffMembers that are no longer assigned this terminal
       services.forEach(l => {
         if (!retailersById[l.retailerId]) {
           wd.services.push(l)

+ 6 - 6
lib/controllers/statistics.js

@@ -1,9 +1,9 @@
-const { Location } = require('../database')
+const { Terminal } = require('../database')
 const sequelize = require('../database/sequelize')
 
 const get = async (req, res) => {
-  const locationIds = (await Location.findAll())
-    .filter(loc => req.claims.LOCATION_ALL_ACCESS || req.claims[`LOCATION_${loc.key}_ACCESS`])
+  const terminalIds = (await Terminal.findAll())
+    .filter(loc => req.claims.TERMINAL_ALL_ACCESS || req.claims[`TERMINAL_${loc.key}_ACCESS`])
     .map(loc => loc.id)
 
   const [results, metadata] = await sequelize.query(`
@@ -15,12 +15,12 @@ const get = async (req, res) => {
       SUM(svc.scanned) as scanned,
       SUM(svc.delivered) / (wd.regularHours + (wd.overtimeHours * 1.5)) as efficiency
     FROM workdays wd
-    JOIN locations loc on wd.locationId = loc.id
+    JOIN terminals loc on wd.terminalId = loc.id
     LEFT JOIN services svc on svc.workdayId = wd.id
-    WHERE loc.id IN(:locationIds)
+    WHERE loc.id IN(:terminalIds)
     GROUP BY loc.key, wd.date
   `, {
-    replacements: { locationIds }
+    replacements: { terminalIds }
   })
   res.status(200).send(results)
 

+ 16 - 15
lib/database/index.js

@@ -1,9 +1,10 @@
+require('./migrations')
 // TODO: App Specific Models
 const {database} = require('@alancnet/material-framework/server')
-const { Location, Retailer } = database
+const { Terminal, Retailer } = database
 const initialize = require('./initialize')
 
-// const Location = require('./location')
+// const Terminal = require('./terminal')
 const Workday = require('./workday')
 const Service = require('./service')
 //const Retailer = require('./retailer')
@@ -11,8 +12,8 @@ const StaffMember = require('./staff-member')
 const StaffingAgency = require('./staffing-agency')
 const Labor = require('./labor')
 
-const LocationWorkday = Location.hasMany(Workday)
-const WorkdayLocation = Workday.belongsTo(Location)
+const TerminalWorkday = Terminal.hasMany(Workday)
+const WorkdayTerminal = Workday.belongsTo(Terminal)
 
 const WorkdayService = Workday.hasMany(Service)
 const ServiceWorkday = Service.belongsTo(Workday)
@@ -20,11 +21,11 @@ const ServiceWorkday = Service.belongsTo(Workday)
 const RetailerService = Retailer.hasMany(Service)
 const ServiceRetailer = Service.belongsTo(Retailer)
 
-const LocationStaffMember = Location.hasMany(StaffMember)
-const StaffMemberLocation = StaffMember.belongsTo(Location)
+const TerminalStaffMember = Terminal.hasMany(StaffMember)
+const StaffMemberTerminal = StaffMember.belongsTo(Terminal)
 
-const LocationRetailer = Location.hasMany(Retailer)
-const RetailerLocation = Retailer.belongsTo(Location)
+const TerminalRetailer = Terminal.hasMany(Retailer)
+const RetailerTerminal = Retailer.belongsTo(Terminal)
 
 // const StaffingAgencyStaffMember = StaffingAgency.hasMany(StaffMember)
 // const StaffMemberStaffingAgency = StaffMember.belongsTo(StaffingAgency)
@@ -38,21 +39,21 @@ const init = async () => {
 
 module.exports = Object.assign(database, {
   init,
-  Location,
+  Terminal,
   Workday,
   Service,
   Retailer,
   StaffMember,
   StaffingAgency,
-  LocationWorkday,
-  WorkdayLocation,
+  TerminalWorkday,
+  WorkdayTerminal,
   WorkdayService,
   ServiceWorkday,
   RetailerService,
   ServiceRetailer,
-  LocationStaffMember,
-  StaffMemberLocation,
+  TerminalStaffMember,
+  StaffMemberTerminal,
   Labor,
-  LocationRetailer,
-  RetailerLocation
+  TerminalRetailer,
+  RetailerTerminal
 })

+ 21 - 21
lib/database/initialize.js

@@ -1,6 +1,6 @@
 const { controllers: C } = require('@alancnet/material-framework/server')
 const { register } = C.auth.permissions
-const locations = [
+const terminals = [
   {
     name: 'Las Vegas',
     key: 'LAS'
@@ -50,12 +50,12 @@ const roles = [
       'LABOR_CATEGORY_UPDATE',
       'LABOR_ENTRY',
       'LABOR_VIEW',
-      'LOCATION_ALL_ACCESS',
-      'LOCATION_CREATE',
-      'LOCATION_DELETE',
-      'LOCATION_READ',
-      'LOCATION_UNDELETE',
-      'LOCATION_UPDATE',
+      'TERMINAL_ALL_ACCESS',
+      'TERMINAL_CREATE',
+      'TERMINAL_DELETE',
+      'TERMINAL_READ',
+      'TERMINAL_UNDELETE',
+      'TERMINAL_UPDATE',
       'METRICS_VIEW',
       'RETAILER_CREATE',
       'RETAILER_DELETE',
@@ -88,10 +88,10 @@ const roles = [
       'VIEW_INCOME_DELIVERY',
       'VIEW_INCOME_OPS',
       'VIEW_INCOME_WAREHOUSE',
-      'VIEW_LOCATION_LAS',
-      'VIEW_LOCATION_LAX',
-      'VIEW_LOCATION_PHX',
-      'VIEW_LOCATION_SFO'
+      'VIEW_TERMINAL_LAS',
+      'VIEW_TERMINAL_LAX',
+      'VIEW_TERMINAL_PHX',
+      'VIEW_TERMINAL_SFO'
     ].join(',')
   },
   {
@@ -99,7 +99,7 @@ const roles = [
     key: 'TERMINAL_MANAGER',
     permissions: [
       'LABOR_CATEGORY_READ',
-      'LOCATION_READ',
+      'TERMINAL_READ',
       'METRICS_VIEW',
       'RETAILER_CREATE',
       'RETAILER_DELETE',
@@ -121,7 +121,7 @@ const roles = [
     key: 'ACCOUNTING',
     permissions: [
       'LABOR_CATEGORY_READ',
-      'LOCATION_READ',
+      'TERMINAL_READ',
       'RETAILER_READ',
       'STAFFING_AGENCY_CREATE',
       'STAFFING_AGENCY_DELETE',
@@ -141,20 +141,20 @@ const roles = [
     name: 'Standard User',
     key: 'USER',
   }
-].concat(locations.map(loc => ({
+].concat(terminals.map(loc => ({
   name: `${loc.name}`,
   key: `${loc.key}`,
-  permissions: `LOCATION_${loc.key}_ACCESS`
+  permissions: `TERMINAL_${loc.key}_ACCESS`
 })))
 
 
 
-const initializeLocations = async db => {
+const initializeTerminals = async db => {
 
-  for (let location of locations) {
-    const record = await db.upsert(db.Location, location)
-    register(`LOCATION_${location.key}_ACCESS`, `Access ${location.name}.`)
-    console.log(`Upserted Location ${location.name}: ${JSON.stringify(record)}`) 
+  for (let terminal of terminals) {
+    const record = await db.upsert(db.Terminal, terminal)
+    register(`TERMINAL_${terminal.key}_ACCESS`, `Access ${terminal.name}.`)
+    console.log(`Upserted Terminal ${terminal.name}: ${JSON.stringify(record)}`) 
   }
 }
 
@@ -174,7 +174,7 @@ const initializeLaborCategories = async db => {
 }
 
 const init = async (db) => {
-  await initializeLocations(db)
+  await initializeTerminals(db)
   await initializeRoles(db)
   await initializeLaborCategories(db)
 }

+ 1 - 1
lib/database/labor.js

@@ -12,7 +12,7 @@ const Labor = sequelize.define('labor', {
   laborCategoryId: Sequelize.UUID,
   regularHours: Sequelize.DOUBLE,
   overtimeHours: Sequelize.DOUBLE,
-  laborCost: Sequelize.DECIMAL,
+  laborCost: Sequelize.DECIMAL(19, 4),
 }, {
   paranoid: true,
   indexes: [

+ 26 - 0
lib/database/migrations/1.01-location-to-terminal.js

@@ -0,0 +1,26 @@
+const chalk = require('chalk')
+module.exports = {
+  version: 1.01,
+  name: 'Location to Terminal',
+  description: 'Refactors `Location` to `Terminal`',
+  up: async (queryInterface, Sequelize) => {
+    // Tables with locationId: 
+    // Retailer
+    // Service
+    // StaffMember
+    // Workday
+
+    console.log(chalk.red('Renaming locationId -> terminalId on retailers'))
+    await queryInterface.renameColumn('retailers', 'locationId', 'terminalId')
+
+    console.log(chalk.red('Renaming locationId -> terminalId on staffMembers'))
+    await queryInterface.renameColumn('staffMembers', 'locationId', 'terminalId')
+
+    console.log(chalk.red('Renaming locationId -> terminalId on workdays'))
+    await queryInterface.renameColumn('workdays', 'locationId', 'terminalId')
+
+    console.log(chalk.red('Renaming table locations -> terminals'))
+    await queryInterface.renameTable('locations', 'terminals')
+    return 1.01
+  }
+}

+ 8 - 0
lib/database/migrations/index.js

@@ -0,0 +1,8 @@
+const migrations = require('@alancnet/material-framework/lib/database/migrations')
+module.exports = Object.assign(migrations, {
+  'special-dispatch-app': [
+    require('./1.01-location-to-terminal.js')
+  ]
+})
+
+module.exports['special-dispatch-app'].defaultVersion = -1

+ 1 - 1
lib/database/retailer.js

@@ -13,7 +13,7 @@ const Retailer = sequelize.define('retailer', {
     unique: true
   },
   address: Sequelize.STRING,
-  locationId: Sequelize.UUID,
+  terminalId: Sequelize.UUID,
   distanceMiles: Sequelize.DOUBLE
 }, {
   paranoid: true,

+ 3 - 2
lib/database/staff-member.js

@@ -12,8 +12,9 @@ const StaffMember = sequelize.define('staffMember', {
   name: Sequelize.STRING,
   title: Sequelize.STRING,
   identifier: Sequelize.STRING,
-  locationId: Sequelize.UUID,
-  wage: Sequelize.DECIMAL
+  terminalId: Sequelize.UUID,
+  wage: Sequelize.DECIMAL(19, 4),
+  salary: Sequelize.DECIMAL(19, 4)
 }, {
   paranoid: true,
   indexes: [

+ 3 - 3
lib/database/workday.js

@@ -7,11 +7,11 @@ const Workday = sequelize.define('workday', {
     defaultValue: Sequelize.UUIDV1,
     primaryKey: true
   },
-  locationId: Sequelize.UUID,
+  terminalId: Sequelize.UUID,
   date: Sequelize.DATEONLY,
   regularHours: Sequelize.DOUBLE,
   overtimeHours: Sequelize.DOUBLE,
-  laborCost: Sequelize.DECIMAL,
+  laborCost: Sequelize.DECIMAL(19, 4),
   cartons: Sequelize.INTEGER
 
 }, {
@@ -19,7 +19,7 @@ const Workday = sequelize.define('workday', {
   indexes: [
     {
       unique: true,
-      fields: ['locationId', 'date']
+      fields: ['terminalId', 'date']
     }
   ]
 })

+ 5 - 5
lib/integration/locations.js

@@ -1,21 +1,21 @@
 const _ = require('lodash')
-const { init, Location } = require('../database')
+const { init, Terminal } = require('../database')
 
 module.exports = async () => {
 
-  await Location.upsert({
+  await Terminal.upsert({
     name: 'Los Angeles',
     key: 'LAX'
   }),
-  await Location.upsert({
+  await Terminal.upsert({
     name: 'San Francisco',
     key: 'SFO'
   }),
-  await Location.upsert({
+  await Terminal.upsert({
     name: 'Las Vegas',
     key: 'LAS'
   })
-  return _.chain(await Location.findAll())
+  return _.chain(await Terminal.findAll())
     .map(o => [o.key, o])
     .fromPairs()
     .value()

+ 5 - 5
lib/integration/xlsx-reports.js

@@ -1,14 +1,14 @@
 const _ = require('lodash')
 const { init, Retailer, Service, Workday } = require('../database')
 const { title } = require('change-case')
-const locations = require('./locations')
+const terminals = require('./terminals')
 
 const XLSX = require('xlsx')
 
 const $import = async (locKey, filename) => {
   await init()
-  const locs = await locations()
-  const location = locs[locKey]
+  const locs = await terminals()
+  const terminal = locs[locKey]
   const book = XLSX.readFile(filename)
   const sheets = []
   for (let sheetName of book.SheetNames) {
@@ -67,14 +67,14 @@ const $import = async (locKey, filename) => {
   
   for (let workday of workdays) {
     await Workday.upsert({
-      locationId: location.id,
+      terminalId: terminal.id,
       date: workday.date,
       regularHours: workday.regularHours,
       overtimeHours: workday.overtimeHours
     })
 
     const wd = await Workday.find({where: {
-      locationId: location.id,
+      terminalId: terminal.id,
       date: workday.date
     }})
 

+ 1 - 1
lib/permissions.js

@@ -1,7 +1,7 @@
 const { controllers: C } = require('@alancnet/material-framework/server')
 const { register } = C.auth.permissions
 
-register('LOCATION_ALL_ACCESS', 'Access records for entire organization. Does not grant access to location-specific views. ')
+register('TERMINAL_ALL_ACCESS', 'Access records for entire organization. Does not grant access to terminal-specific views. ')
 register('METRICS_VIEW', 'View metrics / statistics.')
 register('LABOR_VIEW', 'View labor / hours worked.')
 register('LABOR_ENTRY', 'Enter labor / hours worked.')

+ 7 - 7
lib/routes.js

@@ -3,18 +3,18 @@ const { routes:crudRoutes } = require('@alancnet/material-framework/lib/crud')
 
 module.exports = app => {
   app.get('/api/statistics', C.auth.verify('METRICS_VIEW'), C.statistics.get)
-  crudRoutes({ app, apiPrefix: '/api/staff-members/:location', controller: C.staffMember, camelName: 'staffMember' })
+  crudRoutes({ app, apiPrefix: '/api/staff-members/:terminal', controller: C.staffMember, camelName: 'staffMember' })
  // crudRoutes({ app, controller: C.staffMember, camelName: 'staffMember' })
   crudRoutes({ app, controller: C.staffingAgency, camelName: 'staffingAgency' })
 
   // Labor
-  app.get('/api/labor/:location', C.labor.list)
-  app.get('/api/labor/:location/:week', C.labor.get)
-  app.patch('/api/labor/:location/:week', C.labor.patch)
+  app.get('/api/labor/:terminal', C.labor.list)
+  app.get('/api/labor/:terminal/:week', C.labor.get)
+  app.patch('/api/labor/:terminal/:week', C.labor.patch)
 
   // Services
-  app.get('/api/services/:location', C.services.list)
-  app.get('/api/services/:location/:week', C.services.get)
-  app.patch('/api/services/:location/:week', C.services.patch)
+  app.get('/api/services/:terminal', C.services.list)
+  app.get('/api/services/:terminal/:week', C.services.get)
+  app.patch('/api/services/:terminal/:week', C.services.patch)
 
 }