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