falta CR
gitea/salix/pipeline/head This commit has test failures Details

This commit is contained in:
Javi Gallego 2020-05-15 12:17:34 +02:00
parent 6692ac2e02
commit 3815edfbea
20 changed files with 257 additions and 15 deletions

View File

@ -0,0 +1,20 @@
USE `util`;
DROP procedure IF EXISTS `time_createTable`;
DELIMITER $$
USE `util`$$
CREATE DEFINER=`root`@`%` PROCEDURE `time_createTable`(vStarted DATE, vEnded DATE)
BEGIN
DECLARE vCurrentDate DATE;
DROP TEMPORARY TABLE IF EXISTS tmp.tTime;
CREATE TEMPORARY TABLE tmp.tTime (dated DATE PRIMARY KEY);
SET vCurrentDate = vStarted;
WHILE vCurrentDate <= vEnded DO
INSERT INTO tmp.tTime (dated) VALUES (vCurrentDate);
SET vCurrentDate = DATE_ADD(vCurrentDate, INTERVAL 1 DAY);
END WHILE;
END$$
DELIMITER ;

View File

@ -0,0 +1,2 @@
ALTER TABLE `vn`.`zoneConfig`
ADD COLUMN `forwardDays` INT(10) NOT NULL DEFAULT 7 COMMENT 'days forward to show zone_upcomingDeliveries' AFTER `scope`;

View File

@ -0,0 +1,78 @@
USE `vn`;
DROP procedure IF EXISTS `zone_upcomingDeliveries`;
DELIMITER $$
USE `vn`$$
CREATE PROCEDURE `zone_upcomingDeliveries` ()
BEGIN
DECLARE vForwardDays INT;
SELECT forwardDays INTO vForwardDays FROM zoneConfig;
CALL util.time_createTable(CURDATE(), DATE_ADD(CURDATE(), INTERVAL vForwardDays DAY));
DROP TEMPORARY TABLE IF EXISTS tLandings;
CREATE TEMPORARY TABLE tLandings
(INDEX (eventFk))
ENGINE = MEMORY
SELECT e.id eventFk,
@travelingDays := IFNULL(e.travelingDays, z.travelingDays) travelingDays,
TIMESTAMPADD(DAY, @travelingDays, ti.dated) landed,
ti.dated shipped
FROM zone z
JOIN zoneEvent e ON e.zoneFk = z.id
JOIN tmp.tTime ti ON ti.dated BETWEEN curdate() AND TIMESTAMPADD(DAY, vForwardDays, curdate());
DROP TEMPORARY TABLE IF EXISTS tmp.zoneOption;
CREATE TEMPORARY TABLE tmp.zoneOption
ENGINE = MEMORY
SELECT *
FROM (
SELECT z.id zoneFk,
TIME(IFNULL(e.`hour`, z.`hour`)) `hour`,
l.travelingDays,
IFNULL(e.price, z.price) price,
IFNULL(e.bonus, z.bonus) bonus,
l.landed,
l.shipped
FROM zone z
JOIN zoneEvent e ON e.zoneFk = z.id
JOIN tLandings l ON l.eventFk = e.id
WHERE (
e.`type` = 'day'
AND e.`dated` = l.landed
) OR (
e.`type` != 'day'
AND e.weekDays & (1 << WEEKDAY(l.landed))
AND (e.`started` IS NULL OR l.landed >= e.`started`)
AND (e.`ended` IS NULL OR l.landed <= e.`ended`)
)
ORDER BY
zoneFk,
CASE
WHEN e.`type` = 'day'
THEN 1
WHEN e.`type` = 'range'
THEN 2
ELSE 3
END
) t
GROUP BY zoneFk, landed;
DELETE t FROM tmp.zoneOption t
JOIN zoneExclusion e
ON e.zoneFk = t.zoneFk AND e.`dated` = t.landed;
SELECT zo.*, zg.`name`, (ELT(WEEKDAY(zo.shipped) + 1, 'Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado', 'Domingo')) weekday
FROM tmp.zoneOption zo
JOIN zone z ON z.id = zo.zoneFk
JOIN zoneIncluded zi ON zi.zoneFk = z.id
JOIN zoneGeo zg ON zg.id = zi.geoFk AND zg.depth = 1
WHERE z.`name` like '%zon%'
GROUP BY shipped, zg.`name`
ORDER BY shipped, zg.`name`;
DROP TEMPORARY TABLE tmp.tTime, tLandings;
END$$
DELIMITER ;

