Skip to content

Commit a1faea2

Browse files
authored
OLMIS-8249: Mark invalid adjustment quantity fields (#89)
1 parent 26c5d70 commit a1faea2

3 files changed

Lines changed: 153 additions & 8 deletions

File tree

src/openlmis-adjustments/adjustments-modal.controller.js

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@
2929
.controller('AdjustmentsModalController', AdjustmentsModalController);
3030

3131
AdjustmentsModalController.$inject = [
32-
'$filter', '$q', 'modalDeferred', 'title', 'message', 'isDisabled', 'adjustments',
32+
'$filter', '$q', '$scope', 'modalDeferred', 'title', 'message', 'isDisabled', 'adjustments',
3333
'reasons', 'summaries', 'preSave', 'preCancel', 'filterReasons', 'showInDoses', 'lineItem',
34-
'quantityUnitCalculateService', 'alertService'
34+
'quantityUnitCalculateService', 'alertService', 'messageService'
3535
];
3636

37-
function AdjustmentsModalController($filter, $q, modalDeferred, title, message, isDisabled,
37+
function AdjustmentsModalController($filter, $q, $scope, modalDeferred, title, message, isDisabled,
3838
adjustments, reasons, summaries, preSave, preCancel,
3939
filterReasons, showInDoses, lineItem, quantityUnitCalculateService,
40-
alertService) {
40+
alertService, messageService) {
4141

4242
var vm = this;
4343

@@ -47,6 +47,7 @@
4747
vm.cancel = cancel;
4848
vm.save = save;
4949
vm.hasInvalidAdjustments = hasInvalidAdjustments;
50+
vm.validateAdjustment = validateAdjustment;
5051

5152
/**
5253
* @ngdoc property
@@ -230,7 +231,10 @@
230231
* back to the modal without applying any changes;
231232
*/
232233
function save() {
234+
angular.forEach(vm.adjustments, validateAdjustment);
235+
233236
if (hasInvalidAdjustments()) {
237+
$scope.$broadcast('openlmis-form-submit');
234238
alertService.error('openlmisAdjustments.quantityGreaterThanZero');
235239
return;
236240
}
@@ -269,6 +273,25 @@
269273
});
270274
}
271275

276+
/**
277+
* @ngdoc method
278+
* @methodOf openlmis-adjustments.controller:AdjustmentsModalController
279+
* @name validateAdjustment
280+
*
281+
* @description
282+
* Validates a single adjustment and stores an error message on its quantityInvalid property
283+
* when the quantity is not greater than zero. The message is consumed by the openlmis-invalid
284+
* directive on the quantity cell, marking the reasons that block the adjustments update - the
285+
* same mechanism used by the stock add products modal.
286+
*
287+
* @param {Object} adjustment the adjustment to validate
288+
*/
289+
function validateAdjustment(adjustment) {
290+
adjustment.quantityInvalid = hasValidQuantity(adjustment)
291+
? undefined
292+
: messageService.get('openlmisAdjustments.quantityGreaterThanZero');
293+
}
294+
272295
function hasValidQuantity(adjustment) {
273296
return adjustment !== undefined
274297
&& adjustment !== null

src/openlmis-adjustments/adjustments-modal.controller.spec.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ describe('AdjustmentsModalController', function() {
2323
this.$rootScope = $injector.get('$rootScope');
2424
this.$controller = $injector.get('$controller');
2525
this.alertService = $injector.get('alertService');
26+
this.messageService = $injector.get('messageService');
27+
});
28+
29+
this.$scope = this.$rootScope.$new();
30+
31+
spyOn(this.messageService, 'get').andCallFake(function(key) {
32+
return key;
2633
});
2734

2835
this.modalDeferred = this.$q.defer();
@@ -427,8 +434,121 @@ describe('AdjustmentsModalController', function() {
427434

428435
});
429436

437+
describe('validateAdjustment', function() {
438+
439+
beforeEach(function() {
440+
this.initController();
441+
});
442+
443+
it('should clear quantityInvalid when quantity is greater than zero', function() {
444+
var adjustment = {
445+
quantity: 5,
446+
quantityInvalid: 'openlmisAdjustments.quantityGreaterThanZero'
447+
};
448+
449+
this.vm.validateAdjustment(adjustment);
450+
451+
expect(adjustment.quantityInvalid).toBeUndefined();
452+
});
453+
454+
it('should set quantityInvalid message when quantity is zero', function() {
455+
var adjustment = {
456+
quantity: 0
457+
};
458+
459+
this.vm.validateAdjustment(adjustment);
460+
461+
expect(adjustment.quantityInvalid).toBe('openlmisAdjustments.quantityGreaterThanZero');
462+
});
463+
464+
it('should set quantityInvalid message when quantity is negative', function() {
465+
var adjustment = {
466+
quantity: -5
467+
};
468+
469+
this.vm.validateAdjustment(adjustment);
470+
471+
expect(adjustment.quantityInvalid).toBe('openlmisAdjustments.quantityGreaterThanZero');
472+
});
473+
474+
it('should set quantityInvalid message when quantity is empty', function() {
475+
var adjustment = {
476+
quantity: ''
477+
};
478+
479+
this.vm.validateAdjustment(adjustment);
480+
481+
expect(adjustment.quantityInvalid).toBe('openlmisAdjustments.quantityGreaterThanZero');
482+
});
483+
484+
it('should set quantityInvalid message when quantity is undefined', function() {
485+
var adjustment = {};
486+
487+
this.vm.validateAdjustment(adjustment);
488+
489+
expect(adjustment.quantityInvalid).toBe('openlmisAdjustments.quantityGreaterThanZero');
490+
});
491+
492+
it('should set quantityInvalid message when quantity is not a number', function() {
493+
var adjustment = {
494+
quantity: 'abc'
495+
};
496+
497+
this.vm.validateAdjustment(adjustment);
498+
499+
expect(adjustment.quantityInvalid).toBe('openlmisAdjustments.quantityGreaterThanZero');
500+
});
501+
502+
});
503+
504+
describe('save marking', function() {
505+
506+
it('should mark every invalid adjustment when saving', function() {
507+
var message = 'openlmisAdjustments.quantityGreaterThanZero';
508+
509+
this.adjustments = [{
510+
reason: this.reasons[0],
511+
quantity: 0
512+
}, {
513+
reason: this.reasons[1],
514+
quantity: 5
515+
}, {
516+
reason: this.reasons[2],
517+
quantity: ''
518+
}];
519+
520+
this.initController();
521+
this.vm.$onInit();
522+
523+
this.vm.save();
524+
525+
expect(this.vm.adjustments[0].quantityInvalid).toBe(message);
526+
expect(this.vm.adjustments[1].quantityInvalid).toBeUndefined();
527+
expect(this.vm.adjustments[2].quantityInvalid).toBe(message);
528+
});
529+
530+
it('should broadcast openlmis-form-submit when saving invalid adjustments', function() {
531+
spyOn(this.$scope, '$broadcast').andCallThrough();
532+
533+
this.adjustments = [{
534+
reason: this.reasons[0],
535+
quantity: 0
536+
}];
537+
538+
this.initController();
539+
this.vm.$onInit();
540+
541+
this.vm.save();
542+
543+
expect(this.$scope.$broadcast).toHaveBeenCalledWith('openlmis-form-submit');
544+
});
545+
546+
});
547+
430548
function initController() {
431549
this.vm = this.$controller('AdjustmentsModalController', {
550+
$scope: this.$scope,
551+
messageService: this.messageService,
432552
modalDeferred: this.modalDeferred,
433553
adjustments: this.adjustments,
434554
reasons: this.reasons,

src/openlmis-adjustments/adjustments-modal.html

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,14 @@ <h4>{{vm.title | message}}</h4>
4848
<tbody>
4949
<tr ng-repeat="adjustment in vm.adjustments | orderBy:'':true">
5050
<td>{{adjustment.reason.name}}</td>
51-
<td>
51+
<td openlmis-invalid="{{adjustment.quantityInvalid}}">
5252
<div ng-if="vm.isDisabled">{{adjustment.quantity}}</div>
53-
<openlmis-quantity-unit-input
54-
show-in-doses="vm.showInDoses"
53+
<openlmis-quantity-unit-input
54+
show-in-doses="vm.showInDoses"
5555
item="adjustment"
56-
net-content="vm.lineItem.orderable.netContent"/>
56+
net-content="vm.lineItem.orderable.netContent"
57+
on-change-quantity="vm.validateAdjustment(adjustment)"
58+
input-class="{'error': adjustment.quantityInvalid}"/>
5759
</td>
5860
<td ng-if="!vm.isDisabled">
5961
<input type="button" class="danger"

0 commit comments

Comments
 (0)