Merge branch 'dev' of https://git.verdnatura.es/salix into dev

This commit is contained in:
gerard 2018-08-23 12:31:14 +02:00
commit 67afda853c
13 changed files with 208 additions and 80 deletions

View File

@ -28,14 +28,15 @@ describe('Client', () => {
describe('onSubmit()', () => { describe('onSubmit()', () => {
it('should perform a POST query', () => { it('should perform a POST query', () => {
let started = new Date();
controller.creditClassification = { controller.creditClassification = {
started: new Date(), started: started,
credit: 300, credit: 300,
grade: 1 grade: 1
}; };
let newData = { let newData = {
started: new Date(), started: started,
credit: 300, credit: 300,
grade: 1, grade: 1,
clientFk: 101 clientFk: 101

View File

@ -0,0 +1,15 @@
import ngModule from '../module';
/**
* Returns a formatted date based on input filter.
*
* @return {String} The string result
*/
dateTime.$inject = ['$filter'];
export default function dateTime($filter) {
return function(input, format) {
return $filter('date')(new Date(input), format);
};
}
ngModule.filter('dateTime', dateTime);

View File

@ -1,3 +1,4 @@
import './phone'; import './phone';
import './ucwords'; import './ucwords';
import './dash-if-empty'; import './dash-if-empty';
import './dateTime';

View File

@ -21,7 +21,7 @@
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
<vn-th></vn-th> <vn-th></vn-th>
<vn-th field="id" number>Id</vn-th> <vn-th field="ticketFk" number>Id</vn-th>
<vn-th field="salesPersonFk">Salesperson</vn-th> <vn-th field="salesPersonFk">Salesperson</vn-th>
<vn-th field="shipped">Date</vn-th> <vn-th field="shipped">Date</vn-th>
<vn-th>Hour</vn-th> <vn-th>Hour</vn-th>
@ -32,24 +32,24 @@
<vn-th field="warehouseFk">Warehouse</vn-th> <vn-th field="warehouseFk">Warehouse</vn-th>
<vn-th field="refFk" number>Invoice</vn-th> <vn-th field="refFk" number>Invoice</vn-th>
<vn-th field="routeFk" number>Route</vn-th> <vn-th field="routeFk" number>Route</vn-th>
<vn-th number>Total</vn-th> <vn-th field="total" number>Total</vn-th>
<vn-th></vn-th> <vn-th></vn-th>
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="ticket in tickets" <vn-tr ng-repeat="ticket in tickets"
class="{{::$ctrl.compareDate(ticket.shipped)}} clickable" class="{{::$ctrl.compareDate(ticket.shipped)}} clickable"
ui-sref="ticket.card.summary({id: {{::ticket.id}}})"> ui-sref="ticket.card.summary({id: {{::ticket.ticketFk}}})">
<vn-td> <vn-td>
<vn-icon ng-show="ticket.problem" class="bright" <vn-icon ng-show="ticket.problem" class="bright"
vn-tooltip="{{ticket.problem}}" vn-tooltip="{{ticket.problem}}"
icon="warning"> icon="warning">
</vn-icon> </vn-icon>
</vn-td> </vn-td>
<vn-td number>{{::ticket.id}}</vn-td> <vn-td number>{{::ticket.ticketFk}}</vn-td>
<vn-td>{{::ticket.salesPerson | dashIfEmpty}}</vn-td> <vn-td>{{::ticket.salesPerson | dashIfEmpty}}</vn-td>
<vn-td>{{::ticket.shipped | date:'dd/MM/yyyy'}}</vn-td> <vn-td>{{::ticket.shipped | dateTime: 'dd/MM/yyyy'}}</vn-td>
<vn-td>{{::ticket.shipped | date:'HH:mm'}}</vn-td> <vn-td>{{::ticket.shipped | dateTime: 'HH:mm'}}</vn-td>
<vn-td> <vn-td>
<span <span
class="link" class="link"

View File

@ -52,7 +52,7 @@ export default class Controller {
} }
} }
], ],
order: 'shipped DESC' order: 'shipped DESC, ticketFk'
}; };
} }
@ -90,6 +90,7 @@ export default class Controller {
if (comparation < 0) if (comparation < 0)
return 'success'; return 'success';
} }
showDescriptor(event, clientFk) { showDescriptor(event, clientFk) {
this.$.descriptor.clientFk = clientFk; this.$.descriptor.clientFk = clientFk;
this.$.descriptor.parent = event.target; this.$.descriptor.parent = event.target;

View File

@ -6,8 +6,10 @@ USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketGetProblems`() CREATE DEFINER=`root`@`%` PROCEDURE `ticketGetProblems`()
BEGIN BEGIN
/* /*
* Necesita la tabla tmp.ticket * Obtiene los problemas de uno o varios tickets
* *
* @table tmp.ticketGetProblems(ticketFk, clientFk, warehouseFk, shipped)
* @return tmp.ticketProblems
*/ */
DECLARE vWarehouse INT; DECLARE vWarehouse INT;
DECLARE vDate DATE; DECLARE vDate DATE;
@ -17,7 +19,7 @@ BEGIN
DECLARE vCursor CURSOR FOR DECLARE vCursor CURSOR FOR
SELECT DISTINCT tt.warehouseFk, date(tt.shipped) SELECT DISTINCT tt.warehouseFk, date(tt.shipped)
FROM tmp.ticket tt FROM tmp.ticketGetProblems tt
WHERE DATE(tt.shipped) BETWEEN CURDATE() WHERE DATE(tt.shipped) BETWEEN CURDATE()
AND TIMESTAMPADD(DAY, 1.9, CURDATE()); AND TIMESTAMPADD(DAY, 1.9, CURDATE());
@ -34,7 +36,7 @@ BEGIN
-- CONGELADO -- CONGELADO
INSERT INTO tmp.ticketProblems(ticketFk, problem) INSERT INTO tmp.ticketProblems(ticketFk, problem)
SELECT DISTINCT tt.ticketFk, 'Freezed' SELECT DISTINCT tt.ticketFk, 'Freezed'
FROM tmp.ticket tt FROM tmp.ticketGetProblems tt
JOIN vn.client c ON c.id = tt.clientFk JOIN vn.client c ON c.id = tt.clientFk
WHERE c.isFreezed; WHERE c.isFreezed;
@ -45,26 +47,26 @@ BEGIN
(PRIMARY KEY (ticketFk)) (PRIMARY KEY (ticketFk))
ENGINE = MEMORY ENGINE = MEMORY
SELECT tt.ticketFk, c.id SELECT tt.ticketFk, c.id
FROM tmp.ticket tt FROM tmp.ticketGetProblems tt
JOIN vn.client c ON c.id = tt.clientFk JOIN vn.client c ON c.id = tt.clientFk
WHERE c.isFreezed = 0; WHERE c.isFreezed = 0;
DROP TEMPORARY TABLE IF EXISTS tmp.client_list; DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt;
CREATE TEMPORARY TABLE tmp.client_list CREATE TEMPORARY TABLE tmp.clientGetDebt
(PRIMARY KEY (Id_Cliente)) (PRIMARY KEY (clientFk))
ENGINE = MEMORY ENGINE = MEMORY
SELECT DISTINCT tt.clientFk AS Id_Cliente SELECT DISTINCT tt.clientFk
FROM tmp.ticket tt; FROM tmp.ticketGetProblems tt;
-- RIESGO -- RIESGO
CALL vn2008.risk_vs_client_list(CURDATE()); CALL clientGetDebt(CURDATE());
INSERT INTO tmp.ticketProblems(ticketFk, problem) INSERT INTO tmp.ticketProblems(ticketFk, problem)
SELECT DISTINCT tt.ticketFk, 'Risk' SELECT DISTINCT tt.ticketFk, 'Risk'
FROM tmp.ticketListFiltered tt FROM tmp.ticketListFiltered tt
JOIN vn.ticket t ON t.id = tt.ticketFk JOIN vn.ticket t ON t.id = tt.ticketFk
JOIN vn.agencyMode a ON t.agencyModeFk = a.id JOIN vn.agencyMode a ON t.agencyModeFk = a.id
JOIN tmp.risk r ON r.Id_Cliente = t.clientFk JOIN tmp.risk r ON r.clientFk = t.clientFk
JOIN vn.client c ON c.id = t.clientFk JOIN vn.client c ON c.id = t.clientFk
WHERE r.risk > c.credit + 10 WHERE r.risk > c.credit + 10
AND a.deliveryMethodFk != 3; -- para que las recogidas se preparen AND a.deliveryMethodFk != 3; -- para que las recogidas se preparen
@ -76,7 +78,7 @@ BEGIN
-- CODIGO 100 -- CODIGO 100
INSERT INTO tmp.ticketProblems(ticketFk, problem) INSERT INTO tmp.ticketProblems(ticketFk, problem)
SELECT DISTINCT tt.ticketFk, 'Code 100' SELECT DISTINCT tt.ticketFk, 'Code 100'
FROM tmp.ticket tt FROM tmp.ticketGetProblems tt
JOIN sale s ON s.ticketFk = tt.ticketFk JOIN sale s ON s.ticketFk = tt.ticketFk
WHERE s.itemFk = 100; WHERE s.itemFk = 100;
@ -96,7 +98,7 @@ BEGIN
-- El disponible es menor que 0 -- El disponible es menor que 0
INSERT INTO tmp.ticketProblems(ticketFk, problem) INSERT INTO tmp.ticketProblems(ticketFk, problem)
SELECT tt.ticketFk, i.name SELECT tt.ticketFk, i.name
FROM tmp.ticket tt FROM tmp.ticketGetProblems tt
JOIN vn.ticket t ON t.id = tt.ticketFk JOIN vn.ticket t ON t.id = tt.ticketFk
LEFT JOIN vn.sale s ON s.ticketFk = t.id LEFT JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk JOIN vn.item i ON i.id = s.itemFk
@ -120,7 +122,7 @@ BEGIN
-- Amarillo: El disponible es mayor que cero y la cantidad supera el visible, estando aun sin preparar -- Amarillo: El disponible es mayor que cero y la cantidad supera el visible, estando aun sin preparar
INSERT INTO tmp.ticketProblems(ticketFk, problem) INSERT INTO tmp.ticketProblems(ticketFk, problem)
SELECT tt.ticketFk, CONCAT('Delay', i.name) SELECT tt.ticketFk, CONCAT('Delay', i.name)
FROM tmp.ticket tt FROM tmp.ticketGetProblems tt
JOIN vn.ticket t ON t.id = tt.ticketFk JOIN vn.ticket t ON t.id = tt.ticketFk
LEFT JOIN vn.sale s ON s.ticketFk = t.id LEFT JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk JOIN vn.item i ON i.id = s.itemFk
@ -140,7 +142,9 @@ BEGIN
CLOSE vCursor; CLOSE vCursor;
DROP TEMPORARY TABLE tmp.ticketListFiltered; DROP TEMPORARY TABLE
tmp.clientGetDebt,
tmp.ticketListFiltered;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -1,32 +0,0 @@
USE `vn`;
DROP procedure IF EXISTS `ticketFilter`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketFilter`()
BEGIN
/**
* Obtiene un listado de tickets
* junto con el precio total y los problemas
*
* @table tmp.ticket(ticketFk) Identificadores de los tickets a calcular
* @return Listado de tickets
*/
CALL ticketGetTotal();
CALL ticketGetProblems();
DROP TEMPORARY TABLE IF EXISTS tmp.ticketFilter;
CREATE TEMPORARY TABLE tmp.ticketFilter ENGINE = MEMORY
SELECT t.*, tt.total, tp.problem
FROM tmp.ticket t
JOIN tmp.ticketTotal tt ON tt.ticketFk = t.ticketFk
LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = t.ticketFk;
DROP TEMPORARY TABLE
tmp.ticket,
tmp.ticketTotal,
tmp.ticketProblems;
END$$
DELIMITER ;

View File

@ -0,0 +1,70 @@
DROP procedure IF EXISTS vn.`clientGetDebt`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE vn.`clientGetDebt`(vDate DATE)
BEGIN
/**
* Calcula el riesgo para los clientes activos
*
* @table tmp.clientGetDebt(clientFk)
* @param vDate Fecha maxima de los registros
* @return tmp.risk
*/
DECLARE vStarted DATETIME DEFAULT TIMESTAMPADD(DAY, - DAYOFMONTH(CURDATE()) - 5, CURDATE());
DECLARE vEnded DATETIME;
SET vEnded = TIMESTAMP(IFNULL(vDate, CURDATE()), '23:59:59');
DROP TEMPORARY TABLE IF EXISTS tmp.ticket;
CREATE TEMPORARY TABLE tmp.ticket
(INDEX (ticketFk))
ENGINE = MEMORY
SELECT id ticketFk, c.clientFk
FROM ticket t
JOIN tmp.clientGetDebt c ON c.clientFk = t.clientFk
WHERE refFk IS NULL
AND shipped BETWEEN vStarted AND vEnded;
CALL ticketGetTotal();
DROP TEMPORARY TABLE IF EXISTS tClientRisk;
CREATE TEMPORARY TABLE tClientRisk
ENGINE = MEMORY
SELECT cr.customer_id clientFk, SUM(cr.amount) amount
FROM bi.customer_risk cr
JOIN tmp.clientGetDebt c ON c.clientFk = cr.customer_id
GROUP BY cr.customer_id;
INSERT INTO tClientRisk
SELECT c.clientFk, SUM(r.amountPaid)
FROM receipt r
JOIN tmp.clientGetDebt c ON c.clientFk = r.clientFk
WHERE r.payed > vStarted
GROUP BY c.clientFk;
INSERT INTO tClientRisk
SELECT t.clientFk, CAST(-SUM(t.amount) / 100 AS DECIMAL(10,2))
FROM hedera.tpvTransaction t
JOIN tmp.clientGetDebt c ON c.clientFk = t.clientFk
WHERE t.receiptFk IS NULL
AND t.status = 'ok'
GROUP BY t.clientFk;
INSERT INTO tClientRisk
SELECT t.clientFk, total
FROM tmp.ticketTotal tt
JOIN tmp.ticket t ON t.ticketFk = tt.ticketFk;
DROP TEMPORARY TABLE IF EXISTS tmp.risk;
CREATE TEMPORARY TABLE tmp.risk
(PRIMARY KEY (clientFk))
ENGINE = MEMORY
SELECT clientFk, SUM(amount) risk
FROM client c
JOIN tClientRisk cr ON cr.clientFk = c.id
WHERE c.isActive
GROUP BY c.id;
END$$
DELIMITER ;

View File

@ -20,14 +20,14 @@ describe('item clone()', () => {
}); });
it('should attempt to clone the given item but give an error as it doesnt exist', async() => { it('should attempt to clone the given item but give an error as it doesnt exist', async() => {
let result; let error;
try { let itemFk = 999;
let itemFk = 999; await app.models.Item.clone(itemFk)
result = await app.models.Item.clone(itemFk); .catch(e => {
} catch (error) { expect(e.message).toContain('Cannot convert undefined or null to object');
expect(error.toString()).toContain('Cannot convert undefined or null to object'); error = e;
} });
expect(result).toBeFalsy(); expect(error).toBeDefined();
}); });
}); });

