Skip to content

Commit

Permalink
OLMIS-7443 Add lot management view page
Browse files Browse the repository at this point in the history
  • Loading branch information
hdsldv committed Nov 29, 2021
1 parent da87655 commit a9d8351
Show file tree
Hide file tree
Showing 9 changed files with 1,461 additions and 2 deletions.
787 changes: 786 additions & 1 deletion npm-shrinkwrap.json

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions src/admin-lot-list/admin-lot-list.module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* This program is part of the OpenLMIS logistics management information system platform software.
* Copyright © 2017 VillageReach
*
* This program is free software: you can redistribute it and/or modify it under the terms
* of the GNU Affero General Public License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*  
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
* See the GNU Affero General Public License for more details. You should have received a copy of
* the GNU Affero General Public License along with this program. If not, see
* http://www.gnu.org/licenses.  For additional information contact [email protected]
*/

(function() {

'use strict';

/**
* @module admin-lot-list
*
* @description
* Provides lot list screen for administrator.
*/
angular.module('admin-lot-list', [
'openlmis-admin',
'openlmis-pagination',
'openlmis-repository',
'openlmis-rights',
'referencedata-lot',
'referencedata-orderable'
]);
})();
114 changes: 114 additions & 0 deletions src/admin-lot-list/admin-lot-list.routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* This program is part of the OpenLMIS logistics management information system platform software.
* Copyright © 2017 VillageReach
*
* This program is free software: you can redistribute it and/or modify it under the terms
* of the GNU Affero General Public License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*  
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
* See the GNU Affero General Public License for more details. You should have received a copy of
* the GNU Affero General Public License along with this program. If not, see
* http://www.gnu.org/licenses.  For additional information contact [email protected]
*/

(function() {

'use strict';

angular.module('admin-lot-list').config(routes);

routes.$inject = ['$stateProvider', 'ADMINISTRATION_RIGHTS'];

function routes($stateProvider, ADMINISTRATION_RIGHTS) {

$stateProvider.state('openlmis.administration.lots', {
showInNavigation: true,
label: 'adminLotList.lots',
url: '/lots?orderableId&expirationDateFrom&expirationDateTo&page&size',
controller: 'LotListController',
templateUrl: 'admin-lot-list/lot-list.html',
controllerAs: 'vm',
accessRights: [ADMINISTRATION_RIGHTS.LOTS_MANAGE],
resolve: {
paginatedLots: function($q, $stateParams, paginationService, lotService) {
return paginationService.registerUrl($stateParams, function(stateParams) {
if (!stateParams.hasOwnProperty('orderableId')
|| stateParams.orderableId === null) {
return $q(function(resolve) {
resolve({
content: []
});
});
}

var params = angular.copy(stateParams);

params.page = stateParams.page;
params.size = stateParams.size;
params.tradeItemIdIgnored = true;

if (params.orderableId === '*') {
delete params.orderableId;
}

return lotService.query(params);
});
},
lots: function(paginatedLots, orderables) {
return paginatedLots.map(function(lot) {
var orderable = orderables.find(function(p) {
if (p.identifiers.hasOwnProperty('tradeItem') && lot.tradeItemId !== null) {
return p.identifiers.tradeItem.toLowerCase()
=== lot.tradeItemId.toLowerCase();
}

return false;
});

var noProductMsg = 'No product';

return {
productCode: orderable === undefined
? noProductMsg
: orderable.productCode,
productName: orderable === undefined
? noProductMsg
: orderable.fullProductName,
lotCode: lot.lotCode,
expirationDate: lot.expirationDate,
manufacturedDate: lot.manufactureDate
};
});
},
orderables: function($q, orderableService) {
var deferred = $q.defer();

orderableService.search().then(function(response) {
// NOP Confirm that only orderables with lots should be visible
// deferred.resolve(response.content.filter(function (x) {
// return !angular.equals(x.identifiers, {});
// }));
deferred.resolve(response.content);
}, deferred.reject);

return deferred.promise;
},
orderablesFilterOptions: function(orderables) {
return [
{
value: '*',
name: 'All'
}
].concat(orderables.map(function(p) {
return {
value: p.id,
name: p.fullProductName
};
}));
}
}
});
}
})();
229 changes: 229 additions & 0 deletions src/admin-lot-list/admin-lot-list.routes.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
/*
* This program is part of the OpenLMIS logistics management information system platform software.
* Copyright © 2017 VillageReach
*
* This program is free software: you can redistribute it and/or modify it under the terms
* of the GNU Affero General Public License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*  
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
* See the GNU Affero General Public License for more details. You should have received a copy of
* the GNU Affero General Public License along with this program. If not, see
* http://www.gnu.org/licenses.  For additional information contact [email protected]
*/

