Ticket list refactor. Ticket problems, ticket total #245 & #461

This commit is contained in:
Joan Sanchez 2018-08-08 14:26:54 +02:00
parent 55c13604e6
commit 671c6bd3ff
6 changed files with 306 additions and 39 deletions

View File

@ -1,6 +1,6 @@
<vn-crud-model
vn-id="model"
url="/ticket/api/Tickets"
url="/ticket/api/Tickets/filter"
filter="::$ctrl.filter"
limit="20"
data="tickets"
@ -17,55 +17,63 @@
</vn-card>
</div>
<vn-card margin-medium-v pad-medium>
<table class="vn-grid">
<thead>
<tr>
<th translate number>Id</th>
<th translate>Salesperson</th>
<th translate>Date</th>
<th translate>Hour</th>
<th translate>Alias</th>
<th translate>Province</th>
<th translate>State</th>
<th translate>Agency</th>
<th translate>Warehouse</th>
<th translate number>Invoice</th>
<th translate number>Route</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="ticket in tickets"
<vn-table model="model">
<vn-thead>
<vn-tr>
<vn-th></vn-th>
<vn-th field="id" number>Id</vn-th>
<vn-th field="salesPersonFk">Salesperson</vn-th>
<vn-th field="shipped">Date</vn-th>
<vn-th>Hour</vn-th>
<vn-th field="nickname">Alias</vn-th>
<vn-th field="provinceFk">Province</vn-th>
<vn-th field="stateFk" >State</vn-th>
<vn-th field="agencyModeFk">Agency</vn-th>
<vn-th field="warehouseFk">Warehouse</vn-th>
<vn-th field="refFk" number>Invoice</vn-th>
<vn-th field="routeFk" number>Route</vn-th>
<vn-th number>Total</vn-th>
<vn-th></vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="ticket in tickets"
class="{{::$ctrl.compareDate(ticket.shipped)}} clickable"
ui-sref="ticket.card.summary({id: {{::ticket.id}}})">
<th number>{{::ticket.id}}</th>
<td>{{::ticket.client.salesPerson.name | dashIfEmpty}}</td>
<td>{{::ticket.shipped | date:'dd/MM/yyyy'}}</td>
<td>{{::ticket.shipped | date:'HH:mm'}}</td>
<td>
<vn-td>
<vn-icon ng-show="ticket.problem" class="bright"
vn-tooltip="{{ticket.problem}}"
icon="warning">
</vn-icon>
</vn-td>
<vn-td number>{{::ticket.id}}</vn-td>
<vn-td>{{::ticket.salesPerson | dashIfEmpty}}</vn-td>
<vn-td>{{::ticket.shipped | date:'dd/MM/yyyy'}}</vn-td>
<vn-td>{{::ticket.shipped | date:'HH:mm'}}</vn-td>
<vn-td>
<span
class="link"
ng-click="$ctrl.showDescriptor($event, ticket.clientFk)">
{{::ticket.nickname}}
</span>
</td>
<td>{{::ticket.address.province.name}}</td>
<td>{{::ticket.tracking.state.name}}</td>
<td>{{::ticket.agencyMode.name}}</td>
<td>{{::ticket.warehouse.name}}</td>
<td number>{{::ticket.refFk | dashIfEmpty}}</td>
<td number>{{::ticket.routeFk | dashIfEmpty}}</td>
<td>
</vn-td>
<vn-td>{{::ticket.province}}</vn-td>
<vn-td>{{::ticket.state}}</vn-td>
<vn-td>{{::ticket.agencyMode}}</vn-td>
<vn-td>{{::ticket.warehouse}}</vn-td>
<vn-td number>{{::ticket.refFk | dashIfEmpty}}</vn-td>
<vn-td number>{{::ticket.routeFk | dashIfEmpty}}</vn-td>
<vn-td number>{{::ticket.total | currency: '€': 2}}</vn-td>
<vn-td>
<vn-icon-button
ng-click="$ctrl.preview($event, ticket)"
vn-tooltip="Preview"
icon="desktop_windows">
</vn-icon-button>
</td>
</tr>
</tbody>
</table>
<vn-client-descriptor-popover vn-id="descriptor"></vn-client-descriptor-popover>
</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-card>
<vn-pagination
model="model"
@ -77,4 +85,5 @@
<tpl-body>
<vn-ticket-summary ticket="$ctrl.ticketSelected"></vn-ticket-summary>
</tpl-body>
</vn-dialog>
</vn-dialog>
<vn-client-descriptor-popover vn-id="descriptor"></vn-client-descriptor-popover>