View File

@ -0,0 +1,40 @@
const app = require(`${servicesDir}/item/server/server`);
describe('item updateTaxes()', () => {
afterAll(async() => {
let taxesInFixtures = [{id: 509368, taxClassFk: 1}];
await app.models.Item.updateTaxes(taxesInFixtures);
});
it('should throw an error if the taxClassFk is blank', async() => {
let error;
let taxes = [{id: 509368, taxClassFk: undefined}];
await app.models.Item.updateTaxes(taxes)
.catch(err => {
expect(err.message).toEqual('Tax class cannot be blank');
error = err;
});
expect(error).toBeDefined();
});
it('should update the tax of a given country of an item', async() => {
let taxCountry = await app.models.ItemTaxCountry.findById(509368);
expect(taxCountry.taxClassFk).toEqual(1);
let taxes = [{id: 509368, taxClassFk: 2}];
let result = await app.models.Item.updateTaxes(taxes);
expect(result).toBeTruthy();
});
it('should confirm the tax class was updated', async() => {
let taxCountry = await app.models.ItemTaxCountry.findById(509368);
expect(taxCountry.taxClassFk).toEqual(2);
});
});

View File

@ -11,7 +11,7 @@ module.exports = Self => {
description: 'The item id', description: 'The item id',
http: {source: 'path'} http: {source: 'path'}
}, { }, {
arg: 'niches', arg: 'taxes',
type: ['object'], type: ['object'],
required: true, required: true,
description: 'The list of taxes to update', description: 'The list of taxes to update',
@ -27,7 +27,7 @@ module.exports = Self => {
} }
}); });
Self.updateTaxes = async(id, taxes) => { Self.updateTaxes = async taxes => {
let promises = []; let promises = [];
for (let tax of taxes) { for (let tax of taxes) {
if (!tax.taxClassFk) if (!tax.taxClassFk)

View File

@ -27,13 +27,12 @@ module.exports = Self => {
let stmts = []; let stmts = [];
let stmt; let stmt;
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticket'); stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.filter');
stmt = new ParameterizedSQL( stmt = new ParameterizedSQL(
`CREATE TEMPORARY TABLE tmp.ticket `CREATE TEMPORARY TABLE tmp.filter
(PRIMARY KEY (ticketFk)) ENGINE = MEMORY (PRIMARY KEY (ticketFk)) ENGINE = MEMORY
SELECT SELECT
t.id,
t.id AS ticketFk, t.id AS ticketFk,
t.shipped, t.shipped,
t.nickname, t.nickname,
@ -49,7 +48,8 @@ module.exports = Self => {
w.name AS warehouse, w.name AS warehouse,
am.name AS agencyMode, am.name AS agencyMode,
st.name AS state, st.name AS state,
wk.name AS salesPerson wk.name AS salesPerson,
0 AS total
FROM ticket t FROM ticket t
LEFT JOIN address a ON a.id = t.addressFk LEFT JOIN address a ON a.id = t.addressFk
LEFT JOIN province p ON p.id = a.provinceFk LEFT JOIN province p ON p.id = a.provinceFk
@ -62,17 +62,45 @@ module.exports = Self => {
stmt.merge(Self.buildSuffix(filter, 't')); stmt.merge(Self.buildSuffix(filter, 't'));
stmts.push(stmt); stmts.push(stmt);
stmts.push('CALL ticketFilter()'); stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticket');
stmts.push(`
CREATE TEMPORARY TABLE tmp.ticket
(PRIMARY KEY (ticketFk)) ENGINE = MEMORY
SELECT ticketFk FROM tmp.filter`);
stmts.push('CALL ticketGetTotal()');
stmt = new ParameterizedSQL( stmts.push(`
`SELECT * FROM tmp.ticketFilter tfl` UPDATE tmp.filter f
); JOIN tmp.ticketTotal tt ON f.ticketFk = tt.ticketFk
stmt.merge(Self.buildSuffix(filter, 'tfl')); SET f.total = tt.total`);
let rsIndex = stmts.push(stmt) - 1;
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticketGetProblems');
stmts.push(`
CREATE TEMPORARY TABLE tmp.ticketGetProblems
(PRIMARY KEY (ticketFk)) ENGINE = MEMORY
SELECT ticketFk, clientFk, warehouseFk, shipped
FROM tmp.filter`);
stmts.push('CALL ticketGetProblems()');
stmt = new ParameterizedSQL(`
SELECT
f.*,
tp.problem
FROM tmp.filter f
LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.ticketFk`);
stmt.merge(Self.buildSuffix(filter, 'f'));
let ticketsIndex = stmts.push(stmt) - 1;
stmts.push(
`DROP TEMPORARY TABLE
tmp.filter,
tmp.ticket,
tmp.ticketTotal,
tmp.ticketGetProblems`);
let sql = ParameterizedSQL.join(stmts, ';'); let sql = ParameterizedSQL.join(stmts, ';');
let tickets = await Self.rawStmt(sql); let result = await Self.rawStmt(sql);
return tickets[rsIndex]; return result[ticketsIndex];
}; };
}; };

View File

@ -4,7 +4,7 @@ describe('ticket filter()', () => {
it('should call the filter method', async() => { it('should call the filter method', async() => {
let filter = {order: 'shipped DESC'}; let filter = {order: 'shipped DESC'};
let result = await app.models.Ticket.filter(filter); let result = await app.models.Ticket.filter(filter);
let ticketId = result[0].id; let ticketId = result[0].ticketFk;
expect(ticketId).toEqual(15); expect(ticketId).toEqual(15);
}); });