3771-ticket.expedition #970

Merged
joan merged 7 commits from 3771-ticket.expedition into dev 2022-05-13 13:38:38 +00:00
12 changed files with 207 additions and 31 deletions

View File

@ -0,0 +1,2 @@
INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES('ExpeditionState', '*', 'READ', 'ALLOW', 'ROLE', 'employee');

View File

@ -854,18 +854,35 @@ INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPack
('cc', 1640038.00, 56.00, 220.00, 128.00, 1, CURDATE(), 15, 90.00), ('cc', 1640038.00, 56.00, 220.00, 128.00, 1, CURDATE(), 15, 90.00),
('pallet 100', 2745600.00, 100.00, 220.00, 120.00, 1, CURDATE(), 16, 0.00); ('pallet 100', 2745600.00, 100.00, 220.00, 120.00, 1, CURDATE(), 16, 0.00);
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`, `externalId`, `packagingFk`) INSERT INTO `vn`.`expeditionStateType`(`id`, `description`, `code`)
VALUES VALUES
(1, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 15, 1, 1, 18, 'UR9000006041', 94), (1, 'En reparto', 'ON DELIVERY'),
(2, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 16, 2, 1, 18, 'UR9000006041', 94), (2, 'Entregada', 'DELIVERED'),
(3, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 3, 1, 18, 'UR9000006041', 94), (3, 'Perdida', 'LOST');
(4, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 4, 1, 18, 'UR9000006041', 94),
(5, 1, 2, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 1, 1, 18, NULL, 94),
(6, 7, 3, 71, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), NULL, 1, 1, 18, NULL, 94), INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`, `externalId`, `packagingFk`, `stateTypeFk`)
(7, 2, 4, 71, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), NULL, 1, 1, 18, NULL, 94), VALUES
(8, 3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), NULL, 1, 1, 18, NULL, 94), (1, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 15, 1, 1, 18, 'UR9000006041', 94, 1),
(9, 3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 1, 1, 18, NULL, 94), (2, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 16, 2, 1, 18, 'UR9000006041', 94, 1),
(10, 7, 7, 71, NOW(), NULL, 1, 1, 18, NULL, 94); (3, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 3, 1, 18, 'UR9000006041', 94, 2),
(4, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 4, 1, 18, 'UR9000006041', 94, 2),
(5, 1, 2, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 1, 1, 18, NULL, 94, 3),
(6, 7, 3, 71, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), NULL, 1, 1, 18, NULL, 94, 3),
(7, 2, 4, 71, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), NULL, 1, 1, 18, NULL, 94, NULL),
(8, 3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), NULL, 1, 1, 18, NULL, 94, 1),
(9, 3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 1, 1, 18, NULL, 94, 2),
(10, 7, 7, 71, NOW(), NULL, 1, 1, 18, NULL, 94, 3);
INSERT INTO `vn`.`expeditionState`(`id`, `created`, `expeditionFk`, `typeFk`, `userFk`)
VALUES
(1, CURDATE(), 1, 1, 1),
(2, CURDATE(), 2, 1, 1),
(3, CURDATE(), 3, 1, 1),
(4, CURDATE(), 3, 2, 1106),
(5, CURDATE(), 5, 1, 1106),
(6, CURDATE(), 5, 3, 1106);
INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`, `created`, `pvp`) INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`, `created`, `pvp`)
VALUES VALUES

View File

@ -0,0 +1,41 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => {
Self.remoteMethod('filter', {
description: 'Find all instances of the model matched by filter from the data source.',
accessType: 'READ',
accepts: [
{
arg: 'filter',
type: 'object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
http: {source: 'query'},
},
],
returns: {
type: ['object'],
root: true,
},
http: {
path: `/filter`,
verb: 'GET',
},
});
Self.filter = async(filter, options) => {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const stmt = new ParameterizedSQL(
`SELECT es.created, u.name, u.id workerFk, est.description state
FROM vn.expeditionState es
JOIN vn.expeditionStateType est ON est.id = es.typeFk
JOIN account.user u ON u.id = es.userFk
`);
stmt.merge(Self.buildSuffix(filter, 'es'));
return Self.rawStmt(stmt, myOptions);
};
};

View File

@ -0,0 +1,21 @@
const models = require('vn-loopback/server/server').models;
describe('expeditionState filter()', () => {
it('should return the expedition states matching the filter', async() => {
const tx = await models.ExpeditionState.beginTransaction({});
try {
const options = {transaction: tx};
const filter = {where: {expeditionFk: 5}};
const response = await models.ExpeditionState.filter(filter, options);
expect(response.length).toEqual(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -47,9 +47,10 @@ module.exports = Self => {
e.packagingFk, e.packagingFk,
es.workerFk expeditionScanWorkerFk, es.workerFk expeditionScanWorkerFk,
su.name scannerUserName, su.name scannerUserName,
es.scanned es.scanned,
FROM est.description state
vicent marked this conversation as resolved Outdated

this is defined as description but used as state at front, should be renamed to match the context using alias

this is defined as description but used as state at front, should be renamed to match the context using alias
vn.expedition e FROM vn.expedition e
LEFT JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk
LEFT JOIN vn.item i2 ON i2.id = e.itemFk LEFT JOIN vn.item i2 ON i2.id = e.itemFk
INNER JOIN vn.item i1 ON i1.id = e.isBox INNER JOIN vn.item i1 ON i1.id = e.isBox
LEFT JOIN vn.packaging p ON p.id = e.packagingFk LEFT JOIN vn.packaging p ON p.id = e.packagingFk

View File

@ -14,6 +14,9 @@
"Expedition": { "Expedition": {
"dataSource": "vn" "dataSource": "vn"
}, },
"ExpeditionState": {
"dataSource": "vn"
},
"Packaging": { "Packaging": {
"dataSource": "vn" "dataSource": "vn"
}, },

View File

@ -0,0 +1,3 @@
module.exports = function(Self) {
require('../methods/expedition-state/filter')(Self);
};

View File

@ -0,0 +1,28 @@
{
"name": "ExpeditionState",
"base": "VnModel",
"options": {
"mysql": {
"table": "expeditionState"
}
},
"properties": {
"id": {
"id": true,
"type": "number",
"description": "Identifier"
},
"created": {
"type": "date"
},
"expeditionFk": {
"type": "number"
},
"typeFk": {
"type": "number"
},
"userFk": {
"type": "number"
}
}
}

View File

@ -19,10 +19,9 @@
<vn-th field="freightItemName">Package type</vn-th> <vn-th field="freightItemName">Package type</vn-th>
<vn-th field="counter" number>Counter</vn-th> <vn-th field="counter" number>Counter</vn-th>
<vn-th field="externalId" number>externalId</vn-th> <vn-th field="externalId" number>externalId</vn-th>
<vn-th field="workerFk">Packager</vn-th>
<vn-th field="created" expand>Created</vn-th> <vn-th field="created" expand>Created</vn-th>
<vn-th field="expeditionScanWorkerFk">Palletizer</vn-th> <vn-th field="state" expand>State</vn-th>
<vn-th field="scanned" expand>Scanned</vn-th> <vn-th></vn-th>
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
@ -33,7 +32,7 @@
vn-tooltip="Delete expedition"> vn-tooltip="Delete expedition">
</vn-icon-button> </vn-icon-button>
</vn-td> </vn-td>
<vn-td number>{{expedition.id | zeroFill:6}}</vn-td> <vn-td number expand>{{expedition.id | zeroFill:6}}</vn-td>
<vn-td number> <vn-td number>
<span <span
ng-class="{link: expedition.packagingItemFk}" ng-class="{link: expedition.packagingItemFk}"
@ -45,20 +44,15 @@
<vn-td>{{::expedition.freightItemName}}</vn-td> <vn-td>{{::expedition.freightItemName}}</vn-td>
<vn-td number>{{::expedition.counter}}</vn-td> <vn-td number>{{::expedition.counter}}</vn-td>
<vn-td expand>{{::expedition.externalId}}</vn-td> <vn-td expand>{{::expedition.externalId}}</vn-td>
<vn-td>
<span
class="link"
ng-click="workerDescriptor.show($event, expedition.workerFk)">
{{::expedition.userName | dashIfEmpty}}
</span>
</vn-td>
<vn-td shrink-datetime>{{::expedition.created | date:'dd/MM/yyyy HH:mm'}}</vn-td> <vn-td shrink-datetime>{{::expedition.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
<vn-td>{{::expedition.state}}</vn-td>
<vn-td> <vn-td>
<span class="link" ng-click="workerDescriptor.show($event, expedition.expeditionScanWorkerFk)"> <vn-icon-button
{{::expedition.scannerUserName | dashIfEmpty}} vn-click-stop="$ctrl.showLog(expedition)"
</span> vn-tooltip="Status log"
icon="history">
</vn-icon-button>
</vn-td> </vn-td>
<vn-td shrink-datetime>{{::expedition.scanned | date:'dd/MM/yyyy HH:mm'}}</vn-td>
</vn-tr> </vn-tr>
</vn-tbody> </vn-tbody>
</vn-table> </vn-table>
@ -78,3 +72,43 @@
question="Delete expedition" question="Delete expedition"
message="Are you sure you want to delete this expedition?"> message="Are you sure you want to delete this expedition?">
</vn-confirm> </vn-confirm>
<vn-popup vn-id="statusLog">
<vn-crud-model
vn-id="model"
url="ExpeditionStates/filter"
link="{expeditionFk: $ctrl.expedition.id}"
data="expeditionStates"
order="created DESC"
auto-load="true">
</vn-crud-model>
<vn-data-viewer model="model">
<vn-card class="vn-w-md">
<vn-table model="model">
<vn-thead>
<vn-tr>
<vn-th field="state">State</vn-th>
<vn-th field="worker">Worker</vn-th>
<vn-th field="created">Created</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="expeditionState in expeditionStates">
<vn-td>{{::expeditionState.state}}</vn-td>
<vn-td expand>
<span
ng-class="{'link': expeditionState.workerFk}"
ng-click="workerDescriptor.show($event, expeditionState.workerFk)">
{{::expeditionState.name || 'System' | translate}}
</span>
</vn-td>
<vn-td shrink-datetime>{{::expeditionState.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-card>
</vn-data-viewer>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>
</vn-popup>

View File

@ -6,6 +6,11 @@ class Controller extends Section {
return this.$http.delete(`Expeditions/${id}`) return this.$http.delete(`Expeditions/${id}`)
.then(() => this.$.model.refresh()); .then(() => this.$.model.refresh());
} }
showLog(expedition) {
this.expedition = expedition;
this.$.statusLog.show();
}
} }
ngModule.vnComponent('vnTicketExpedition', { ngModule.vnComponent('vnTicketExpedition', {

View File

@ -5,10 +5,12 @@ describe('Ticket', () => {
let controller; let controller;
let $scope; let $scope;
let $httpBackend; let $httpBackend;
let $window;
beforeEach(ngModule('ticket')); beforeEach(ngModule('ticket'));
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => { beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$window_) => {
$window = _$window_;
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
$scope = $rootScope.$new(); $scope = $rootScope.$new();
$scope.model = { $scope.model = {
@ -30,5 +32,23 @@ describe('Ticket', () => {
expect($scope.model.refresh).toHaveBeenCalledWith(); expect($scope.model.refresh).toHaveBeenCalledWith();
}); });
}); });
describe('showLog()', () => {
it('should show the popover status log', () => {
controller.$.statusLog = {show: () => {}};
jest.spyOn(controller.$.statusLog, 'show');
const expedition = {id: 1};
const event = new MouseEvent('click', {
view: $window,
bubbles: true,
cancelable: true
});
controller.showLog(event, expedition);
expect(controller.$.statusLog.show).toHaveBeenCalledWith();
});
});
}); });
}); });

View File

@ -0,0 +1 @@
Status log: Hitorial de estados