7195_roadmap2 #2554
|
@ -26,10 +26,11 @@
|
||||||
<mrw:Nif><%= expeditionData.fi %></mrw:Nif>
|
<mrw:Nif><%= expeditionData.fi %></mrw:Nif>
|
||||||
<mrw:Nombre><%= expeditionData.clientName %></mrw:Nombre>
|
<mrw:Nombre><%= expeditionData.clientName %></mrw:Nombre>
|
||||||
<mrw:Telefono><%= expeditionData.phone %></mrw:Telefono>
|
<mrw:Telefono><%= expeditionData.phone %></mrw:Telefono>
|
||||||
|
<mrw:Observaciones><%= expeditionData.deliveryObservation %></mrw:Observaciones>
|
||||||
</mrw:DatosEntrega>
|
</mrw:DatosEntrega>
|
||||||
<mrw:DatosServicio>
|
<mrw:DatosServicio>
|
||||||
<mrw:Fecha><%= expeditionData.created %></mrw:Fecha>
|
<mrw:Fecha><%= expeditionData.created %></mrw:Fecha>
|
||||||
<mrw:Referencia><%= expeditionData.expeditionDataId %></mrw:Referencia>
|
<mrw:Referencia><%= expeditionData.reference %></mrw:Referencia>
|
||||||
<mrw:CodigoServicio><%= expeditionData.serviceType %></mrw:CodigoServicio>
|
<mrw:CodigoServicio><%= expeditionData.serviceType %></mrw:CodigoServicio>
|
||||||
<mrw:NumeroBultos>1</mrw:NumeroBultos>
|
<mrw:NumeroBultos>1</mrw:NumeroBultos>
|
||||||
<mrw:EntregaSabado><%= expeditionData.weekDays %></mrw:EntregaSabado>
|
<mrw:EntregaSabado><%= expeditionData.weekDays %></mrw:EntregaSabado>
|
||||||
|
|
|
@ -45,7 +45,7 @@ module.exports = Self => {
|
||||||
`SELECT
|
`SELECT
|
||||||
CASE co.code
|
CASE co.code
|
||||||
WHEN 'ES' THEN a.postalCode
|
WHEN 'ES' THEN a.postalCode
|
||||||
WHEN 'PT' THEN LEFT(a.postalCode, 4)
|
WHEN 'PT' THEN LEFT(a.postalCode, mc.portugalPostCodeTrim)
|
||||||
WHEN 'AD' THEN REPLACE(a.postalCode, 'AD', '00')
|
WHEN 'AD' THEN REPLACE(a.postalCode, 'AD', '00')
|
||||||
END postalCode,
|
END postalCode,
|
||||||
a.city,
|
a.city,
|
||||||
|
@ -56,9 +56,10 @@ module.exports = Self => {
|
||||||
c.phone,
|
c.phone,
|
||||||
DATE_FORMAT(t.shipped, '%d/%m/%Y') created,
|
DATE_FORMAT(t.shipped, '%d/%m/%Y') created,
|
||||||
t.shipped,
|
t.shipped,
|
||||||
e.id expeditionId,
|
CONCAT( e.ticketFk, LPAD(e.counter, mc.counterWidth, '0')) reference,
|
||||||
LPAD(IF(mw.params IS NULL, ms.serviceType, mw.serviceType), 4 ,'0') serviceType,
|
LPAD(IF(mw.params IS NULL, ms.serviceType, mw.serviceType), mc.serviceTypeWidth,'0') serviceType,
|
||||||
IF(mw.weekdays, 'S', 'N') weekDays
|
IF(mw.weekdays, 'S', 'N') weekDays,
|
||||||
|
oa.description deliveryObservation
|
||||||
FROM expedition e
|
FROM expedition e
|
||||||
JOIN ticket t ON e.ticketFk = t.id
|
JOIN ticket t ON e.ticketFk = t.id
|
||||||
JOIN agencyMode am ON am.id = t.agencyModeFk
|
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||||
|
@ -66,8 +67,12 @@ module.exports = Self => {
|
||||||
LEFT JOIN mrwServiceWeekday mw ON mw.weekdays = DATE_FORMAT(t.shipped, '%a')
|
LEFT JOIN mrwServiceWeekday mw ON mw.weekdays = DATE_FORMAT(t.shipped, '%a')
|
||||||
JOIN client c ON t.clientFk = c.id
|
JOIN client c ON t.clientFk = c.id
|
||||||
JOIN address a ON t.addressFk = a.id
|
JOIN address a ON t.addressFk = a.id
|
||||||
|
LEFT JOIN addressObservation oa ON oa.addressFk = a.id
|
||||||
|
LEFT JOIN observationType ot ON ot.id = oa.observationTypeFk
|
||||||
|
AND ot.code = 'delivery'
|
||||||
JOIN province p ON a.provinceFk = p.id
|
JOIN province p ON a.provinceFk = p.id
|
||||||
JOIN country co ON co.id = p.countryFk
|
JOIN country co ON co.id = p.countryFk
|
||||||
|
JOIN mrwConfig mc
|
||||||
WHERE e.id = ?
|
WHERE e.id = ?
|
||||||
LIMIT 1`;
|
LIMIT 1`;
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,7 @@ BEGIN
|
||||||
*/
|
*/
|
||||||
DECLARE vClient INT DEFAULT NULL;
|
DECLARE vClient INT DEFAULT NULL;
|
||||||
|
|
||||||
-- SET vPhone = vPhone COLLATE 'utf8_unicode_ci';
|
CREATE OR REPLACE TEMPORARY TABLE tClient
|
||||||
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tClient;
|
|
||||||
CREATE TEMPORARY TABLE tClient
|
|
||||||
ENGINE = MEMORY
|
ENGINE = MEMORY
|
||||||
SELECT id clientFk
|
SELECT id clientFk
|
||||||
FROM `client`
|
FROM `client`
|
||||||
|
@ -27,13 +24,14 @@ BEGIN
|
||||||
OR mobile = vPhone
|
OR mobile = vPhone
|
||||||
UNION
|
UNION
|
||||||
SELECT clientFk
|
SELECT clientFk
|
||||||
FROM vn.clientContact
|
FROM clientContact
|
||||||
WHERE phone = vPhone;
|
WHERE phone = vPhone;
|
||||||
|
|
||||||
SELECT t.clientFk INTO vClient
|
SELECT t.clientFk INTO vClient
|
||||||
FROM tClient t
|
FROM tClient t
|
||||||
JOIN `client` c ON c.id = t.clientFk
|
JOIN `client` c ON c.id = t.clientFk
|
||||||
WHERE c.isActive
|
WHERE c.isActive
|
||||||
|
AND c.salesPersonFk
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
|
|
||||||
DROP TEMPORARY TABLE tClient;
|
DROP TEMPORARY TABLE tClient;
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS expeditionDeadLine TIME NULL
|
||||||
|
COMMENT 'This field stores the latest time by which expeditions can be generated to be sent today';
|
|
@ -0,0 +1,9 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS counterWidth INT UNSIGNED NULL
|
||||||
|
COMMENT 'If it does not reach the required value, it will be padded with zeros on the left to meet the specified length.';
|
||||||
|
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS serviceTypeWidth INT UNSIGNED NULL
|
||||||
|
COMMENT 'If it does not reach the required value, it will be padded with zeros on the left to meet the specified length.';
|
||||||
|
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS portugalPostCodeTrim INT UNSIGNED NULL
|
||||||
|
COMMENT 'It will trim the last characters of the postal code';
|
|
@ -61,7 +61,8 @@
|
||||||
"Changed sale discount": "I have changed the following lines discounts from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed sale discount": "I have changed the following lines discounts from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Created claim": "I have created the claim [{{claimId}}]({{{claimUrl}}}) for the following lines from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Created claim": "I have created the claim [{{claimId}}]({{{claimUrl}}}) for the following lines from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Changed sale price": "I have changed the price of [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) from {{oldPrice}}€ ➔ *{{newPrice}}€* of the ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale price": "I have changed the price of [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) from {{oldPrice}}€ ➔ *{{newPrice}}€* of the ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
"Changed sale quantity": "I have changed the quantity of [{{itemId}} {{concept}}]({{{itemUrl}}}) from {{oldQuantity}} ➔ *{{newQuantity}}* of the ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale quantity": "I have changed {{changes}} of the ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
|
"Changes in sales": "the quantity of [{{itemId}} {{concept}}]({{{itemUrl}}}) from {{oldQuantity}} ➔ *{{newQuantity}}*",
|
||||||
"Changed sale reserved state": "I have changed the following lines reserved state from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed sale reserved state": "I have changed the following lines reserved state from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Bought units from buy request": "Bought {{quantity}} units of [{{itemId}} {{concept}}]({{{urlItem}}}) for the ticket id [{{ticketId}}]({{{url}}})",
|
"Bought units from buy request": "Bought {{quantity}} units of [{{itemId}} {{concept}}]({{{urlItem}}}) for the ticket id [{{ticketId}}]({{{url}}})",
|
||||||
"MESSAGE_INSURANCE_CHANGE": "I have changed the insurence credit of client [{{clientName}} ({{clientId}})]({{{url}}}) to *{{credit}} €*",
|
"MESSAGE_INSURANCE_CHANGE": "I have changed the insurence credit of client [{{clientName}} ({{clientId}})]({{{url}}}) to *{{credit}} €*",
|
||||||
|
|
|
@ -124,7 +124,8 @@
|
||||||
"Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
"Changed sale quantity": "He cambiado la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* del ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale quantity": "He cambiado {{changes}} del ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
|
"Changes in sales": "la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}*",
|
||||||
"State": "Estado",
|
"State": "Estado",
|
||||||
"regular": "normal",
|
"regular": "normal",
|
||||||
"reserved": "reservado",
|
"reserved": "reservado",
|
||||||
|
@ -358,8 +359,8 @@
|
||||||
"Select ticket or client": "Elija un ticket o un client",
|
"Select ticket or client": "Elija un ticket o un client",
|
||||||
"It was not able to create the invoice": "No se pudo crear la factura",
|
"It was not able to create the invoice": "No se pudo crear la factura",
|
||||||
"ticketCommercial": "El ticket {{ ticket }} para el vendedor {{ salesMan }} está en preparación. (mensaje generado automáticamente)",
|
"ticketCommercial": "El ticket {{ ticket }} para el vendedor {{ salesMan }} está en preparación. (mensaje generado automáticamente)",
|
||||||
"This PDA is already assigned to another user": "Este PDA ya está asignado a otro usuario",
|
"This PDA is already assigned to another user": "Esta PDA ya está asignado a otro usuario",
|
||||||
"You can only have one PDA": "Solo puedes tener un PDA",
|
"You can only have one PDA": "Solo puedes tener una PDA",
|
||||||
"Incoterms and Customs agent are required for a non UEE member": "Se requieren Incoterms y agente de aduanas para un no miembro de la UEE",
|
"Incoterms and Customs agent are required for a non UEE member": "Se requieren Incoterms y agente de aduanas para un no miembro de la UEE",
|
||||||
"You can not use the same password": "No puedes usar la misma contraseña"
|
"You can not use the same password": "No puedes usar la misma contraseña"
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,8 +123,9 @@
|
||||||
"Added sale to ticket": "J'ai ajouté la ligne suivante au ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}",
|
"Added sale to ticket": "J'ai ajouté la ligne suivante au ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}",
|
||||||
"Changed sale discount": "J'ai changé le rabais des lignes suivantes du ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed sale discount": "J'ai changé le rabais des lignes suivantes du ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Created claim": "J'ai créé la réclamation [{{claimId}}]({{{claimUrl}}}) des lignes suivantes du ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Created claim": "J'ai créé la réclamation [{{claimId}}]({{{claimUrl}}}) des lignes suivantes du ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Changed sale price": "J'ai changé le prix de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* du ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale price": " le prix de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* du ticket [{{ticketId}}]({{{ticketUrl}}})",,
|
||||||
"Changed sale quantity": "J'ai changé la quantité de {{itemId}} {{concept}} de {{oldQuantity}} ➔ {{newQuantity}} du ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale quantity": "J'ai changé {{changes}} du ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
|
"Changes in sales": "la quantité de {{itemId}} {{concept}} de {{oldQuantity}} ➔ {{newQuantity}}",
|
||||||
"State": "État",
|
"State": "État",
|
||||||
"regular": "normal",
|
"regular": "normal",
|
||||||
"reserved": "réservé",
|
"reserved": "réservé",
|
||||||
|
|
|
@ -124,7 +124,8 @@
|
||||||
"Changed sale discount": "Desconto da venda alterado no ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed sale discount": "Desconto da venda alterado no ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Created claim": "Reclamação criada [{{claimId}}]({{{claimUrl}}}) no ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Created claim": "Reclamação criada [{{claimId}}]({{{claimUrl}}}) no ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Changed sale price": "Preço da venda alterado para [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* no ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale price": "Preço da venda alterado para [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* no ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
"Changed sale quantity": "Quantidade da venda alterada para [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* no ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale quantity": "Quantidade da venda alterada para {{changes}} no ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
|
"Changes in sales": " [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* ",
|
||||||
"State": "Estado",
|
"State": "Estado",
|
||||||
"regular": "normal",
|
"regular": "normal",
|
||||||
"reserved": "reservado",
|
"reserved": "reservado",
|
||||||
|
|
|
@ -85,8 +85,12 @@ exports.translateValues = async(instance, changes, options = {}) => {
|
||||||
exports.getChanges = (original, changes) => {
|
exports.getChanges = (original, changes) => {
|
||||||
const oldChanges = {};
|
const oldChanges = {};
|
||||||
const newChanges = {};
|
const newChanges = {};
|
||||||
|
const dateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
||||||
|
|
||||||
for (let property in changes) {
|
for (let property in changes) {
|
||||||
|
if (dateRegex.test(original[property]))
|
||||||
|
original[property] = new Date(Date.parse(original[property]));
|
||||||
|
|
||||||
const firstChar = property.substring(0, 1);
|
const firstChar = property.substring(0, 1);
|
||||||
const isPrivate = firstChar == '$';
|
const isPrivate = firstChar == '$';
|
||||||
if (isPrivate) return;
|
if (isPrivate) return;
|
||||||
|
|
|
@ -6,6 +6,7 @@ describe('claimBeginning', () => {
|
||||||
const claimManagerId = 72;
|
const claimManagerId = 72;
|
||||||
const activeCtx = {
|
const activeCtx = {
|
||||||
accessToken: {userId: claimManagerId},
|
accessToken: {userId: claimManagerId},
|
||||||
|
__: value => value
|
||||||
};
|
};
|
||||||
const ctx = {req: activeCtx};
|
const ctx = {req: activeCtx};
|
||||||
|
|
||||||
|
|
|
@ -88,15 +88,17 @@ module.exports = Self => {
|
||||||
const updatedClaim = await claim.updateAttributes(args, myOptions);
|
const updatedClaim = await claim.updateAttributes(args, myOptions);
|
||||||
|
|
||||||
// When pickup has been changed
|
// When pickup has been changed
|
||||||
if (salesPerson && changedPickup && updatedClaim.pickup)
|
if (salesPerson) {
|
||||||
await notifyPickUp(ctx, salesPerson.id, claim);
|
if (changedPickup && updatedClaim.pickup)
|
||||||
|
await notifyPickUp(ctx, salesPerson.id, claim);
|
||||||
|
|
||||||
// When claimState has been changed
|
// When claimState has been changed
|
||||||
if (args.claimStateFk) {
|
if (args.claimStateFk) {
|
||||||
const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions);
|
const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions);
|
||||||
await notifyStateChange(ctx, salesPerson.id, claim, newState.description);
|
await notifyStateChange(ctx, salesPerson.id, claim, newState.description);
|
||||||
if (newState.code == 'canceled')
|
if (newState.code == 'canceled')
|
||||||
await notifyStateChange(ctx, claim.workerFk, claim, newState.description);
|
await notifyStateChange(ctx, claim.workerFk, claim, newState.description);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
if (tx) await tx.commit();
|
||||||
|
|
|
@ -4,7 +4,7 @@ module.exports = Self => {
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'barcode',
|
arg: 'barcode',
|
||||||
type: 'number',
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'barcode'
|
description: 'barcode'
|
||||||
}],
|
}],
|
||||||
|
@ -18,7 +18,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.toItem = async(barcode, options) => {
|
Self.toItem = async (barcode, options) => {
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
|
|
|
@ -2,10 +2,12 @@ const models = require('vn-loopback/server/server').models;
|
||||||
const LoopBackContext = require('loopback-context');
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('ticket setDelivered()', () => {
|
describe('ticket setDelivered()', () => {
|
||||||
const userId = 50;
|
const userId = 49;
|
||||||
const activeCtx = {
|
const activeCtx = {
|
||||||
accessToken: {userId: userId},
|
accessToken: {userId: userId},
|
||||||
|
__: value => value
|
||||||
};
|
};
|
||||||
|
const ctx = {req: activeCtx};
|
||||||
|
|
||||||
beforeAll(async() => {
|
beforeAll(async() => {
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
@ -19,8 +21,6 @@ describe('ticket setDelivered()', () => {
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const ctx = {req: {accessToken: {userId: 49}}};
|
|
||||||
|
|
||||||
const originalTicketOne = await models.Ticket.findById(8, null, options);
|
const originalTicketOne = await models.Ticket.findById(8, null, options);
|
||||||
const originalTicketTwo = await models.Ticket.findById(10, null, options);
|
const originalTicketTwo = await models.Ticket.findById(10, null, options);
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ describe('ticket state()', () => {
|
||||||
const productionId = 49;
|
const productionId = 49;
|
||||||
const activeCtx = {
|
const activeCtx = {
|
||||||
accessToken: {userId: 9},
|
accessToken: {userId: 9},
|
||||||
|
__: value => value
|
||||||
};
|
};
|
||||||
const ctx = {req: activeCtx};
|
const ctx = {req: activeCtx};
|
||||||
const now = Date.vnNew();
|
const now = Date.vnNew();
|
||||||
|
@ -88,7 +89,8 @@ describe('ticket state()', () => {
|
||||||
const ticket = await models.Ticket.create(sampleTicket, options);
|
const ticket = await models.Ticket.create(sampleTicket, options);
|
||||||
|
|
||||||
activeCtx.accessToken.userId = productionId;
|
activeCtx.accessToken.userId = productionId;
|
||||||
const params = {ticketFk: ticket.id, stateFk: 3};
|
const stateOk = await models.State.findOne({where: {code: 'OK'}}, options);
|
||||||
|
const params = {ticketFk: ticket.id, stateFk: stateOk.id};
|
||||||
|
|
||||||
const ticketTracking = await models.Ticket.state(ctx, params, options);
|
const ticketTracking = await models.Ticket.state(ctx, params, options);
|
||||||
|
|
||||||
|
@ -112,16 +114,68 @@ describe('ticket state()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const ticket = await models.Ticket.create(sampleTicket, options);
|
const ticket = await models.Ticket.create(sampleTicket, options);
|
||||||
const ctx = {req: {accessToken: {userId: 18}}};
|
activeCtx.accessToken.userId = salesPersonId;
|
||||||
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, userFk: 1};
|
const paramsAssigned = {ticketFk: ticket.id, stateFk: assignedState.id, userFk: 1};
|
||||||
const res = await models.Ticket.state(ctx, params, options);
|
const resAssigned = await models.Ticket.state(ctx, paramsAssigned, options);
|
||||||
|
|
||||||
expect(res.ticketFk).toBe(params.ticketFk);
|
expect(resAssigned.ticketFk).toBe(paramsAssigned.ticketFk);
|
||||||
expect(res.stateFk).toBe(params.stateFk);
|
expect(resAssigned.stateFk).toBe(paramsAssigned.stateFk);
|
||||||
expect(res.userFk).toBe(params.userFk);
|
expect(resAssigned.userFk).toBe(paramsAssigned.userFk);
|
||||||
expect(res.userFk).toBe(1);
|
expect(resAssigned.userFk).toBe(1);
|
||||||
expect(res.id).toBeDefined();
|
expect(resAssigned.id).toBeDefined();
|
||||||
|
|
||||||
|
activeCtx.accessToken.userId = productionId;
|
||||||
|
const packedState = await models.State.findOne({where: {code: 'PACKED'}}, options);
|
||||||
|
const paramsPacked = {ticketFk: ticket.id, stateFk: packedState.id, userFk: salesPersonId};
|
||||||
|
const resPacked = await models.Ticket.state(ctx, paramsPacked, options);
|
||||||
|
|
||||||
|
expect(resPacked.stateFk).toBe(paramsPacked.stateFk);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should equalize the quantities of quantity and originalQuantity' +
|
||||||
|
' if they are different', async() => {
|
||||||
|
const tx = await models.TicketTracking.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const ticket = await models.Ticket.create(sampleTicket, options);
|
||||||
|
activeCtx.accessToken.userId = salesPersonId;
|
||||||
|
|
||||||
|
const sampleSale = {
|
||||||
|
ticketFk: ticket.id,
|
||||||
|
itemFk: 1,
|
||||||
|
concept: 'Test',
|
||||||
|
quantity: 10,
|
||||||
|
originalQuantity: 6
|
||||||
|
};
|
||||||
|
await models.Sale.create(sampleSale, options);
|
||||||
|
const assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}}, options);
|
||||||
|
const paramsAssigned = {ticketFk: ticket.id, stateFk: assignedState.id, userFk: 1};
|
||||||
|
const resAssigned = await models.Ticket.state(ctx, paramsAssigned, options);
|
||||||
|
|
||||||
|
expect(resAssigned.ticketFk).toBe(paramsAssigned.ticketFk);
|
||||||
|
expect(resAssigned.stateFk).toBe(paramsAssigned.stateFk);
|
||||||
|
expect(resAssigned.userFk).toBe(paramsAssigned.userFk);
|
||||||
|
expect(resAssigned.userFk).toBe(1);
|
||||||
|
expect(resAssigned.id).toBeDefined();
|
||||||
|
|
||||||
|
activeCtx.accessToken.userId = productionId;
|
||||||
|
const packedState = await models.State.findOne({where: {code: 'PACKED'}}, options);
|
||||||
|
const paramsPacked = {ticketFk: ticket.id, stateFk: packedState.id, userFk: salesPersonId};
|
||||||
|
const resPacked = await models.Ticket.state(ctx, paramsPacked, options);
|
||||||
|
|
||||||
|
const sale = await models.Sale.findOne({where: {ticketFk: ticket.id}}, options);
|
||||||
|
|
||||||
|
expect(resPacked.stateFk).toBe(paramsPacked.stateFk);
|
||||||
|
expect(sale.quantity).toBe(sale.originalQuantity);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -64,7 +64,63 @@ module.exports = Self => {
|
||||||
if ((ticketState && !oldStateAllowed) || !newStateAllowed)
|
if ((ticketState && !oldStateAllowed) || !newStateAllowed)
|
||||||
throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED');
|
throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED');
|
||||||
|
|
||||||
await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [params.ticketFk, params.code], myOptions);
|
const ticket = await models.Ticket.findById(params.ticketFk, {
|
||||||
|
include: [{
|
||||||
|
relation: 'client',
|
||||||
|
scope: {
|
||||||
|
fields: ['salesPersonFk']
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
fields: ['id', 'clientFk']
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
const salesPersonFk = ticket.client().salesPersonFk;
|
||||||
|
if (salesPersonFk) {
|
||||||
|
const sales = await Self.rawSql(`
|
||||||
|
SELECT DISTINCT s.id,
|
||||||
|
s.itemFk,
|
||||||
|
s.concept,
|
||||||
|
s.originalQuantity AS oldQuantity,
|
||||||
|
s.quantity AS newQuantity
|
||||||
|
FROM vn.sale s
|
||||||
|
JOIN vn.saleTracking st ON st.saleFk = s.id
|
||||||
|
JOIN vn.ticket t ON t.id = s.ticketFk
|
||||||
|
JOIN vn.client c ON c.id = t.clientFk
|
||||||
|
JOIN vn.ticketState ts ON ts.ticketFk = t.id
|
||||||
|
JOIN vn.state s2 ON s2.id = ts.stateFk
|
||||||
|
WHERE s.ticketFk = ?
|
||||||
|
AND st.isChecked
|
||||||
|
AND s.originalQuantity IS NOT NULL
|
||||||
|
AND s.originalQuantity <> s.quantity
|
||||||
|
AND s2.\`order\` < (SELECT \`order\` FROM vn.state WHERE code = 'CHECKED')
|
||||||
|
ORDER BY st.created DESC
|
||||||
|
`, [params.ticketFk], myOptions);
|
||||||
|
|
||||||
|
let changes = '';
|
||||||
|
const url = await models.Url.getUrl();
|
||||||
|
const $t = ctx.req.__;
|
||||||
|
for (let sale of sales) {
|
||||||
|
changes += `\r\n-` + $t('Changes in sales', {
|
||||||
|
itemId: sale.itemFk,
|
||||||
|
concept: sale.concept,
|
||||||
|
oldQuantity: sale.oldQuantity,
|
||||||
|
newQuantity: sale.newQuantity,
|
||||||
|
itemUrl: `${url}item/${sale.itemFk}/summary`
|
||||||
|
});
|
||||||
|
const currentSale = await models.Sale.findById(sale.id, null, myOptions);
|
||||||
|
await currentSale.updateAttributes({
|
||||||
|
originalQuantity: currentSale.quantity
|
||||||
|
}, myOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = $t('Changed sale quantity', {
|
||||||
|
ticketId: ticket.id,
|
||||||
|
changes: changes,
|
||||||
|
ticketUrl: `${url}ticket/${ticket.id}/sale`
|
||||||
|
});
|
||||||
|
await models.Chat.sendCheckingPresence(ctx, salesPersonFk, message, myOptions);
|
||||||
|
}
|
||||||
|
await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticket.id, params.code], myOptions);
|
||||||
|
|
||||||
const ticketTracking = await models.TicketTracking.findOne({
|
const ticketTracking = await models.TicketTracking.findOne({
|
||||||
where: {ticketFk: params.ticketFk},
|
where: {ticketFk: params.ticketFk},
|
||||||
|
|
|
@ -54,8 +54,8 @@
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
ng-model="$ctrl.worker.originCountryFk"
|
ng-model="$ctrl.worker.originCountryFk"
|
||||||
url="Countries"
|
url="Countries"
|
||||||
fields="['id', 'country', 'code']"
|
fields="['id', 'name', 'code']"
|
||||||
show-field="country"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
label="Origin country">
|
label="Origin country">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
|
|
|
@ -5,6 +5,7 @@ describe('zone deletezone()', () => {
|
||||||
const userId = 9;
|
const userId = 9;
|
||||||
const activeCtx = {
|
const activeCtx = {
|
||||||
accessToken: {userId: userId},
|
accessToken: {userId: userId},
|
||||||
|
__: value => value
|
||||||
};
|
};
|
||||||
const ctx = {req: activeCtx};
|
const ctx = {req: activeCtx};
|
||||||
const zoneId = 9;
|
const zoneId = 9;
|
||||||
|
@ -15,19 +16,15 @@ describe('zone deletezone()', () => {
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
active: activeCtx
|
active: activeCtx
|
||||||
});
|
});
|
||||||
try {
|
const originalTickets = await models.Ticket.find({
|
||||||
const originalTickets = await models.Ticket.find({
|
where: {
|
||||||
where: {
|
zoneFk: zoneId
|
||||||
zoneFk: zoneId
|
}
|
||||||
}
|
});
|
||||||
});
|
ticketIDs = originalTickets.map(ticket => ticket.id);
|
||||||
ticketIDs = originalTickets.map(ticket => ticket.id);
|
originalTicketStates = await models.TicketState.find({where: {
|
||||||
originalTicketStates = await models.TicketState.find({where: {
|
ticketFk: {inq: ticketIDs},
|
||||||
ticketFk: {inq: ticketIDs},
|
code: 'FIXING'}});
|
||||||
code: 'FIXING'}});
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete a zone and update their tickets', async() => {
|
it('should delete a zone and update their tickets', async() => {
|
||||||
|
|
Loading…
Reference in New Issue