describe('openlmis.administration.lot state', function() {

'use strict';

beforeEach(function() {
module('admin-lot-list');

inject(function($injector) {
this.$state = $injector.get('$state');
this.$location = $injector.get('$location');
this.$rootScope = $injector.get('$rootScope');
this.$q = $injector.get('$q');
this.$templateCache = $injector.get('$templateCache');
this.$stateParams = $injector.get('$stateParams');

this.orderableService = $injector.get('orderableService');
this.lotService = $injector.get('lotService');

this.PageDataBuilder = $injector.get('PageDataBuilder');
this.OrderableDataBuilder = $injector.get('OrderableDataBuilder');
this.LotDataBuilder = $injector.get('LotDataBuilder');
});

this.orderableWithTradeItem = new this.OrderableDataBuilder().build();
this.orderableWithTradeItem.identifiers = {
tradeItem: 'tradeItem'
};
this.orderables = [
new this.OrderableDataBuilder().build(),
new this.OrderableDataBuilder().build()
];

spyOn(this.orderableService, 'search').andReturn(this.$q.when(
new this.PageDataBuilder()
.withContent(this.orderables)
.build()
));

this.defaultLot = new this.LotDataBuilder().build();

spyOn(this.lotService, 'query').andReturn(this.$q.when(
new this.PageDataBuilder()
.withContent([this.defaultLot])
.build()
));

this.$state.go('openlmis');
this.$rootScope.$apply();

this.goToUrl = function(url) {
this.$location.url(url);
this.$rootScope.$apply();
};

this.getResolvedValue = function(name) {
return this.$state.$current.locals.globals[name];
};
});

it('should be available under /administration/lot URL', function() {
expect(this.$state.current.name).not.toEqual('openlmis.administration.lots');

this.goToUrl('/administration/lots');

expect(this.$state.current.name).toEqual('openlmis.administration.lots');
});

it('should use template', function() {
spyOn(this.$templateCache, 'get').andCallThrough();

this.goToUrl('/administration/lots');

expect(this.$templateCache.get).toHaveBeenCalledWith('admin-lot-list/lot-list.html');
});

it('should resolve orderables', function() {
this.goToUrl('/administration/lots');

expect(this.$state.current.name).toEqual('openlmis.administration.lots');
expect(this.getResolvedValue('orderables')).toEqual(this.orderables);
expect(this.orderableService.search).toHaveBeenCalled();
});

it('should resolve orderablesFilterOptions with All option as first element', function() {
this.goToUrl('/administration/lots');

var options = this.getResolvedValue('orderablesFilterOptions');

expect(options[0].value).toEqual('*');
expect(options[0].name).toEqual('All');
});

it('should resolve empty paginatedLots when orderableId filter is empty ', function() {
this.goToUrl('/administration/lots');

var paginatedLots = this.getResolvedValue('paginatedLots');

expect(paginatedLots.length).toEqual(0);
});

it('should resolve non-empty paginatedLots when orderableId filter is * ', function() {
this.lotService.query.andReturn(this.$q.when({
content: [
new this.LotDataBuilder().build()
]
}));

this.goToUrl('/administration/lots?orderableId=*');

var paginatedLots = this.getResolvedValue('paginatedLots');

expect(this.lotService.query).toHaveBeenCalledWith({
page: 0,
size: 10,
tradeItemIdIgnored: true
});

expect(paginatedLots.length).toNotEqual(0);
});

it('should resolve non-empty paginatedLots when orderableId filter is set ', function() {
var lot = new this.LotDataBuilder().build();
this.lotService.query.andReturn(this.$q.when({
content: [lot]
}));

this.goToUrl('/administration/lots?orderableId=123');

var paginatedLots = this.getResolvedValue('paginatedLots');

expect(this.lotService.query).toHaveBeenCalledWith({
page: 0,
size: 10,
tradeItemIdIgnored: true,
orderableId: '123'
});

expect(paginatedLots.length).toEqual(1);
expect(paginatedLots[0]).toEqual(lot);
});

it('should resolve non-empty paginatedLots when expirationDateFrom filter is set ', function() {
var lot = new this.LotDataBuilder().build();
this.lotService.query.andReturn(this.$q.when({
content: [lot]
}));

this.goToUrl('/administration/lots?expirationDateFrom=1970-01-01&orderableId=*');

var paginatedLots = this.getResolvedValue('paginatedLots');

expect(this.lotService.query).toHaveBeenCalledWith({
page: 0,
size: 10,
tradeItemIdIgnored: true,
expirationDateFrom: '1970-01-01'
});

expect(paginatedLots.length).toEqual(1);
expect(paginatedLots[0]).toEqual(lot);
});

it('should resolve non-empty paginatedLots when expirationDateTo filter is set ', function() {
var lot = new this.LotDataBuilder().build();
this.lotService.query.andReturn(this.$q.when({
content: [lot]
}));

this.goToUrl('/administration/lots?expirationDateTo=1970-01-01&orderableId=*');

var paginatedLots = this.getResolvedValue('paginatedLots');

expect(this.lotService.query).toHaveBeenCalledWith({
page: 0,
size: 10,
tradeItemIdIgnored: true,
expirationDateTo: '1970-01-01'
});

expect(paginatedLots.length).toEqual(1);

expect(paginatedLots[0]).toEqual(lot);
});

it('should resolve lots ', function() {
var orderableWithTradeItem = new this.OrderableDataBuilder().build();
orderableWithTradeItem.identifiers = {
tradeItem: 'tradeItem'
};

this.orderableService.search.andReturn(this.$q.when(
new this.PageDataBuilder()
.withContent([orderableWithTradeItem])
.build()
));

var lotWithMatchingOrderable = new this.LotDataBuilder().build();
lotWithMatchingOrderable.tradeItemId = 'tradeItem';

this.lotService.query.andReturn(this.$q.when({
content: [
lotWithMatchingOrderable,
new this.LotDataBuilder().build()
]
}));

this.goToUrl('/administration/lots?orderableId=*');

var lots = this.getResolvedValue('lots');

expect(lots.length).toEqual(2);
});

});
Loading

0 comments on commit a9d8351

Please sign in to comment.