#6321 - Negative tickets #1945
|
@ -0,0 +1,68 @@
|
|||
DROP PROCEDURE IF EXISTS vn.item_getLack;
|
||||
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_getLack`(
|
||||
IN vForce BOOLEAN DEFAULT TRUE,
|
||||
IN vDays INT DEFAULT 2,
|
||||
IN vCustomWhere TEXT,
|
||||
)
|
||||
|
||||
BEGIN
|
||||
/**
|
||||
* Calcula una tabla con el máximo negativo visible para cada producto y almacen
|
||||
*
|
||||
* @param vForce Fuerza el recalculo del stock
|
||||
* @param vDays Numero de dias a considerar
|
||||
* @param vSearch Filtro items
|
||||
**/
|
||||
|
||||
CALL `cache`.stock_refresh(vForce);
|
||||
CALL item_getMinacum(NULL, util.VN_CURDATE(), vDays, NULL);
|
||||
CALL item_getMinETD();
|
||||
CALL item_zoneClosure();
|
||||
|
||||
|
||||
SET @sqlQuery = CONCAT(`SELECT i.id itemFk,
|
||||
i.longName,
|
||||
w.id warehouseFk,
|
||||
p.`name` producer,
|
||||
i.`size`,
|
||||
i.category,
|
||||
w.name warehouse,
|
||||
SUM(IFNULL(sub.amount,0)) lack,
|
||||
i.inkFk,
|
||||
IFNULL(im.timed, util.midnight()) timed,
|
||||
IFNULL(izc.timed, util.midnight()) minTimed
|
||||
FROM (SELECT item_id,
|
||||
warehouse_id,
|
||||
amount
|
||||
FROM cache.stock
|
||||
WHERE amount > 0
|
||||
UNION ALL
|
||||
SELECT itemFk,
|
||||
warehouseFk,
|
||||
amount
|
||||
FROM tmp.itemMinacum
|
||||
) sub
|
||||
JOIN warehouse w ON w.id = sub.warehouse_id
|
||||
JOIN item i ON i.id = sub.item_id
|
||||
LEFT JOIN producer p ON p.id = i.producerFk
|
||||
JOIN itemType it ON it.id = i.typeFk
|
||||
JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||
LEFT JOIN tmp.itemMinETD im ON im.itemFk = i.id
|
||||
LEFT JOIN tmp.itemZoneClosure izc ON izc.itemFk = i.id
|
||||
WHERE w.isForTicket
|
||||
AND ic.display
|
||||
AND it.code != 'GEN'
|
||||
AND `,vCustomWhere,`
|
||||
GROUP BY i.id, w.id
|
||||
HAVING lack < 0;`);
|
||||
CALL `exec`(@sqlQuery);
|
||||
|
||||
DROP TEMPORARY TABLE tmp.itemMinacum;
|
||||
DROP TEMPORARY TABLE tmp.itemMinETD;
|
||||
DROP TEMPORARY TABLE tmp.itemZoneClosure;
|
||||
END
|
||||
$$
|
||||
DELIMITER ;
|
|
@ -2,7 +2,18 @@ DROP PROCEDURE IF EXISTS vn.item_getLack;
|
|||
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_getLack`(IN vForce BOOLEAN, IN vDays INT, IN vCustomWhere VARCHAR(500))
|
||||
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_getLack`(
|
||||
IN vForce BOOLEAN DEFAULT TRUE,
|
||||
IN vDays INT DEFAULT 2,
|
||||
IN vId INT DEFAULT NULL,
|
||||
IN vLongname INT DEFAULT NULL,
|
||||
IN vSupplier VARCHAR DEFAULT NULL,
|
||||
IN vColor VARCHAR DEFAULT NULL,
|
||||
IN vSize INT DEFAULT NULL,
|
||||
IN vOrigen VARCHAR DEFAULT NULL,
|
||||
IN vLack INT DEFAULT NULL
|
||||
)
|
||||
|
||||
BEGIN
|
||||
/**
|
||||
* Calcula una tabla con el máximo negativo visible para cada producto y almacen
|
||||
|
@ -50,7 +61,14 @@ BEGIN
|
|||
WHERE w.isForTicket
|
||||
AND ic.display
|
||||
AND it.code != 'GEN'
|
||||
AND (vCustomWhere IS NULL OR vCustomWhere = '' OR vCustomWhere)
|
||||
AND (vId IS NULL OR i.id = vId)
|
||||
AND (vLongname IS NULL OR i.longName = vLongname)
|
||||
AND (vSupplier IS NULL OR p.`name` LIKE CONCAT('%', vSupplier, '%'))
|
||||
AND (vColor IS NULL OR vColor = i.inkFk)
|
||||
AND (vSize IS NULL OR vSize = i.`size`)
|
||||
AND (vOrigen IS NULL OR vOrigen = w.name)
|
||||
AND (vLack IS NULL OR vLack = lack)
|
||||
|
||||
GROUP BY i.id, w.id
|
||||
HAVING lack < 0;
|
||||
|
||||
|
|
|
@ -1,14 +1,52 @@
|
|||
/* eslint-disable no-console */
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('itemLack', {
|
||||
description: 'Download a ticket delivery note document',
|
||||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'ctx',
|
||||
type: 'object',
|
||||
http: {source: 'context'}
|
||||
},
|
||||
{
|
||||
arg: 'filter',
|
||||
type: 'object',
|
||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||
http: {source: 'query'}
|
||||
},
|
||||
{
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
description: 'The item id',
|
||||
},
|
||||
{
|
||||
arg: 'longname',
|
||||
type: 'string',
|
||||
description: 'The item id',
|
||||
},
|
||||
{
|
||||
arg: 'supplier',
|
||||
type: 'string',
|
||||
description: 'The client fiscal id',
|
||||
},
|
||||
{
|
||||
arg: 'color',
|
||||
type: 'string',
|
||||
description: 'The item id',
|
||||
},
|
||||
{
|
||||
arg: 'size',
|
||||
type: 'string', description: 'The item id',
|
||||
},
|
||||
{
|
||||
arg: 'origen',
|
||||
type: 'string', description: 'The item id',
|
||||
},
|
||||
{
|
||||
arg: 'lack',
|
||||
type: 'number', description: 'The item id',
|
||||
}
|
||||
],
|
||||
returns: [
|
||||
{
|
||||
|
@ -25,15 +63,107 @@ module.exports = Self => {
|
|||
|
||||
Self.itemLack = async(ctx, filter, options) => {
|
||||
const myOptions = {};
|
||||
|
||||
// const versionSQL = false;
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
// if (versionSQL) {
|
||||
// const filterKeyOrder = ['id', 'longname', 'supplier', 'colour', 'size', 'origen', 'lack'];
|
||||
|
||||
// let query = 'CALL vn.item_getLack(?, ?)';
|
||||
// const {body} = ctx;
|
||||
|
||||
// const result = await Self.rawSql(query, [true, 2]);
|
||||
// let procedureParams = [true, 2];
|
||||
// procedureParams.push(...filterKeyOrder.map(clave => body || null));
|
||||
// const procedureArgs = Array(procedureParams.length).fill('?').join(', ');
|
||||
// let query = `CALL vn.item_getLack(${procedureArgs})`;
|
||||
|
||||
// if (tx) await tx.commit();
|
||||
// const result = await Self.rawSql(query, procedureParams, myOptions);
|
||||
// console.log('qUERY:', query);
|
||||
// console.log('Argumentos procedimiento:', procedureArgs);
|
||||
// console.log('PArametros del procedimiento:', procedureParams);
|
||||
// // const result = await Self.rawSql(query, [true, 2, ...procedureParams]);
|
||||
// // console.log('Resultado', result);
|
||||
// return result;
|
||||
// } else {
|
||||
// const where = buildFilter(ctx.args, (param, value) => {
|
||||
// switch (param) {
|
||||
// case 'id':
|
||||
// return {'i.id': value};
|
||||
// case 'longname':
|
||||
// return {'i.longName': value};
|
||||
// case 'name':
|
||||
// return {'p.name': {like: `%${value}%`}};
|
||||
// case 'color':
|
||||
// return {'i.inkFk': value};
|
||||
// case 'size':
|
||||
// return {'i.size': value};
|
||||
// case 'origen':
|
||||
// return {'w.name': value};
|
||||
// case 'lack':
|
||||
// return {'lack': value};
|
||||
// }
|
||||
// }) ?? {};
|
||||
|
||||
// const stmts = [
|
||||
// 'CALL cache.stock_refresh(vForce);',
|
||||
// 'CALL item_getMinacum(NULL, util.VN_CURDATE(), vDays, NULL);',
|
||||
// 'CALL item_getMinETD();',
|
||||
// 'CALL item_zoneClosure();'
|
||||
// ];
|
||||
|
||||
// const stmt = new ParameterizedSQL(`
|
||||
// SELECT i.id itemFk,
|
||||
// i.longName,
|
||||
// w.id warehouseFk,
|
||||
// p.name producer,
|
||||
// i.size,
|
||||
// i.category,
|
||||
// w.name warehouse,
|
||||
// SUM(IFNULL(sub.amount,0)) lack,
|
||||
// i.inkFk,
|
||||
// IFNULL(im.timed, util.midnight()) timed,
|
||||
// IFNULL(izc.timed, util.midnight()) minTimed
|
||||
// FROM (SELECT item_id,
|
||||
// warehouse_id,
|
||||
// amount
|
||||
// FROM cache.stock
|
||||
// WHERE amount > 0
|
||||
// UNION ALL
|
||||
// SELECT itemFk,
|
||||
// warehouseFk,
|
||||
// amount
|
||||
// FROM tmp.itemMinacum
|
||||
// ) sub
|
||||
// JOIN warehouse w ON w.id = sub.warehouse_id
|
||||
// JOIN item i ON i.id = sub.item_id
|
||||
// LEFT JOIN producer p ON p.id = i.producerFk
|
||||
// JOIN itemType it ON it.id = i.typeFk
|
||||
// JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||
// LEFT JOIN tmp.itemMinETD im ON im.itemFk = i.id
|
||||
// LEFT JOIN tmp.itemZoneClosure izc ON izc.itemFk = i.id
|
||||
// WHERE w.isForTicket
|
||||
// AND ic.display
|
||||
// AND it.code != 'GEN'
|
||||
// `);
|
||||
|
||||
// const sqlWhere = conn.makeWhere(where);
|
||||
|
||||
// stmt.merge(sqlWhere);
|
||||
// stmt.merge(`
|
||||
// GROUP BY i.id, w.id
|
||||
// HAVING lack < 0;`
|
||||
// );
|
||||
// stmts.push(`
|
||||
// DROP TEMPORARY TABLE tmp.itemMinacum;
|
||||
// DROP TEMPORARY TABLE tmp.itemMinETD;
|
||||
// DROP TEMPORARY TABLE tmp.itemZoneClosure;
|
||||
// `);
|
||||
// stmt.merge(conn.makeSuffix(filter));
|
||||
// const itemsIndex = stmts.push(stmt) - 1;
|
||||
|
||||
// const sql = ParameterizedSQL.join(stmts, ';');
|
||||
// const result = await conn.executeStmt(sql, myOptions);
|
||||
// return itemsIndex === 0 ? result : result[itemsIndex];
|
||||
// }
|
||||
|
||||
return [
|
||||
{
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('Item Lack', () => {
|
||||
it('should return data with NO filters', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await models.Ticket.itemLack(3, options);
|
||||
|
||||
expect(result).toBeFalsy();
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return data with filters', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await models.Ticket.isEmpty(8, options);
|
||||
|
||||
expect(result).toBeFalsy();
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue