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: {
|
ticketFuture: {
|
||||||
openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
|
openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
|
||||||
originDated: 'vn-date-picker[label="Origin ETD"]',
|
originDated: 'vn-date-picker[label="Origin date"]',
|
||||||
futureDated: 'vn-date-picker[label="Destination ETD"]',
|
futureDated: 'vn-date-picker[label="Destination date"]',
|
||||||
shipped: 'vn-date-picker[label="Origin date"]',
|
|
||||||
tfShipped: 'vn-date-picker[label="Destination date"]',
|
|
||||||
linesMax: 'vn-textfield[label="Max Lines"]',
|
linesMax: 'vn-textfield[label="Max Lines"]',
|
||||||
litersMax: 'vn-textfield[label="Max Liters"]',
|
litersMax: 'vn-textfield[label="Max Liters"]',
|
||||||
ipt: 'vn-autocomplete[label="Origin IPT"]',
|
ipt: 'vn-autocomplete[label="Origin IPT"]',
|
||||||
|
@ -756,8 +754,8 @@ export default {
|
||||||
multiCheck: 'vn-multi-check',
|
multiCheck: 'vn-multi-check',
|
||||||
tableId: 'vn-textfield[name="id"]',
|
tableId: 'vn-textfield[name="id"]',
|
||||||
tableTfId: 'vn-textfield[name="ticketFuture"]',
|
tableTfId: 'vn-textfield[name="ticketFuture"]',
|
||||||
tableLiters: 'vn-textfield[name="litersMax"]',
|
tableLiters: 'vn-textfield[name="liters"]',
|
||||||
|
|||||||
tableLines: 'vn-textfield[name="linesMax"]',
|
tableLines: 'vn-textfield[name="lines"]',
|
||||||
submit: 'vn-submit[label="Search"]',
|
submit: 'vn-submit[label="Search"]',
|
||||||
table: 'tbody > tr:not(.empty-rows)'
|
table: 'tbody > tr:not(.empty-rows)'
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,9 +16,6 @@ describe('Ticket Future path', () => {
|
||||||
await browser.close();
|
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() => {
|
it('should show errors snackbar because of the required data', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||||
await page.clearInput(selectors.ticketFuture.warehouseFk);
|
await page.clearInput(selectors.ticketFuture.warehouseFk);
|
||||||
|
@ -27,20 +24,6 @@ describe('Ticket Future path', () => {
|
||||||
|
|
||||||
expect(message.text).toContain('warehouseFk is a required argument');
|
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.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
||||||
await page.clearInput(selectors.ticketFuture.futureDated);
|
await page.clearInput(selectors.ticketFuture.futureDated);
|
||||||
await page.waitToClick(selectors.ticketFuture.submit);
|
await page.waitToClick(selectors.ticketFuture.submit);
|
||||||
|
@ -62,40 +45,9 @@ describe('Ticket Future path', () => {
|
||||||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
|
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() => {
|
it('should search with the origin IPT', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
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.ipt);
|
||||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
await page.clearInput(selectors.ticketFuture.tfIpt);
|
||||||
await page.clearInput(selectors.ticketFuture.state);
|
await page.clearInput(selectors.ticketFuture.state);
|
||||||
|
@ -109,8 +61,6 @@ describe('Ticket Future path', () => {
|
||||||
it('should search with the destination IPT', async() => {
|
it('should search with the destination IPT', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
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.ipt);
|
||||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
await page.clearInput(selectors.ticketFuture.tfIpt);
|
||||||
await page.clearInput(selectors.ticketFuture.state);
|
await page.clearInput(selectors.ticketFuture.state);
|
||||||
|
@ -124,8 +74,6 @@ describe('Ticket Future path', () => {
|
||||||
it('should search with the origin grouped state', async() => {
|
it('should search with the origin grouped state', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
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.ipt);
|
||||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
await page.clearInput(selectors.ticketFuture.tfIpt);
|
||||||
await page.clearInput(selectors.ticketFuture.state);
|
await page.clearInput(selectors.ticketFuture.state);
|
||||||
|
@ -139,8 +87,6 @@ describe('Ticket Future path', () => {
|
||||||
it('should search with the destination grouped state', async() => {
|
it('should search with the destination grouped state', async() => {
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
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.ipt);
|
||||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
await page.clearInput(selectors.ticketFuture.tfIpt);
|
||||||
await page.clearInput(selectors.ticketFuture.state);
|
await page.clearInput(selectors.ticketFuture.state);
|
||||||
|
@ -151,8 +97,6 @@ describe('Ticket Future path', () => {
|
||||||
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
|
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
|
||||||
|
|
||||||
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
|
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.ipt);
|
||||||
await page.clearInput(selectors.ticketFuture.tfIpt);
|
await page.clearInput(selectors.ticketFuture.tfIpt);
|
||||||
await page.clearInput(selectors.ticketFuture.state);
|
await page.clearInput(selectors.ticketFuture.state);
|
|
@ -20,3 +20,4 @@ routeFk: route
|
||||||
companyFk: company
|
companyFk: company
|
||||||
agencyModeFk: agency
|
agencyModeFk: agency
|
||||||
ticketFk: ticket
|
ticketFk: ticket
|
||||||
|
mergedTicket: merged ticket
|
||||||
|
|
|
@ -20,3 +20,4 @@ routeFk: ruta
|
||||||
companyFk: empresa
|
companyFk: empresa
|
||||||
agencyModeFk: agencia
|
agencyModeFk: agencia
|
||||||
ticketFk: ticket
|
ticketFk: ticket
|
||||||
|
mergedTicket: ticket fusionado
|
||||||
|
|
|
@ -20,18 +20,6 @@ module.exports = Self => {
|
||||||
description: 'The date to probe',
|
description: 'The date to probe',
|
||||||
required: true
|
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',
|
arg: 'warehouseFk',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
@ -39,15 +27,15 @@ module.exports = Self => {
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'shipped',
|
arg: 'liters',
|
||||||
type: 'date',
|
type: 'number',
|
||||||
description: 'Origin shipped',
|
description: 'Maximum volume of tickets to catapult',
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'tfShipped',
|
arg: 'lines',
|
||||||
type: 'date',
|
type: 'number',
|
||||||
description: 'Destination shipped',
|
description: 'Maximum number of lines of tickets to catapult',
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -120,20 +108,20 @@ module.exports = Self => {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'id':
|
case 'id':
|
||||||
return {'f.id': value};
|
return {'f.id': value};
|
||||||
|
case 'lines':
|
||||||
|
return {'f.lines': {lte: value}};
|
||||||
|
case 'liters':
|
||||||
|
return {'f.liters': {lte: value}};
|
||||||
case 'tfId':
|
case 'tfId':
|
||||||
return {'f.ticketFuture': value};
|
return {'f.ticketFuture': value};
|
||||||
case 'shipped':
|
|
||||||
return { 'f.shipped': value };
|
|
||||||
case 'tfShipped':
|
|
||||||
return { 'f.tfShipped': value };
|
|
||||||
case 'ipt':
|
case 'ipt':
|
||||||
return {'f.ipt': value};
|
return {'f.ipt': value};
|
||||||
case 'tfIpt':
|
case 'tfIpt':
|
||||||
return {'f.tfIpt': value};
|
return {'f.tfIpt': value};
|
||||||
case 'state':
|
case 'state':
|
||||||
return { 'f.code': { like: `%${value}%` } };
|
return {'f.stateCode': {like: `%${value}%`}};
|
||||||
case 'tfState':
|
case 'tfState':
|
||||||
return { 'f.tfCode': { like: `%${value}%` } };
|
return {'f.tfStateCode': {like: `%${value}%`}};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -142,8 +130,8 @@ module.exports = Self => {
|
||||||
let stmt;
|
let stmt;
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(
|
stmt = new ParameterizedSQL(
|
||||||
`CALL vn.ticket_canbePostponed(?,?,?,?,?)`,
|
`CALL vn.ticket_canbePostponed(?,?,?)`,
|
||||||
[args.originDated, args.futureDated, args.litersMax, args.linesMax, args.warehouseFk]);
|
[args.originDated, args.futureDated, args.warehouseFk]);
|
||||||
|
|
||||||
stmts.push(stmt);
|
stmts.push(stmt);
|
||||||
|
|
||||||
|
@ -153,7 +141,7 @@ module.exports = Self => {
|
||||||
CREATE TEMPORARY TABLE tmp.sale_getProblems
|
CREATE TEMPORARY TABLE tmp.sale_getProblems
|
||||||
(INDEX (ticketFk))
|
(INDEX (ticketFk))
|
||||||
ENGINE = MEMORY
|
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
|
FROM tmp.filter f
|
||||||
LEFT JOIN alertLevel al ON al.id = f.alertLevel
|
LEFT JOIN alertLevel al ON al.id = f.alertLevel
|
||||||
WHERE (al.code = 'FREE' OR f.alertLevel IS NULL)`);
|
WHERE (al.code = 'FREE' OR f.alertLevel IS NULL)`);
|
||||||
|
@ -200,9 +188,8 @@ module.exports = Self => {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
if (hasWhere) {
|
if (hasWhere)
|
||||||
filter = mergeFilters(filter, {where: problems});
|
filter = mergeFilters(filter, {where: problems});
|
||||||
}
|
|
||||||
|
|
||||||
stmt.merge(conn.makeWhere(filter.where));
|
stmt.merge(conn.makeWhere(filter.where));
|
||||||
stmt.merge(conn.makeOrderBy(filter.order));
|
stmt.merge(conn.makeOrderBy(filter.order));
|
||||||
|
|
|
@ -111,114 +111,6 @@ describe('TicketFuture getTicketsFuture()', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the tickets matching the correct 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: 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 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() => {
|
it('should return the tickets matching the OK State in origin date', async() => {
|
||||||
const tx = await models.Ticket.beginTransaction({});
|
const tx = await models.Ticket.beginTransaction({});
|
||||||
|
|
||||||
|
@ -231,7 +123,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
||||||
litersMax: 9999,
|
litersMax: 9999,
|
||||||
linesMax: 9999,
|
linesMax: 9999,
|
||||||
warehouseFk: 1,
|
warehouseFk: 1,
|
||||||
state: "OK"
|
state: 'OK'
|
||||||
};
|
};
|
||||||
|
|
||||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||||
|
@ -258,7 +150,7 @@ describe('TicketFuture getTicketsFuture()', () => {
|
||||||
litersMax: 9999,
|
litersMax: 9999,
|
||||||
linesMax: 9999,
|
linesMax: 9999,
|
||||||
warehouseFk: 1,
|
warehouseFk: 1,
|
||||||
tfState: "OK"
|
tfState: 'OK'
|
||||||
};
|
};
|
||||||
|
|
||||||
const ctx = {req: {accessToken: {userId: 9}}, args};
|
const ctx = {req: {accessToken: {userId: 9}}, args};
|
||||||
|
@ -434,5 +326,4 @@ describe('TicketFuture getTicketsFuture()', () => {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -43,14 +43,27 @@ module.exports = Self => {
|
||||||
const fullPath = `${origin}/#!/ticket/${ticket.id}/summary`;
|
const fullPath = `${origin}/#!/ticket/${ticket.id}/summary`;
|
||||||
const fullPathFuture = `${origin}/#!/ticket/${ticket.ticketFuture}/summary`;
|
const fullPathFuture = `${origin}/#!/ticket/${ticket.ticketFuture}/summary`;
|
||||||
const message = $t('Ticket merged', {
|
const message = $t('Ticket merged', {
|
||||||
originDated: dateUtil.toString(new Date(ticket.originETD)),
|
originDated: dateUtil.toString(new Date(ticket.shipped)),
|
||||||
futureDated: dateUtil.toString(new Date(ticket.destETD)),
|
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,
|
id: ticket.id,
|
||||||
tfId: ticket.ticketFuture,
|
tfId: ticket.ticketFuture,
|
||||||
fullPath,
|
fullPath,
|
||||||
fullPathFuture
|
fullPathFuture
|
||||||
});
|
});
|
||||||
if (!ticket.id || !ticket.ticketFuture) continue;
|
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.Sale.updateAll({ticketFk: ticket.id}, {ticketFk: ticket.ticketFuture}, myOptions);
|
||||||
await models.Ticket.setDeleted(ctx, ticket.id, myOptions);
|
await models.Ticket.setDeleted(ctx, ticket.id, myOptions);
|
||||||
await models.Chat.sendCheckingPresence(ctx, ticket.workerFk, message);
|
await models.Chat.sendCheckingPresence(ctx, ticket.workerFk, message);
|
||||||
|
|
|
@ -4,43 +4,26 @@
|
||||||
<vn-date-picker
|
<vn-date-picker
|
||||||
vn-one
|
vn-one
|
||||||
label="Origin date"
|
label="Origin date"
|
||||||
ng-model="filter.shipped"
|
ng-model="filter.originDated"
|
||||||
on-change="$ctrl.from = value">
|
required="true">
|
||||||
</vn-date-picker>
|
</vn-date-picker>
|
||||||
<vn-date-picker
|
<vn-date-picker
|
||||||
vn-one
|
vn-one
|
||||||
label="Destination date"
|
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"
|
ng-model="filter.futureDated"
|
||||||
required="true"
|
required="true">
|
||||||
info="ETD">
|
|
||||||
</vn-date-picker>
|
</vn-date-picker>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal class="vn-px-lg">
|
<vn-horizontal class="vn-px-lg">
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
vn-one
|
vn-one
|
||||||
label="Max Lines"
|
label="Max Lines"
|
||||||
ng-model="filter.linesMax"
|
ng-model="filter.lines">
|
||||||
required="true">
|
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
vn-one
|
vn-one
|
||||||
label="Max Liters"
|
label="Max Liters"
|
||||||
ng-model="filter.litersMax"
|
ng-model="filter.liters">
|
||||||
required="true">
|
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal class="vn-px-lg">
|
<vn-horizontal class="vn-px-lg">
|
||||||
|
@ -48,22 +31,22 @@
|
||||||
data="$ctrl.itemPackingTypes"
|
data="$ctrl.itemPackingTypes"
|
||||||
label="Origin IPT"
|
label="Origin IPT"
|
||||||
value-field="code"
|
value-field="code"
|
||||||
show-field="name"
|
show-field="description"
|
||||||
ng-model="filter.ipt"
|
ng-model="filter.ipt"
|
||||||
info="IPT">
|
info="IPT">
|
||||||
<tpl-item>
|
<tpl-item>
|
||||||
{{name}}
|
{{description}}
|
||||||
</tpl-item>
|
</tpl-item>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
data="$ctrl.itemPackingTypes"
|
data="$ctrl.itemPackingTypes"
|
||||||
label="Destination IPT"
|
label="Destination IPT"
|
||||||
value-field="code"
|
value-field="code"
|
||||||
show-field="name"
|
show-field="description"
|
||||||
ng-model="filter.tfIpt"
|
ng-model="filter.tfIpt"
|
||||||
info="IPT">
|
info="IPT">
|
||||||
<tpl-item>
|
<tpl-item>
|
||||||
{{name}}
|
{{description}}
|
||||||
</tpl-item>
|
</tpl-item>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
|
@ -28,9 +28,8 @@ class Controller extends SearchPanel {
|
||||||
this.$http.get('ItemPackingTypes').then(res => {
|
this.$http.get('ItemPackingTypes').then(res => {
|
||||||
for (let ipt of res.data) {
|
for (let ipt of res.data) {
|
||||||
itemPackingTypes.push({
|
itemPackingTypes.push({
|
||||||
id: ipt.id,
|
description: this.$t(ipt.description),
|
||||||
code: ipt.code,
|
code: ipt.code,
|
||||||
name: this.$t(ipt.code)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.itemPackingTypes = itemPackingTypes;
|
this.itemPackingTypes = itemPackingTypes;
|
||||||
|
|
|
@ -1,9 +1 @@
|
||||||
Future tickets: Tickets a futuro
|
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
|
Warehouse: Almacén
|
||||||
Origin Grouped State: Estado agrupado origen
|
Origin Grouped State: Estado agrupado origen
|
||||||
Destination Grouped State: Estado agrupado destino
|
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
|
IPT: Encajado
|
||||||
|
|
|
@ -44,31 +44,31 @@
|
||||||
<th field="id">
|
<th field="id">
|
||||||
<span translate>Origin ID</span>
|
<span translate>Origin ID</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="originETD">
|
<th field="shipped">
|
||||||
<span translate>Origin ETD</span>
|
<span translate>Origin Date</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="state">
|
<th field="state">
|
||||||
<span translate>Origin State</span>
|
<span translate>Origin State</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="ipt">
|
<th field="ipt" title="Item Packing Type">
|
||||||
<span>IPT</span>
|
<span>IPT</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="litersMax">
|
<th field="liters">
|
||||||
<span translate>Liters</span>
|
<span translate>Liters</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="linesMax">
|
<th field="lines">
|
||||||
<span translate>Available Lines</span>
|
<span translate>Available Lines</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="ticketFuture">
|
<th field="ticketFuture">
|
||||||
<span translate>Destination ID</span>
|
<span translate>Destination ID</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="destETD">
|
<th field="tfShipped">
|
||||||
<span translate>Destination ETD</span>
|
<span translate>Destination Date</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="tfState">
|
<th field="tfState">
|
||||||
<span translate>Destination State</span>
|
<span translate>Destination State</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="tfIpt">
|
<th field="tfIpt" title="Item Packing Type">
|
||||||
<span>IPT</span>
|
<span>IPT</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -125,8 +125,8 @@
|
||||||
{{::ticket.id}}
|
{{::ticket.id}}
|
||||||
</span></td>
|
</span></td>
|
||||||
<td shrink-date>
|
<td shrink-date>
|
||||||
<span class="chip {{$ctrl.compareDate(ticket.originETD)}}">
|
<span class="chip {{$ctrl.compareDate(ticket.shipped)}}">
|
||||||
{{::ticket.originETD | date: 'dd/MM/yyyy'}}
|
{{::ticket.shipped | date: 'dd/MM/yyyy'}}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -146,8 +146,8 @@
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td shrink-date>
|
<td shrink-date>
|
||||||
<span class="chip {{$ctrl.compareDate(ticket.destETD)}}">
|
<span class="chip {{$ctrl.compareDate(ticket.tfShipped)}}">
|
||||||
{{::ticket.destETD | date: 'dd/MM/yyyy'}}
|
{{::ticket.tfShipped | date: 'dd/MM/yyyy'}}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
@ -15,11 +15,11 @@ export default class Controller extends Section {
|
||||||
searchable: false
|
searchable: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'originETD',
|
field: 'shipped',
|
||||||
searchable: false
|
searchable: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'destETD',
|
field: 'tfShipped',
|
||||||
searchable: false
|
searchable: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -35,7 +35,7 @@ export default class Controller extends Section {
|
||||||
autocomplete: {
|
autocomplete: {
|
||||||
url: 'ItemPackingTypes',
|
url: 'ItemPackingTypes',
|
||||||
showField: 'description',
|
showField: 'description',
|
||||||
valueField: 'code'
|
valueField: 'description'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -43,7 +43,7 @@ export default class Controller extends Section {
|
||||||
autocomplete: {
|
autocomplete: {
|
||||||
url: 'ItemPackingTypes',
|
url: 'ItemPackingTypes',
|
||||||
showField: 'description',
|
showField: 'description',
|
||||||
valueField: 'code'
|
valueField: 'description'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -57,9 +57,7 @@ export default class Controller extends Section {
|
||||||
this.filterParams = {
|
this.filterParams = {
|
||||||
originDated: today,
|
originDated: today,
|
||||||
futureDated: today,
|
futureDated: today,
|
||||||
linesMax: '9999',
|
warehouseFk: this.vnConfig.warehouseFk
|
||||||
litersMax: '9999',
|
|
||||||
warehouseFk: 1
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,9 +125,9 @@ export default class Controller extends Section {
|
||||||
return {'id': value};
|
return {'id': value};
|
||||||
case 'ticketFuture':
|
case 'ticketFuture':
|
||||||
return {'ticketFuture': value};
|
return {'ticketFuture': value};
|
||||||
case 'litersMax':
|
case 'liters':
|
||||||
return {'liters': value};
|
return {'liters': value};
|
||||||
case 'linesMax':
|
case 'lines':
|
||||||
return {'lines': value};
|
return {'lines': value};
|
||||||
case 'ipt':
|
case 'ipt':
|
||||||
return {'ipt': value};
|
return {'ipt': value};
|
||||||
|
|
|
@ -18,11 +18,11 @@ describe('Component vnTicketFuture', () => {
|
||||||
controller.$.model.data = [{
|
controller.$.model.data = [{
|
||||||
id: 1,
|
id: 1,
|
||||||
checked: true,
|
checked: true,
|
||||||
state: "OK"
|
state: 'OK'
|
||||||
}, {
|
}, {
|
||||||
id: 2,
|
id: 2,
|
||||||
checked: true,
|
checked: true,
|
||||||
state: "Libre"
|
state: 'Libre'
|
||||||
}];
|
}];
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ describe('Component vnTicketFuture', () => {
|
||||||
it('should return success to the OK tickets', () => {
|
it('should return success to the OK tickets', () => {
|
||||||
const ok = controller.stateColor(controller.$.model.data[0].state);
|
const ok = controller.stateColor(controller.$.model.data[0].state);
|
||||||
const notOk = controller.stateColor(controller.$.model.data[1].state);
|
const notOk = controller.stateColor(controller.$.model.data[1].state);
|
||||||
|
|
||||||
expect(ok).toEqual('success');
|
expect(ok).toEqual('success');
|
||||||
expect(notOk).not.toEqual('success');
|
expect(notOk).not.toEqual('success');
|
||||||
});
|
});
|
||||||
|
@ -74,6 +75,7 @@ describe('Component vnTicketFuture', () => {
|
||||||
it('should return success to the FREE tickets', () => {
|
it('should return success to the FREE tickets', () => {
|
||||||
const notFree = controller.stateColor(controller.$.model.data[0].state);
|
const notFree = controller.stateColor(controller.$.model.data[0].state);
|
||||||
const free = controller.stateColor(controller.$.model.data[1].state);
|
const free = controller.stateColor(controller.$.model.data[1].state);
|
||||||
|
|
||||||
expect(free).toEqual('notice');
|
expect(free).toEqual('notice');
|
||||||
expect(notFree).not.toEqual('notice');
|
expect(notFree).not.toEqual('notice');
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,2 @@
|
||||||
Move confirmation: Do you want to move {{checked}} tickets to the future?
|
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!
|
Success: Tickets moved successfully!
|
||||||
|
|
|
@ -3,20 +3,14 @@ Search tickets: Buscar tickets
|
||||||
Search future tickets by date: Buscar tickets por fecha
|
Search future tickets by date: Buscar tickets por fecha
|
||||||
Problems: Problemas
|
Problems: Problemas
|
||||||
Origin ID: ID origen
|
Origin ID: ID origen
|
||||||
Closing: Cierre
|
|
||||||
Origin State: Estado origen
|
Origin State: Estado origen
|
||||||
Destination State: Estado destino
|
Destination State: Estado destino
|
||||||
Liters: Litros
|
Liters: Litros
|
||||||
Available Lines: Líneas disponibles
|
Available Lines: Líneas disponibles
|
||||||
Destination ID: ID destino
|
Destination ID: ID destino
|
||||||
Destination ETD: ETD Destino
|
|
||||||
Origin ETD: ETD Origen
|
|
||||||
Move tickets: Mover tickets
|
Move tickets: Mover tickets
|
||||||
Move confirmation: ¿Desea mover {{checked}} tickets hacia el futuro?
|
Move confirmation: ¿Desea mover {{checked}} tickets hacia el futuro?
|
||||||
Success: Tickets movidos correctamente
|
Success: Tickets movidos correctamente
|
||||||
ETD: Tiempo estimado de entrega
|
|
||||||
IPT: Encajado
|
IPT: Encajado
|
||||||
FREE: Libre
|
Origin Date: Fecha origen
|
||||||
DELIVERED: Servido
|
Destination Date: Fecha destino
|
||||||
ON_PREPARATION: En preparacion
|
|
||||||
PACKED: Encajado
|
|
||||||
|
|
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.