refs #4131 changeStateRefactor
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Pablo Natek 2023-09-13 19:48:58 +02:00
parent 5536e06ed1
commit 66e851b5ea
21 changed files with 106 additions and 34 deletions

View File

@ -0,0 +1,3 @@
UPDATE `salix`.`ACL`
SET property = 'state'
WHERE property = 'changeState';

View File

@ -0,0 +1,69 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_setState`(
vSelf INT,
vStateCode VARCHAR(255) COLLATE utf8_general_ci
)
BEGIN
/**
* Modifica el estado de un ticket si se cumplen las condiciones necesarias.
*
* @param vSelf el id del ticket
* @param vStateCode estado a modificar del ticket
*/
DECLARE vticketAlertLevel INT;
DECLARE vTicketStateCode VARCHAR(255);
DECLARE vCanChangeState BOOL;
DECLARE vPackedAlertLevel INT;
DECLARE vOnPreparationAlertLevel INT;
DECLARE vNextAlertLevel INT;
DECLARE vZoneFk INT;
SELECT s.alertLevel, s.`code`, s2.alertLevel, t.zoneFk
INTO vticketAlertLevel, vTicketStateCode, vNextAlertLevel , vZoneFk
FROM state s
JOIN ticketTracking tt ON tt.stateFk = s.id
JOIN state s2 ON s2.code = vStateCode
JOIN ticket t ON t.id = tt.ticketFk
WHERE tt.ticketFk = vSelf
ORDER BY tt.created DESC
LIMIT 1;
SELECT id INTO vPackedAlertLevel FROM alertLevel WHERE code = 'PACKED';
SELECT id INTO vOnPreparationAlertLevel
FROM alertLevel
WHERE code = 'ON_PREPARATION';
IF vStateCode = 'OK' AND vZoneFk IS NULL THEN
CALL util.throw('ASSIGN_ZONE_FIRST');
END IF;
IF vNextAlertLevel > vticketAlertLevel &&
vticketAlertLevel < vOnPreparationAlertLevel
THEN
UPDATE sale
SET originalQuantity = quantity
WHERE ticketFk = vSelf;
END IF;
SET vCanChangeState = (
vStateCode <> 'ON_CHECKING' OR
vticketAlertLevel < vPackedAlertLevel
)AND NOT (
vTicketStateCode IN ('CHECKED', 'CHECKING')
AND vStateCode IN ('PREPARED', 'ON_PREPARATION')
);
IF vCanChangeState THEN
INSERT INTO ticketTracking (stateFk, ticketFk, workerFk)
SELECT id, vSelf, account.myUser_getId()
FROM state
WHERE `code` = vStateCode COLLATE utf8_unicode_ci;
IF vStateCode = 'PACKED' THEN
CALL ticket_doCmr(vSelf);
END IF;
ELSE
CALL util.throw('INCORRECT_TICKET_STATE');
END IF;
END$$
DELIMITER ;

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@ export function stringifyParams(data) {
return params; return params;
} }
export function changeState($state, event, data) { export function state($state, event, data) {
const params = stringifyParams(data); const params = stringifyParams(data);
$state.go(data.state, params); $state.go(data.state, params);
@ -53,7 +53,7 @@ export function directive($state, $window) {
if (ctrlPressed || data.target == '_blank') if (ctrlPressed || data.target == '_blank')
openNewTab($state, $window, event, data); openNewTab($state, $window, event, data);
else else
changeState($state, event, data); state($state, event, data);
}); });
$element.on('mousedown', event => { $element.on('mousedown', event => {

View File

@ -21,7 +21,7 @@
value-field="id" value-field="id"
show-field="description" show-field="description"
url="claimStates" url="claimStates"
on-change="$ctrl.changeState(value)"> on-change="$ctrl.state(value)">
</vn-button-menu> </vn-button-menu>
</h5> </h5>
<vn-horizontal> <vn-horizontal>

View File

@ -71,7 +71,7 @@ class Controller extends Summary {
return this.vnFile.getPath(`/api/dms/${dmsId}/downloadFile`); return this.vnFile.getPath(`/api/dms/${dmsId}/downloadFile`);
} }
changeState(value) { state(value) {
const params = { const params = {
id: this.claim.id, id: this.claim.id,
claimStateFk: value claimStateFk: value

View File

@ -28,14 +28,14 @@ describe('Claim', () => {
}); });
}); });
describe('changeState()', () => { describe('state()', () => {
it('should make an HTTP post query, then call the showSuccess()', () => { it('should make an HTTP post query, then call the showSuccess()', () => {
jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis(); jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis();
const expectedParams = {id: 1, claimStateFk: 1}; const expectedParams = {id: 1, claimStateFk: 1};
$httpBackend.when('GET', `Claims/1/getSummary`).respond(200, 24); $httpBackend.when('GET', `Claims/1/getSummary`).respond(200, 24);
$httpBackend.expect('PATCH', `Claims/updateClaim/1`, expectedParams).respond(200); $httpBackend.expect('PATCH', `Claims/updateClaim/1`, expectedParams).respond(200);
controller.changeState(1); controller.state(1);
$httpBackend.flush(); $httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalled(); expect(controller.vnApp.showSuccess).toHaveBeenCalled();

View File

@ -47,7 +47,7 @@ module.exports = Self => {
const promises = []; const promises = [];
for (const id of ticketIds) { for (const id of ticketIds) {
const promise = models.TicketTracking.changeState(ctx, { const promise = models.TicketTracking.state(ctx, {
stateFk: state.id, stateFk: state.id,
workerFk: worker.id, workerFk: worker.id,
ticketFk: id ticketFk: id

View File

@ -1,7 +1,7 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context'); const LoopBackContext = require('loopback-context');
describe('ticket changeState()', () => { describe('ticket state()', () => {
const salesPersonId = 18; const salesPersonId = 18;
const employeeId = 1; const employeeId = 1;
const productionId = 49; const productionId = 49;
@ -47,7 +47,7 @@ describe('ticket changeState()', () => {
activeCtx.accessToken.userId = salesPersonId; activeCtx.accessToken.userId = salesPersonId;
const params = {ticketFk: 2, stateFk: 3}; const params = {ticketFk: 2, stateFk: 3};
await models.TicketTracking.changeState(ctx, params, options); await models.TicketTracking.state(ctx, params, options);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
@ -69,7 +69,7 @@ describe('ticket changeState()', () => {
activeCtx.accessToken.userId = employeeId; activeCtx.accessToken.userId = employeeId;
const params = {ticketFk: 11, stateFk: 13}; const params = {ticketFk: 11, stateFk: 13};
await models.TicketTracking.changeState(ctx, params, options); await models.TicketTracking.state(ctx, params, options);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
@ -91,7 +91,7 @@ describe('ticket changeState()', () => {
activeCtx.accessToken.userId = productionId; activeCtx.accessToken.userId = productionId;
const params = {ticketFk: ticket.id, stateFk: 3}; const params = {ticketFk: ticket.id, stateFk: 3};
const ticketTracking = await models.TicketTracking.changeState(ctx, params, options); const ticketTracking = await models.TicketTracking.state(ctx, params, options);
expect(ticketTracking.__data.ticketFk).toBe(params.ticketFk); expect(ticketTracking.__data.ticketFk).toBe(params.ticketFk);
expect(ticketTracking.__data.stateFk).toBe(params.stateFk); expect(ticketTracking.__data.stateFk).toBe(params.stateFk);
@ -115,7 +115,7 @@ describe('ticket changeState()', () => {
const ctx = {req: {accessToken: {userId: 18}}}; const ctx = {req: {accessToken: {userId: 18}}};
const assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}}, options); const assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}}, options);
const params = {ticketFk: ticket.id, stateFk: assignedState.id, workerFk: 1}; const params = {ticketFk: ticket.id, stateFk: assignedState.id, workerFk: 1};
const res = await models.TicketTracking.changeState(ctx, params, options); const res = await models.TicketTracking.state(ctx, params, options);
expect(res.__data.ticketFk).toBe(params.ticketFk); expect(res.__data.ticketFk).toBe(params.ticketFk);
expect(res.__data.stateFk).toBe(params.stateFk); expect(res.__data.stateFk).toBe(params.stateFk);

View File

@ -1,7 +1,7 @@
const UserError = require('vn-loopback/util/user-error'); const UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('changeState', { Self.remoteMethodCtx('state', {
description: 'Change the state of a ticket', description: 'Change the state of a ticket',
accessType: 'WRITE', accessType: 'WRITE',
accepts: [ accepts: [
@ -18,12 +18,12 @@ module.exports = Self => {
root: true root: true
}, },
http: { http: {
path: `/changeState`, path: `/state`,
verb: 'POST' verb: 'POST'
} }
}); });
Self.changeState = async(ctx, params, options) => { Self.state = async(ctx, params, options) => {
const models = Self.app.models; const models = Self.app.models;
const myOptions = {}; const myOptions = {};
let tx; let tx;

View File

@ -1,5 +1,5 @@
module.exports = function(Self) { module.exports = function(Self) {
require('../methods/ticket-tracking/changeState')(Self); require('../methods/ticket-tracking/state')(Self);
require('../methods/ticket-tracking/setDelivered')(Self); require('../methods/ticket-tracking/setDelivered')(Self);
Self.validatesPresenceOf('stateFk', {message: 'State cannot be blank'}); Self.validatesPresenceOf('stateFk', {message: 'State cannot be blank'});

View File

@ -15,7 +15,7 @@
<vn-button <vn-button
disabled="!$ctrl.isEditable || $ctrl.ticketState == 'OK'" disabled="!$ctrl.isEditable || $ctrl.ticketState == 'OK'"
label="Ok" label="Ok"
vn-http-click="$ctrl.changeState('OK')" vn-http-click="$ctrl.state('OK')"
vn-tooltip="Change ticket state to 'Ok'"> vn-tooltip="Change ticket state to 'Ok'">
</vn-button> </vn-button>
<vn-button-menu <vn-button-menu
@ -24,7 +24,7 @@
value-field="code" value-field="code"
fields="['id', 'name', 'alertLevel', 'code']" fields="['id', 'name', 'alertLevel', 'code']"
url="States/editableStates" url="States/editableStates"
on-change="$ctrl.changeState(value)"> on-change="$ctrl.state(value)">
</vn-button-menu> </vn-button-menu>
<vn-button icon="keyboard_arrow_down" <vn-button icon="keyboard_arrow_down"
label="More" label="More"

View File

@ -179,9 +179,9 @@ class Controller extends Section {
this.card.reload(); this.card.reload();
} }
changeState(value) { state(value) {
const params = {ticketFk: this.$params.id, code: value}; const params = {ticketFk: this.$params.id, code: value};
return this.$http.post('TicketTrackings/changeState', params).then(() => { return this.$http.post('TicketTrackings/state', params).then(() => {
this.vnApp.showSuccess(this.$t('Data saved!')); this.vnApp.showSuccess(this.$t('Data saved!'));
this.card.reload(); this.card.reload();
}).finally(() => this.resetChanges()); }).finally(() => this.resetChanges());

View File

@ -230,15 +230,15 @@ describe('Ticket', () => {
}); });
}); });
describe('changeState()', () => { describe('state()', () => {
it('should make an HTTP post query, then call the showSuccess(), reload() and resetChanges() methods', () => { it('should make an HTTP post query, then call the showSuccess(), reload() and resetChanges() methods', () => {
jest.spyOn(controller.card, 'reload').mockReturnThis(); jest.spyOn(controller.card, 'reload').mockReturnThis();
jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis(); jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis();
jest.spyOn(controller, 'resetChanges').mockReturnThis(); jest.spyOn(controller, 'resetChanges').mockReturnThis();
const expectedParams = {ticketFk: 1, code: 'OK'}; const expectedParams = {ticketFk: 1, code: 'OK'};
$httpBackend.expect('POST', `TicketTrackings/changeState`, expectedParams).respond(200); $httpBackend.expect('POST', `TicketTrackings/state`, expectedParams).respond(200);
controller.changeState('OK'); controller.state('OK');
$httpBackend.flush(); $httpBackend.flush();
expect(controller.card.reload).toHaveBeenCalledWith(); expect(controller.card.reload).toHaveBeenCalledWith();

View File

@ -18,7 +18,7 @@
value-field="code" value-field="code"
fields="['id', 'name', 'alertLevel', 'code']" fields="['id', 'name', 'alertLevel', 'code']"
url="States/editableStates" url="States/editableStates"
on-change="$ctrl.changeState(value)"> on-change="$ctrl.state(value)">
</vn-button-menu> </vn-button-menu>
<vn-ticket-descriptor-menu <vn-ticket-descriptor-menu
ng-if="!$ctrl.isOnTicketCard" ng-if="!$ctrl.isOnTicketCard"

View File

@ -59,13 +59,13 @@ class Controller extends Summary {
this.$.invoiceOutDescriptor.show(event.target, this.summary.invoiceOut.id); this.$.invoiceOutDescriptor.show(event.target, this.summary.invoiceOut.id);
} }
changeState(value) { state(value) {
const params = { const params = {
ticketFk: 'id' in this.ticket ? this.ticket.id : this.$params.id, ticketFk: 'id' in this.ticket ? this.ticket.id : this.$params.id,
code: value code: value
}; };
this.$http.post(`TicketTrackings/changeState`, params) this.$http.post(`TicketTrackings/state`, params)
.then(() => { .then(() => {
if ('id' in this.$params) this.reload(); if ('id' in this.$params) this.reload();
}) })

View File

@ -43,15 +43,15 @@ describe('Ticket', () => {
}); });
}); });
describe('changeState()', () => { describe('state()', () => {
it('should change the state', () => { it('should change the state', () => {
jest.spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
const value = 'myTicketState'; const value = 'myTicketState';
let res = {id: 1, nickname: 'myNickname'}; let res = {id: 1, nickname: 'myNickname'};
$httpBackend.when('GET', `Tickets/1/summary`).respond(200, res); $httpBackend.when('GET', `Tickets/1/summary`).respond(200, res);
$httpBackend.expectPOST(`TicketTrackings/changeState`).respond(200, 'ok'); $httpBackend.expectPOST(`TicketTrackings/state`).respond(200, 'ok');
controller.changeState(value); controller.state(value);
$httpBackend.flush(); $httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!'); expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');

View File

@ -1,4 +1,4 @@
<mg-ajax path="TicketTrackings/changeState" options="vnPost"></mg-ajax> <mg-ajax path="TicketTrackings/state" options="vnPost"></mg-ajax>
<vn-watcher <vn-watcher
vn-id="watcher" vn-id="watcher"
data="$ctrl.params" data="$ctrl.params"

View File

@ -53,7 +53,7 @@ class Controller extends Section {
} }
onSubmit() { onSubmit() {
this.$http.post(`TicketTrackings/changeState`, this.params).then(() => { this.$http.post(`TicketTrackings/state`, this.params).then(() => {
this.$.watcher.updateOriginalData(); this.$.watcher.updateOriginalData();
this.card.reload(); this.card.reload();
this.vnApp.showSuccess(this.$t('Data saved!')); this.vnApp.showSuccess(this.$t('Data saved!'));

View File

@ -61,7 +61,7 @@ describe('Ticket', () => {
jest.spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
jest.spyOn(controller.$state, 'go'); jest.spyOn(controller.$state, 'go');
$httpBackend.expectPOST(`TicketTrackings/changeState`, controller.params).respond({}); $httpBackend.expectPOST(`TicketTrackings/state`, controller.params).respond({});
controller.onSubmit(); controller.onSubmit();
$httpBackend.flush(); $httpBackend.flush();

View File

@ -385,7 +385,7 @@ class Controller extends Section {
}); });
} }
changeState(state, reason) { state(state, reason) {
this.state = state; this.state = state;
this.reason = reason; this.reason = reason;
this.repaint(); this.repaint();