Merge pull request '3771-ticket.expedition' (#970) from 3771-ticket.expedition into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-on: #970
Reviewed-by: Joan Sanchez <joan@verdnatura.es>
This commit is contained in:
Joan Sanchez 2022-05-13 13:38:35 +00:00
commit 567d5b1ad9
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),
('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
(1, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 15, 1, 1, 18, 'UR9000006041', 94),
(2, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 16, 2, 1, 18, 'UR9000006041', 94),
(3, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 3, 1, 18, 'UR9000006041', 94),
(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),
(7, 2, 4, 71, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), NULL, 1, 1, 18, NULL, 94),
(8, 3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), NULL, 1, 1, 18, NULL, 94),
(9, 3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 1, 1, 18, NULL, 94),
(10, 7, 7, 71, NOW(), NULL, 1, 1, 18, NULL, 94);
(1, 'En reparto', 'ON DELIVERY'),
(2, 'Entregada', 'DELIVERED'),
(3, 'Perdida', 'LOST');
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`, `externalId`, `packagingFk`, `stateTypeFk`)
VALUES
(1, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 15, 1, 1, 18, 'UR9000006041', 94, 1),
(2, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 16, 2, 1, 18, 'UR9000006041', 94, 1),
(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`)
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,
es.workerFk expeditionScanWorkerFk,
su.name scannerUserName,
es.scanned
FROM
vn.expedition e
es.scanned,
est.description state
FROM vn.expedition e
LEFT JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk
LEFT JOIN vn.item i2 ON i2.id = e.itemFk
INNER JOIN vn.item i1 ON i1.id = e.isBox
LEFT JOIN vn.packaging p ON p.id = e.packagingFk

View File

@ -14,6 +14,9 @@
"Expedition": {
"dataSource": "vn"
},
"ExpeditionState": {
"dataSource": "vn"
},
"Packaging": {
"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="counter" number>Counter</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="expeditionScanWorkerFk">Palletizer</vn-th>
<vn-th field="scanned" expand>Scanned</vn-th>
<vn-th field="state" expand>State</vn-th>
<vn-th></vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
@ -33,7 +32,7 @@
vn-tooltip="Delete expedition">
</vn-icon-button>
</vn-td>
<vn-td number>{{expedition.id | zeroFill:6}}</vn-td>
<vn-td number expand>{{expedition.id | zeroFill:6}}</vn-td>
<vn-td number>
<span
ng-class="{link: expedition.packagingItemFk}"
@ -45,20 +44,15 @@
<vn-td>{{::expedition.freightItemName}}</vn-td>
<vn-td number>{{::expedition.counter}}</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>{{::expedition.state}}</vn-td>
<vn-td>
<span class="link" ng-click="workerDescriptor.show($event, expedition.expeditionScanWorkerFk)">
{{::expedition.scannerUserName | dashIfEmpty}}
</span>
<vn-icon-button
vn-click-stop="$ctrl.showLog(expedition)"
vn-tooltip="Status log"
icon="history">
</vn-icon-button>
</vn-td>
<vn-td shrink-datetime>{{::expedition.scanned | date:'dd/MM/yyyy HH:mm'}}</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
@ -77,4 +71,44 @@
on-accept="$ctrl.onDialogAccept($data)"
question="Delete 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}`)
.then(() => this.$.model.refresh());
}
showLog(expedition) {
this.expedition = expedition;
this.$.statusLog.show();
}
}
ngModule.vnComponent('vnTicketExpedition', {

View File

@ -5,10 +5,12 @@ describe('Ticket', () => {
let controller;
let $scope;
let $httpBackend;
let $window;
beforeEach(ngModule('ticket'));
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$window_) => {
$window = _$window_;
$httpBackend = _$httpBackend_;
$scope = $rootScope.$new();
$scope.model = {
@ -30,5 +32,23 @@ describe('Ticket', () => {
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