Merge branch 'dev' into 1882-descriptorRefactor
This commit is contained in:
commit
c998097ba1
|
@ -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.time;
|
||||
CREATE TEMPORARY TABLE tmp.time (dated DATE PRIMARY KEY) ENGINE = MEMORY;
|
||||
SET vCurrentDate = vStarted;
|
||||
WHILE vCurrentDate <= vEnded DO
|
||||
INSERT INTO tmp.time (dated) VALUES (vCurrentDate);
|
||||
SET vCurrentDate = DATE_ADD(vCurrentDate, INTERVAL 1 DAY);
|
||||
END WHILE;
|
||||
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
|
@ -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`;
|
|
@ -0,0 +1,80 @@
|
|||
USE `vn`;
|
||||
DROP procedure IF EXISTS `zone_upcomingDeliveries`;
|
||||
|
||||
DELIMITER $$
|
||||
USE `vn`$$
|
||||
CREATE DEFINER=`root`@`localhost` 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.time 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 MAX(zo.`hour`) `hour`, zg.`name`, zo.shipped
|
||||
FROM tmp.zoneOption zo
|
||||
JOIN `zone` z ON z.id = zo.zoneFk
|
||||
JOIN agencyMode am ON am.id = z.agencyModeFk
|
||||
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
||||
JOIN zoneIncluded zi ON zi.zoneFk = z.id
|
||||
JOIN zoneGeo zg ON zg.id = zi.geoFk AND zg.type = 'province'
|
||||
WHERE dm.code = 'DELIVERY'
|
||||
GROUP BY shipped, zg.`name`
|
||||
ORDER BY shipped, zg.`name`;
|
||||
|
||||
DROP TEMPORARY TABLE tmp.time, tLandings;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -1732,7 +1732,8 @@ INSERT INTO `vn`.`zoneIncluded` (`zoneFk`, `geoFk`, `isIncluded`)
|
|||
(8, 3, 0),
|
||||
(8, 4, 0),
|
||||
(8, 5, 0),
|
||||
(8, 1, 1);
|
||||
(8, 1, 1),
|
||||
(10, 10, 1);
|
||||
|
||||
INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `dated`)
|
||||
VALUES
|
||||
|
@ -1943,7 +1944,9 @@ INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `dated`)
|
|||
(7, 'day', DATE_ADD(CURDATE(), INTERVAL +6 DAY));
|
||||
|
||||
INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `weekDays`)
|
||||
VALUES (8, 'indefinitely', 'mon,tue,wed,thu,fri,sat,sun');
|
||||
VALUES
|
||||
(8, 'indefinitely', 'mon,tue,wed,thu,fri,sat,sun'),
|
||||
(10, 'indefinitely', 'mon,tue,wed,thu,fri,sat,sun');
|
||||
|
||||
INSERT INTO `vn`.`workerTimeControl`(`userFk`, `timed`, `manual`, `direction`)
|
||||
VALUES
|
||||
|
|
|
@ -31,7 +31,7 @@ describe('Client Edit billing data path', () => {
|
|||
expect(message.text).toBe('That payment method requires an IBAN');
|
||||
});
|
||||
|
||||
// 2215: Windows (hidden mode): Entity code doesn't get the focus, '9999' is written in entity name.
|
||||
// 2256: Windows (hidden mode): Entity code doesn't get the focus, '9999' is written in entity name.
|
||||
xit(`should create a new BIC code`, async() => {
|
||||
await page.waitToClick(selectors.clientBillingData.newBankEntityButton);
|
||||
await page.write(selectors.clientBillingData.newBankEntityName, 'Gotham City Bank');
|
||||
|
|
|
@ -39,7 +39,7 @@ export default class WeekDays {
|
|||
new WeekDay('wed', 'Wednesday'),
|
||||
new WeekDay('thu', 'Thursday'),
|
||||
new WeekDay('fri', 'Friday'),
|
||||
new WeekDay('sat', 'Friday')
|
||||
new WeekDay('sat', 'Saturday')
|
||||
];
|
||||
|
||||
this.map = {};
|
||||
|
|
|
@ -61,7 +61,6 @@ module.exports = Self => {
|
|||
}, options);
|
||||
}
|
||||
|
||||
|
||||
let query = `
|
||||
CALL vn.item_getVisibleAvailable(?,curdate(),?,?)`;
|
||||
|
||||
|
@ -106,7 +105,6 @@ module.exports = Self => {
|
|||
return ticket.id;
|
||||
}
|
||||
|
||||
|
||||
async function getTicketId(params, options) {
|
||||
const minDate = new Date();
|
||||
minDate.setHours(0, 0, 0, 0);
|
||||
|
|
|
@ -15,7 +15,6 @@ describe('regularize()', () => {
|
|||
it('should create a new ticket and add a line', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 18}}};
|
||||
|
||||
|
||||
let query = `CALL vn.item_getVisibleAvailable(?,curdate(),?,?)`;
|
||||
|
||||
let options = [itemFk, warehouseFk, true];
|
||||
|
|
|
@ -24,9 +24,8 @@ describe('sale updatePrice()', () => {
|
|||
done();
|
||||
});
|
||||
|
||||
|
||||
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 price = 5;
|
||||
|
||||
|
@ -40,7 +39,7 @@ describe('sale updatePrice()', () => {
|
|||
});
|
||||
|
||||
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 = '';
|
||||
|
||||
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() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let ctx = {req: {accessToken: {userId: 18}}};
|
||||
let price = '8';
|
||||
|
||||
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() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let ctx = {req: {accessToken: {userId: 18}}};
|
||||
let price = 5.4;
|
||||
|
||||
await app.models.Sale.updatePrice(ctx, saleId, price);
|
||||
|
|
|
@ -55,8 +55,8 @@ module.exports = Self => {
|
|||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
let salesPerson = sale.ticket().client().salesPersonFk;
|
||||
let usesMana = await models.WorkerMana.findOne({where: {workerFk: salesPerson}, fields: 'amount'}, options);
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
let usesMana = await models.WorkerMana.findOne({where: {workerFk: userId}, fields: 'amount'}, options);
|
||||
let componentCode = usesMana ? 'mana' : 'buyerDiscount';
|
||||
|
||||
let discount = await models.Component.findOne({where: {code: componentCode}}, options);
|
||||
|
@ -83,8 +83,8 @@ module.exports = Self => {
|
|||
|
||||
await sale.updateAttributes({price: newPrice}, options);
|
||||
|
||||
query = `call vn.manaSpellersRequery(?)`;
|
||||
await Self.rawSql(query, [salesPerson], options);
|
||||
query = `CALL vn.manaSpellersRequery(?)`;
|
||||
await Self.rawSql(query, [userId], options);
|
||||
|
||||
await tx.commit();
|
||||
|
||||
|
|
|
@ -163,7 +163,8 @@ module.exports = Self => {
|
|||
if (value) {
|
||||
return {and: [
|
||||
{'st.alertLevel': 0},
|
||||
{'st.code': {neq: 'OK'}}
|
||||
{'st.code': {neq: 'OK'}},
|
||||
{'st.code': {neq: 'BOARDING'}}
|
||||
]};
|
||||
} else {
|
||||
return {and: [
|
||||
|
|
|
@ -76,7 +76,7 @@ module.exports = Self => {
|
|||
});
|
||||
const alertLevel = state ? state.alertLevel : null;
|
||||
|
||||
if (isLocked || (!isSalesPerson && alertLevel > 0 ))
|
||||
if (isLocked || (!isSalesPerson && alertLevel > 0))
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
const ticket = await models.Ticket.findById(id, {
|
||||
|
|
|
@ -14,7 +14,7 @@ Show pallet report: Ver hoja de pallet
|
|||
Change shipped hour: Cambiar 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."
|
||||
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
|
||||
Make invoice: Crear factura
|
||||
Regenerate invoice: Regenerar factura
|
||||
|
|
|
@ -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.toString() == shipped.toString();
|
||||
});
|
||||
|
||||
if (!zoneDetail) {
|
||||
zoneDetail = {
|
||||
shipped: shipped,
|
||||
lines: []
|
||||
};
|
||||
details.push(zoneDetail);
|
||||
}
|
||||
|
||||
zoneDetail.lines.push(zone);
|
||||
}
|
||||
|
||||
return details;
|
||||
};
|
||||
};
|
|
@ -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();
|
||||
|
||||
const firstResultLines = result[0].lines;
|
||||
const secondResultLines = result[1].lines;
|
||||
const thirdResultLines = result[2].lines;
|
||||
|
||||
expect(result.length).toEqual(8);
|
||||
expect(firstResultLines.length).toEqual(1);
|
||||
expect(secondResultLines.length).toEqual(1);
|
||||
expect(thirdResultLines.length).toEqual(1);
|
||||
});
|
||||
});
|
|
@ -3,6 +3,7 @@ module.exports = Self => {
|
|||
require('../methods/zone/getLeaves')(Self);
|
||||
require('../methods/zone/getEvents')(Self);
|
||||
require('../methods/zone/toggleIsIncluded')(Self);
|
||||
require('../methods/zone/getUpcomingDeliveries')(Self);
|
||||
|
||||
Self.validatesPresenceOf('agencyModeFk', {
|
||||
message: `Agency cannot be blank`
|
||||
|
|
|
@ -61,7 +61,7 @@ describe('Zone Component vnZoneDeliveryDays', () => {
|
|||
expect(controller.$.data).toEqual(expectedData);
|
||||
});
|
||||
});
|
||||
|
||||
// Petición #2259 cread
|
||||
xdescribe('onSelection()', () => {
|
||||
it('should not call the show popover method if events array is empty', () => {
|
||||
jest.spyOn(controller.$.zoneEvents, 'show');
|
||||
|
|
|
@ -14,3 +14,4 @@ import './events';
|
|||
import './calendar';
|
||||
import './location';
|
||||
import './calendar';
|
||||
import './upcoming-deliveries';
|
||||
|
|
|
@ -24,6 +24,7 @@ Range of dates: Rango de fechas
|
|||
Search zone by id or name: Buscar zonas por identificador o nombre
|
||||
This zone will be removed: La zona será eliminada
|
||||
To: Hasta
|
||||
Upcoming deliveries: Próximos repartos
|
||||
Volumetric: Volumétrico
|
||||
Warehouse: Almacén
|
||||
Warehouses: Almacenes
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
"menus": {
|
||||
"main": [
|
||||
{"state": "zone.index", "icon": "icon-zone"},
|
||||
{"state": "zone.deliveryDays", "icon": "today"}
|
||||
{"state": "zone.deliveryDays", "icon": "today"},
|
||||
{"state": "zone.upcomingDeliveries", "icon": "today"}
|
||||
],
|
||||
"card": [
|
||||
{"state": "zone.card.basicData", "icon": "settings"},
|
||||
|
@ -33,6 +34,11 @@
|
|||
"state": "zone.deliveryDays",
|
||||
"component": "vn-zone-delivery-days",
|
||||
"description": "Delivery days"
|
||||
}, {
|
||||
"url": "/upcoming-deliveries",
|
||||
"state": "zone.upcomingDeliveries",
|
||||
"component": "vn-upcoming-deliveries",
|
||||
"description": "Upcoming deliveries"
|
||||
}, {
|
||||
"url": "/create",
|
||||
"state": "zone.create",
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<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>{{$ctrl.getWeekDay(detail.shipped)}} - {{detail.shipped | date: 'dd/MM/yyyy'}}</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>
|
|
@ -0,0 +1,23 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends Section {
|
||||
constructor($element, $, vnWeekDays) {
|
||||
super($element, $);
|
||||
this.days = vnWeekDays.days;
|
||||
}
|
||||
|
||||
getWeekDay(jsonDate) {
|
||||
const weekDay = new Date(jsonDate).getDay();
|
||||
|
||||
return this.days[weekDay].locale;
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$element', '$scope', 'vnWeekDays'];
|
||||
|
||||
ngModule.component('vnUpcomingDeliveries', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
import './index';
|
||||
|
||||
describe('component vnUpcomingDeliveries', () => {
|
||||
let $scope;
|
||||
let controller;
|
||||
|
||||
beforeEach(ngModule('zone'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, $rootScope) => {
|
||||
$scope = $rootScope.$new();
|
||||
const $element = angular.element(`<vn-upcoming-deliveries></vn-upcoming-deliveries>`);
|
||||
controller = $componentController('vnUpcomingDeliveries', {$element, $scope});
|
||||
}));
|
||||
|
||||
fdescribe('getWeekDay()', () => {
|
||||
it('should retrieve a weekday for a json passed', () => {
|
||||
let jsonDate = '1970-01-01T22:00:00.000Z';
|
||||
|
||||
expect(controller.getWeekDay(jsonDate)).toEqual('Thursday');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
Family: Familia
|
||||
Percentage: Porcentaje
|
||||
Dwindle: Mermas
|
|
@ -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: $color-main-light;
|
||||
border-bottom: 1px solid $color-primary;
|
||||
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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue