This commit is contained in:
Carlos Jimenez Ruiz 2019-12-10 07:53:13 +01:00
commit 8ba442cf9c
79 changed files with 7015 additions and 36456 deletions

View File

@ -63,7 +63,7 @@ module.exports = Self => {
}
try {
const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId);
const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId, myOptions);
if (!hasWriteRole)
throw new UserError(`You don't have enough privileges`);
@ -83,7 +83,7 @@ module.exports = Self => {
const originPath = `${tempContainer.client.root}/${tempContainer.name}/${file.name}`;
const destinationPath = `${container.client.root}/${pathHash}/${newDms.file}`;
fs.rename(originPath, destinationPath);
await fs.rename(originPath, destinationPath);
addedDms.push(newDms);
}

View File

@ -58,10 +58,11 @@ module.exports = Self => {
*
* @param {Integer} userId The user id
* @param {String} name The role name
* @param {Object} options Options
* @return {Boolean} %true if user has the role, %false otherwise
*/
Self.hasRole = async function(userId, name) {
let roles = await Self.getRoles(userId);
Self.hasRole = async function(userId, name, options) {
let roles = await Self.getRoles(userId, options);
return roles.some(role => role == name);
};
@ -69,15 +70,16 @@ module.exports = Self => {
* Get all user roles.
*
* @param {Integer} userId The user id
* @param {Object} options Options
* @return {Object} User role list
*/
Self.getRoles = async userId => {
Self.getRoles = async(userId, options) => {
let result = await Self.rawSql(
`SELECT r.name
FROM account.user u
JOIN account.roleRole rr ON rr.role = u.role
JOIN account.role r ON r.id = rr.inheritsFrom
WHERE u.id = ?`, [userId]);
WHERE u.id = ?`, [userId], options);
let roles = [];
for (role of result)

View File

@ -5,17 +5,18 @@ module.exports = Self => {
*
* @param {Object} ctx - Request context
* @param {Interger} id - DmsType id
* @param {Object} options - Query options
* @return {Boolean} True for user with read privileges
*/
Self.hasReadRole = async(ctx, id) => {
Self.hasReadRole = async(ctx, id, options) => {
const models = Self.app.models;
const dmsType = await models.DmsType.findById(id, {
include: {
relation: 'readRole'
}
});
}, options);
return await hasRole(ctx, dmsType);
return await hasRole(ctx, dmsType, options);
};
/**
@ -24,17 +25,18 @@ module.exports = Self => {
*
* @param {Object} ctx - Request context
* @param {Interger} id - DmsType id
* @param {Object} options - Query options
* @return {Boolean} True for user with write privileges
*/
Self.hasWriteRole = async(ctx, id) => {
Self.hasWriteRole = async(ctx, id, options) => {
const models = Self.app.models;
const dmsType = await models.DmsType.findById(id, {
include: {
relation: 'writeRole'
}
});
}, options);
return await hasRole(ctx, dmsType);
return await hasRole(ctx, dmsType, options);
};
/**
@ -42,8 +44,9 @@ module.exports = Self => {
* read or write privileges
* @param {Object} ctx - Context
* @param {Object} dmsType - Dms type [read/write]
* @param {Object} options - Query options
*/
async function hasRole(ctx, dmsType) {
async function hasRole(ctx, dmsType, options) {
const models = Self.app.models;
const myUserId = ctx.req.accessToken.userId;
@ -51,8 +54,8 @@ module.exports = Self => {
const writeRole = dmsType.writeRole() && dmsType.writeRole().name;
const requiredRole = readRole || writeRole;
const hasRequiredRole = await models.Account.hasRole(myUserId, requiredRole);
const isRoot = await models.Account.hasRole(myUserId, 'root');
const hasRequiredRole = await models.Account.hasRole(myUserId, requiredRole, options);
const isRoot = await models.Account.hasRole(myUserId, 'root', options);
if (isRoot || hasRequiredRole)
return true;

View File

@ -1,83 +1,2 @@
ALTER TABLE `vn2008`.`department`
ADD COLUMN `parentFk` INT UNSIGNED NULL AFTER `sons`,
ADD COLUMN `path` VARCHAR(255) NULL AFTER `parentFk`,
CHANGE COLUMN `sons` `sons` DECIMAL(10,0) NOT NULL DEFAULT '0' ;
USE `vn`;
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `department` AS
SELECT
`b`.`department_id` AS `id`,
`b`.`name` AS `name`,
`b`.`production` AS `isProduction`,
`b`.`parentFk` AS `parentFk`,
`b`.`path` AS `path`,
`b`.`lft` AS `lft`,
`b`.`rgt` AS `rgt`,
`b`.`isSelected` AS `isSelected`,
`b`.`depth` AS `depth`,
`b`.`sons` AS `sons`
FROM
`vn2008`.`department` `b`;
DROP TRIGGER IF EXISTS `vn2008`.`department_AFTER_DELETE`;
DELIMITER $$
USE `vn2008`$$
CREATE DEFINER = CURRENT_USER TRIGGER `vn2008`.`department_AFTER_DELETE`
AFTER DELETE ON `department` FOR EACH ROW
BEGIN
UPDATE vn.department_recalc SET isChanged = TRUE;
END$$
DELIMITER ;
DROP TRIGGER IF EXISTS `vn2008`.`department_BEFORE_INSERT`;
DELIMITER $$
USE `vn2008`$$
CREATE DEFINER = CURRENT_USER TRIGGER `vn2008`.`department_BEFORE_INSERT`
BEFORE INSERT ON `department` FOR EACH ROW
BEGIN
UPDATE vn.department_recalc SET isChanged = TRUE;
END$$
DELIMITER ;
DROP TRIGGER IF EXISTS `vn2008`.`department_AFTER_UPDATE`;
DELIMITER $$
USE `vn2008`$$
CREATE DEFINER = CURRENT_USER TRIGGER `vn2008`.`department_AFTER_UPDATE`
AFTER UPDATE ON `department` FOR EACH ROW
BEGIN
IF !(OLD.parentFk <=> NEW.parentFk) THEN
UPDATE vn.department_recalc SET isChanged = TRUE;
END IF;
END$$
DELIMITER ;
CREATE TABLE `vn`.`department_recalc` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`isChanged` TINYINT(4) NOT NULL,
PRIMARY KEY (`id`));
INSERT INTO `vn`.`department_recalc` (`id`, `isChanged`) VALUES ('1', '0');
ALTER TABLE `vn2008`.`department`
CHANGE COLUMN `lft` `lft` INT(11) NULL ,
CHANGE COLUMN `rgt` `rgt` INT(11) NULL ;
ALTER TABLE `vn2008`.`department`
DROP INDEX `rgt_UNIQUE` ,
DROP INDEX `lft_UNIQUE` ;
;
ALTER TABLE `vn2008`.`department`
ADD INDEX `lft_rgt_depth_idx` (`lft` ASC, `rgt` ASC, `depth` ASC);
;
UPDATE vn.department SET lft = NULL, rgt = NULL;

View File

@ -33,7 +33,6 @@ BEGIN
DECLARE vAgencyModeId INT;
DECLARE TICKET_FREE INT DEFAULT 2;
DECLARE SYSTEM_WORKER INT DEFAULT 20;
DECLARE cDates CURSOR FOR
SELECT zgs.shipped, r.warehouse_id
@ -44,9 +43,9 @@ BEGIN
GROUP BY r.warehouse_id;
DECLARE cRows CURSOR FOR
SELECT r.id, r.item_id, a.Article, r.amount, r.price, r.rate
SELECT r.id, r.item_id, i.name, r.amount, r.price, r.rate
FROM order_row r
JOIN vn2008.Articles a ON a.Id_Article = r.item_id
JOIN vn.item i ON i.id = r.item_id
WHERE r.amount != 0
AND r.warehouse_id = vWarehouse
AND r.order_id = vOrder
@ -64,12 +63,12 @@ BEGIN
-- Carga los datos del pedido
SELECT o.date_send, o.address_id, o.note,
o.confirmed, cs.Id_Cliente, o.company_id, o.agency_id
o.confirmed, a.clientFk, o.company_id, o.agency_id
INTO vDelivery, vAddress, vNotes,
vIsConfirmed, vClientId, vCompanyId, vAgencyModeId
FROM hedera.`order` o
JOIN vn2008.Consignatarios cs ON cs.Id_Consigna = o.address_id
WHERE id = vOrder;
JOIN vn.address a ON a.id = o.address_id
WHERE o.id = vOrder;
-- Comprueba que el pedido no está confirmado
@ -114,19 +113,18 @@ BEGIN
-- Busca un ticket existente que coincida con los parametros
SELECT Id_Ticket INTO vTicket
FROM vn2008.Tickets t
LEFT JOIN vn.ticketState tls on tls.ticket = t.Id_Ticket
SELECT t.id INTO vTicket
FROM vn.ticket t
LEFT JOIN vn.ticketState tls on tls.ticket = t.id
JOIN `order` o
ON o.address_id = t.Id_Consigna
AND vWarehouse = t.warehouse_id
AND o.agency_id = t.Id_Agencia
AND t.landing = o.date_send
AND vShipment = DATE(t.Fecha)
ON o.address_id = t.addressFk
AND vWarehouse = t.warehouseFk
AND o.agency_id = t.agencyModeFk
AND o.date_send = t.landed
AND vShipment = DATE(t.shipped)
WHERE o.id = vOrder
AND t.Factura IS NULL
AND t.invoiceOutFk IS NULL
AND IFNULL(tls.alertLevel,0) = 0
AND t.Id_Cliente <> 1118
LIMIT 1;
-- Crea el ticket en el caso de no existir uno adecuado
@ -148,24 +146,24 @@ BEGIN
ELSE
INSERT INTO vncontrol.inter
SET Id_Ticket = vTicket,
Id_Trabajador = SYSTEM_WORKER,
Id_Trabajador = vUserId,
state_id = TICKET_FREE;
END IF;
INSERT IGNORE INTO vn2008.order_Tickets
SET order_id = vOrder,
Id_Ticket = vTicket;
INSERT IGNORE INTO vn.orderTicket
SET orderFk = vOrder,
ticketFk = vTicket;
-- Añade las notas
IF vNotes IS NOT NULL AND vNotes != ''
THEN
INSERT INTO vn2008.ticket_observation SET
Id_Ticket = vTicket,
observation_type_id = 4 /* salesperson */ ,
`text` = vNotes
INSERT INTO vn.ticketObservation SET
ticketFk = vTicket,
observationTypeFk = 4 /* salesperson */ ,
`description` = vNotes
ON DUPLICATE KEY UPDATE
`text` = CONCAT(VALUES(`text`),'. ', `text`);
`description` = CONCAT(VALUES(`description`),'. ', `description`);
END IF;
-- Añade los movimientos y sus componentes
@ -181,20 +179,20 @@ BEGIN
LEAVE lRows;
END IF;
INSERT INTO vn2008.Movimientos
INSERT INTO vn.sale
SET
Id_Article = vItem,
Id_Ticket = vTicket,
Concepte = vConcept,
Cantidad = vAmount,
Preu = vPrice,
CostFixat = 0,
PrecioFijado = TRUE;
itemFk = vItem,
ticketFk = vTicket,
concept = vConcept,
quantity = vAmount,
price = vPrice,
priceFixed = 0,
isPriceFixed = TRUE;
SET vSale = LAST_INSERT_ID();
INSERT INTO vn2008.Movimientos_componentes
(Id_Movimiento, Id_Componente, Valor)
INSERT INTO vn.saleComponent
(saleFk, componentFk, `value`)
SELECT vSale, cm.component_id, cm.price
FROM order_component cm
JOIN bi.tarifa_componentes tc
@ -215,20 +213,20 @@ BEGIN
CREATE TEMPORARY TABLE tComponents
(INDEX (saleFk))
ENGINE = MEMORY
SELECT SUM(mc.Valor) valueSum, mc.Id_Movimiento saleFk
FROM vn2008.Movimientos_componentes mc
JOIN bi.tarifa_componentes tc USING(Id_Componente)
SELECT SUM(sc.`value`) valueSum, sc.saleFk
FROM vn.saleComponent sc
JOIN bi.tarifa_componentes tc ON tc.Id_Componente = sc.componentFk
JOIN bi.tarifa_componentes_series tcs
ON tcs.tarifa_componentes_series_id = tc.tarifa_componentes_series_id
AND tcs.base
JOIN vn2008.Movimientos m
ON m.Id_Movimiento = mc.Id_Movimiento
WHERE m.Id_Ticket = vTicket
GROUP BY mc.Id_Movimiento;
JOIN vn.sale s
ON s.id = sc.saleFk
WHERE s.ticketFk = vTicket
GROUP BY sc.saleFk;
UPDATE vn2008.Movimientos m
JOIN tComponents mc ON mc.saleFk = m.Id_Movimiento
SET m.CostFixat = valueSum;
UPDATE vn.sale s
JOIN tComponents mc ON mc.saleFk = s.id
SET s.priceFixed = valueSum;
DROP TEMPORARY TABLE tComponents;
END LOOP;

View File

@ -39,16 +39,16 @@ BEGIN
CALL util.throw ('NOT_ZONE_WITH_THIS_PARAMETERS');
END IF;
END IF;
INSERT INTO vn2008.Tickets (
Id_Cliente,
Fecha,
Id_Consigna,
Id_Agencia,
Alias,
warehouse_id,
Id_Ruta,
empresa_id,
landing,
INSERT INTO ticket (
clientFk,
shipped,
addressFk,
agencyModeFk,
nickname,
warehouseFk,
routeFk,
companyFk,
landed,
zoneFk
)
SELECT

View File

@ -1,34 +0,0 @@
DROP procedure IF EXISTS `vn`.`buy_notifyPassport`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`buy_notifyPassport`(
IN vBuyFk INT,
IN vItemFk INT,
IN vStickers SMALLINT,
IN vPacking SMALLINT
)
BEGIN
INSERT INTO vn.mail(`subject`,`body`,`sender`)
SELECT 'Solicitar pasaporte',
CONCAT(
'Etiquetas: ', IFNULL(vStickers, 0),
', Packing: ', IFNULL(vPacking, 0),
', Nombre: ', IFNULL(i.`name`, 0),
', buy_edi: ', IFNULL(e.id, 0),
', Nombre botánico: ', IFNULL(g.latin_genus_name, ''), ' ', IFNULL(s.latin_species_name, ''),
', Productor: ',IFNULL(es.company_name, IFNULL(p.`name`, ''))
)
,'ekt@verdnatura.es'
FROM item i
LEFT JOIN itemBotanical ib ON ib.itemFk = i.id
LEFT JOIN edi.genus g ON g.genus_id = ib.genusFk
LEFT JOIN edi.specie s ON IFNULL(s.specie_id, ib.specieFk) = ib.specieFk
LEFT JOIN producer p ON p.id = i.producerFk
LEFT JOIN buy b ON b.id = vBuyFk
LEFT JOIN edi.ekt e ON b.ektFk = e.id
LEFT JOIN edi.supplier es ON es.supplier_id = e.pro
WHERE i.id = vItemFk;
END$$
DELIMITER ;

View File

@ -1,149 +0,0 @@
DROP procedure IF EXISTS `vn`.`duaTaxBooking`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`duaTaxBooking`(vDuaFk INT)
BEGIN
DECLARE vBookNumber INT;
DECLARE vBookDated DATE;
DECLARE vDiff DECIMAL(10,2);
DECLARE vApunte BIGINT;
SELECT IFNULL(d.ASIEN,MAX(x.ASIEN) + 1 )
INTO vBookNumber
FROM XDiario x
LEFT JOIN dua d ON d.id = vDuaFk ;
SELECT IFNULL(bookEntried, CURDATE()) INTO vBookDated
FROM dua
WHERE id = vDuaFk;
-- Apunte de la aduana
INSERT INTO XDiario(
ASIEN,
FECHA,
SUBCTA,
CONCEPTO,
EUROHABER,
SERIE,
empresa_id,
CLAVE,
FACTURA)
SELECT
vBookNumber,
d.bookEntried,
'4700000999',
CONCAT('DUA ',d.code),
sum(di.amount * tr.rate / 100) EUROHABER,
'R',
d.companyFk,
vDuaFk,
vDuaFk
FROM duaIntrastat di
JOIN intrastat ist ON ist.id = di.intrastatFk
JOIN (SELECT rate, taxClassFk
FROM
(SELECT rate, taxClassFk
FROM invoiceInTaxBookingAccount ta
WHERE ta.effectived <= vBookDated
ORDER BY ta.effectived DESC
) tba
GROUP BY taxClassFk
) tr ON tr.taxClassFk = ist.taxClassFk
JOIN dua d ON d.id = di.duaFk
WHERE di.duaFk = vDuaFk;
-- Apuntes por tipo de IVA y proveedor
INSERT INTO XDiario(
ASIEN,
FECHA,
SUBCTA,
CONTRA,
EURODEBE,
BASEEURO,
CONCEPTO,
FACTURA,
IVA,
AUXILIAR,
SERIE,
FECHA_EX,
FECHA_OP,
FACTURAEX,
NFACTICK,
L340,
LDIFADUAN,
TIPOCLAVE,
TIPOEXENCI,
TIPONOSUJE,
TIPOFACT,
TIPORECTIF,
TERIDNIF,
TERNIF,
TERNOM,
empresa_id,
FECREGCON
)
SELECT
vBookNumber ASIEN,
vBookDated FECHA,
tr.account SUBCTA,
'4330002067' CONTRA,
sum(dt.tax) EURODEBE,
sum(dt.base) BASEEURO,
CONCAT('DUA nº',d.code) CONCEPTO,
d.id FACTURA,
dt.rate IVA,
'*' AUXILIAR,
'D' SERIE,
d.issued FECHA_EX,
d.operated FECHA_OP,
d.code FACTURAEX,
1 NFACTICK,
1 L340,
TRUE LDIFADUAN,
1 TIPOCLAVE,
1 TIPOEXENCI,
1 TIPONOSUJE,
5 TIPOFACT,
1 TIPORECTIF,
IF(s.countryFk IN (30, 1), 1, 4) TERIDNIF,
s.nif TERNIF,
s.name TERNOM,
d.companyFk,
d.booked FECREGCON
FROM duaTax dt
JOIN dua d ON dt.duaFk = d.id
JOIN (SELECT account, rate
FROM
(SELECT rate, account
FROM invoiceInTaxBookingAccount ta
WHERE ta.effectived <= vBookDated
AND taxAreaFk = 'WORLD'
ORDER BY ta.effectived DESC
) tba
GROUP BY rate
) tr ON tr.rate = dt.rate
JOIN supplier s ON s.id = d.companyFk
WHERE d.id = vDuaFk
GROUP BY dt.rate;
SELECT SUM(EURODEBE) -SUM(EUROHABER), MAX(id) INTO vDiff, vApunte
FROM XDiario
WHERE ASIEN = vBookNumber;
UPDATE XDiario
SET BASEEURO = 100 * (EURODEBE - vDiff) / IVA,
EURODEBE = EURODEBE - vDiff
WHERE id = vApunte;
UPDATE dua
SET ASIEN = vBookNumber
WHERE id = vDuaFk;
END$$
DELIMITER ;

View File

@ -1,119 +0,0 @@
USE `vn`;
DROP procedure IF EXISTS `itemDiary`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `itemDiary`(IN vItemId INT, IN vWarehouse INT)
BEGIN
DECLARE vDateInventory DATETIME;
DECLARE vCurdate DATE DEFAULT CURDATE();
DECLARE vDayEnd DATETIME DEFAULT util.dayEnd(vCurdate);
-- traduccion: date, alertLevel, origin, reference, name, In, Out, Balance
SELECT Fechainventario INTO vDateInventory FROM vn2008.tblContadores;
SET @a = 0;
SELECT DATE(date) AS date,
alertLevel,
stateName,
origin,
reference,
clientFk,
name,
`in`,
`out`,
@a := @a + IFNULL(`in`,0) - IFNULL(`out`,0) as balance,
isPicked,
isTicket
FROM
( SELECT tr.landed as date,
b.quantity as `in`,
NULL as `out`,
IF(tr.isReceived != FALSE,3, IF(tr.isDelivered,1,0)) as alertLevel,
st.name AS stateName,
s.name as name,
e.ref as reference,
e.id as origin,
s.id as clientFk,
TRUE isPicked,
FALSE AS isTicket
FROM vn.buy b
JOIN vn.entry e ON e.id = b.entryFk
JOIN vn.travel tr ON tr.id = e.travelFk
JOIN vn.supplier s ON s.id = e.supplierFk
JOIN vn.alertLevel al ON al.alertLevel =
CASE
WHEN tr.isReceived != FALSE THEN 3
WHEN tr.isDelivered THEN 1
ELSE 0
END
JOIN vn.state st ON st.code = al.code
WHERE tr.landed >= vDateInventory
AND vWarehouse = tr.warehouseInFk
AND b.itemFk = vItemId
AND e.isInventory = 0
AND e.isRaid = 0
UNION ALL
SELECT tr.shipped as date,
NULL as `in`,
b.quantity as `out`,
IF(tr.isReceived != FALSE,3, IF(tr.isDelivered,1,0)) as alertLevel,
st.name AS stateName,
s.name as name,
e.ref as reference,
e.id as origin,
s.id as clientFk,
TRUE isPicked,
FALSE AS isTicket
FROM vn.buy b
JOIN vn.entry e ON e.id = b.entryFk
JOIN vn.travel tr ON tr.id = e.travelFk
JOIN vn.warehouse w ON w.id = tr.warehouseOutFk
JOIN vn.supplier s ON s.id = e.supplierFk
JOIN vn.alertLevel al ON al.alertLevel =
CASE
WHEN tr.isReceived != FALSE THEN 3
WHEN tr.isDelivered THEN 1
ELSE 0
END
JOIN vn.state st ON st.code = al.code
WHERE tr.shipped >= vDateInventory
AND vWarehouse =tr.warehouseOutFk
AND s.id <> 4
AND b.itemFk = vItemId
AND e.isInventory = 0
AND w.isFeedStock = 0
AND e.isRaid = 0
UNION ALL
SELECT t.shipped as date,
NULL as `in`,
s.quantity as `out`,
al.alertLevel as alertLevel,
st.name AS stateName,
t.nickname as name,
t.refFk as reference,
t.id as origin,
t.clientFk,
stk.id as isPicked, -- TRUE as isPicked
TRUE as isTicket
FROM vn.sale s
JOIN vn.ticket t ON t.id = s.ticketFk
LEFT JOIN vn.ticketState ts ON ts.ticket = t.id
LEFT JOIN vn.state st ON st.code = ts.code
JOIN vn.client c ON c.id = t.clientFk
JOIN vn.alertLevel al ON al.alertLevel =
CASE
WHEN t.shipped < vCurdate THEN 3
WHEN t.shipped > vDayEnd THEN 0
ELSE IFNULL(ts.alertLevel, 0)
END
LEFT JOIN vn.saleTracking stk ON stk.saleFk = s.id AND stk.stateFk = 14 -- comentar
WHERE t.shipped >= vDateInventory
AND s.itemFk = vItemId
AND vWarehouse =t.warehouseFk
) AS itemDiary
ORDER BY date, isTicket, alertLevel DESC, isPicked DESC, `in` DESC, `out` DESC;
END$$
DELIMITER ;

View File

@ -1,4 +1,3 @@
USE `vn`;
ALTER TABLE `vn`.`ticketRequest`
DROP FOREIGN KEY `fgnAtender`;
@ -10,44 +9,12 @@ ADD CONSTRAINT `fgnAtender`
REFERENCES `vn`.`worker` (`id`)
ON UPDATE CASCADE;
USE `vn2008`;
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn2008`.`Ordenes` AS
SELECT
`tr`.`id` AS `Id_ORDEN`,
`tr`.`description` AS `ORDEN`,
`tr`.`requesterFk` AS `requesterFk`,
`tr`.`attenderFk` AS `attenderFk`,
`tr`.`quantity` AS `CANTIDAD`,
`tr`.`itemFk` AS `Id_ARTICLE`,
`tr`.`price` AS `PRECIOMAX`,
`tr`.`isOk` AS `isOk`,
`tr`.`saleFk` AS `Id_Movimiento`,
`tr`.`ticketFk` AS `ticketFk`,
`tr`.`response` AS `COMENTARIO`,
`tr`.`created` AS `odbc_date`,
`tr`.`ordered` AS `datORDEN`,
`tr`.`shipped` AS `datTICKET`,
`tr`.`salesPersonCode` AS `CodVENDEDOR`,
`tr`.`buyerCode` AS `CodCOMPRADOR`,
`tr`.`price__` AS `PREU`,
`tr`.`clientFk` AS `Id_CLIENTE`,
`tr`.`ok__` AS `OK`,
`tr`.`total` AS `TOTAL`,
`tr`.`buyed` AS `datCOMPRA`,
`tr`.`ko__` AS `KO`
FROM
`vn`.`ticketRequest` `tr`;
USE `vn`;
DROP TRIGGER IF EXISTS `vn`.`ticketRequest_beforeInsert`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` TRIGGER `vn`.`ticketRequest_beforeInsert` BEFORE INSERT ON `ticketRequest` FOR EACH ROW
BEGIN
IF NEW.ticketFk IS NULL THEN
@ -68,7 +35,6 @@ DELIMITER ;
DROP TRIGGER IF EXISTS `vn`.`ticketRequest_beforeUpdate`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` TRIGGER `vn`.`ticketRequest_beforeUpdate` BEFORE UPDATE ON `ticketRequest` FOR EACH ROW
BEGIN
IF NEW.saleFk <> OLD.saleFk THEN
@ -85,24 +51,4 @@ BEGIN
END$$
DELIMITER ;
USE `vn`;
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`ticketRequest__` AS
SELECT
`t`.`Id_ORDEN` AS `id`,
`t`.`ORDEN` AS `description`,
`t`.`requesterFk` AS `requesterFk`,
`t`.`attenderFk` AS `attenderFk`,
`t`.`CANTIDAD` AS `quantity`,
`t`.`Id_ARTICLE` AS `itemFk`,
`t`.`PRECIOMAX` AS `price`,
`t`.`isOk` AS `isOk`,
`t`.`Id_Movimiento` AS `saleFk`,
`t`.`ticketFk` AS `ticketFk`,
`t`.`COMENTARIO` AS `response`,
`t`.`odbc_date` AS `created`
FROM
`vn2008`.`Ordenes` `t`;

View File

@ -0,0 +1,53 @@
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn2008`.`Ordenes` AS
SELECT
`tr`.`id` AS `Id_ORDEN`,
`tr`.`description` AS `ORDEN`,
`tr`.`requesterFk` AS `requesterFk`,
`tr`.`attenderFk` AS `attenderFk`,
`tr`.`quantity` AS `CANTIDAD`,
`tr`.`itemFk` AS `Id_ARTICLE`,
`tr`.`price` AS `PRECIOMAX`,
`tr`.`isOk` AS `isOk`,
`tr`.`saleFk` AS `Id_Movimiento`,
`tr`.`ticketFk` AS `ticketFk`,
`tr`.`response` AS `COMENTARIO`,
`tr`.`created` AS `odbc_date`,
`tr`.`ordered` AS `datORDEN`,
`tr`.`shipped` AS `datTICKET`,
`tr`.`salesPersonCode` AS `CodVENDEDOR`,
`tr`.`buyerCode` AS `CodCOMPRADOR`,
`tr`.`price__` AS `PREU`,
`tr`.`clientFk` AS `Id_CLIENTE`,
`tr`.`ok__` AS `OK`,
`tr`.`total` AS `TOTAL`,
`tr`.`buyed` AS `datCOMPRA`,
`tr`.`ko__` AS `KO`
FROM
`vn`.`ticketRequest` `tr`;
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`ticketRequest__` AS
SELECT
`t`.`Id_ORDEN` AS `id`,
`t`.`ORDEN` AS `description`,
`t`.`requesterFk` AS `requesterFk`,
`t`.`attenderFk` AS `attenderFk`,
`t`.`CANTIDAD` AS `quantity`,
`t`.`Id_ARTICLE` AS `itemFk`,
`t`.`PRECIOMAX` AS `price`,
`t`.`isOk` AS `isOk`,
`t`.`Id_Movimiento` AS `saleFk`,
`t`.`ticketFk` AS `ticketFk`,
`t`.`COMENTARIO` AS `response`,
`t`.`odbc_date` AS `created`
FROM
`vn2008`.`Ordenes` `t`;

View File

@ -1,59 +0,0 @@
DROP procedure IF EXISTS `vn`.`buy_afterUpsert`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`buy_afterUpsert`(vSelf INT)
BEGIN
/**
* Triggered actions when a buy is updated or inserted.
*
* @param vSelf The buy reference
*/
DECLARE vEntryFk INT;
DECLARE vItemFk INT;
DECLARE vStickers INT;
DECLARE vPacking INT;
DECLARE vWarehouse INT;
DECLARE vWarehouseOut INT;
DECLARE vIsMerchandise BOOL;
DECLARE vIsFeedStock BOOL;
SELECT entryFk, itemFk, stickers, packing
INTO vEntryFk, vItemFk, vStickers, vPacking
FROM buy
WHERE id = vSelf;
SELECT t.warehouseInFk, t.warehouseOutFk
INTO vWarehouse, vWarehouseOut
FROM entry e
JOIN travel t ON t.id = e.travelFk
WHERE e.id = vEntryFk;
SELECT k.merchandise INTO vIsMerchandise
FROM itemCategory k
JOIN itemType it ON it.categoryFk = k.id
JOIN item i ON i.typeFk = it.id
WHERE i.id = vItemFk;
IF vIsMerchandise THEN
REPLACE bi.rotacion SET
Id_Article = vItemFk,
warehouse_id = vWarehouse,
cm3 = buy_getUnitVolume(vSelf);
END IF;
SELECT isFeedStock INTO vIsFeedStock
FROM warehouse WHERE id = vWarehouseOut AND id <> 13;
IF vIsFeedStock AND vn2008.has_notify_passport(vItemFk, vSelf) THEN
CALL vn.buy_notifyPassport(vSelf, vItemFk, vStickers, vPacking);
INSERT IGNORE INTO producer(`name`)
SELECT es.company_name
FROM buy b
JOIN edi.ekt be ON be.id = b.ektFk
JOIN edi.supplier es ON es.supplier_id = be.pro
WHERE b.id = 1;
END IF;
END$$
DELIMITER ;

View File

@ -1,16 +0,0 @@
DROP procedure IF EXISTS `vn2008`.`notify_passport`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn2008`.`notify_passport`(
IN vItemFk INT,
IN vStickers SMALLINT,
IN vPacking SMALLINT,
IN vBuyFk INT
)
BEGIN
-- DPRECATED use vn.buy_notifyPassport
CALL vn.buy_notifyPassport(vBuyFk, vItemFk, vStickers, vPacking);
END$$
DELIMITER ;

View File

@ -0,0 +1,58 @@
DROP TRIGGER IF EXISTS `vn`.`entry_beforeUpdate`;
DELIMITER $$
CREATE DEFINER=`root`@`%` TRIGGER `vn`.`entry_beforeUpdate`
BEFORE UPDATE ON `entry`
FOR EACH ROW
BEGIN
DECLARE vIsVirtual BOOL;
DECLARE vPrintedCount INT;
DECLARE vHasDistinctWarehouses BOOL;
IF !(NEW.travelFk <=> OLD.travelFk) THEN
SELECT COUNT(*) > 0 INTO vIsVirtual
FROM entryVirtual WHERE entryFk = NEW.id;
SELECT !(o.warehouseInFk <=> n.warehouseInFk)
OR !(o.warehouseOutFk <=> n.warehouseOutFk)
INTO vHasDistinctWarehouses
FROM travel o, travel n
WHERE o.id = OLD.travelFk
AND n.id = NEW.travelFk;
IF vIsVirtual AND vHasDistinctWarehouses THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'A cloned entry cannot be moved to a travel with different warehouses';
END IF;
IF NEW.travelFk IS NULL THEN
SELECT COUNT(*) INTO vPrintedCount
FROM buy
WHERE entryFk = OLD.id
AND printedStickers > 0;
IF vPrintedCount > 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'An entry that contains lines with printed labels cannot be deleted';
END IF;
END IF;
END IF;
IF !(NEW.supplierFk <=> OLD.supplierFk) THEN
SET NEW.currencyFk = entry_getCurrency(NEW.currencyFk, NEW.supplierFk);
END IF;
IF !(NEW.travelFk <=> OLD.travelFk)
OR !(NEW.currencyFk <=> OLD.currencyFk) THEN
SET NEW.commission = entry_getCommission(NEW.travelFk, NEW.currencyFk,NEW.supplierFk);
END IF;
IF !(ABS(NEW.isBooked) <=> ABS(OLD.isBooked)) THEN
INSERT INTO entryLog SET
action = 'update',
description = 'Cambia a Contabilizada',
userFk = myWorker_getId(),
originFk = NEW.id;
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,120 @@
DROP procedure IF EXISTS `hedera`.`tpvTransaction_confirm`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`tpvTransaction_confirm`(
vAmount INT
,vOrder INT
,vMerchant INT
,vCurrency INT
,vResponse INT
,vErrorCode VARCHAR(10)
)
BEGIN
/**
* Confirma una transacción previamente iniciada, reescribiendo
* sus datos por los confirmados por el banco (solo si estos difieren).
* Genera el recibo y su correspondiente entrada en caja.
*
* @param vAmount Cantidad confirmada
* @param vOrder Identificador de transacción
* @param vMerchant Identificador de comercio
* @param vCurrency Identificador de moneda
* @param vResponse Identificador de respuesta del banco
* @param vErrorCode Código de error del banco, si lo hubiera
*/
DECLARE vReceipt INT;
DECLARE vStatus VARCHAR(10);
DECLARE vCustomer INT;
DECLARE vBank INT;
DECLARE vCompany INT;
DECLARE vEmployee INT;
DECLARE vIsDuplicated BOOLEAN;
DECLARE vDate DATE;
DECLARE vConcept VARCHAR(25) DEFAULT 'Cobro Web';
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
SELECT COUNT(*) > 0 INTO vIsDuplicated
FROM tpvTransaction
WHERE id = vOrder AND response IS NOT NULL
FOR UPDATE;
IF vIsDuplicated
THEN
CALL util.throw ('TRANSACTION_DUPLICATED');
END IF;
IF vResponse BETWEEN 0 AND 99
THEN
SELECT
t.clientFk
,m.bankFk
,m.companyFk
,c.employeeFk
,DATE(t.created)
INTO
vCustomer
,vBank
,vCompany
,vEmployee
,vDate
FROM tpvMerchant m
JOIN tpvConfig c
LEFT JOIN tpvTransaction t ON t.id = vOrder
WHERE m.id = vMerchant;
INSERT INTO vn.receipt
SET
amountPaid = vAmount / 100
,payed = vDate
,workerFk = vEmployee
,bankFk = vBank
,clientFk = vCustomer
,companyFk = vCompany
,invoiceFk = vConcept
,isConciliate = TRUE;
SET vReceipt = LAST_INSERT_ID();
SET vStatus = 'ok';
-- Código redundante
DO vn.till_new
(
vCustomer
,vBank
,vAmount / 100
,vConcept
,vDate
,'A'
,TRUE
,vCustomer
,vCompany
,vEmployee
);
ELSE
SET vReceipt = NULL;
SET vStatus = 'ko';
END IF;
UPDATE tpvTransaction
SET
merchantFk = vMerchant
,receiptFk = vReceipt
,amount = vAmount
,response = vResponse
,errorCode = vErrorCode
,status = vStatus
WHERE id = vOrder;
COMMIT;
END$$
DELIMITER ;

View File

@ -0,0 +1,87 @@
USE `hedera`;
DROP procedure IF EXISTS `tpvTransaction_undo`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `tpvTransaction_undo`(vSelf INT)
BEGIN
DECLARE vCustomer INT;
DECLARE vAmount DOUBLE;
DECLARE vReceipt INT;
DECLARE vDate DATE;
DECLARE vBank INT;
DECLARE vAccount VARCHAR(12);
DECLARE vSubaccount VARCHAR(12);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
SELECT
t.clientFk
,t.amount / 100
,t.receiptFk
,DATE(t.created)
,m.bankFk
INTO
vCustomer
,vAmount
,vReceipt
,vDate
,vBank
FROM tpvTransaction t
JOIN tpvMerchant m ON m.id = t.merchantFk
JOIN tpvConfig c
WHERE t.id = vSelf
FOR UPDATE;
-- Elimina el recibo
DELETE FROM vn.receipt
WHERE id = vReceipt LIMIT 1;
-- Elimina la entrada de cajas
DELETE FROM vn.till
WHERE bankFk = vBank
AND DATE(dated) = vDate
AND `in` = vAmount
LIMIT 1;
-- Elimina los asientos contables
SELECT accountingAccount INTO vSubaccount
FROM vn.`client` WHERE id = vCustomer;
SELECT account INTO vAccount
FROM vn.bank WHERE id = vBank;
DELETE FROM vn.XDiario
WHERE SUBCTA = vSubaccount
AND CONTRA = vAccount
AND DATE(FECHA) = vDate
AND EUROHABER = vAmount
LIMIT 1;
DELETE FROM vn.XDiario
WHERE CONTRA = vSubaccount
AND SUBCTA = vAccount
AND DATE(FECHA) = vDate
AND EURODEBE = vAmount
LIMIT 1;
-- Actualiza la transaccion
UPDATE tpvTransaction
SET response = NULL, status = 'started'
WHERE id = vSelf;
COMMIT;
END$$
DELIMITER ;

View File

@ -0,0 +1,123 @@
DROP procedure IF EXISTS `vn2008`.`clean`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn2008`.`clean`(IN `v_full` TINYINT(1))
proc: BEGIN
DECLARE v_date DATETIME;
DECLARE v_date18 DATETIME;
DECLARE v_date26 DATETIME;
DECLARE v_date8 DATE;
DECLARE v_date6 DATE;
DECLARE v_date3Month DATE;
DECLARE vDate2000 DATE;
DECLARE vRangeDeleteTicket INT;
DECLARE strtable varchar(15) DEFAULT NULL;
DECLARE done BIT DEFAULT 0;
SET v_date = TIMESTAMPADD(MONTH, -2, CURDATE());
SET v_date18 = TIMESTAMPADD(MONTH, -18,CURDATE());
SET v_date26 = TIMESTAMPADD(MONTH, -26,CURDATE());
SET v_date3Month = TIMESTAMPADD(MONTH, -3, CURDATE());
SET v_date8 = TIMESTAMPADD(DAY, -8,CURDATE());
SET v_date6 = TIMESTAMPADD(DAY, -6,CURDATE());
SET vRangeDeleteTicket = 60;
DELETE FROM cdr WHERE calldate < v_date;
DELETE FROM Monitoring WHERE ODBC_TIME < v_date;
DELETE FROM Conteo WHERE Fecha < v_date;
DELETE FROM XDiario WHERE FECHA < v_date3Month OR FECHA IS NULL;
DELETE FROM mail WHERE DATE_ODBC < v_date;
-- DELETE FROM Cajas WHERE CajaFecha < v_date18;
DELETE rr FROM Recibos_recorded rr JOIN Recibos r ON rr.Id_Recibos = r.Id WHERE r.Fechacobro < v_date;
SELECT MAX(idTickets_dits)
INTO @id
FROM Tickets_dits
WHERE ODBC_DATE < v_date;
DELETE FROM Tickets_dits WHERE idTickets_dits <= @id;
DELETE FROM expeditions_deleted WHERE odbc_date < v_date26;
DELETE FROM Entradas_dits WHERE ODBC_DATE < v_date18;
DELETE FROM log_articles WHERE ODBC_DATE < v_date;
DELETE FROM Splits WHERE Fecha < v_date18;
DELETE ts FROM Tickets_stack ts JOIN Tickets t ON ts.Id_Ticket = t.Id_Ticket WHERE t.Fecha < v_date;
DELETE tobs FROM movement_label tobs JOIN Movimientos m ON tobs.Id_Movimiento = m.Id_Movimiento
JOIN Tickets t ON m.Id_Ticket = t.Id_Ticket WHERE t.Fecha < v_date;
DELETE FROM chat WHERE odbc_date < v_date;
DELETE FROM Extractos WHERE Fecha < v_date;
DELETE FROM Remesas WHERE `Fecha Remesa` < v_date18;
DELETE FROM Stockcontrol WHERE Datestart < v_date18;
-- DELETE FROM reference_rate WHERE date < v_date18;
DELETE FROM hedera.`order` WHERE date_send < v_date18;
-- DELETE FROM Ordenes WHERE odbc_date < v_date18; JGF 2018-12-21 Si estan en un turno no hay que borrarlas.
SELECT MAX(inter_id)
INTO @id
FROM vncontrol.inter
WHERE odbc_date < v_date18;
DELETE FROM vncontrol.inter WHERE inter_id <= @id;
DELETE FROM Entradas_dits WHERE ODBC_DATE < v_date;
DELETE FROM cyc_declaration WHERE Fecha < v_date18;
DELETE FROM travel_reserve WHERE odbc_date < v_date;
-- DELETE FROM syslog.systemevents WHERE odbc_date < v_date8;
DELETE FROM cache.departure_limit WHERE Fecha < TIMESTAMPADD(MONTH,-1,CURDATE());
DELETE co
FROM Compres_ok co JOIN Compres c ON c.Id_Compra = co.Id_Compra
JOIN Entradas e ON e.Id_Entrada = c.Id_Entrada
JOIN travel t ON t.id = e.travel_id
WHERE t.landing <= v_date;
DELETE FROM vn2008.scan WHERE odbc_date < v_date6 AND id <> 1;
SET vDate2000 = TIMESTAMPADD(YEAR, 2000 - YEAR(CURDATE()), CURDATE());
IF v_full
THEN
DELETE t FROM Tickets t
LEFT JOIN Tickets_turno tt ON tt.Id_Ticket = t.Id_Ticket
WHERE Fecha NOT IN ('2000-01-01','2000-01-02')
AND YEAR(Fecha) = 2000
AND ABS(DATEDIFF(Fecha,vDate2000)) > vRangeDeleteTicket
AND tt.Id_Ticket IS NULL;
DELETE e.* FROM Entradas e
LEFT JOIN recibida_entrada re ON e.Id_Entrada = re.Id_Entrada
WHERE travel_id IS NULL
AND re.Id_Entrada IS NULL;
END IF;
-- Tickets Nulos PAK 11/10/2016
UPDATE vn2008.Tickets
SET empresa_id = 965
WHERE Id_Cliente = 31
AND empresa_id != 965;
-- Equipos duplicados
DELETE w.*
FROM vn2008.workerTeam w
JOIN (SELECT id, team, workerFk, COUNT(*) - 1 as duplicated
FROM vn.workerTeam
GROUP BY team,workerFk
HAVING duplicated
) d ON d.team = w.team AND d.workerFk = w.user AND d.id != w.id;
-- CAP 29/10/2018 Mantenimiento tabla Movimientos_componentes
DELETE mc
FROM vn2008.Movimientos_componentes mc
JOIN vn2008.Movimientos mv
ON mv.Id_Movimiento=mc.Id_Movimiento
JOIN vn2008.Tickets t
ON t.Id_Ticket= mv.Id_Ticket
WHERE t.Fecha<v_date18;
END$$
DELIMITER ;

View File

@ -0,0 +1,55 @@
DROP procedure IF EXISTS `vn`.`clean`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`clean`()
BEGIN
DECLARE vDateShort DATETIME;
DECLARE vOneYearAgo DATE;
DECLARE vFourYearsAgo DATE;
DECLARE v18Month DATE;
DECLARE v26Month DATE;
DECLARE v3Month DATE;
SET vDateShort = TIMESTAMPADD(MONTH, -2, CURDATE());
SET vOneYearAgo = TIMESTAMPADD(YEAR,-1,CURDATE());
SET vFourYearsAgo = TIMESTAMPADD(YEAR,-4,CURDATE());
SET v18Month = TIMESTAMPADD(MONTH, -18,CURDATE());
SET v26Month = TIMESTAMPADD(MONTH, -26,CURDATE());
SET v3Month = TIMESTAMPADD(MONTH, -3, CURDATE());
DELETE FROM `message` WHERE sendDate < vDateShort;
DELETE FROM messageInbox WHERE sendDate < vDateShort;
DELETE FROM messageInbox WHERE sendDate < vDateShort;
DELETE FROM workerTimeControl WHERE timed < vFourYearsAgo;
DELETE FROM itemShelving WHERE created < CURDATE() AND visible = 0;
DELETE FROM ticketDown WHERE created < TIMESTAMPADD(DAY,-1,CURDATE());
DELETE FROM entryLog WHERE creationDate < vDateShort;
DELETE FROM expedition WHERE created < v26Month;
DELETE FROM sms WHERE created < v18Month;
DELETE FROM saleTracking WHERE created < vDateShort;
DELETE tobs FROM ticketObservation tobs
JOIN ticket t ON tobs.shipped = t.id WHERE t.shipped < vDateShort;
DELETE FROM sharingCart where ended < vDateShort;
DELETE FROM sharingClient where ended < vDateShort;
DELETE tw.* FROM ticketWeekly tw
LEFT JOIN sale s ON s.ticketFk = tw.ticketFk WHERE s.itemFk IS NULL;
DELETE FROM claim WHERE ticketCreated < v18Month;
DELETE FROM message WHERE sendDate < vDateShort;
DELETE sc FROM saleChecked sc
JOIN sale s ON mc.Id_Movimiento = s.id WHERE s.created < vDateShort;
DELETE bm
FROM buyMark bm
JOIN buy b ON b.id = bm.id
JOIN entry e ON e.id = b.entryFk
JOIN travel t ON t.id = e.travelFk
WHERE t.landed <= vDateShort;
DELETE FROM stowaway WHERE created < v3Month;
CALL shelving_clean;
CALL ticketPackagingRecovery;
END$$
DELIMITER ;

View File

@ -1,3 +1,4 @@
[mysqld]
innodb_log_file_size = 4M
innodb_autoextend_increment = 4
innodb_page_size = 8K

View File

@ -36,7 +36,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-11-22 14:03:55
-- Dump completed on 2019-11-26 14:02:56
USE `account`;
-- MySQL dump 10.13 Distrib 5.7.28, for Linux (x86_64)
--
@ -94,7 +94,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-11-22 14:03:55
-- Dump completed on 2019-11-26 14:02:57
USE `salix`;
-- MySQL dump 10.13 Distrib 5.7.28, for Linux (x86_64)
--
@ -142,7 +142,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-11-22 14:03:55
-- Dump completed on 2019-11-26 14:02:57
USE `vn`;
-- MySQL dump 10.13 Distrib 5.7.28, for Linux (x86_64)
--
@ -300,54 +300,6 @@ LOCK TABLES `sample` WRITE;
INSERT INTO `sample` VALUES (1,'Carta_1','Aviso inicial por saldo deudor',0,'0'),(2,'Carta_2','Reiteracion de aviso por saldo deudor',0,'0'),(3,'Cred_Up','Notificación de aumento de crédito',0,'0'),(4,'Cred_down','Notificación de reducción de crédito',0,'0'),(5,'Pet_CC','Petición de datos bancarios B2B',0,'0'),(6,'SolCredito','Solicitud de crédito',0,'0'),(7,'LeyPago','Ley de pagos',0,'0'),(8,'Pet_CC_Core','Petición de datos bancarios CORE',0,'0'),(9,'nueva_alta','Documento de nueva alta de cliente',0,'0'),(10,'client_welcome','Email de bienvenida para nuevo cliente',0,'0'),(11,'setup_printer','Email de instalación de impresora',0,'0'),(12,'client-welcome','Email de bienvenida como nuevo cliente',1,'0'),(13,'printer-setup','Email de instalación y configuración de impresora de coronas',1,'0'),(14,'sepa-core','Email de solicitud de datos bancarios core',1,'1'),(15,'letter-debtor-st','Email de aviso inicial por saldo deudor',1,'1'),(16,'letter-debtor-nd','Email de aviso reiterado por saldo deudor',1,'1'),(17,'client-lcr','Email de solicitud de datos bancarios LCR',1,'1');
/*!40000 ALTER TABLE `sample` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-11-22 14:03:55
USE `vn2008`;
-- MySQL dump 10.13 Distrib 5.7.28, for Linux (x86_64)
--
-- Host: db.verdnatura.es Database: vn2008
-- ------------------------------------------------------
-- Server version 5.6.25-4-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Dumping data for table `accion_dits`
--
LOCK TABLES `accion_dits` WRITE;
/*!40000 ALTER TABLE `accion_dits` DISABLE KEYS */;
INSERT INTO `accion_dits` VALUES (0,'Abono del ticket'),(104,'Abre a pesar del aviso'),(81,'Abre Entrada'),(116,'Abre Margenes'),(31,'Abre ticket'),(149,'Abre traslado'),(148,'Abre travel'),(12,'Acepta envio'),(64,'Acepta envio a pesar del aviso'),(23,'Aglutinació'),(92,'Añade credito'),(112,'Añade linea'),(132,'Añade manualmente Preparacion'),(33,'Añade promoción'),(144,'Añade ticket'),(129,'Bioniza Linea'),(130,'Bioniza Lineas Ok'),(128,'Bioniza Ticket'),(133,'Borra expedition'),(63,'Borrar promoción'),(80,'Cambia'),(106,'Cambia Activo'),(119,'Cambia Agencia'),(60,'Cambia almacen'),(56,'Cambia Article'),(53,'Cambia cantidad'),(78,'Cambia Categoria'),(34,'Cambia Cliente'),(74,'Cambia Color'),(110,'Cambia Comercial'),(166,'Cambia concepto'),(137,'Cambia Conductor'),(82,'Cambia Consignatario'),(105,'Cambia Contabilizada'),(142,'Cambia Coste'),(114,'Cambia Costefijo'),(108,'Cambia crédito'),(97,'Cambia CyC'),(126,'Cambia de agencia sin eliminar la ruta'),(89,'Cambia delivered'),(98,'Cambia Descuento'),(163,'Cambia el turno'),(3,'Cambia Empresa'),(147,'Cambia etiquetas'),(107,'Cambia Factura mail'),(6,'Cambia Fecha'),(37,'Cambia forma de pago'),(122,'Cambia gestdoc_id'),(135,'Cambia grouping y lo falca'),(1,'Cambia hora'),(143,'Cambia hora fin'),(118,'Cambia Id_Agencia'),(140,'Cambia km_end'),(139,'Cambia km_start'),(90,'Cambia landing'),(79,'Cambia Medida'),(77,'Cambia Nicho'),(120,'Cambia No Vincular'),(14,'Cambia obs de:'),(141,'Cambia Ok'),(73,'Cambia Origen'),(150,'Cambia packing'),(117,'Cambia Precio'),(85,'Cambia Received'),(131,'Cambia Recibido Core VNH'),(72,'Cambia Recibido Sepa'),(161,'Cambia salario'),(86,'Cambia Shipment'),(11,'Cambia solucion'),(76,'Cambia Tallos'),(109,'Cambia Tarifa '),(13,'Cambia Tipo'),(121,'Cambia Todos a No Vincular'),(138,'Cambia Vehiculo'),(94,'Cambia Vencimiento'),(88,'Cambia Warehouse de entrada'),(87,'Cambia Warehouse de salida'),(115,'Cambiazo'),(61,'Cambio de fecha'),(93,'Cobro Web'),(32,'Crea Cliente'),(145,'Crea clon'),(83,'Crea Entrada'),(19,'Crea Promoción'),(136,'Crea Ruta'),(84,'Crea Ticket'),(51,'Crea Utilidades->Abono desde el Ticket'),(52,'CREDITO SUPERADO'),(30,'DESBLOQUEA A PESAR DEL AVISO'),(8,'Desbloquea en preparación'),(5,'Desbloquea servido'),(9,'Desmarca seguro'),(54,'Elimina'),(127,'Elimina desde traslado'),(156,'Elimina horario'),(125,'Elimina la ruta por cambio de agencia'),(167,'Elimina la ruta por cambio de consignatario'),(168,'Elimina la ruta por cambio de fecha'),(160,'Elimina precio'),(165,'Elimina ticket turno'),(153,'Elimina zona'),(22,'Eliminación ticket'),(57,'Envia por AZKAR 13 a pesar del aviso'),(68,'Envio a'),(28,'FACTURA MULTIPLE'),(29,'FACTURA RAPIDA'),(111,'Factura Serie'),(58,'FALCA PREU'),(113,'Fusion'),(36,'Genera un abono santos al ticket'),(66,'Genera una reserva santos al ticket'),(69,'Hace click en Pedido'),(20,'Hace click en Ver'),(18,'Imprime CTRL_F5'),(134,'Imprime Ctrl_F5 con credito superado'),(26,'Imprimir Albarán'),(96,'Inserta cantidad en negativo'),(155,'Inserta horario'),(158,'Inserta precio'),(164,'Inserta ticket turno'),(95,'Inserta travel'),(151,'Inserta zona'),(124,'Intenta recalcular tarifas'),(59,'LLIBERA PREU'),(4,'Marca como Servido'),(7,'Marca en preparación'),(10,'Marca seguro de verano'),(157,'Modifica horario'),(159,'Modifica precio'),(154,'Modifica zona'),(99,'No desbloquea los precios'),(103,'No especificado'),(71,'No respeta disponible'),(101,'No respeta grouping'),(100,'No respeta packing'),(123,'Recalcula tarifas'),(2,'Recalculació'),(16,'Reimprime F5'),(67,'Reimprime F5 a pesar del aviso'),(65,'Reserva santos del ticket'),(146,'Revisa Ticket desde Web'),(70,'Revisado PDA'),(50,'S\'ha utilitzat la funció Imprimir_Etiquetas del TPV'),(27,'Se envia a revision'),(91,'Se imprime split'),(15,'SMS'),(102,'Split a MERCAFLOR'),(21,'Ticket Split(Automático)'),(25,'TOUR desde ticket'),(24,'TOUR hacia ticket'),(162,'Validado'),(17,'Visualiza CTRL_F5');
/*!40000 ALTER TABLE `accion_dits` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping data for table `container`
--
LOCK TABLES `container` WRITE;
/*!40000 ALTER TABLE `container` DISABLE KEYS */;
INSERT INTO `container` VALUES (1,'atado'),(2,'bandeja'),(3,'blister'),(4,'bola'),(5,'bolsa'),(6,'bote'),(7,'botella'),(8,'bulto'),(9,'caja'),(10,'capazo'),(11,'CC'),(13,'cubo'),(14,'ejemplar'),(15,'expositor'),(16,'fardo'),(17,'full'),(18,'garba'),(21,'maceta'),(22,'macetero'),(23,'metro'),(24,'pack'),(25,'paquete'),(26,'pieza'),(27,'rollo'),(28,'saco'),(29,'set'),(30,'sobre'),(31,'tabaco'),(32,'tallo'),(33,'tubo'),(34,'vaso'),(35,'x 2 media'),(36,NULL),(37,'pallet');
/*!40000 ALTER TABLE `container` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping data for table `department`
@ -355,19 +307,9 @@ UNLOCK TABLES;
LOCK TABLES `department` WRITE;
/*!40000 ALTER TABLE `department` DISABLE KEYS */;
INSERT INTO `department` VALUES (1,'VERDNATURA',1,78,763,0,NULL,NULL,NULL,0,0,0,0),(22,'COMPRAS',65,66,NULL,72,596,2,5,0,0,1,0),(23,'CAMARA',41,42,NULL,72,604,2,6,1,0,0,0),(31,'INFORMATICA',11,12,NULL,72,127,3,9,0,0,0,0),(34,'CONTABILIDAD',4,5,NULL,0,NULL,NULL,NULL,0,0,0,0),(35,'FINANZAS',6,7,NULL,0,NULL,NULL,NULL,0,0,0,0),(36,'LABORAL',8,9,NULL,0,NULL,NULL,NULL,0,0,0,0),(37,'PRODUCCION',15,24,NULL,72,230,3,11,0,0,0,0),(38,'SACADO',20,21,NULL,72,230,4,14,1,0,0,0),(39,'ENCAJADO',22,23,NULL,72,230,4,12,1,0,0,0),(41,'ADMINISTRACION',3,10,NULL,72,599,3,8,0,0,0,0),(43,'VENTAS',51,64,NULL,0,NULL,NULL,NULL,0,0,0,0),(44,'GERENCIA',2,25,NULL,72,300,2,7,0,0,0,0),(45,'LOGISTICA',26,37,NULL,72,596,3,19,0,0,0,0),(46,'REPARTO',38,39,NULL,72,659,3,10,0,0,0,0),(48,'ALMACENAJE',40,47,NULL,0,NULL,NULL,NULL,0,0,0,0),(49,'PROPIEDAD',48,75,NULL,72,1008,1,1,0,0,0,0),(52,'CARGA AEREA',27,28,NULL,72,163,4,28,0,0,0,0),(53,'MARKETING Y COMUNICACIÓN',60,61,NULL,72,1238,0,0,0,0,0,0),(54,'ORNAMENTALES',76,77,NULL,72,433,3,21,0,0,0,0),(55,'TALLER NATURAL',68,69,NULL,72,695,2,23,0,0,0,0),(56,'TALLER ARTIFICIAL',70,71,NULL,72,1780,2,24,0,0,0,0),(58,'CAMPOS',73,74,NULL,72,225,2,2,0,0,0,0),(59,'MANTENIMIENTO',49,50,NULL,72,1907,4,16,0,0,0,0),(60,'RECLAMACIONES',58,59,NULL,72,563,3,20,0,0,0,0),(61,'VNH',35,36,NULL,73,1297,3,17,0,0,0,0),(63,'VENTAS FRANCIA',62,63,NULL,72,277,2,27,0,0,0,0),(66,'VERDNAMADRID',31,32,NULL,72,163,3,18,0,0,0,0),(68,'COMPLEMENTOS',43,44,NULL,72,617,3,26,1,0,0,0),(69,'VERDNABARNA',33,34,NULL,74,432,3,22,0,0,0,0),(77,'PALETIZADO',18,19,NULL,72,230,4,15,1,0,0,0),(80,'EQUIPO J VALLES',56,57,NULL,72,693,3,4,0,0,0,0),(86,'LIMPIEZA',13,14,NULL,72,599,0,0,0,0,0,0),(89,'COORDINACION',16,17,NULL,0,NULL,NULL,NULL,1,0,0,0),(90,'TRAILER',29,30,NULL,0,NULL,NULL,NULL,0,0,0,0),(91,'ARTIFICIAL',45,46,NULL,0,NULL,NULL,NULL,1,0,0,0),(92,'EQUIPO SILVERIO',54,55,NULL,0,NULL,NULL,NULL,0,0,0,0),(93,'CONFECCION',67,72,NULL,0,NULL,NULL,NULL,0,0,0,0),(94,'EQUIPO J BROCAL',52,53,NULL,0,NULL,NULL,NULL,0,0,1,0);
INSERT INTO `department` VALUES (1,'VERDNATURA',1,78,763,0,NULL,NULL,NULL,0,0,0,0,NULL,NULL),(22,'COMPRAS',65,66,NULL,72,596,2,5,0,0,1,0,NULL,NULL),(23,'CAMARA',41,42,NULL,72,604,2,6,1,0,0,0,NULL,NULL),(31,'INFORMATICA',11,12,NULL,72,127,3,9,0,0,0,0,NULL,NULL),(34,'CONTABILIDAD',4,5,NULL,0,NULL,NULL,NULL,0,0,0,0,NULL,NULL),(35,'FINANZAS',6,7,NULL,0,NULL,NULL,NULL,0,0,0,0,NULL,NULL),(36,'LABORAL',8,9,NULL,0,NULL,NULL,NULL,0,0,0,0,NULL,NULL),(37,'PRODUCCION',15,24,NULL,72,230,3,11,0,0,0,0,NULL,NULL),(38,'SACADO',20,21,NULL,72,230,4,14,1,0,0,0,NULL,NULL),(39,'ENCAJADO',22,23,NULL,72,230,4,12,1,0,0,0,NULL,NULL),(41,'ADMINISTRACION',3,10,NULL,72,599,3,8,0,0,0,0,NULL,NULL),(43,'VENTAS',51,64,NULL,0,NULL,NULL,NULL,0,0,0,0,NULL,NULL),(44,'GERENCIA',2,25,NULL,72,300,2,7,0,0,0,0,NULL,NULL),(45,'LOGISTICA',26,37,NULL,72,596,3,19,0,0,0,0,NULL,NULL),(46,'REPARTO',38,39,NULL,72,659,3,10,0,0,0,0,NULL,NULL),(48,'ALMACENAJE',40,47,NULL,0,NULL,NULL,NULL,0,0,0,0,NULL,NULL),(49,'PROPIEDAD',48,75,NULL,72,1008,1,1,0,0,0,0,NULL,NULL),(52,'CARGA AEREA',27,28,NULL,72,163,4,28,0,0,0,0,NULL,NULL),(53,'MARKETING Y COMUNICACIÓN',60,61,NULL,72,1238,0,0,0,0,0,0,NULL,NULL),(54,'ORNAMENTALES',76,77,NULL,72,433,3,21,0,0,0,0,NULL,NULL),(55,'TALLER NATURAL',68,69,NULL,72,695,2,23,0,0,0,0,NULL,NULL),(56,'TALLER ARTIFICIAL',70,71,NULL,72,1780,2,24,0,0,0,0,NULL,NULL),(58,'CAMPOS',73,74,NULL,72,225,2,2,0,0,0,0,NULL,NULL),(59,'MANTENIMIENTO',49,50,NULL,72,1907,4,16,0,0,0,0,NULL,NULL),(60,'RECLAMACIONES',58,59,NULL,72,563,3,20,0,0,0,0,NULL,NULL),(61,'VNH',35,36,NULL,73,1297,3,17,0,0,0,0,NULL,NULL),(63,'VENTAS FRANCIA',62,63,NULL,72,277,2,27,0,0,0,0,NULL,NULL),(66,'VERDNAMADRID',31,32,NULL,72,163,3,18,0,0,0,0,NULL,NULL),(68,'COMPLEMENTOS',43,44,NULL,72,617,3,26,1,0,0,0,NULL,NULL),(69,'VERDNABARNA',33,34,NULL,74,432,3,22,0,0,0,0,NULL,NULL),(77,'PALETIZADO',18,19,NULL,72,230,4,15,1,0,0,0,NULL,NULL),(80,'EQUIPO J VALLES',56,57,NULL,72,693,3,4,0,0,0,0,NULL,NULL),(86,'LIMPIEZA',13,14,NULL,72,599,0,0,0,0,0,0,NULL,NULL),(89,'COORDINACION',16,17,NULL,0,NULL,NULL,NULL,1,0,0,0,NULL,NULL),(90,'TRAILER',29,30,NULL,0,NULL,NULL,NULL,0,0,0,0,NULL,NULL),(91,'ARTIFICIAL',45,46,NULL,0,NULL,NULL,NULL,1,0,0,0,NULL,NULL),(92,'EQUIPO SILVERIO',54,55,NULL,0,NULL,NULL,NULL,0,0,0,0,NULL,NULL),(93,'CONFECCION',67,72,NULL,0,NULL,NULL,NULL,0,0,0,0,NULL,NULL),(94,'EQUIPO J BROCAL',52,53,NULL,0,NULL,NULL,NULL,0,0,1,0,NULL,NULL);
/*!40000 ALTER TABLE `department` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping data for table `Grupos`
--
LOCK TABLES `Grupos` WRITE;
/*!40000 ALTER TABLE `Grupos` DISABLE KEYS */;
INSERT INTO `Grupos` VALUES (1,'administrative','Contabilidad',5),(2,'administrator','Administradores',5),(3,'advancedUser','Usuarios avanzados',5),(4,'developer','Informaticos',4),(5,'clientManagement','Gestion Clientes',4),(6,'salesPerson','Comerciales',4),(7,'wages','Salarios',5),(8,'salesPersonDirector','Dir Comercial',4),(9,'advancedSalesPerson','Comercial avanzado',4),(10,'','Compradores',4),(11,'','Control descuentos',4),(12,'takeOrder','Sacador',1),(13,'packer','Encajador',2),(14,' deliveryMan','Repartidor',3),(15,'','No Recalcular',4),(17,'other','Otros',4),(18,'','Operaciones',4),(19,'','Visa',5),(20,'market','Mercado',4),(21,'','Gerencia',5),(22,'','ComercialExclusivo',4),(23,'','Responsables Entradas',5),(24,'teamBoss','Jefes de equipo',4),(25,'','Responsables Encajado',0),(26,'confection','Confeccion',0),(27,'claims','Reclamaciones',0),(28,'','Ranking Carteras Limpias',0),(29,'','No bionicos',0),(30,'','Tirar a Faltas',0),(31,'','Greuges',0),(32,'','Responsables Agencias',0),(33,'','Entradas EXPRESS',0),(34,'','Sustituciones',0),(35,'router','Enrutador',4);
/*!40000 ALTER TABLE `Grupos` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@ -378,7 +320,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-11-22 14:03:55
-- Dump completed on 2019-11-26 14:02:57
USE `bi`;
-- MySQL dump 10.13 Distrib 5.7.28, for Linux (x86_64)
--
@ -426,7 +368,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-11-22 14:03:55
-- Dump completed on 2019-11-26 14:02:57
USE `cache`;
-- MySQL dump 10.13 Distrib 5.7.28, for Linux (x86_64)
--
@ -464,7 +406,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-11-22 14:03:55
-- Dump completed on 2019-11-26 14:02:57
USE `hedera`;
-- MySQL dump 10.13 Distrib 5.7.28, for Linux (x86_64)
--
@ -522,7 +464,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-11-22 14:03:55
-- Dump completed on 2019-11-26 14:02:57
USE `postgresql`;
-- MySQL dump 10.13 Distrib 5.7.28, for Linux (x86_64)
--
@ -577,7 +519,7 @@ UNLOCK TABLES;
LOCK TABLES `professional_category` WRITE;
/*!40000 ALTER TABLE `professional_category` DISABLE KEYS */;
INSERT INTO `professional_category` VALUES (1,'Mozos',5,1,27.5),(2,'Encargados',3,1,27.5),(4,'Comprador',3,1,27.5),(5,'Aux Administracion',NULL,1,27.5),(6,'Of Administracion',3,1,27.5),(7,'Jefe Administracion',2,1,27.5),(8,'Informatico',3,1,27.5),(9,'Directivo',1,0,27.5),(10,'Aux Ventas',4,1,27.5),(11,'Vendedor',4,1,27.5),(12,'Jefe de Ventas',4,0,27.5),(13,'Repartidor',5,1,27.5),(14,'Aprendices',6,1,27.5),(15,'Técnicos',2,1,27.5),(16,'Aux Florista',5,1,27.5),(17,'Florista',4,1,27.5),(18,'Jefe Floristas',2,1,27.5),(19,'Técnico marketing',3,1,27.5),(20,'Auxiliar marketing',4,1,27.5),(21,'Aux Informática',4,1,27.5),(22,'Peón agrícola',5,1,27.5),(23,'Oficial mantenimiento',4,1,27.5),(24,'Aux mantenimiento',5,1,27.5),(25,'Mozo Aeropuerto',5,1,27.5),(26,'Coordinador',2,1,27.5),(28,'Aux Logistica',4,1,27.5),(29,'Oficial Logistica',3,1,27.5),(30,'Subencargado',4,1,27.5);
INSERT INTO `professional_category` VALUES (1,'Mozos',5,1,27.5),(2,'Encargados',3,1,27.5),(4,'Comprador',3,1,27.5),(5,'Aux Administracion',NULL,1,27.5),(6,'Of Administracion',3,1,27.5),(7,'Jefe Administracion',2,1,27.5),(8,'Informatico',3,1,27.5),(9,'Directivo',1,0,27.5),(10,'Aux Ventas',4,1,27.5),(11,'Vendedor',4,1,27.5),(12,'Jefe de Ventas',4,0,27.5),(13,'Repartidor',5,1,27.5),(14,'Aprendices',NULL,1,27.5),(15,'Técnicos',2,1,27.5),(16,'Aux Florista',5,1,27.5),(17,'Florista',4,1,27.5),(18,'Jefe Floristas',2,1,27.5),(19,'Técnico marketing',3,1,27.5),(20,'Auxiliar marketing',4,1,27.5),(21,'Aux Informática',4,1,27.5),(22,'Peón agrícola',5,1,27.5),(23,'Oficial mantenimiento',4,1,27.5),(24,'Aux mantenimiento',5,1,27.5),(25,'Mozo Aeropuerto',5,1,27.5),(26,'Coordinador',2,1,27.5),(28,'Aux Logistica',4,1,27.5),(29,'Oficial Logistica',3,1,27.5),(30,'Subencargado',4,1,27.5);
/*!40000 ALTER TABLE `professional_category` ENABLE KEYS */;
UNLOCK TABLES;
@ -610,4 +552,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-11-22 14:03:55
-- Dump completed on 2019-11-26 14:02:57

View File

@ -1,3 +1,7 @@
-- FIXME: cuando se eliminen los procedimientos de la cache, se podra eliminar esta linea
CREATE SCHEMA IF NOT EXISTS `vn2008`;
ALTER TABLE `vn`.`itemTaxCountry` AUTO_INCREMENT = 1;
ALTER TABLE `vn`.`address` AUTO_INCREMENT = 1;
ALTER TABLE `vn`.`zoneGeo` AUTO_INCREMENT = 1;
@ -17,7 +21,7 @@ INSERT INTO `vn`.`bionicConfig` (`generalInflationCoeficient`, `minimumDensityVo
INSERT INTO `account`.`user`(`id`,`name`, `nickname`, `password`,`role`,`active`,`email`, `lang`)
SELECT id, name, CONCAT(name, 'Nick'),MD5('nightmare'), id, 1, CONCAT(name, '@mydomain.com'), 'es'
FROM `account`.`role`;
FROM `account`.`role` WHERE id <> 20;
INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `userFk`, `bossFk`)
SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id, 9
@ -331,8 +335,8 @@ INSERT INTO `vn`.`clientObservation`(`id`, `clientFk`, `workerFk`, `text`, `crea
(6, 106, 5, 'My name is Legion, for we are many!', CURDATE()),
(7, 107, 9, 'I think our first move should be calling the Avengers..', CURDATE()),
(8, 108, 9, 'Just because someone stumbles and loses their path, does not mean they are lost forever.', CURDATE()),
(9, 109, 20, 'HULK SMASH! ...', CURDATE()),
(10, 110, 20, 'They say everyone is born a hero. But if you let it, life will push you over the line until you are the villain.', CURDATE());
(9, 109, 18, 'HULK SMASH! ...', CURDATE()),
(10, 110, 18, 'They say everyone is born a hero. But if you let it, life will push you over the line until you are the villain.', CURDATE());
INSERT INTO `vn`.`observationType`(`id`,`description`)
VALUES
@ -601,16 +605,16 @@ INSERT INTO `vn`.`mandate`(`id`, `clientFk`, `companyFk`, `code`, `created`, `ma
VALUES
(1, 102, 442, '1-1', CURDATE(), 2);
INSERT INTO `vn`.`itemCategory`(`id`, `name`, `display`, `color`, `icon`)
INSERT INTO `vn`.`itemCategory`(`id`, `name`, `display`, `color`, `icon`, `code`)
VALUES
(1, 'Plant', 1, 'B92A26', 'icon-plant'),
(2, 'Flower', 2, 'dcf711', 'icon-flower'),
(3, 'Logistic', 0, 'b9f711', NULL),
(4, 'Handmade', 1, NULL, 'icon-handmade'),
(5, 'Artificial', 1, NULL, 'icon-artificial'),
(6, 'Green', 1, NULL, 'icon-greenery'),
(7, 'Accessories', 1, NULL, 'icon-accessory'),
(8, 'Fruit', 1, NULL, 'icon-fruit');
(1, 'Plant', 1, 'B92A26', 'icon-plant', 'plant'),
(2, 'Flower', 2, 'dcf711', 'icon-flower', 'flower'),
(3, 'Logistic', 0, 'b9f711', NULL, 'logistical'),
(4, 'Handmade', 1, NULL, 'icon-handmade', 'handmade'),
(5, 'Artificial', 1, NULL, 'icon-artificial', 'artificial'),
(6, 'Green', 1, NULL, 'icon-greenery', 'greenery'),
(7, 'Accessories', 1, NULL, 'icon-accessory', 'accessory'),
(8, 'Fruit', 1, NULL, 'icon-fruit', 'fruit');
INSERT INTO `vn`.`itemType`(`id`, `code`, `name`, `categoryFk`, `life`,`workerFk`, `isPackaging`)
VALUES
@ -885,6 +889,11 @@ INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
(32, 36, -92.324),
(32, 39, 0.994);
INSERT INTO `vncontrol`.`accion`(`accion_id`, `accion`)
VALUES
(3, 'ACTION ONE'),
(4, 'ACTIOn TWO');
INSERT INTO `vn`.`saleTracking`(`saleFk`, `isChecked`, `created`, `originalQuantity`, `workerFk`, `actionFk`, `id`, `stateFk`)
VALUES
(1, 0, CURDATE(), 5, 55, 3, 1, 14),
@ -1356,6 +1365,7 @@ INSERT INTO `vn`.`clientContact`(`id`, `clientFk`, `name`, `phone`)
La otra manera es poner el calculo con los 2 trabajadores que utilizamos ahora mismo para los tickets
*/
call vn.manaSpellersRequery(19);
call vn.manaSpellersRequery(18);
@ -1869,7 +1879,8 @@ INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `wa
VALUES
(1, 14, '1.txt', 'text/plain', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', CURDATE()),
(2, 5, '2.txt', 'text/plain', 5, 1, 442, 1, TRUE, 'Client:104', 'Client:104 dms for the client', CURDATE()),
(3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 104', 'Client:104 readme', CURDATE());
(3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 104', 'Client:104 readme', CURDATE()),
(4, 3, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Worker: 106', 'Worker:106 readme', CURDATE());
INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`)
VALUES
@ -1880,6 +1891,10 @@ INSERT INTO `vn`.`clientDms`(`clientFk`, `dmsFk`)
(104, 2),
(104, 3);
INSERT INTO `vn`.`workerDocument`(`id`, `worker`, `document`)
VALUES
(1, 106, 4);
INSERT INTO `vn`.`device` (`sn`, `model`, `userFk`)
VALUES
('aaa', 'android', '9');
@ -1916,7 +1931,6 @@ INSERT INTO `vn`.`userPhone`(`id`, `userFk`, `typeFk`, `phone`)
(22, 17, 'personalPhone', 623111111),
(23, 18, 'personalPhone', 623111111),
(24, 19, 'personalPhone', 623111111),
(25, 20, 'personalPhone', 623111111),
(26, 21, 'personalPhone', 623111111),
(27, 22, 'personalPhone', 623111111),
(28, 30, 'personalPhone', 623111111),
@ -1955,4 +1969,5 @@ INSERT INTO `vn`.`userPhone`(`id`, `userFk`, `typeFk`, `phone`)
INSERT INTO `vn`.`workerTimeControlParams` (`id`, `dayBreak`, `weekBreak`, `weekScope`, `dayWorkMax`, `dayStayMax`)
VALUES
(1, 43200, 129600, 734400, 43200, 50400);
(1, 43200, 129600, 734400, 43200, 50400);

View File

@ -1,4 +1,3 @@
USE `vn2008`;
-- Import compiled functions
CREATE AGGREGATE FUNCTION minacum RETURNS INT SONAME 'minacum.so';

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ INI_FILE="config.production.ini"
dump_tables() {
SCHEMA=$1
echo "USE \`$SCHEMA\`;" >> "$DUMPED_FILE"
mysqldump --defaults-file="$INI_FILE" --no-create-info $@ >> "$DUMPED_FILE"
mysqldump --defaults-file="$INI_FILE" --no-create-info --skip-triggers $@ >> "$DUMPED_FILE"
}
echo "" > "$DUMPED_FILE"
@ -48,21 +48,11 @@ TABLES=(
ticketUpdateAction
state
sample
department
)
dump_tables ${TABLES[@]}
TABLES=(
vn2008
accion_dits
businessReasonEnd
container
department
Grupos
iva_group_codigo
tarifa_componentes
tarifa_componentes_series
)
dump_tables ${TABLES[@]}
TABLES=(
bi

View File

@ -14,13 +14,13 @@ SCHEMAS=(
stock
util
vn
vn2008
vncontrol
)
mysqldump \
--defaults-file=config.production.ini \
--default-character-set=utf8 \
--column-statistics=0 \
--no-data --comments \
--triggers --routines --events \
--databases \

View File

@ -1,8 +1,3 @@
<vn-crud-model auto-load="true"
url="Zones/{{$ctrl.$params.id}}/warehouses"
include="{relation: 'warehouse'}"
data="zoneWarehouses">
</vn-crud-model>
<vn-card class="summary">
<h5>#{{$ctrl.summary.id}} - {{$ctrl.summary.name}}</h5>
<vn-horizontal class="vn-pa-md">
@ -34,14 +29,14 @@
<vn-horizontal class="vn-pa-md">
<vn-auto>
<h4 translate>Warehouses</h4>
<vn-table model="model">
<vn-table model="model" auto-load="false">
<vn-thead>
<vn-tr>
<vn-th>Name</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="zoneWarehouse in zoneWarehouses">
<vn-tr ng-repeat="zoneWarehouse in $ctrl.zoneWarehouses">
<vn-td>{{zoneWarehouse.warehouse.name}}</vn-td>
</vn-tr>
</vn-tbody>

View File

@ -2,6 +2,11 @@ import ngModule from '../module';
import Component from 'core/lib/component';
class Controller extends Component {
constructor($element, $, $httpParamSerializer) {
super($element, $);
this.$httpParamSerializer = $httpParamSerializer;
}
get zone() {
return this._zone;
}
@ -12,21 +17,45 @@ class Controller extends Component {
if (!value) return;
this.getSummary();
this.getWarehouses();
}
getSummary() {
let filter = {
include: {relation: 'agencyMode', fields: ['name']},
where: {id: this.zone.id}
const params = {
filter: {
include: {
relation: 'agencyMode',
fields: ['name']
},
where: {
id: this.zone.id
}
}
};
filter = encodeURIComponent(JSON.stringify((filter)));
this.$http.get(`Zones/findOne?filter=${filter}`).then(res => {
if (res && res.data)
this.summary = res.data;
const serializedParams = this.$httpParamSerializer(params);
this.$http.get(`Zones/findOne?${serializedParams}`).then(res => {
this.summary = res.data;
});
}
getWarehouses() {
const params = {
filter: {
include: {
relation: 'warehouse',
fields: ['name']
}
}
};
const serializedParams = this.$httpParamSerializer(params);
this.$http.get(`Zones/${this.zone.id}/warehouses?${serializedParams}`).then(res => {
this.zoneWarehouses = res.data;
});
}
}
Controller.$inject = ['$element', '$scope', '$httpParamSerializer'];
ngModule.component('vnZoneSummary', {
template: require('./index.html'),
controller: Controller,

View File

@ -0,0 +1,68 @@
import './index';
describe('component vnZoneSummary', () => {
let $element;
let $scope;
let controller;
let $httpBackend;
let $httpParamSerializer;
beforeEach(ngModule('agency'));
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
$httpBackend = _$httpBackend_;
$httpParamSerializer = _$httpParamSerializer_;
$scope = $rootScope.$new();
$element = angular.element(`<vn-zone-summary></vn-zone-summary>`);
controller = $componentController('vnZoneSummary', {$element, $scope});
}));
describe('zone setter', () => {
it('should set the zone and then call both getSummary() and getWarehouses()', () => {
spyOn(controller, 'getSummary');
spyOn(controller, 'getWarehouses');
controller.zone = {id: 1};
expect(controller.getSummary).toHaveBeenCalledWith();
expect(controller.getWarehouses).toHaveBeenCalledWith();
});
});
describe('getSummary()', () => {
it('should perform a get and then store data on the controller', () => {
controller._zone = {id: 1};
let params = {
filter: {
include: {
relation: 'agencyMode',
fields: ['name']
},
where: {
id: controller._zone.id
}
}
};
const serializedParams = $httpParamSerializer(params);
const query = `Zones/findOne?${serializedParams}`;
$httpBackend.expectGET(query).respond({id: 1});
controller.getSummary();
$httpBackend.flush();
expect(controller.summary).toBeDefined();
});
});
xdescribe('getEntries()', () => {
it('should call the getEntries method to get the entries data', () => {
controller._travel = {id: 999};
const query = `/api/Travels/${controller._travel.id}/getEntries`;
$httpBackend.expectGET(query).respond('I am the entries');
controller.getEntries();
$httpBackend.flush();
expect(controller.entries).toEqual('I am the entries');
});
});
});

View File

@ -1,6 +1,6 @@
module.exports = Self => {
Self.remoteMethodCtx('removeFile', {
description: 'Removes a ticket document',
description: 'Removes a claim document',
accessType: 'WRITE',
accepts: {
arg: 'id',

View File

@ -18,8 +18,8 @@ class Controller {
this._claim = value;
// Get DMS on summary load
/* if (value)
this.$.$applyAsync(() => this.loadDms()); */
if (value)
this.$.$applyAsync(() => this.loadDms());
}
loadDms() {

View File

@ -20,7 +20,7 @@ module.exports = Self => {
Self.removeFile = async(ctx, id) => {
const models = Self.app.models;
const clientDms = await models.ClientDms.findById(id);
const clientDms = await Self.findById(id);
await models.Dms.removeFile(ctx, clientDms.dmsFk);

View File

@ -7,7 +7,7 @@ describe('Client activeWorkersWithRole', () => {
let isSalesPerson = await app.models.Account.hasRole(result[0].id, 'salesPerson');
expect(result.length).toEqual(15);
expect(result.length).toEqual(14);
expect(isSalesPerson).toBeTruthy();
});
@ -17,7 +17,7 @@ describe('Client activeWorkersWithRole', () => {
let isBuyer = await app.models.Account.hasRole(result[0].id, 'buyer');
expect(result.length).toEqual(12);
expect(result.length).toEqual(11);
expect(isBuyer).toBeTruthy();
});
});

View File

@ -6,7 +6,7 @@ describe('Client listWorkers', () => {
.then(result => {
let amountOfEmployees = Object.keys(result).length;
expect(amountOfEmployees).toEqual(50);
expect(amountOfEmployees).toEqual(49);
done();
})
.catch(done.fail);

View File

@ -49,7 +49,6 @@ module.exports = function(Self) {
let query = `SELECT vn.invoiceSerial(?, ?, ?) AS serial`;
let [result] = await Self.rawSql(query, [ticket.clientFk, ticket.companyFk, 'R'], options);
let serial = result.serial;
let stmts = [];
stmt = new ParameterizedSQL('CALL vn.invoiceOut_newFromTicket(?, ?, ?, @invoiceId)', [

View File

@ -1,6 +1,6 @@
import './index.js';
fdescribe('Ticket Component vnTicketDescriptor', () => {
describe('Ticket Component vnTicketDescriptor', () => {
let $httpParamSerializer;
let $httpBackend;
let controller;

View File

@ -25,7 +25,7 @@ module.exports = Self => {
let stmt;
stmt = new ParameterizedSQL(`
SELECT e.travelFk, e.id, e.isConfirmed, e.ref, e.notes, e.evaNotes,
SELECT e.travelFk, e.id, e.isConfirmed, e.ref, e.notes, e.evaNotes AS observation,
s.name AS supplierName,
CAST((SUM(IF(p.volume > 0,p.volume,p.width * p.depth * IF(p.height, p.height, i.size + pconfig.upperGap))
* b.stickers)/1000000)/((pcc.width*pcc.depth*pcc.height)/1000000) AS DECIMAL(10,2)) cc,

View File

@ -5,5 +5,7 @@
"dataSource": "vn"
},"TravelLog": {
"dataSource": "vn"
},"Currency": {
"dataSource": "vn"
}
}

View File

@ -0,0 +1,25 @@
{
"name": "Currency",
"base": "VnModel",
"options": {
"mysql": {
"table": "currency"
}
},
"properties": {
"id": {
"type": "Number",
"id": true,
"description": "Identifier"
},
"code": {
"type": "String"
},
"name": {
"type": "String"
},
"ratio": {
"type": "Number"
}
}
}

View File

@ -42,10 +42,10 @@
"created": {
"type": "date"
},
"evaNotes": {
"observation": {
"type": "String",
"mysql": {
"columnName": "observation"
"columnName": "evaNotes"
}
},
"isBlocked": {
@ -70,6 +70,11 @@
"type": "belongsTo",
"model": "Company",
"foreignKey": "companyFk"
},
"currency": {
"type": "belongsTo",
"model": "Currency",
"foreignKey": "currencyFk"
}
}
}

View File

@ -82,7 +82,7 @@
</vn-icon>
<vn-icon
ng-if="entry.notes.length"
vn-tooltip="{{entry.evaNotes}}"
vn-tooltip="{{entry.observation}}"
icon="insert_drive_file">
</vn-icon>
</vn-td>

View File

@ -0,0 +1,23 @@
module.exports = Self => {
Self.remoteMethodCtx('allowedContentTypes', {
description: 'Returns a list of allowed contentTypes',
accessType: 'READ',
returns: {
type: ['Object'],
root: true
},
http: {
path: `/allowedContentTypes`,
verb: 'GET'
}
});
Self.allowedContentTypes = async() => {
const storageConnector = Self.app.dataSources.storage.connector;
const allowedContentTypes = storageConnector.allowedContentTypes;
const modelAllowedContentTypes = Self.definition.settings.allowedContentTypes;
return modelAllowedContentTypes || allowedContentTypes;
};
};

View File

@ -0,0 +1,30 @@
module.exports = Self => {
Self.remoteMethodCtx('removeFile', {
description: 'Removes a worker document',
accessType: 'WRITE',
accepts: {
arg: 'id',
type: 'Number',
description: 'The document id',
http: {source: 'path'}
},
returns: {
type: 'Object',
root: true
},
http: {
path: `/:id/removeFile`,
verb: 'POST'
}
});
Self.removeFile = async(ctx, id) => {
const models = Self.app.models;
const workerDms = await Self.findById(id);
await models.Dms.removeFile(ctx, workerDms.dmsFk);
return workerDms.destroy();
};
};

View File

@ -0,0 +1,18 @@
const app = require('vn-loopback/server/server');
describe('WorkerDms removeFile()', () => {
const workerDmsFk = 1;
it(`should return an error for a user without enough privileges`, async() => {
let clientId = 101;
let ctx = {req: {accessToken: {userId: clientId}}};
let error;
await app.models.WorkerDms.removeFile(ctx, workerDmsFk).catch(e => {
error = e;
}).finally(() => {
expect(error.message).toEqual(`You don't have enough privileges`);
});
expect(error).toBeDefined();
});
});

View File

@ -0,0 +1,19 @@
const app = require('vn-loopback/server/server');
describe('Worker uploadFile()', () => {
it(`should return an error for a user without enough privileges`, async() => {
let workerId = 106;
let currentUserId = 102;
let hhrrDataId = 3;
let ctx = {req: {accessToken: {userId: currentUserId}}, args: {dmsTypeId: hhrrDataId}};
let error;
await app.models.Worker.uploadFile(ctx, workerId).catch(e => {
error = e;
}).finally(() => {
expect(error.message).toEqual(`You don't have enough privileges`);
});
expect(error).toBeDefined();
});
});

View File

@ -0,0 +1,76 @@
module.exports = Self => {
Self.remoteMethodCtx('uploadFile', {
description: 'Upload and attach a file to a client',
accessType: 'WRITE',
accepts: [{
arg: 'id',
type: 'Number',
description: 'The worker id',
http: {source: 'path'}
}, {
arg: 'warehouseId',
type: 'Number',
description: 'The warehouse id',
required: true
}, {
arg: 'companyId',
type: 'Number',
description: 'The company id',
required: true
}, {
arg: 'dmsTypeId',
type: 'Number',
description: 'The dms type id',
required: true
}, {
arg: 'reference',
type: 'String',
required: true
}, {
arg: 'description',
type: 'String',
required: true
}, {
arg: 'hasFile',
type: 'Boolean',
description: 'True if has an attached file',
required: true
}],
returns: {
type: 'Object',
root: true
},
http: {
path: `/:id/uploadFile`,
verb: 'POST'
}
});
Self.uploadFile = async(ctx, id) => {
const models = Self.app.models;
const promises = [];
const tx = await Self.beginTransaction({});
try {
const options = {transaction: tx};
const uploadedFiles = await models.Dms.uploadFile(ctx, options);
uploadedFiles.forEach(dms => {
const newWorkerDms = models.WorkerDms.create({
workerFk: id,
dmsFk: dms.id
}, options);
promises.push(newWorkerDms);
});
const resolvedPromises = await Promise.all(promises);
await tx.commit();
return resolvedPromises;
} catch (err) {
await tx.rollback();
throw err;
}
};
};

View File

@ -20,6 +20,9 @@
"WorkCenterHoliday": {
"dataSource": "vn"
},
"WorkerDms": {
"dataSource": "vn"
},
"Worker": {
"dataSource": "vn"
},

View File

@ -0,0 +1,4 @@
module.exports = Self => {
require('../methods/worker-dms/removeFile')(Self);
require('../methods/worker-dms/allowedContentTypes')(Self);
};

View File

@ -0,0 +1,47 @@
{
"name": "WorkerDms",
"base": "Loggable",
"log": {
"model":"ClientLog",
"relation": "worker",
"showField": "dmsFk"
},
"options": {
"mysql": {
"table": "workerDocument"
}
},
"properties": {
"id": {
"type": "Number",
"id": true
},
"dmsFk": {
"type": "Number",
"required": true,
"mysql": {
"columnName": "document"
}
},
"workerFk": {
"type": "Number",
"required": true,
"mysql": {
"columnName": "worker"
}
}
},
"relations": {
"worker": {
"type": "belongsTo",
"model": "Worker",
"foreignKey": "workerFk"
},
"dms": {
"type": "belongsTo",
"model": "Dms",
"foreignKey": "dmsFk"
}
}
}

View File

@ -3,4 +3,5 @@ module.exports = Self => {
require('../methods/worker/mySubordinates')(Self);
require('../methods/worker/isSubordinate')(Self);
require('../methods/worker/getWorkedHours')(Self);
require('../methods/worker/uploadFile')(Self);
};

View File

@ -0,0 +1,83 @@
<mg-ajax path="dms/upload" options="vnPost"></mg-ajax>
<vn-watcher
vn-id="watcher"
data="$ctrl.dms">
</vn-watcher>
<form
name="form"
ng-submit="$ctrl.onSubmit()"
class="vn-ma-md"
enctype="multipart/form-data">
<div class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-horizontal>
<vn-textfield
vn-one
vn-focus
label="Reference"
ng-model="$ctrl.dms.reference"
rule>
</vn-textfield>
<vn-autocomplete vn-one
label="Company"
ng-model="$ctrl.dms.companyId"
url="Companies"
show-field="code"
value-field="id">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one
label="Warehouse"
ng-model="$ctrl.dms.warehouseId"
url="Warehouses"
show-field="name"
value-field="id">
</vn-autocomplete>
<vn-autocomplete vn-one
label="Type"
ng-model="$ctrl.dms.dmsTypeId"
url="DmsTypes"
show-field="name"
value-field="id">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-textarea
vn-one
label="Description"
ng-model="$ctrl.dms.description"
rule>
</vn-textarea>
</vn-horizontal>
<vn-horizontal>
<vn-input-file
vn-one
label="File"
ng-model="$ctrl.dms.files"
on-change="$ctrl.onFileChange($files)"
accept="{{$ctrl.allowedContentTypes}}"
required="true"
multiple="true">
<append>
<vn-icon vn-none
color-marginal
title="{{$ctrl.contentTypesInfo}}"
icon="info">
</vn-icon>
</append>
</vn-input-file>
</vn-horizontal>
<vn-vertical>
<vn-check
label="Generate identifier for original file"
ng-model="$ctrl.dms.hasFile">
</vn-check>
</vn-vertical>
</vn-card>
<vn-button-bar>
<vn-submit label="Upload"></vn-submit>
<vn-button ui-sref="worker.card.dms.index" label="Cancel"></vn-button>
</vn-button-bar>
</div>
</form>

View File

@ -0,0 +1,114 @@
import ngModule from '../../module';
import Component from 'core/lib/component';
import './style.scss';
class Controller extends Component {
constructor($element, $, vnConfig) {
super($element, $);
this.vnConfig = vnConfig;
this.dms = {
files: [],
hasFile: false,
hasFileAttached: false
};
}
get worker() {
return this._worker;
}
set worker(value) {
this._worker = value;
if (value) {
this.setDefaultParams();
this.getAllowedContentTypes();
}
}
getAllowedContentTypes() {
this.$http.get('workerDms/allowedContentTypes').then(res => {
const contentTypes = res.data.join(', ');
this.allowedContentTypes = contentTypes;
});
}
get contentTypesInfo() {
return this.$translate.instant('ContentTypesInfo', {
allowedContentTypes: this.allowedContentTypes
});
}
setDefaultParams() {
const params = {filter: {
where: {code: 'hhrrData'}
}};
this.$http.get('DmsTypes/findOne', {params}).then(res => {
const dmsType = res.data && res.data;
const companyId = this.vnConfig.companyFk;
const warehouseId = this.vnConfig.warehouseFk;
const defaultParams = {
reference: this.worker.id,
warehouseId: warehouseId,
companyId: companyId,
dmsTypeId: dmsType.id,
description: this.$translate.instant('WorkerFileDescription', {
dmsTypeName: dmsType.name,
workerId: this.worker.id,
workerName: this.worker.name
}).toUpperCase()
};
this.dms = Object.assign(this.dms, defaultParams);
});
}
onSubmit() {
const query = `Workers/${this.worker.id}/uploadFile`;
const options = {
method: 'POST',
url: query,
params: this.dms,
headers: {
'Content-Type': undefined
},
transformRequest: files => {
const formData = new FormData();
for (let i = 0; i < files.length; i++)
formData.append(files[i].name, files[i]);
return formData;
},
data: this.dms.files
};
this.$http(options).then(res => {
if (res) {
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
this.$.watcher.updateOriginalData();
this.$state.go('worker.card.dms.index');
}
});
}
onFileChange(files) {
let hasFileAttached = false;
if (files.length > 0)
hasFileAttached = true;
this.$.$applyAsync(() => {
this.dms.hasFileAttached = hasFileAttached;
});
}
}
Controller.$inject = ['$element', '$scope', 'vnConfig'];
ngModule.component('vnWorkerDmsCreate', {
template: require('./index.html'),
controller: Controller,
bindings: {
worker: '<'
}
});

View File

@ -0,0 +1,77 @@
import './index';
describe('Client', () => {
describe('Component vnWorkerDmsCreate', () => {
let $element;
let controller;
let $scope;
let $httpBackend;
let $httpParamSerializer;
beforeEach(ngModule('worker'));
beforeEach(angular.mock.inject(($compile, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
$scope = $rootScope.$new();
$httpBackend = _$httpBackend_;
$httpParamSerializer = _$httpParamSerializer_;
$element = $compile(`<vn-worker-dms-create></vn-worker-dms-create>`)($rootScope);
controller = $element.controller('vnWorkerDmsCreate');
controller._worker = {id: 101, name: 'Bruce wayne'};
}));
describe('worker() setter', () => {
it('should set the worker data and then call setDefaultParams() and getAllowedContentTypes()', () => {
spyOn(controller, 'setDefaultParams');
spyOn(controller, 'getAllowedContentTypes');
controller.worker = {
id: 15,
name: 'Bruce wayne'
};
expect(controller.worker).toBeDefined();
expect(controller.setDefaultParams).toHaveBeenCalledWith();
expect(controller.getAllowedContentTypes).toHaveBeenCalledWith();
});
});
describe('setDefaultParams()', () => {
it('should perform a GET query and define the dms property on controller', () => {
$httpBackend.whenRoute('GET', `DmsTypes`).respond({id: 12, code: 'hhrrData'});
const params = {filter: {
where: {code: 'hhrrData'}
}};
let serializedParams = $httpParamSerializer(params);
$httpBackend.when('GET', `DmsTypes/findOne?${serializedParams}`).respond({id: 12, code: 'hhrrData'});
controller.setDefaultParams();
$httpBackend.flush();
expect(controller.dms).toBeDefined();
expect(controller.dms.reference).toEqual(101);
expect(controller.dms.dmsTypeId).toEqual(12);
});
});
describe('onFileChange()', () => {
it('should set dms hasFileAttached property to true if has any files', () => {
const files = [{id: 1, name: 'MyFile'}];
controller.onFileChange(files);
$scope.$apply();
expect(controller.dms.hasFileAttached).toBeTruthy();
});
});
describe('getAllowedContentTypes()', () => {
it('should make an HTTP GET request to get the allowed content types', () => {
const expectedResponse = ['image/png', 'image/jpg'];
$httpBackend.when('GET', `workerDms/allowedContentTypes`).respond(expectedResponse);
$httpBackend.expect('GET', `workerDms/allowedContentTypes`);
controller.getAllowedContentTypes();
$httpBackend.flush();
expect(controller.allowedContentTypes).toBeDefined();
expect(controller.allowedContentTypes).toEqual('image/png, image/jpg');
});
});
});
});

View File

@ -0,0 +1,7 @@
vn-ticket-request {
.vn-textfield {
margin: 0!important;
max-width: 100px;
}
}

View File

@ -0,0 +1,82 @@
<vn-watcher
vn-id="watcher"
data="$ctrl.dms">
</vn-watcher>
<form
name="form"
ng-submit="$ctrl.onSubmit()"
class="vn-ma-md"
enctype="multipart/form-data">
<div class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-horizontal>
<vn-textfield
vn-one
vn-focus
label="Reference"
ng-model="$ctrl.dms.reference"
rule>
</vn-textfield>
<vn-autocomplete vn-one required="true"
label="Company"
ng-model="$ctrl.dms.companyId"
url="Companies"
show-field="code"
value-field="id">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one required="true"
label="Warehouse"
ng-model="$ctrl.dms.warehouseId"
url="Warehouses"
show-field="name"
value-field="id">
</vn-autocomplete>
<vn-autocomplete vn-one required="true"
label="Type"
ng-model="$ctrl.dms.dmsTypeId"
url="DmsTypes"
show-field="name"
value-field="id">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-textarea
vn-one
required="true"
label="Description"
ng-model="$ctrl.dms.description"
rule>
</vn-textarea>
</vn-horizontal>
<vn-horizontal>
<vn-input-file
vn-one
label="File"
ng-model="$ctrl.dms.files"
on-change="$ctrl.onFileChange($files)"
accept="{{$ctrl.allowedContentTypes}}"
multiple="true">
<append>
<vn-icon vn-none
color-marginal
title="{{$ctrl.contentTypesInfo}}"
icon="info">
</vn-icon>
</append>
</vn-input-file>
</vn-horizontal>
<vn-vertical>
<vn-check disabled="true"
label="Generate identifier for original file"
ng-model="$ctrl.dms.hasFile">
</vn-check>
</vn-vertical>
</vn-card>
<vn-button-bar>
<vn-submit label="Save"></vn-submit>
<vn-button ui-sref="worker.card.dms.index" label="Cancel"></vn-button>
</vn-button-bar>
</div>
</form>

View File

@ -0,0 +1,94 @@
import ngModule from '../../module';
import Component from 'core/lib/component';
import './style.scss';
class Controller extends Component {
get worker() {
return this._worker;
}
set worker(value) {
this._worker = value;
if (value) {
this.setDefaultParams();
this.getAllowedContentTypes();
}
}
getAllowedContentTypes() {
this.$http.get('WorkerDms/allowedContentTypes').then(res => {
const contentTypes = res.data.join(', ');
this.allowedContentTypes = contentTypes;
});
}
get contentTypesInfo() {
return this.$translate.instant('ContentTypesInfo', {
allowedContentTypes: this.allowedContentTypes
});
}
setDefaultParams() {
const path = `Dms/${this.$params.dmsId}`;
this.$http.get(path).then(res => {
const dms = res.data && res.data;
this.dms = {
reference: dms.reference,
warehouseId: dms.warehouseFk,
companyId: dms.companyFk,
dmsTypeId: dms.dmsTypeFk,
description: dms.description,
hasFile: dms.hasFile,
hasFileAttached: false,
files: []
};
});
}
onSubmit() {
const query = `dms/${this.$params.dmsId}/updateFile`;
const options = {
method: 'POST',
url: query,
params: this.dms,
headers: {
'Content-Type': undefined
},
transformRequest: files => {
const formData = new FormData();
for (let i = 0; i < files.length; i++)
formData.append(files[i].name, files[i]);
return formData;
},
data: this.dms.files
};
this.$http(options).then(res => {
if (res) {
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
this.$.watcher.updateOriginalData();
this.$state.go('worker.card.dms.index');
}
});
}
onFileChange(files) {
let hasFileAttached = false;
if (files.length > 0)
hasFileAttached = true;
this.$.$applyAsync(() => {
this.dms.hasFileAttached = hasFileAttached;
});
}
}
ngModule.component('vnWorkerDmsEdit', {
template: require('./index.html'),
controller: Controller,
bindings: {
worker: '<'
}
});

View File

@ -0,0 +1,84 @@
import './index';
describe('Worker', () => {
describe('Component vnClientDmsEdit', () => {
let controller;
let $scope;
let $element;
let $httpBackend;
beforeEach(ngModule('worker'));
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => {
$scope = $rootScope.$new();
$httpBackend = _$httpBackend_;
$element = angular.element(`<vn-worker-dms-edit></vn-worker-dms-edit`);
controller = $componentController('vnWorkerDmsEdit', {$element, $scope});
controller._worker = {id: 106};
controller.$params = {dmsId: 4};
}));
describe('worker() setter', () => {
it('should set the worker data and then call setDefaultParams() and getAllowedContentTypes()', () => {
spyOn(controller, 'setDefaultParams');
spyOn(controller, 'getAllowedContentTypes');
controller._worker = undefined;
controller.worker = {
id: 106
};
expect(controller.setDefaultParams).toHaveBeenCalledWith();
expect(controller.worker).toBeDefined();
expect(controller.getAllowedContentTypes).toHaveBeenCalledWith();
});
});
describe('setDefaultParams()', () => {
it('should perform a GET query and define the dms property on controller', () => {
const dmsId = 4;
const expectedResponse = {
reference: 101,
warehouseFk: 1,
companyFk: 442,
dmsTypeFk: 3,
description: 'Test',
hasFile: false,
hasFileAttached: false
};
$httpBackend.when('GET', `Dms/${dmsId}`).respond(expectedResponse);
$httpBackend.expect('GET', `Dms/${dmsId}`).respond(expectedResponse);
controller.setDefaultParams();
$httpBackend.flush();
expect(controller.dms).toBeDefined();
expect(controller.dms.reference).toEqual(101);
expect(controller.dms.dmsTypeId).toEqual(3);
});
});
describe('onFileChange()', () => {
it('should set dms hasFileAttached property to true if has any files', () => {
const files = [{id: 1, name: 'MyFile'}];
controller.dms = {hasFileAttached: false};
controller.onFileChange(files);
$scope.$apply();
expect(controller.dms.hasFileAttached).toBeTruthy();
});
});
describe('getAllowedContentTypes()', () => {
it('should make an HTTP GET request to get the allowed content types', () => {
const expectedResponse = ['image/png', 'image/jpg'];
$httpBackend.when('GET', `WorkerDms/allowedContentTypes`).respond(expectedResponse);
$httpBackend.expect('GET', `WorkerDms/allowedContentTypes`);
controller.getAllowedContentTypes();
$httpBackend.flush();
expect(controller.allowedContentTypes).toBeDefined();
expect(controller.allowedContentTypes).toEqual('image/png, image/jpg');
});
});
});
});

View File

@ -0,0 +1,7 @@
vn-ticket-request {
.vn-textfield {
margin: 0!important;
max-width: 100px;
}
}

View File

@ -0,0 +1,117 @@
<vn-crud-model
vn-id="model"
url="WorkerDms"
link="{workerFk: $ctrl.$params.id}"
filter="::$ctrl.filter"
limit="20"
data="$ctrl.workerDms"
order="dmsFk DESC"
auto-load="true">
</vn-crud-model>
<vn-data-viewer
model="model"
class="vn-w-lg">
<vn-card>
<vn-table model="model">
<vn-thead>
<vn-tr>
<vn-th field="dmsFk" shrink>Id</vn-th>
<vn-th field="dmsTypeFk" shrink>Type</vn-th>
<vn-th field="hardCopyNumber" shrink number>Order</vn-th>
<vn-th field="reference" shrink>Reference</vn-th>
<vn-th expand>Description</vn-th>
<vn-th field="hasFile" shrink>Original</vn-th>
<vn-th shrink>File</vn-th>
<vn-th shrink>Employee</vn-th>
<vn-th field="created">Created</vn-th>
<vn-th shrink></vn-th>
<vn-th shrink></vn-th>
<vn-th shrink></vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="document in $ctrl.workerDms">
<vn-td number shrink>{{::document.dmsFk}}</vn-td>
<vn-td shrink>
<span title="{{::document.dms.dmsType.name}}">
{{::document.dms.dmsType.name}}
</span>
</vn-td>
<vn-td shrink number>
<span class="chip" title="{{::document.dms.hardCopyNumber}}"
ng-class="{'message': document.dms.hardCopyNumber}">
{{::document.dms.hardCopyNumber}}
</span>
</vn-td>
<vn-td shrink>
<span title="{{::document.dms.reference}}">
{{::document.dms.reference}}
</span>
</vn-td>
<vn-td expand>
<span title="{{::document.dms.description}}">
{{::document.dms.description}}
</span>
</vn-td>
<vn-td shrink>
<vn-check disabled="true"
ng-model="document.dms.hasFile">
</vn-check>
</vn-td>
<vn-td shrink>
<a target="_blank"
title="{{'Download file' | translate}}"
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}">{{::document.dms.file}}
</a>
</vn-td>
<vn-td shrink>
<span class="link"
ng-click="$ctrl.showWorkerDescriptor($event, document.dms.workerFk)">
{{::document.dms.worker.user.nickname | dashIfEmpty}}
</span></vn-td>
<vn-td>
{{::document.dms.created | date:'dd/MM/yyyy HH:mm'}}
</vn-td>
<vn-td shrink>
<a target="_blank"
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}">
<vn-icon-button
icon="cloud_download"
title="{{'Download file' | translate}}">
</vn-icon-button>
</a>
</vn-td>
<vn-td shrink>
<vn-icon-button ui-sref="worker.card.dms.edit({dmsId: {{::document.dmsFk}}})"
icon="edit"
title="{{'Edit file' | translate}}">
</vn-icon-button>
</vn-td>
<vn-td shrink>
<vn-icon-button
icon="delete"
ng-click="$ctrl.showDeleteConfirm($index)"
title="{{'Remove file' | translate}}"
tabindex="-1">
</vn-icon-button>
</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-card>
</vn-data-viewer>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>
<a ui-sref="worker.card.dms.create"
vn-tooltip="Upload file"
vn-bind="+"
fixed-bottom-right>
<vn-float-button icon="add"></vn-float-button>
</a>
<vn-confirm
vn-id="confirm"
message="This file will be deleted"
question="Are you sure you want to continue?"
on-response="$ctrl.deleteDms($response)">
</vn-confirm>

View File

@ -0,0 +1,76 @@
import ngModule from '../../module';
import Component from 'core/lib/component';
import './style.scss';
class Controller extends Component {
constructor($element, $, vnToken) {
super($element, $);
this.accessToken = vnToken.token;
this.filter = {
include: {
relation: 'dms',
scope: {
fields: [
'dmsTypeFk',
'reference',
'hardCopyNumber',
'workerFk',
'description',
'hasFile',
'file',
'created',
],
include: [{
relation: 'dmsType',
scope: {
fields: ['name']
}
},
{
relation: 'worker',
scope: {
fields: ['userFk'],
include: {
relation: 'user',
scope: {
fields: ['nickname']
}
},
}
}]
},
}
};
}
showWorkerDescriptor(event, workerFk) {
event.preventDefault();
event.stopImmediatePropagation();
this.$.workerDescriptor.parent = event.target;
this.$.workerDescriptor.workerFk = workerFk;
this.$.workerDescriptor.show();
}
showDeleteConfirm(index) {
this.dmsIndex = index;
this.$.confirm.show();
}
deleteDms(response) {
if (response === 'accept') {
const dmsFk = this.workerDms[this.dmsIndex].dmsFk;
const query = `WorkerDms/${dmsFk}/removeFile`;
this.$http.post(query).then(() => {
this.$.model.remove(this.dmsIndex);
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
});
}
}
}
Controller.$inject = ['$element', '$scope', 'vnToken'];
ngModule.component('vnWorkerDmsIndex', {
template: require('./index.html'),
controller: Controller,
});

View File

@ -0,0 +1,42 @@
import './index';
import crudModel from 'core/mocks/crud-model';
describe('Worker', () => {
describe('Component vnWorkerDmsIndex', () => {
let $componentController;
let $scope;
let $element;
let $httpBackend;
let controller;
beforeEach(ngModule('worker'));
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_) => {
$componentController = _$componentController_;
$httpBackend = _$httpBackend_;
$scope = $rootScope.$new();
$element = angular.element(`<vn-worker-dms-index></vn-worker-dms-index`);
controller = $componentController('vnWorkerDmsIndex', {$element, $scope});
controller.$.model = crudModel;
}));
describe('deleteDms()', () => {
it('should make an HTTP Post query', () => {
const dmsId = 4;
const dmsIndex = 0;
spyOn(controller.vnApp, 'showSuccess');
spyOn(controller.$.model, 'remove');
controller.workerDms = [{dmsFk: 4}];
controller.dmsIndex = dmsIndex;
$httpBackend.when('POST', `WorkerDms/${dmsId}/removeFile`).respond({});
$httpBackend.expect('POST', `WorkerDms/${dmsId}/removeFile`);
controller.deleteDms('accept');
$httpBackend.flush();
expect(controller.$.model.remove).toHaveBeenCalledWith(dmsIndex);
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
});
});
});
});

View File

@ -0,0 +1,9 @@
Type: Tipo
File management: Gestión documental
File: Fichero
Hard copy: Copia
This file will be deleted: Este fichero va a ser borrado
Are you sure?: Estas seguro?
File deleted: Fichero eliminado
Remove file: Eliminar fichero
Download file: Descargar fichero

View File

@ -0,0 +1,6 @@
vn-client-risk-index {
.totalBox {
display: table;
float: right;
}
}

View File

@ -0,0 +1,2 @@
ClientFileDescription: "{{dmsTypeName}} from client {{clientName}} id {{clientId}}"
ContentTypesInfo: Allowed file types {{allowedContentTypes}}

View File

@ -0,0 +1,20 @@
Reference: Referencia
Description: Descripción
Company: Empresa
Upload file: Subir fichero
Edit file: Editar fichero
Upload: Subir
File: Fichero
WorkerFileDescription: "{{dmsTypeName}} del empleado {{workerName}} id {{workerId}}"
ContentTypesInfo: "Tipos de archivo permitidos: {{allowedContentTypes}}"
Generate identifier for original file: Generar identificador para archivo original
Are you sure you want to continue?: ¿Seguro que quieres continuar?
File management: Gestión documental
Hard copy: Copia
This file will be deleted: Este fichero va a ser borrado
Are you sure?: ¿Seguro?
File deleted: Fichero eliminado
Remove file: Eliminar fichero
Download file: Descargar fichero
Created: Creado
Employee: Empleado

View File

@ -14,3 +14,6 @@ import './calendar';
import './time-control';
import './log';
import './phones';
import './dms/index';
import './dms/create';
import './dms/edit';

View File

@ -13,7 +13,8 @@
{"state": "worker.card.pbx", "icon": "icon-pbx"},
{"state": "worker.card.calendar", "icon": "icon-calendar"},
{"state": "worker.card.timeControl", "icon": "access_time"},
{"state": "worker.card.phones", "icon": "contact_phone"}
{"state": "worker.card.phones", "icon": "contact_phone"},
{"state": "worker.card.dms.index", "icon": "cloud_upload"}
]
},
"routes": [
@ -89,6 +90,36 @@
"params": {
"worker": "$ctrl.worker"
}
},
{
"url": "/dms",
"state": "worker.card.dms",
"abstract": true,
"component": "ui-view"
},
{
"url": "/index",
"state": "worker.card.dms.index",
"component": "vn-worker-dms-index",
"description": "File management"
},
{
"url": "/create",
"state": "worker.card.dms.create",
"component": "vn-worker-dms-create",
"description": "Upload file",
"params": {
"worker": "$ctrl.worker"
}
},
{
"url": "/:dmsId/edit",
"state": "worker.card.dms.edit",
"component": "vn-worker-dms-edit",
"description": "Edit file",
"params": {
"worker": "$ctrl.worker"
}
}
]
}

View File

@ -4,7 +4,7 @@
*/
.grid {
font-family: Helvetica, Arial, sans-serif;
font-family: Arial, sans-serif;
font-size: 16px !important;
width: 100%
}

View File

@ -1,4 +1,5 @@
// Import global filters
require('./date');
require('./uppercase');
require('./currency');
require('./percentage');

View File

@ -0,0 +1,5 @@
const Vue = require('vue');
Vue.filter('uppercase', function(value) {
return value.toUpperCase();
});

View File

@ -0,0 +1,8 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/spacing.css`,
`${appPath}/common/css/misc.css`,
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/email.css`])
.mergeStyles();

View File

@ -0,0 +1,6 @@
[
{
"filename": "campaing-metrics",
"component": "campaign-metrics"
}
]

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html v-bind:lang="locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-lg">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p>{{$t('description')}}</p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,23 @@
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
module.exports = {
name: 'campaign-metrics',
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
props: {
clientId: {
required: true
},
from: {
required: true
},
to: {
required: true
}
}
};

View File

@ -0,0 +1,7 @@
subject: Informe consumo campaña
title: Informe consumo campaña
dear: Estimado cliente
description: Con motivo de esta próxima campaña, me complace
relacionarle a continuación el consumo que nos consta en su cuenta para las
mismas fechas del año pasado. Espero le sea de utilidad para preparar su pedido.
Al mismo tiempo aprovecho la ocasión para saludarle cordialmente.

View File

@ -0,0 +1,9 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/spacing.css`,
`${appPath}/common/css/misc.css`,
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -0,0 +1,11 @@
.column-oriented {
margin-top: 50px !important;
}
.bottom-line > tr {
border-bottom: 1px solid #ccc;
}
.bottom-line tr:nth-last-child() {
border-bottom: none;
}

View File

@ -0,0 +1,100 @@
<!DOCTYPE html>
<html v-bind:lang="locale">
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
<div class="columns">
<div class="size50">
<h1 class="title uppercase">{{$t('title')}}</h1>
<div class="size75">
<table class="row-oriented">
<tbody>
<tr>
<td class="font gray">{{$t('Client')}}</td>
<th>{{client.id}}</th>
</tr>
<tr>
<td class="font gray">{{$t('From')}}</td>
<th>{{from | date('%d-%m-%Y')}}</th>
</tr>
<tr>
<td class="font gray">{{$t('To')}}</td>
<th>{{to | date('%d-%m-%Y')}}</th>
</tr>
</tbody>
</table>
</div>
</div>
<div class="size50">
<div class="panel">
<div class="header">{{$t('clientData')}}</div>
<div class="body">
<h3 class="uppercase">{{client.socialName}}</h3>
<div>
{{client.street}}
</div>
<div>
{{client.postcode}}, {{client.city}} ({{client.province}})
</div>
<div>
{{client.country}}
</div>
</div>
</div>
</div>
</div>
<table class="column-oriented">
<thead>
<tr>
<th class="number">{{$t('Code')}}</th>
<th class="number">{{$t('Quantity')}}</th>
<th>{{$t('Concept')}}</th>
</tr>
</thead>
<tbody class="row-oriented bottom-line">
<tr v-for="sale in sales">
<td class="number">{{sale.itemFk}}</td>
<td class="number">{{Math.trunc(sale.subtotal)}}</td>
<td>
{{sale.concept}} <span class="font gray">{{sale.subName | uppercase}}</span>
<section>
<span class="font gray">{{sale.tag5}}</span>
<span>{{sale.value5}}</span>
<span class="font gray">{{sale.tag6}}</span>
<span>{{sale.value6}}</span>
<span class="font gray">{{sale.tag7}}</span>
<span>{{sale.value7}}</span>
</section>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<report-footer id="pageFooter"
v-bind:left-text="$t('client', [client.id])"
v-bind:center-text="client.socialName"
v-bind="$props">
</report-footer>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,78 @@
const Component = require(`${appPath}/core/component`);
const db = require(`${appPath}/core/database`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
module.exports = {
name: 'campaign-metrics',
async serverPrefetch() {
this.to = new Date(this.to);
this.from = new Date(this.from);
this.client = await this.fetchClient(this.clientId);
this.sales = await this.fetchSales(this.clientId, this.from, this.to);
if (!this.client)
throw new Error('Something went wrong');
},
methods: {
fetchClient(clientId) {
return db.findOne(
`SELECT
c.street,
c.socialName,
c.city,
c.postcode,
c.id,
c.name AS clientName,
p.name AS province,
co.country
FROM client c
JOIN province p ON c.provinceFk = p.id
JOIN country co ON c.countryFk = co.id
WHERE
c.id = ?`, [clientId]);
},
fetchSales(clientId, from, to) {
return db.rawSql(
`SELECT
SUM(s.quantity) AS subtotal,
s.itemFk,
s.concept,
i.subName,
i.tag5,
i.value5,
i.tag6,
i.value6,
i.tag7,
i.value7
FROM sale s
JOIN ticket t ON t.id = s.ticketFk
JOIN item i ON i.id = s.itemFk
JOIN itemType it ON it.id = i.typeFk
WHERE
t.clientFk = ? AND it.isPackaging = FALSE
AND DATE(t.shipped) BETWEEN ? AND ?
GROUP BY s.itemFk
ORDER BY i.typeFk , i.name , i.size`, [clientId, from, to]);
},
},
components: {
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
},
props: {
clientId: {
required: true
},
from: {
required: true,
type: Date
},
to: {
required: true,
type: Date
}
}
};

View File

@ -0,0 +1,11 @@
title: Consumo de campaña
Client: Cliente
clientData: Datos del cliente
dated: Fecha
From: Desde
To: Hasta
client: Cliente {0}
Code: Código
Quantity: Cantidad
Stems: Tallos
Concept: Concepto