diff --git a/app/controllers/clients.js b/app/controllers/clients.js index ae077f1..2660361 100644 --- a/app/controllers/clients.js +++ b/app/controllers/clients.js @@ -85,7 +85,7 @@ exports.create = function(req, res, next) { var client = new Client({ name: req.body.name, - identifier: req.body.identifier, + identifier: req.body.identifier.toUpperCase(), contacts: req.body.contacts, address: req.body.address, notes: req.body.notes, @@ -106,13 +106,44 @@ exports.create = function(req, res, next) { }) }; +exports.isUnique = function(req, res, next) { + + var field = req.param('field'); + var value = req.param('value'); + var key = req.param('key'); + + if (!field || !value) { + return res.json(400, 'missing field or value'); + } + + var query = {}; + + if (field === 'identifier') { + query[field] = value.toUpperCase(); + } else { + query[field] = value; + } + + if (key) { + query['_id'] = { $ne: key }; + } + + Client.find(query) + .exec(function(err, result) { + if (err) return next(err); + res.json({ + isUnique: result.length === 0 + }); + }); +}; + exports.update = function(req, res, next) { var id = req.param('client_id'); log.info("clients.update %s %j", id, req.body); return Client.findById(id, function(err, client) { client.name = req.body.name; - client.identifier = req.body.identifier; + client.identifier = req.body.identifier.toUpperCase(); client.contacts = req.body.contacts; client.address = req.body.address; client.frequencies = req.body.frequencies; diff --git a/app/controllers/workorders.js b/app/controllers/workorders.js index 4dd52cf..c3e3231 100644 --- a/app/controllers/workorders.js +++ b/app/controllers/workorders.js @@ -132,7 +132,7 @@ module.exports = function(config, calendar) { return callback(null); var description = generateDescription(client, workorder, req.user, null, techs); - var techDescription = appendNotes(description, client); + var techDescription = appendNotes(description, client, workorder); var to = req.body.emails; var techTo = generateToLine(techs); @@ -302,7 +302,7 @@ module.exports = function(config, calendar) { var description = generateDescription(client, workorder, createdBy, modifiedBy, techs); - var techDescription = appendNotes(description, client); + var techDescription = appendNotes(description, client, workorder); var to = req.body.emails; var techTo = generateToLine(techs); @@ -394,17 +394,21 @@ function generateLocation(client) { return sprintf("%(street1)s %(street2)s %(city)s, %(state)s. %(zip)s", data); } -function appendNotes(message, client) { +function appendNotes(message, client, workorder) { var template = "%(message)s\n" + "Tech Notes:\n" + " %(notes)s\n" + + "\n" + + "Alternative Contact:\n" + + " %(alternativeContact)s\n" + "\n"; if (client.notes && client.notes['tech']) { var resources = { message: message || '', - notes: client.notes['tech'] || '' + notes: client.notes['tech'] || '', + alternativeContact: workorder.alternativeContact || '' }; return sprintf(template, resources); @@ -491,7 +495,6 @@ function generateDescription(client, workorder, createdBy, modifiedBy) { } function generateAttendees(techs, workorder) { - console.log('here'); return techs.map(function(t) { return t.email; }).concat(workorder.emails); } diff --git a/config/routes.js b/config/routes.js index f2dc6f0..b82c524 100644 --- a/config/routes.js +++ b/config/routes.js @@ -32,6 +32,7 @@ module.exports = function(app, auth, piler, calendar, directory, config) { var clients = require('../app/controllers/clients'); app.get('/api/clients', clients.index); + app.get('/api/clients/isUnique', clients.isUnique); app.get('/api/clients/frequencies', clients.frequencies); app.get('/api/clients/:client_id', clients.get); app.get('/api/clients/:client_id/workorders', clients.workorders); diff --git a/public/js/controllers.js b/public/js/controllers.js index 4b82e74..01e7a63 100644 --- a/public/js/controllers.js +++ b/public/js/controllers.js @@ -66,7 +66,15 @@ biomed.SchedulePmsCtrl = function($scope, Clients) { $scope.month = moment().month(); + $scope.frequencies = []; + var allData = Clients.frequencies(function() { + if (allData) { + angular.forEach(allData[0].frequencies, function(value, key) { + $scope.frequencies.push(key); + }); + } + filter(); $scope.loading = false; }); @@ -80,12 +88,9 @@ biomed.SchedulePmsCtrl = function($scope, Clients) { angular.forEach(client.frequencies, function(value, key) { if (value[$scope.month]) { - reason.push(key); - -// $scope.pms.push({ -// reason: key, -// client: client -// }); + if (!$scope.frequency || $scope.frequency == key) { + reason.push(key); + } } }); @@ -120,6 +125,7 @@ biomed.SchedulePmsCtrl = function($scope, Clients) { }; $scope.$watch('month', filter); + $scope.$watch('frequency', filter); }; biomed.UsersIndexCtrl = function($scope, $filter, $routeParams, $location, Users, LocationBinder) { @@ -676,7 +682,7 @@ biomed.AccountingIndexCtrl = function($scope, $filter, $routeParams, Workorders, var defaultEnd = moment().toDate(); var defaultStart = moment(defaultEnd).subtract('days', 7).toDate(); - LocationBinder($scope, ['query', 'start', 'end'], { + LocationBinder($scope, ['query', 'status', 'start', 'end'], { start: defaultStart, end: defaultEnd }); @@ -693,6 +699,8 @@ biomed.AccountingIndexCtrl = function($scope, $filter, $routeParams, Workorders, $scope.$watch('query', filter); + $scope.$watch('status', filter); + $scope.$watch('start', fetchData); $scope.$watch('end', fetchData); @@ -709,10 +717,14 @@ biomed.AccountingIndexCtrl = function($scope, $filter, $routeParams, Workorders, } function filter() { - filteredData = $filter('filter')(data, $scope.query); + filteredData = $filter('filter')(data, { + $: $scope.query, + status: $scope.status + }); index = initialPageSize; $scope.canLoad = true; $scope.workorders = filteredData.slice(0, initialPageSize); + $scope.total = filteredData.length; }; $scope.selectedCls = function(column) { @@ -729,6 +741,11 @@ biomed.AccountingIndexCtrl = function($scope, $filter, $routeParams, Workorders, } }; + $scope.selectPage = function(status) { + console.log('SelectPage: ' + status); + $scope.status = status; + } + function fetchData() { $scope.loading = true; @@ -971,14 +988,14 @@ biomed.WorkorderAddCtrl = function($scope, $location, Workorders, Schedule, Clie }; function updateUsers() { - Users.index({ group: $scope.group }, function(result) { + Users.index({ group: $scope.group, perms: 'workorder.schedulable' }, function(result) { $scope.users = result; }); } function updateAllUsers() { - var criteria = {}; + var criteria = { perms: 'workorder.schedulable' }; Users.index(criteria, function(result) { result.sort(function(a,b) { @@ -1029,6 +1046,24 @@ biomed.WorkorderEditCtrl = function($scope, $routeParams, Workorders, Schedule, $scope.remarks = createController(); $scope.scheduling = createSchedulingController(); + function updateStatus() { + if ($scope.status.model.invoiceNumber && $scope.status.model.checkNumber) { + $scope.status.model.status = 'paid'; + } else if ($scope.status.model.invoiceNumber) { + $scope.status.model.status = 'invoiced'; + } else { + $scope.status.model.status = 'scheduled'; + } + } + + $scope.$watch('status.model.invoiceNumber', function() { + updateStatus(); + }); + + $scope.$watch('status.model.checkNumber', function() { + updateStatus(); + }); + $scope.destroy = function() { Workorders.destroy({id: $scope.master._id}); window.history.back(); @@ -1185,13 +1220,13 @@ biomed.WorkorderEditCtrl = function($scope, $routeParams, Workorders, Schedule, } function updateUsers() { - Users.index({ group: $scope.group }, function(result) { + Users.index({ group: $scope.group, perms: 'workorder.schedulable' }, function(result) { $scope.users = result; }); } function updateAllUsers() { - var criteria = {}; + var criteria = {perms: 'workorder.schedulable'}; Users.index(criteria, function(result) { result.sort(function(a,b) { diff --git a/public/js/directives.js b/public/js/directives.js index 880ffe1..3ec6128 100644 --- a/public/js/directives.js +++ b/public/js/directives.js @@ -834,4 +834,37 @@ angular.module('biomed.directives', []) }); } }; -}); +}) +.directive('abUnique', function(Clients, $timeout) { + return { + restrict: 'A', + require: 'ngModel', + link: function(scope, element, attrs, ngModel) { + var stop_timeout; + return scope.$watch(function() { + return ngModel.$modelValue; + }, function(name) { + $timeout.cancel(stop_timeout); + + if (!name) { + ngModel.$setValidity('unique', true); + } + + stop_timeout = $timeout(function() { + var keyProperty = scope.$eval(attrs.abUnique); + + if (name) { + Clients.isUnique({ + key: keyProperty.key, + field: keyProperty.field, + value: name + }, function(result) { + console.log('unique = ' + result.isUnique); + ngModel.$setValidity('unique', result.isUnique); + }); + } + }, 200); + }); + } + }; +}) diff --git a/public/js/services.js b/public/js/services.js index 0e6d338..ec14116 100644 --- a/public/js/services.js +++ b/public/js/services.js @@ -4,13 +4,14 @@ angular.module('biomed.services', []) { id: "@id", cmd: "@cmd" }, { index: { method: 'GET', params: {}, isArray: true }, - frequencies:{ method: 'GET', params: { cmd: 'frequencies' }, isArray: true }, + frequencies: { method: 'GET', params: { cmd: 'frequencies' }, isArray: true }, get: { method: 'GET', params: { id: 0} }, create: { method: 'POST', params: {} }, update: { method: 'POST', params: { id: 0} }, destroy: { method: 'DELETE', params: { id: 0 } }, - workorders: { method: 'GET', params: { id: 0, cmd: 'workorders' }, isArray: true }, - tags: { method: 'GET', params: { id: 0, cmd: 'tags' }, isArray: true } + workorders: { method: 'GET', params: { id: 0, cmd: 'workorders' }, isArray: true }, + tags: { method: 'GET', params: { id: 0, cmd: 'tags' }, isArray: true }, + isUnique: { method: 'GET', params: { cmd: 'isUnique' } }, }); }) .factory("Posts", function($resource) { diff --git a/public/partials/accounting/index.html b/public/partials/accounting/index.html index 1f92a08..6a0cbd9 100644 --- a/public/partials/accounting/index.html +++ b/public/partials/accounting/index.html @@ -11,8 +11,15 @@ + All + Scheduled + Invoiced + Paid
+
+ Total: {{total}} +
Start:
@@ -32,9 +39,7 @@ Client Date Invoice # - Invoice Date Check # - Paid Date Status @@ -48,9 +53,7 @@ {{workorder.client.name}} ({{workorder.client.identifier}}) {{workorder.scheduling.start | date}} {{workorder.invoiceNumber}} - {{workorder.invoicedOn | date}} {{workorder.checkNumber}} - {{workorder.paidOn | date}} {{workorder.status}} diff --git a/public/partials/clients/add.html b/public/partials/clients/add.html index 9a74a69..ea01262 100644 --- a/public/partials/clients/add.html +++ b/public/partials/clients/add.html @@ -6,7 +6,7 @@

New Client

-
+
@@ -17,10 +17,20 @@
-
+
+
- + + Identifier must be unique
@@ -190,7 +200,7 @@
- +
-
+ diff --git a/public/partials/clients/edit.html b/public/partials/clients/edit.html index 322fd27..251ab41 100644 --- a/public/partials/clients/edit.html +++ b/public/partials/clients/edit.html @@ -31,8 +31,15 @@
- + Required + Identifier must be unique
diff --git a/public/partials/schedule/pms.html b/public/partials/schedule/pms.html index 90a855c..d86e510 100644 --- a/public/partials/schedule/pms.html +++ b/public/partials/schedule/pms.html @@ -9,9 +9,14 @@
Create new Workorder + Frequency: +
Month: -
+
- -
+ +
diff --git a/public/partials/users/index.html b/public/partials/users/index.html index def8734..42068d2 100644 --- a/public/partials/users/index.html +++ b/public/partials/users/index.html @@ -21,7 +21,7 @@ - + @@ -35,9 +35,11 @@ + + @@ -56,9 +58,11 @@ + +
GroupsPermissionsPermissions
NameTags Messages EditBilling Site Admin FrequencySchedulable
diff --git a/public/partials/workorders/edit.html b/public/partials/workorders/edit.html index 218b921..5dfca4e 100644 --- a/public/partials/workorders/edit.html +++ b/public/partials/workorders/edit.html @@ -16,39 +16,7 @@
- {{master.status}}
- Edit -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- - - -
+ {{master.status}}
@@ -345,6 +313,35 @@
+
+ +
+
+ Invoice Number: {{master.invoiceNumber}}
+ Check Number: {{master.checkNumber}}
+ Edit +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ + + +
+
+
+