View File

@ -0,0 +1,146 @@
USE `vn`;
DROP procedure IF EXISTS `ticketGetProblems`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketGetProblems`()
BEGIN
/*
* Necesita la tabla tmp.ticket
*
*/
DECLARE vWarehouse INT;
DECLARE vDate DATE;
DECLARE vAvailableCache INT;
DECLARE vVisibleCache INT;
DECLARE vDone INT DEFAULT 0;
DECLARE vCursor CURSOR FOR
SELECT DISTINCT tt.warehouseFk, date(tt.shipped)
FROM tmp.ticket tt
WHERE DATE(tt.shipped) BETWEEN CURDATE()
AND TIMESTAMPADD(DAY, 1.9, CURDATE());
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketProblems;
CREATE TEMPORARY TABLE tmp.ticketProblems (
ticketFk INT(11),
problem VARCHAR(50),
INDEX (ticketFk)
)
ENGINE = MEMORY;
-- CONGELADO
INSERT INTO tmp.ticketProblems(ticketFk, problem)
SELECT DISTINCT tt.ticketFk, 'CONGELADO'
FROM tmp.ticket tt
JOIN vn.client c ON c.id = tt.clientFk
WHERE c.isFreezed;
-- eliminamos tickets con problemas para no volverlos a mirar
DROP TEMPORARY TABLE IF EXISTS tmp.ticketListFiltered;
CREATE TEMPORARY TABLE tmp.ticketListFiltered
(PRIMARY KEY (ticketFk))
ENGINE = MEMORY
SELECT tt.ticketFk, c.id
FROM tmp.ticket tt
JOIN vn.client c ON c.id = tt.clientFk
WHERE c.isFreezed = 0;
DROP TEMPORARY TABLE IF EXISTS tmp.client_list;
CREATE TEMPORARY TABLE tmp.client_list
(PRIMARY KEY (Id_Cliente))
ENGINE = MEMORY
SELECT DISTINCT tt.clientFk AS Id_Cliente
FROM tmp.ticket tt;
-- RIESGO
CALL vn2008.risk_vs_client_list(CURDATE());
INSERT INTO tmp.ticketProblems(ticketFk, problem)
SELECT DISTINCT tt.ticketFk, 'RIESGO'
FROM tmp.ticketListFiltered tt
JOIN vn.ticket t ON t.id = tt.ticketFk
JOIN vn.agencyMode a ON t.agencyModeFk = a.id
JOIN tmp.risk r ON r.Id_Cliente = t.clientFk
JOIN vn.client c ON c.id = t.clientFk
WHERE r.risk > c.credit + 10
AND a.deliveryMethodFk != 3; -- para que las recogidas se preparen
-- eliminamos tickets con problemas para no volverlos a mirar
DELETE tlf FROM tmp.ticketListFiltered tlf
JOIN tmp.ticketProblems tp ON tlf.ticketFk = tp.ticketFk;
-- CODIGO 100
INSERT INTO tmp.ticketProblems(ticketFk, problem)
SELECT DISTINCT tt.ticketFk, 'COD 100'
FROM tmp.ticket tt
JOIN sale s ON s.ticketFk = tt.ticketFk
WHERE s.itemFk = 100;
-- eliminamos tickets con problemas para no volverlos a mirar
DELETE tlf FROM tmp.ticketListFiltered tlf
JOIN tmp.ticketProblems tp ON tlf.ticketFk = tp.ticketFk;
OPEN vCursor;
WHILE NOT vDone
DO
FETCH vCursor INTO vWarehouse, vDate;
CALL cache.visible_refresh(vVisibleCache, FALSE, vWarehouse);
CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouse, vDate);
-- El disponible es menor que 0
INSERT INTO tmp.ticketProblems(ticketFk, problem)
SELECT tt.ticketFk, i.name
FROM tmp.ticket tt
JOIN vn.ticket t ON t.id = tt.ticketFk
LEFT JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.itemType it on it.id = i.typeFk
LEFT JOIN cache.visible v ON i.id = v.item_id
AND v.calc_id = vVisibleCache
LEFT JOIN cache.available av ON av.item_id = i.id
AND av.calc_id = vAvailableCache
WHERE date(t.shipped) = vDate
AND categoryFk != 6
AND s.quantity > IFNULL(v.visible, 0)
AND IFNULL(av.available, 0) < 0
AND s.isPicked = FALSE
AND NOT i.generic
AND vWarehouse = t.warehouseFk;
-- eliminamos tickets con problemas para no volverlos a mirar
DELETE tlf FROM tmp.ticketListFiltered tlf
JOIN tmp.ticketProblems tp ON tlf.ticketFk = tp.ticketFk;
-- Amarillo: El disponible es mayor que cero y la cantidad supera el visible, estando aun sin preparar
INSERT INTO tmp.ticketProblems(ticketFk, problem)
SELECT tt.ticketFk, CONCAT('RETRASO ', i.name)
FROM tmp.ticket tt
JOIN vn.ticket t ON t.id = tt.ticketFk
LEFT JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.itemType it on it.id = i.typeFk
LEFT JOIN cache.visible v ON i.id = v.item_id AND v.calc_id = vVisibleCache
LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache
WHERE IFNULL(av.available, 0) >= 0
AND s.quantity > IFNULL(v.visible, 0)
AND s.isPicked = FALSE
AND s.reserved = FALSE
AND it.categoryFk != 6
AND date(t.shipped) = vDate
AND NOT i.generic
AND CURDATE() = vDate
AND t.warehouseFk = vWarehouse;
END WHILE;
CLOSE vCursor;
DROP TEMPORARY TABLE tmp.ticketListFiltered;
END$$
DELIMITER ;

View File

@ -0,0 +1,32 @@
USE `vn`;
DROP procedure IF EXISTS `ticketGetFullList`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketGetFullList`()
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.ticketFullList;
CREATE TEMPORARY TABLE tmp.ticketFullList 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,68 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => {
Self.remoteMethod('filter', {
description: 'Find all instances of the model matched by filter from the data source.',
accessType: 'READ',
accepts: [
{
arg: 'filter',
type: 'Object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
http: {source: 'query'}
}
],
returns: {
type: ['Object'],
root: true
},
http: {
path: `/filter`,
verb: 'GET'
}
});
Self.filter = async filter => {
let stmt = new ParameterizedSQL(
`DROP TEMPORARY TABLE IF EXISTS tmp.ticket;
CREATE TEMPORARY TABLE tmp.ticket
(PRIMARY KEY (ticketFk)) ENGINE = MEMORY
SELECT
t.id,
t.id AS ticketFk,
t.shipped,
t.nickname,
t.refFk,
t.routeFk,
t.agencyModeFk,
t.warehouseFk,
t.clientFk,
c.salesPersonFk,
a.provinceFk,
ts.stateFk,
p.name AS province,
w.name AS warehouse,
am.name AS agencyMode,
st.name AS state,
wk.name AS salesPerson
FROM ticket t
LEFT JOIN address a ON a.id = t.addressFk
LEFT JOIN province p ON p.id = a.provinceFk
LEFT JOIN warehouse w ON w.id = t.warehouseFk
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
LEFT JOIN ticketState ts ON ts.ticketFk = t.id
LEFT JOIN state st ON st.id = ts.stateFk
LEFT JOIN client c ON c.id = t.clientFk
LEFT JOIN worker wk ON wk.id = c.salesPersonFk`);
stmt.merge(Self.buildSuffix(filter, 't'));
stmt.merge(';CALL ticketGetFullList()');
stmt.merge(';SELECT * FROM tmp.ticketFullList tfl');
stmt.merge(Self.buildSuffix(filter, 'tfl'));
let result = await Self.rawStmt(stmt);
return result[3];
};
};

View File

@ -0,0 +1,11 @@
const app = require(`${servicesDir}/ticket/server/server`);
describe('ticket filter()', () => {
it('should call the filter method', async() => {
let filter = {order: 'shipped DESC'};
let result = await app.models.Ticket.filter(filter);
let ticketId = result[0].id;
expect(ticketId).toEqual(15);
});
});

View File

@ -15,4 +15,5 @@ module.exports = Self => {
require('../methods/ticket/getSales')(Self);
require('../methods/ticket/getSalesPersonMana')(Self);
require('../methods/ticket/getShipped')(Self);
require('../methods/ticket/filter')(Self);
};