fixes #4962 Refactor Ticket Tour a Futuro #1212
|
@ -0,0 +1,73 @@
|
|||
DROP PROCEDURE IF EXISTS `vn`.`ticket_canbePostponed`;
|
||||
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_canbePostponed`(vOriginDated DATE, vFutureDated DATE, vWarehouseFk INT)
|
||||
BEGIN
|
||||
/**
|
||||
* Devuelve un listado de tickets susceptibles de fusionarse con otros tickets en el futuro
|
||||
*
|
||||
* @param vOriginDated Fecha en cuestión
|
||||
* @param vFutureDated Fecha en el futuro a sondear
|
||||
* @param vWarehouseFk Identificador de vn.warehouse
|
||||
*/
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.filter;
|
||||
CREATE TEMPORARY TABLE tmp.filter
|
||||
(INDEX (id))
|
||||
SELECT sv.ticketFk id,
|
||||
GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt,
|
||||
CAST(sum(litros) AS DECIMAL(10,0)) liters,
|
||||
CAST(count(*) AS DECIMAL(10,0)) `lines`,
|
||||
st.name state,
|
||||
sub2.id ticketFuture,
|
||||
sub2.iptd tfIpt,
|
||||
sub2.state tfState,
|
||||
t.clientFk,
|
||||
t.warehouseFk,
|
||||
ts.alertLevel,
|
||||
t.shipped,
|
||||
sub2.shipped tfShipped,
|
||||
t.workerFk,
|
||||
st.code stateCode,
|
||||
sub2.code tfStateCode
|
||||
FROM vn.saleVolume sv
|
||||
JOIN vn.sale s ON s.id = sv.saleFk
|
||||
JOIN vn.item i ON i.id = s.itemFk
|
||||
JOIN vn.ticket t ON t.id = sv.ticketFk
|
||||
JOIN vn.address a ON a.id = t.addressFk
|
||||
JOIN vn.province p ON p.id = a.provinceFk
|
||||
JOIN vn.country c ON c.id = p.countryFk
|
||||
JOIN vn.ticketState ts ON ts.ticketFk = t.id
|
||||
JOIN vn.state st ON st.id = ts.stateFk
|
||||
JOIN vn.alertLevel al ON al.id = ts.alertLevel
|
||||
LEFT JOIN vn.ticketParking tp ON tp.ticketFk = t.id
|
||||
LEFT JOIN (
|
||||
SELECT *
|
||||
FROM (
|
||||
SELECT
|
||||
t.addressFk ,
|
||||
t.id,
|
||||
t.shipped,
|
||||
st.name state,
|
||||
st.code code,
|
||||
GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) iptd
|
||||
FROM vn.ticket t
|
||||
JOIN vn.ticketState ts ON ts.ticketFk = t.id
|
||||
JOIN vn.state st ON st.id = ts.stateFk
|
||||
JOIN vn.sale s ON s.ticketFk = t.id
|
||||
JOIN vn.item i ON i.id = s.itemFk
|
||||
WHERE t.shipped BETWEEN vFutureDated
|
||||
AND util.dayend(vFutureDated)
|
||||
AND t.warehouseFk = vWarehouseFk
|
||||
GROUP BY t.id
|
||||
) sub
|
||||
GROUP BY sub.addressFk
|
||||
) sub2 ON sub2.addressFk = t.addressFk AND t.id != sub2.id
|
||||
WHERE t.shipped BETWEEN vOriginDated AND util.dayend(vOriginDated)
|
||||
AND t.warehouseFk = vWarehouseFk
|
||||
AND al.code = 'FREE'
|
||||
AND tp.ticketFk IS NULL
|
||||
GROUP BY sv.ticketFk
|
||||
HAVING ticketFuture;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -735,10 +735,8 @@ export default {
|
|||
},
|
||||
ticketFuture: {
|
||||
openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
|
||||
originDated: 'vn-date-picker[label="Origin ETD"]',
|
||||
futureDated: 'vn-date-picker[label="Destination ETD"]',
|
||||
shipped: 'vn-date-picker[label="Origin date"]',
|
||||
tfShipped: 'vn-date-picker[label="Destination date"]',
|
||||
originDated: 'vn-date-picker[label="Origin date"]',
|
||||
futureDated: 'vn-date-picker[label="Destination date"]',
|
||||
linesMax: 'vn-textfield[label="Max Lines"]',
|
||||
litersMax: 'vn-textfield[label="Max Liters"]',
|
||||
ipt: 'vn-autocomplete[label="Origin IPT"]',
|
||||
|
@ -756,8 +754,8 @@ export default {
|
|||
multiCheck: 'vn-multi-check',
|
||||
tableId: 'vn-textfield[name="id"]',
|
||||
tableTfId: 'vn-textfield[name="ticketFuture"]',
|
||||
tableLiters: 'vn-textfield[name="litersMax"]',
|
||||
tableLines: 'vn-textfield[name="linesMax"]',
|
||||
tableLiters: 'vn-textfield[name="liters"]',
|
||||
|
||||
tableLines: 'vn-textfield[name="lines"]',
|
||||
submit: 'vn-submit[label="Search"]',
|
||||
table: 'tbody > tr:not(.empty-rows)'
|
||||
},
|
||||
|
|
|
@ -16,9 +16,6 @@ describe('Ticket Future path', () => {
|
|||
await browser.close();
|
||||
});
|
||||
|
||||
const now = new Date();
|
||||
const tomorrow = new Date(now.getDate() + 1);
|
||||
|
||||
it('should show errors snackbar because of the required data', async() => {
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
await page.clearInput(selectors.ticketFuture.warehouseFk);
|
||||
|
@ -27,20 +24,6 @@ describe('Ticket Future path', () => {
|
|||
|
||||
expect(message.text).toContain('warehouseFk is a required argument');
|
||||
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
await page.clearInput(selectors.ticketFuture.litersMax);
|
||||
await page.waitToClick(selectors.ticketFuture.submit);
|
||||
message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('litersMax is a required argument');
|
||||
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
await page.clearInput(selectors.ticketFuture.linesMax);
|
||||
await page.waitToClick(selectors.ticketFuture.submit);
|
||||
message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('linesMax is a required argument');
|
||||
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
await page.clearInput(selectors.ticketFuture.futureDated);
|
||||
await page.waitToClick(selectors.ticketFuture.submit);
|
||||
|
@ -62,40 +45,9 @@ describe('Ticket Future path', () => {
|
|||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
|
||||
});
|
||||
|
||||
it('should search with the origin shipped today', async() => {
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
await page.pickDate(selectors.ticketFuture.shipped, now);
|
||||
await page.waitToClick(selectors.ticketFuture.submit);
|
||||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
|
||||
});
|
||||
|
||||
it('should search with the origin shipped tomorrow', async() => {
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
await page.pickDate(selectors.ticketFuture.shipped, tomorrow);
|
||||
await page.waitToClick(selectors.ticketFuture.submit);
|
||||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
|
||||
});
|
||||
|
||||
it('should search with the destination shipped today', async() => {
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
await page.clearInput(selectors.ticketFuture.shipped);
|
||||
await page.pickDate(selectors.ticketFuture.tfShipped, now);
|
||||
await page.waitToClick(selectors.ticketFuture.submit);
|
||||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
|
||||
});
|
||||
|
||||
it('should search with the destination shipped tomorrow', async() => {
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
await page.pickDate(selectors.ticketFuture.tfShipped, tomorrow);
|
||||
await page.waitToClick(selectors.ticketFuture.submit);
|
||||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
|
||||
});
|
||||
|
||||
it('should search with the origin IPT', async() => {
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
|
||||
await page.clearInput(selectors.ticketFuture.shipped);
|
||||
await page.clearInput(selectors.ticketFuture.tfShipped);
|
||||
await page.clearInput(selectors.ticketFuture.ipt);
|
||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
||||
await page.clearInput(selectors.ticketFuture.state);
|
||||
|
@ -109,8 +61,6 @@ describe('Ticket Future path', () => {
|
|||
it('should search with the destination IPT', async() => {
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
|
||||
await page.clearInput(selectors.ticketFuture.shipped);
|
||||
await page.clearInput(selectors.ticketFuture.tfShipped);
|
||||
await page.clearInput(selectors.ticketFuture.ipt);
|
||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
||||
await page.clearInput(selectors.ticketFuture.state);
|
||||
|
@ -124,8 +74,6 @@ describe('Ticket Future path', () => {
|
|||
it('should search with the origin grouped state', async() => {
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
|
||||
await page.clearInput(selectors.ticketFuture.shipped);
|
||||
await page.clearInput(selectors.ticketFuture.tfShipped);
|
||||
await page.clearInput(selectors.ticketFuture.ipt);
|
||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
||||
await page.clearInput(selectors.ticketFuture.state);
|
||||
|
@ -139,8 +87,6 @@ describe('Ticket Future path', () => {
|
|||
it('should search with the destination grouped state', async() => {
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
|
||||
await page.clearInput(selectors.ticketFuture.shipped);
|
||||
await page.clearInput(selectors.ticketFuture.tfShipped);
|
||||
await page.clearInput(selectors.ticketFuture.ipt);
|
||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
||||
await page.clearInput(selectors.ticketFuture.state);
|
||||
|
@ -151,8 +97,6 @@ describe('Ticket Future path', () => {
|
|||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
|
||||
|
||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||
await page.clearInput(selectors.ticketFuture.shipped);
|
||||
await page.clearInput(selectors.ticketFuture.tfShipped);
|
||||
await page.clearInput(selectors.ticketFuture.ipt);
|
||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
||||
await page.clearInput(selectors.ticketFuture.state);
|
|
@ -20,3 +20,4 @@ routeFk: route
|
|||
companyFk: company
|
||||
agencyModeFk: agency
|
||||
ticketFk: ticket
|
||||
mergedTicket: merged ticket
|
||||
|
|
|
@ -20,3 +20,4 @@ routeFk: ruta
|
|||
companyFk: empresa
|
||||
agencyModeFk: agencia
|
||||
ticketFk: ticket
|
||||
mergedTicket: ticket fusionado
|
||||
|
|
|
@ -20,18 +20,6 @@ module.exports = Self => {
|
|||
description: 'The date to probe',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'litersMax',
|
||||
type: 'number',
|
||||
description: 'Maximum volume of tickets to catapult',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'linesMax',
|
||||
type: 'number',
|
||||
description: 'Maximum number of lines of tickets to catapult',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'warehouseFk',
|
||||
type: 'number',
|
||||
|
@ -39,15 +27,15 @@ module.exports = Self => {
|
|||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'shipped',
|
||||
type: 'date',
|
||||
description: 'Origin shipped',
|
||||
arg: 'liters',
|
||||
type: 'number',
|
||||
description: 'Maximum volume of tickets to catapult',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
arg: 'tfShipped',
|
||||
type: 'date',
|
||||
description: 'Destination shipped',
|
||||
arg: 'lines',
|
||||
type: 'number',
|
||||
description: 'Maximum number of lines of tickets to catapult',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
|
@ -108,7 +96,7 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getTicketsFuture = async (ctx, options) => {
|
||||
Self.getTicketsFuture = async(ctx, options) => {
|
||||
const args = ctx.args;
|
||||
const conn = Self.dataSource.connector;
|
||||
const myOptions = {};
|
||||
|
@ -118,32 +106,32 @@ module.exports = Self => {
|
|||
|
||||
const where = buildFilter(ctx.args, (param, value) => {
|
||||
switch (param) {
|
||||
case 'id':
|
||||
return { 'f.id': value };
|
||||
case 'tfId':
|
||||
return { 'f.ticketFuture': value };
|
||||
case 'shipped':
|
||||
return { 'f.shipped': value };
|
||||
case 'tfShipped':
|
||||
return { 'f.tfShipped': value };
|
||||
case 'ipt':
|
||||
return { 'f.ipt': value };
|
||||
case 'tfIpt':
|
||||
return { 'f.tfIpt': value };
|
||||
case 'state':
|
||||
return { 'f.code': { like: `%${value}%` } };
|
||||
case 'tfState':
|
||||
return { 'f.tfCode': { like: `%${value}%` } };
|
||||
case 'id':
|
||||
return {'f.id': value};
|
||||
case 'lines':
|
||||
return {'f.lines': {lte: value}};
|
||||
case 'liters':
|
||||
return {'f.liters': {lte: value}};
|
||||
case 'tfId':
|
||||
return {'f.ticketFuture': value};
|
||||
case 'ipt':
|
||||
return {'f.ipt': value};
|
||||
case 'tfIpt':
|
||||
return {'f.tfIpt': value};
|
||||
case 'state':
|
||||
return {'f.stateCode': {like: `%${value}%`}};
|
||||
case 'tfState':
|
||||
return {'f.tfStateCode': {like: `%${value}%`}};
|
||||
}
|
||||
});
|
||||
|
||||
let filter = mergeFilters(ctx.args.filter, { where });
|
||||
let filter = mergeFilters(ctx.args.filter, {where});
|
||||
const stmts = [];
|
||||
let stmt;
|
||||
|
||||
stmt = new ParameterizedSQL(
|
||||
`CALL vn.ticket_canbePostponed(?,?,?,?,?)`,
|
||||
[args.originDated, args.futureDated, args.litersMax, args.linesMax, args.warehouseFk]);
|
||||
`CALL vn.ticket_canbePostponed(?,?,?)`,
|
||||
[args.originDated, args.futureDated, args.warehouseFk]);
|
||||
|
||||
stmts.push(stmt);
|
||||
|
||||
|
@ -153,7 +141,7 @@ module.exports = Self => {
|
|||
CREATE TEMPORARY TABLE tmp.sale_getProblems
|
||||
(INDEX (ticketFk))
|
||||
ENGINE = MEMORY
|
||||
SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped
|
||||
SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped, f.lines, f.liters
|
||||
FROM tmp.filter f
|
||||
LEFT JOIN alertLevel al ON al.id = f.alertLevel
|
||||
WHERE (al.code = 'FREE' OR f.alertLevel IS NULL)`);
|
||||
|
@ -174,35 +162,34 @@ module.exports = Self => {
|
|||
let range;
|
||||
let hasWhere;
|
||||
switch (args.problems) {
|
||||
case true:
|
||||
condition = `or`;
|
||||
hasProblem = true;
|
||||
range = { neq: null };
|
||||
hasWhere = true;
|
||||
break;
|
||||
case true:
|
||||
condition = `or`;
|
||||
hasProblem = true;
|
||||
range = {neq: null};
|
||||
hasWhere = true;
|
||||
break;
|
||||
|
||||
case false:
|
||||
condition = `and`;
|
||||
hasProblem = null;
|
||||
range = null;
|
||||
hasWhere = true;
|
||||
break;
|
||||
case false:
|
||||
condition = `and`;
|
||||
hasProblem = null;
|
||||
range = null;
|
||||
hasWhere = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const problems = {
|
||||
[condition]: [
|
||||
{ 'tp.isFreezed': hasProblem },
|
||||
{ 'tp.risk': hasProblem },
|
||||
{ 'tp.hasTicketRequest': hasProblem },
|
||||
{ 'tp.itemShortage': range },
|
||||
{ 'tp.hasComponentLack': hasProblem },
|
||||
{ 'tp.isTooLittle': hasProblem }
|
||||
{'tp.isFreezed': hasProblem},
|
||||
{'tp.risk': hasProblem},
|
||||
{'tp.hasTicketRequest': hasProblem},
|
||||
{'tp.itemShortage': range},
|
||||
{'tp.hasComponentLack': hasProblem},
|
||||
{'tp.isTooLittle': hasProblem}
|
||||
]
|
||||
};
|
||||
|
||||
if (hasWhere) {
|
||||
filter = mergeFilters(filter, { where: problems });
|
||||
}
|
||||
if (hasWhere)
|
||||
filter = mergeFilters(filter, {where: problems});
|
||||
|
||||
stmt.merge(conn.makeWhere(filter.where));
|
||||
stmt.merge(conn.makeOrderBy(filter.order));
|
||||
|
|
|
@ -5,11 +5,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
today.setHours(0, 0, 0, 0);
|
||||
const tomorrow = new Date(today.getDate() + 1);
|
||||
|
||||
it('should return the tickets passing the required data', async () => {
|
||||
it('should return the tickets passing the required data', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -19,7 +19,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
warehouseFk: 1,
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
|
@ -30,11 +30,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the problems on true', async () => {
|
||||
it('should return the tickets matching the problems on true', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -45,7 +45,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
problems: true
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
|
@ -57,11 +57,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the problems on false', async () => {
|
||||
it('should return the tickets matching the problems on false', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -72,7 +72,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
problems: false
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(0);
|
||||
|
@ -84,11 +84,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the problems on null', async () => {
|
||||
it('should return the tickets matching the problems on null', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -99,7 +99,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
problems: null
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
|
@ -111,11 +111,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the correct origin shipped', async () => {
|
||||
it('should return the tickets matching the OK State in origin date', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -123,118 +123,10 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
litersMax: 9999,
|
||||
linesMax: 9999,
|
||||
warehouseFk: 1,
|
||||
shipped: today
|
||||
state: 'OK'
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the an incorrect origin shipped', async () => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
futureDated: today,
|
||||
litersMax: 9999,
|
||||
linesMax: 9999,
|
||||
warehouseFk: 1,
|
||||
shipped: tomorrow
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(0);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the correct destination shipped', async () => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
futureDated: today,
|
||||
litersMax: 9999,
|
||||
linesMax: 9999,
|
||||
warehouseFk: 1,
|
||||
tfShipped: today
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the an incorrect destination shipped', async () => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
futureDated: today,
|
||||
litersMax: 9999,
|
||||
linesMax: 9999,
|
||||
warehouseFk: 1,
|
||||
tfShipped: tomorrow
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(0);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the OK State in origin date', async () => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
futureDated: today,
|
||||
litersMax: 9999,
|
||||
linesMax: 9999,
|
||||
warehouseFk: 1,
|
||||
state: "OK"
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(1);
|
||||
|
@ -246,11 +138,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the OK State in destination date', async () => {
|
||||
it('should return the tickets matching the OK State in destination date', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -258,10 +150,10 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
litersMax: 9999,
|
||||
linesMax: 9999,
|
||||
warehouseFk: 1,
|
||||
tfState: "OK"
|
||||
tfState: 'OK'
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
|
@ -273,11 +165,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the correct IPT in origin date', async () => {
|
||||
it('should return the tickets matching the correct IPT in origin date', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -288,7 +180,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
ipt: null
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
|
@ -300,11 +192,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the incorrect IPT in origin date', async () => {
|
||||
it('should return the tickets matching the incorrect IPT in origin date', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -315,7 +207,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
ipt: 0
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(0);
|
||||
|
@ -327,11 +219,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the correct IPT in destination date', async () => {
|
||||
it('should return the tickets matching the correct IPT in destination date', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -342,7 +234,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
tfIpt: null
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
|
@ -354,11 +246,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the incorrect IPT in destination date', async () => {
|
||||
it('should return the tickets matching the incorrect IPT in destination date', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -369,7 +261,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
tfIpt: 0
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(0);
|
||||
|
@ -381,11 +273,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the ID in origin date', async () => {
|
||||
it('should return the tickets matching the ID in origin date', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -396,7 +288,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
id: 13
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(1);
|
||||
|
@ -408,11 +300,11 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should return the tickets matching the ID in destination date', async () => {
|
||||
it('should return the tickets matching the ID in destination date', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = { transaction: tx };
|
||||
const options = {transaction: tx};
|
||||
|
||||
const args = {
|
||||
originDated: today,
|
||||
|
@ -423,7 +315,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
tfId: 12
|
||||
};
|
||||
|
||||
const ctx = { req: { accessToken: { userId: 9 } }, args };
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||
const result = await models.Ticket.getTicketsFuture(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
|
@ -434,5 +326,4 @@ describe('TicketFuture getTicketsFuture()', () => {
|
|||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -43,14 +43,27 @@ module.exports = Self => {
|
|||
const fullPath = `${origin}/#!/ticket/${ticket.id}/summary`;
|
||||
const fullPathFuture = `${origin}/#!/ticket/${ticket.ticketFuture}/summary`;
|
||||
const message = $t('Ticket merged', {
|
||||
originDated: dateUtil.toString(new Date(ticket.originETD)),
|
||||
futureDated: dateUtil.toString(new Date(ticket.destETD)),
|
||||
originDated: dateUtil.toString(new Date(ticket.shipped)),
|
||||
futureDated: dateUtil.toString(new Date(ticket.tfShipped)),
|
||||
alexandre marked this conversation as resolved
Outdated
jgallego
commented
que es tf? llegint veig que es abreviatura de ticket future. que es tf? llegint veig que es abreviatura de ticket future.
Com ticket ja es sap jo posaria ticket.futureShipped
|
||||
id: ticket.id,
|
||||
tfId: ticket.ticketFuture,
|
||||
fullPath,
|
||||
fullPathFuture
|
||||
});
|
||||
if (!ticket.id || !ticket.ticketFuture) continue;
|
||||
|
||||
const ticketFutureLogRecord = {
|
||||
originFk: ticket.ticketFuture,
|
||||
userFk: ctx.req.accessToken.userId,
|
||||
action: 'update',
|
||||
changedModel: 'Ticket',
|
||||
changedModelId: ticket.ticketFuture,
|
||||
changedModelValue: ticket.ticketFuture,
|
||||
oldInstance: {},
|
||||
newInstance: {mergedTicket: ticket.id}
|
||||
};
|
||||
|
||||
await models.TicketLog.create(ticketFutureLogRecord, myOptions);
|
||||
await models.Sale.updateAll({ticketFk: ticket.id}, {ticketFk: ticket.ticketFuture}, myOptions);
|
||||
await models.Ticket.setDeleted(ctx, ticket.id, myOptions);
|
||||
await models.Chat.sendCheckingPresence(ctx, ticket.workerFk, message);
|
||||
|
|
|
@ -4,43 +4,26 @@
|
|||
<vn-date-picker
|
||||
vn-one
|
||||
label="Origin date"
|
||||
ng-model="filter.shipped"
|
||||
on-change="$ctrl.from = value">
|
||||
ng-model="filter.originDated"
|
||||
required="true">
|
||||
</vn-date-picker>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="Destination date"
|
||||
ng-model="filter.tfShipped">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="Origin ETD"
|
||||
ng-model="filter.originDated"
|
||||
required="true"
|
||||
info="ETD">
|
||||
</vn-date-picker>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="Destination ETD"
|
||||
ng-model="filter.futureDated"
|
||||
required="true"
|
||||
info="ETD">
|
||||
required="true">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Max Lines"
|
||||
ng-model="filter.linesMax"
|
||||
required="true">
|
||||
ng-model="filter.lines">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Max Liters"
|
||||
ng-model="filter.litersMax"
|
||||
required="true">
|
||||
ng-model="filter.liters">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
|
@ -48,22 +31,22 @@
|
|||
data="$ctrl.itemPackingTypes"
|
||||
label="Origin IPT"
|
||||
value-field="code"
|
||||
show-field="name"
|
||||
show-field="description"
|
||||
ng-model="filter.ipt"
|
||||
info="IPT">
|
||||
<tpl-item>
|
||||
{{name}}
|
||||
{{description}}
|
||||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
data="$ctrl.itemPackingTypes"
|
||||
label="Destination IPT"
|
||||
value-field="code"
|
||||
show-field="name"
|
||||
show-field="description"
|
||||
ng-model="filter.tfIpt"
|
||||
info="IPT">
|
||||
<tpl-item>
|
||||
{{name}}
|
||||
{{description}}
|
||||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
|
|
|
@ -28,9 +28,8 @@ class Controller extends SearchPanel {
|
|||
this.$http.get('ItemPackingTypes').then(res => {
|
||||
for (let ipt of res.data) {
|
||||
itemPackingTypes.push({
|
||||
id: ipt.id,
|
||||
description: this.$t(ipt.description),
|
||||
code: ipt.code,
|
||||
name: this.$t(ipt.code)
|
||||
});
|
||||
}
|
||||
this.itemPackingTypes = itemPackingTypes;
|
||||
|
|
|
@ -1,9 +1 @@
|
|||
Future tickets: Tickets a futuro
|
||||
FREE: Free
|
||||
DELIVERED: Delivered
|
||||
ON_PREPARATION: On preparation
|
||||
PACKED: Packed
|
||||
F: Fruits and vegetables
|
||||
V: Vertical
|
||||
H: Horizontal
|
||||
P: Feed
|
||||
|
|
|
@ -11,13 +11,4 @@ With problems: Con problemas
|
|||
Warehouse: Almacén
|
||||
Origin Grouped State: Estado agrupado origen
|
||||
Destination Grouped State: Estado agrupado destino
|
||||
FREE: Libre
|
||||
DELIVERED: Servido
|
||||
ON_PREPARATION: En preparacion
|
||||
PACKED: Encajado
|
||||
F: Frutas y verduras
|
||||
V: Vertical
|
||||
H: Horizontal
|
||||
P: Pienso
|
||||
ETD: Tiempo estimado de entrega
|
||||
IPT: Encajado
|
||||
|
|
|
@ -44,31 +44,31 @@
|
|||
<th field="id">
|
||||
<span translate>Origin ID</span>
|
||||
</th>
|
||||
<th field="originETD">
|
||||
<span translate>Origin ETD</span>
|
||||
<th field="shipped">
|
||||
<span translate>Origin Date</span>
|
||||
</th>
|
||||
<th field="state">
|
||||
<span translate>Origin State</span>
|
||||
</th>
|
||||
<th field="ipt">
|
||||
<th field="ipt" title="Item Packing Type">
|
||||
<span>IPT</span>
|
||||
</th>
|
||||
<th field="litersMax">
|
||||
<th field="liters">
|
||||
<span translate>Liters</span>
|
||||
</th>
|
||||
<th field="linesMax">
|
||||
<th field="lines">
|
||||
<span translate>Available Lines</span>
|
||||
</th>
|
||||
<th field="ticketFuture">
|
||||
<span translate>Destination ID</span>
|
||||
</th>
|
||||
<th field="destETD">
|
||||
<span translate>Destination ETD</span>
|
||||
<th field="tfShipped">
|
||||
<span translate>Destination Date</span>
|
||||
</th>
|
||||
<th field="tfState">
|
||||
<span translate>Destination State</span>
|
||||
</th>
|
||||
<th field="tfIpt">
|
||||
<th field="tfIpt" title="Item Packing Type">
|
||||
<span>IPT</span>
|
||||
</th>
|
||||
</tr>
|
||||
|
@ -125,8 +125,8 @@
|
|||
{{::ticket.id}}
|
||||
</span></td>
|
||||
<td shrink-date>
|
||||
<span class="chip {{$ctrl.compareDate(ticket.originETD)}}">
|
||||
{{::ticket.originETD | date: 'dd/MM/yyyy'}}
|
||||
<span class="chip {{$ctrl.compareDate(ticket.shipped)}}">
|
||||
{{::ticket.shipped | date: 'dd/MM/yyyy'}}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
|
@ -146,8 +146,8 @@
|
|||
</span>
|
||||
</td>
|
||||
<td shrink-date>
|
||||
<span class="chip {{$ctrl.compareDate(ticket.destETD)}}">
|
||||
{{::ticket.destETD | date: 'dd/MM/yyyy'}}
|
||||
<span class="chip {{$ctrl.compareDate(ticket.tfShipped)}}">
|
||||
{{::ticket.tfShipped | date: 'dd/MM/yyyy'}}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
|
|
|
@ -15,11 +15,11 @@ export default class Controller extends Section {
|
|||
searchable: false
|
||||
},
|
||||
{
|
||||
field: 'originETD',
|
||||
field: 'shipped',
|
||||
searchable: false
|
||||
},
|
||||
{
|
||||
field: 'destETD',
|
||||
field: 'tfShipped',
|
||||
searchable: false
|
||||
},
|
||||
{
|
||||
|
@ -35,7 +35,7 @@ export default class Controller extends Section {
|
|||
autocomplete: {
|
||||
url: 'ItemPackingTypes',
|
||||
showField: 'description',
|
||||
valueField: 'code'
|
||||
valueField: 'description'
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ export default class Controller extends Section {
|
|||
autocomplete: {
|
||||
url: 'ItemPackingTypes',
|
||||
showField: 'description',
|
||||
valueField: 'code'
|
||||
valueField: 'description'
|
||||
}
|
||||
},
|
||||
]
|
||||
|
@ -57,9 +57,7 @@ export default class Controller extends Section {
|
|||
this.filterParams = {
|
||||
originDated: today,
|
||||
futureDated: today,
|
||||
linesMax: '9999',
|
||||
litersMax: '9999',
|
||||
warehouseFk: 1
|
||||
warehouseFk: this.vnConfig.warehouseFk
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -113,7 +111,7 @@ export default class Controller extends Section {
|
|||
}
|
||||
|
||||
moveTicketsFuture() {
|
||||
let params = { tickets: this.checked };
|
||||
let params = {tickets: this.checked};
|
||||
return this.$http.post('Tickets/merge', params)
|
||||
.then(() => {
|
||||
this.$.model.refresh();
|
||||
|
@ -123,18 +121,18 @@ export default class Controller extends Section {
|
|||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'id':
|
||||
return { 'id': value };
|
||||
case 'ticketFuture':
|
||||
return { 'ticketFuture': value };
|
||||
case 'litersMax':
|
||||
return { 'liters': value };
|
||||
case 'linesMax':
|
||||
return { 'lines': value };
|
||||
case 'ipt':
|
||||
return { 'ipt': value };
|
||||
case 'tfIpt':
|
||||
return { 'tfIpt': value };
|
||||
case 'id':
|
||||
return {'id': value};
|
||||
case 'ticketFuture':
|
||||
return {'ticketFuture': value};
|
||||
case 'liters':
|
||||
return {'liters': value};
|
||||
case 'lines':
|
||||
return {'lines': value};
|
||||
case 'ipt':
|
||||
return {'ipt': value};
|
||||
case 'tfIpt':
|
||||
return {'tfIpt': value};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,16 +13,16 @@ describe('Component vnTicketFuture', () => {
|
|||
$httpBackend = _$httpBackend_;
|
||||
$window = _$window_;
|
||||
const $element = angular.element('<vn-ticket-future></vn-ticket-future>');
|
||||
controller = $componentController('vnTicketFuture', { $element });
|
||||
controller = $componentController('vnTicketFuture', {$element});
|
||||
controller.$.model = crudModel;
|
||||
controller.$.model.data = [{
|
||||
id: 1,
|
||||
checked: true,
|
||||
state: "OK"
|
||||
state: 'OK'
|
||||
}, {
|
||||
id: 2,
|
||||
checked: true,
|
||||
state: "Libre"
|
||||
state: 'Libre'
|
||||
}];
|
||||
}));
|
||||
|
||||
|
@ -67,6 +67,7 @@ describe('Component vnTicketFuture', () => {
|
|||
it('should return success to the OK tickets', () => {
|
||||
const ok = controller.stateColor(controller.$.model.data[0].state);
|
||||
const notOk = controller.stateColor(controller.$.model.data[1].state);
|
||||
|
||||
expect(ok).toEqual('success');
|
||||
expect(notOk).not.toEqual('success');
|
||||
});
|
||||
|
@ -74,6 +75,7 @@ describe('Component vnTicketFuture', () => {
|
|||
it('should return success to the FREE tickets', () => {
|
||||
const notFree = controller.stateColor(controller.$.model.data[0].state);
|
||||
const free = controller.stateColor(controller.$.model.data[1].state);
|
||||
|
||||
expect(free).toEqual('notice');
|
||||
expect(notFree).not.toEqual('notice');
|
||||
});
|
||||
|
|
|
@ -1,6 +1,2 @@
|
|||
Move confirmation: Do you want to move {{checked}} tickets to the future?
|
||||
FREE: Free
|
||||
DELIVERED: Delivered
|
||||
ON_PREPARATION: On preparation
|
||||
PACKED: Packed
|
||||
Success: Tickets moved successfully!
|
||||
|
|
|
@ -3,20 +3,14 @@ Search tickets: Buscar tickets
|
|||
Search future tickets by date: Buscar tickets por fecha
|
||||
Problems: Problemas
|
||||
Origin ID: ID origen
|
||||
Closing: Cierre
|
||||
Origin State: Estado origen
|
||||
Destination State: Estado destino
|
||||
Liters: Litros
|
||||
Available Lines: Líneas disponibles
|
||||
Destination ID: ID destino
|
||||
Destination ETD: ETD Destino
|
||||
Origin ETD: ETD Origen
|
||||
Move tickets: Mover tickets
|
||||
Move confirmation: ¿Desea mover {{checked}} tickets hacia el futuro?
|
||||
Success: Tickets movidos correctamente
|
||||
ETD: Tiempo estimado de entrega
|
||||
IPT: Encajado
|
||||
FREE: Libre
|
||||
DELIVERED: Servido
|
||||
ON_PREPARATION: En preparacion
|
||||
PACKED: Encajado
|
||||
Origin Date: Fecha origen
|
||||
Destination Date: Fecha destino
|
||||
|
|
Loading…
Reference in New Issue
perque canvies el nom? l'anterior a mi em pareixia correcte, no son litros exactes, sino litros màxims
Ho he tingut que posar aixina perque com en el procediment se diu 'lines' i 'liters' al ordenar me donava error. En veritat no passa res perque en el buscador ja apareix que son litres i linies màximes.