View File

@ -1711,10 +1711,12 @@ INSERT INTO `vn`.`zoneIncluded` (`zoneFk`, `geoFk`, `isIncluded`)
(3, 3, 0), (3, 3, 0),
(3, 4, 0), (3, 4, 0),
(3, 5, 0), (3, 5, 0),
(3, 10, 1),
(3, 1, 1), (3, 1, 1),
(4, 3, 0), (4, 3, 0),
(4, 4, 0), (4, 4, 0),
(4, 5, 0), (4, 5, 0),
(4, 10, 1),
(4, 1, 1), (4, 1, 1),
(5, 3, 1), (5, 3, 1),
(5, 4, 0), (5, 4, 0),

View File

@ -61,7 +61,6 @@ module.exports = Self => {
}, options); }, options);
} }
let query = ` let query = `
CALL vn.item_getVisibleAvailable(?,curdate(),?,?)`; CALL vn.item_getVisibleAvailable(?,curdate(),?,?)`;
@ -106,7 +105,6 @@ module.exports = Self => {
return ticket.id; return ticket.id;
} }
async function getTicketId(params, options) { async function getTicketId(params, options) {
const minDate = new Date(); const minDate = new Date();
minDate.setHours(0, 0, 0, 0); minDate.setHours(0, 0, 0, 0);

View File

@ -15,7 +15,6 @@ describe('regularize()', () => {
it('should create a new ticket and add a line', async() => { it('should create a new ticket and add a line', async() => {
let ctx = {req: {accessToken: {userId: 18}}}; let ctx = {req: {accessToken: {userId: 18}}};
let query = `CALL vn.item_getVisibleAvailable(?,curdate(),?,?)`; let query = `CALL vn.item_getVisibleAvailable(?,curdate(),?,?)`;
let options = [itemFk, warehouseFk, true]; let options = [itemFk, warehouseFk, true];

View File

@ -24,9 +24,8 @@ describe('sale updatePrice()', () => {
done(); done();
}); });
it('should throw an error if the ticket is not editable', async() => { it('should throw an error if the ticket is not editable', async() => {
let ctx = {req: {accessToken: {userId: 9}}}; let ctx = {req: {accessToken: {userId: 18}}};
let immutableSaleId = 1; let immutableSaleId = 1;
let price = 5; let price = 5;
@ -40,7 +39,7 @@ describe('sale updatePrice()', () => {
}); });
it('should return 0 if the price is an empty string', async() => { it('should return 0 if the price is an empty string', async() => {
let ctx = {req: {accessToken: {userId: 9}}}; let ctx = {req: {accessToken: {userId: 18}}};
let price = ''; let price = '';
await app.models.Sale.updatePrice(ctx, saleId, price); await app.models.Sale.updatePrice(ctx, saleId, price);
@ -50,7 +49,7 @@ describe('sale updatePrice()', () => {
}); });
it('should now set price as a decimal number in a string', async() => { it('should now set price as a decimal number in a string', async() => {
let ctx = {req: {accessToken: {userId: 9}}}; let ctx = {req: {accessToken: {userId: 18}}};
let price = '8'; let price = '8';
await app.models.Sale.updatePrice(ctx, saleId, price); await app.models.Sale.updatePrice(ctx, saleId, price);
@ -60,7 +59,7 @@ describe('sale updatePrice()', () => {
}); });
it('should set price as a decimal number and check the sale has the mana component', async() => { it('should set price as a decimal number and check the sale has the mana component', async() => {
let ctx = {req: {accessToken: {userId: 9}}}; let ctx = {req: {accessToken: {userId: 18}}};
let price = 5.4; let price = 5.4;
await app.models.Sale.updatePrice(ctx, saleId, price); await app.models.Sale.updatePrice(ctx, saleId, price);

View File

@ -55,8 +55,8 @@ module.exports = Self => {
if (!isEditable) if (!isEditable)
throw new UserError(`The sales of this ticket can't be modified`); throw new UserError(`The sales of this ticket can't be modified`);
let salesPerson = sale.ticket().client().salesPersonFk; const userId = ctx.req.accessToken.userId;
let usesMana = await models.WorkerMana.findOne({where: {workerFk: salesPerson}, fields: 'amount'}, options); let usesMana = await models.WorkerMana.findOne({where: {workerFk: userId}, fields: 'amount'}, options);
let componentCode = usesMana ? 'mana' : 'buyerDiscount'; let componentCode = usesMana ? 'mana' : 'buyerDiscount';
let discount = await models.Component.findOne({where: {code: componentCode}}, options); let discount = await models.Component.findOne({where: {code: componentCode}}, options);
@ -83,8 +83,8 @@ module.exports = Self => {
await sale.updateAttributes({price: newPrice}, options); await sale.updateAttributes({price: newPrice}, options);
query = `call vn.manaSpellersRequery(?)`; query = `CALL vn.manaSpellersRequery(?)`;
await Self.rawSql(query, [salesPerson], options); await Self.rawSql(query, [userId], options);
await tx.commit(); await tx.commit();

View File

@ -163,7 +163,8 @@ module.exports = Self => {
if (value) { if (value) {
return {and: [ return {and: [
{'st.alertLevel': 0}, {'st.alertLevel': 0},
{'st.code': {neq: 'OK'}} {'st.code': {neq: 'OK'}},
{'st.code': {neq: 'BOARDING'}}
]}; ]};
} else { } else {
return {and: [ return {and: [

View File

@ -14,7 +14,7 @@ Show pallet report: Ver hoja de pallet
Change shipped hour: Cambiar hora de envío Change shipped hour: Cambiar hora de envío
Shipped hour: Hora de envío Shipped hour: Hora de envío
Make a payment: "Verdnatura le comunica:\rSu pedido está pendiente de pago.\rPor favor, entre en la página web y efectue el pago con tarjeta.\rMuchas gracias." Make a payment: "Verdnatura le comunica:\rSu pedido está pendiente de pago.\rPor favor, entre en la página web y efectue el pago con tarjeta.\rMuchas gracias."
Minimum is needed: "Verdnatura le recuerda:\rEs necesario llegar a un importe mínimo de 50€ (Sin IVA) en su pedido {{ticketId}} del día {{created | date: 'dd/MM/yyyy'}} para recibirlo sin portes adicionales." Minimum is needed: "Verdnatura le recuerda:\rEs necesario un importe mínimo de 50€ (Sin IVA) en su pedido {{ticketId}} del día {{created | date: 'dd/MM/yyyy'}} para recibirlo sin portes adicionales."
Ticket invoiced: Ticket facturado Ticket invoiced: Ticket facturado
Make invoice: Crear factura Make invoice: Crear factura
Regenerate invoice: Regenerar factura Regenerate invoice: Regenerar factura

View File

@ -0,0 +1,41 @@
module.exports = Self => {
Self.remoteMethod('getUpcomingDeliveries', {
description: 'Returns the upcomings deliveries',
accessType: 'READ',
accepts: [],
returns: {
type: ['Object'],
root: true
},
http: {
path: `/getUpcomingDeliveries`,
verb: 'GET'
}
});
Self.getUpcomingDeliveries = async() => {
const [zones] = await Self.rawSql(`CALL vn.zone_upcomingDeliveries()`);
const details = [];
for (let zone of zones) {
const shipped = zone.shipped;
let zoneDetail = details.find(zone => {
return zone.shipped == shipped;
});
if (!zoneDetail) {
zoneDetail = {
shipped: shipped,
lines: []
};
details.push(zoneDetail);
}
zoneDetail.lines.push(zone);
}
return details;
};
};

View File

@ -0,0 +1,16 @@
const app = require('vn-loopback/server/server');
describe('zone getUpcomingDeliveries()', () => {
it('should check returns data', async() => {
let result = await app.models.Zone.getUpcomingDeliveries();
console.log(result);
const firstResultLines = result[0].lines;
const secondResultLines = result[1].lines;
const thirdResultLines = result[2].lines;
expect(result.length).toEqual(7);
expect(firstResultLines.length).toEqual(2);
expect(secondResultLines.length).toEqual(1);
expect(thirdResultLines.length).toEqual(1);
});
});

View File

@ -3,6 +3,7 @@ module.exports = Self => {
require('../methods/zone/getLeaves')(Self); require('../methods/zone/getLeaves')(Self);
require('../methods/zone/getEvents')(Self); require('../methods/zone/getEvents')(Self);
require('../methods/zone/toggleIsIncluded')(Self); require('../methods/zone/toggleIsIncluded')(Self);
require('../methods/zone/getUpcomingDeliveries')(Self);
Self.validatesPresenceOf('agencyModeFk', { Self.validatesPresenceOf('agencyModeFk', {
message: `Agency cannot be blank` message: `Agency cannot be blank`

View File

@ -14,3 +14,4 @@ import './events';
import './calendar'; import './calendar';
import './location'; import './location';
import './calendar'; import './calendar';
import './upcoming-deliveries';

View File

@ -24,6 +24,7 @@ Range of dates: Rango de fechas
Search zone by id or name: Buscar zonas por identificador o nombre Search zone by id or name: Buscar zonas por identificador o nombre
This zone will be removed: La zona será eliminada This zone will be removed: La zona será eliminada
To: Hasta To: Hasta
Upcoming deliveries: Próximos repartos
Volumetric: Volumétrico Volumetric: Volumétrico
Warehouse: Almacén Warehouse: Almacén
Warehouses: Almacenes Warehouses: Almacenes

View File

@ -7,7 +7,8 @@
"menus": { "menus": {
"main": [ "main": [
{"state": "zone.index", "icon": "icon-zone"}, {"state": "zone.index", "icon": "icon-zone"},
{"state": "zone.deliveryDays", "icon": "today"} {"state": "zone.deliveryDays", "icon": "today"},
{"state": "zone.upcomingDeliveries", "icon": "today"}
], ],
"card": [ "card": [
{"state": "zone.card.basicData", "icon": "settings"}, {"state": "zone.card.basicData", "icon": "settings"},
@ -33,6 +34,11 @@
"state": "zone.deliveryDays", "state": "zone.deliveryDays",
"component": "vn-zone-delivery-days", "component": "vn-zone-delivery-days",
"description": "Delivery days" "description": "Delivery days"
}, {
"url": "/upcoming-deliveries?q",
"state": "zone.upcomingDeliveries",
"component": "vn-upcoming-deliveries",
"description": "Upcoming deliveries"
}, { }, {
"url": "/create", "url": "/create",
"state": "zone.create", "state": "zone.create",

View File

@ -0,0 +1,31 @@
<vn-crud-model auto-load="true"
vn-id="model"
url="Zones/getUpcomingDeliveries"
data="details">
</vn-crud-model>
<vn-data-viewer model="model">
<vn-card>
<section ng-repeat="detail in details" class="vn-pa-md">
<vn-horizontal class="header">
<h5><span translate>{{detail.shipped}}</span></h5>
</vn-horizontal>
<vn-table>
<vn-thead>
<vn-tr>
<vn-th class="waste-family">Province</vn-th>
<vn-th number>Closing</vn-th>
<vn-th number>Id</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="zone in detail.lines">
<vn-td class="waste-family">{{::zone.name}}</vn-td>
<vn-td number>{{::zone.hour}}</vn-td>
<vn-td number>{{::zone.zoneFk}}</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</section>
</vn-card>
</vn-data-viewer>

View File

@ -0,0 +1,18 @@
import ngModule from '../module';
import Section from 'salix/components/section';
import './style.scss';
class Controller extends Section {
constructor($element, $, vnWeekDays) {
super($element, $);
this.weekDays = [];
this.weekdayNames = vnWeekDays.locales;
}
}
Controller.$inject = ['$element', '$scope', 'vnWeekDays'];
ngModule.component('vnUpcomingDeliveries', {
template: require('./index.html'),
controller: Section
});

View File

@ -0,0 +1,3 @@
Family: Familia
Percentage: Porcentaje
Dwindle: Mermas

View File

@ -0,0 +1,25 @@
@import "variables";
vn-upcoming-deliveries {
.header {
margin-bottom: 16px;
text-transform: uppercase;
font-size: 1.25rem;
line-height: 1;
padding: 7px;
padding-bottom: 7px;
padding-bottom: 4px;
font-weight: lighter;
background-color: #fde6ca;
border-bottom: 1px solid #f7931e;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
vn-table vn-th.waste-family,
vn-table vn-td.waste-family {
max-width: 64px;
width: 64px
}
}