Merge branch 'dev' of verdnatura/salix into test
gitea/salix/test This commit looks good Details

This commit is contained in:
Joan Sanchez 2019-12-13 14:26:32 +00:00 committed by Gitea
commit 29f437d716
171 changed files with 10140 additions and 51173 deletions

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
FROM mysql:5.6.42 FROM mysql:8.0.18
ENV MYSQL_ROOT_PASSWORD root ENV MYSQL_ROOT_PASSWORD root
ENV TZ Europe/Madrid ENV TZ Europe/Madrid
@ -7,36 +7,33 @@ ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y --no-install-recommends curl ca-certificates \ && apt-get install -y --no-install-recommends curl ca-certificates \
&& curl -sL https://apt.verdnatura.es/conf/verdnatura.gpg | apt-key add - \ && curl -sL https://apt.verdnatura.es/conf/verdnatura.gpg | apt-key add - \
&& echo "deb http://apt.verdnatura.es/ jessie main" > /etc/apt/sources.list.d/vn.list \ && echo "deb http://apt.verdnatura.es/ stretch main" > /etc/apt/sources.list.d/vn.list \
&& apt-get update \ && apt-get update \
&& apt-get install -y --allow-unauthenticated vn-mysql \ && apt-get install -y vn-mysql libmysqlclient21 \
&& apt-get purge -y --auto-remove curl ca-certificates \ && apt-get purge -y --auto-remove curl ca-certificates \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# XXX: Removes the last script line to avoid daemon to be started COPY docker/docker.cnf /etc/mysql/conf.d/
RUN cp /usr/local/bin/docker-entrypoint.sh /usr/local/bin/docker-init.sh \ COPY docker/docker-init.sh docker/docker-start.sh /usr/local/bin/
&& sed -i '$ d' /usr/local/bin/docker-init.sh
WORKDIR /docker-entrypoint-initdb.d
ARG STAMP=unknown
COPY import-changes.sh config.ini /docker-entrypoint-initdb.d/import/
COPY docker.cnf /etc/mysql/mysql.conf.d/
COPY changes /docker-entrypoint-initdb.d/import/changes
COPY docker-boot.sh /docker-entrypoint-initdb.d/
COPY dump /docker-entrypoint-initdb.d/dump
RUN mkdir /mysql-data \ RUN mkdir /mysql-data \
&& /usr/local/bin/docker-init.sh mysqld --datadir /mysql-data \ && chown -R mysql:mysql /mysql-data
&& chown -R mysql:mysql /mysql-data \
WORKDIR /docker-entrypoint-initdb.d
COPY dump dump
COPY docker/docker-boot.sh /docker-entrypoint-initdb.d/
COPY changes import/changes
COPY import-changes.sh config.ini import/
ARG STAMP=unknown
RUN gosu mysql docker-init.sh mysqld \
&& rm -rf /docker-entrypoint-initdb.d/* && rm -rf /docker-entrypoint-initdb.d/*
COPY docker-start.sh /usr/local/bin/ USER mysql
ENTRYPOINT ["docker-start.sh"] ENTRYPOINT ["docker-start.sh"]
USER mysql CMD ["mysqld"]
CMD ["mysqld", "--datadir", "/mysql-data"]
#HEALTHCHECK --interval=5s --timeout=10s --retries=200 \ #HEALTHCHECK --interval=5s --timeout=10s --retries=200 \
# CMD mysqladmin ping -h 127.0.0.1 -u root || exit 1 # CMD mysqladmin ping -h 127.0.0.1 -u root || exit 1

View File

@ -7,7 +7,7 @@ CREATE DEFINER=`root`@`%` PROCEDURE `zone_getWarehouse`(vAddress INT, vLanded DA
BEGIN BEGIN
/** /**
* Devuelve el listado de agencias disponibles para la fecha, * Devuelve el listado de agencias disponibles para la fecha,
* dirección y warehouse pasadas * dirección y almacén pasados.
* *
* @param vAddress * @param vAddress
* @param vWarehouse warehouse * @param vWarehouse warehouse
@ -30,7 +30,8 @@ BEGIN
JOIN agencyMode am ON am.id = z.agencyModeFk JOIN agencyMode am ON am.id = z.agencyModeFk
JOIN zoneWarehouse zw ON zw.zoneFk = zo.zoneFk JOIN zoneWarehouse zw ON zw.zoneFk = zo.zoneFk
WHERE zw.warehouseFk WHERE zw.warehouseFk
GROUP BY z.agencyModeFk; GROUP BY z.agencyModeFk
ORDER BY agencyMode;
DROP TEMPORARY TABLE DROP TEMPORARY TABLE
tmp.zone, tmp.zone,

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; UPDATE vn.department SET lft = NULL, rgt = NULL;

View File

@ -1,5 +1,5 @@
CREATE TABLE `vn`.`travelLog` ( CREATE TABLE `vn`.`travelLog` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`originFk` int(10) unsigned NOT NULL, `originFk` int(10) unsigned NOT NULL,
`userFk` int(10) unsigned DEFAULT NULL, `userFk` int(10) unsigned DEFAULT NULL,
`action` set('insert','update','delete') COLLATE utf8_unicode_ci NOT NULL, `action` set('insert','update','delete') COLLATE utf8_unicode_ci NOT NULL,
@ -13,6 +13,6 @@ CREATE TABLE `vn`.`travelLog` (
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `originFk` (`originFk`), KEY `originFk` (`originFk`),
KEY `userFk` (`userFk`), KEY `userFk` (`userFk`),
CONSTRAINT `travelLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `travelLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `vn`.`travel` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `travelLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE CONSTRAINT `travelLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

View File

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

View File

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

View File

@ -36,7 +36,7 @@ BEGIN
CALL vn.zone_getShippedWarehouse(vlanded, vAddressFk, vAgencyModeFk); CALL vn.zone_getShippedWarehouse(vlanded, vAddressFk, vAgencyModeFk);
SELECT id INTO vZoneFk FROM tmp.zoneGetShipped SELECT zoneFk INTO vZoneFk FROM tmp.zoneGetShipped
WHERE shipped = vShipped AND warehouseFk = vWarehouseFk LIMIT 1; WHERE shipped = vShipped AND warehouseFk = vWarehouseFk LIMIT 1;
INSERT INTO vn2008.Tickets ( INSERT INTO vn2008.Tickets (

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

@ -0,0 +1,51 @@
DROP TRIGGER IF EXISTS `vn`.`client_beforeUpdate`;
DELIMITER $$
CREATE DEFINER=`root`@`%` TRIGGER `vn`.`client_beforeUpdate`
BEFORE UPDATE ON `client`
FOR EACH ROW
BEGIN
DECLARE vText VARCHAR(255) DEFAULT NULL;
-- Comprueba que el formato de los teléfonos es válido
IF !(NEW.phone <=> OLD.phone) THEN
CALL pbx.phone_isValid(NEW.phone);
END IF;
IF !(NEW.mobile <=> OLD.mobile) THEN
CALL pbx.phone_isValid(NEW.mobile);
END IF;
IF !(NEW.fax <=> OLD.fax) THEN
CALL pbx.phone_isValid(NEW.fax);
END IF;
IF NEW.payMethodFk = 4 AND NEW.dueDay = 0 THEN
SET NEW.dueDay = 5;
END IF;
-- Avisar al comercial si ha llegado la documentación sepa/core
IF NEW.hasSepaVnl AND !OLD.hasSepaVnl THEN
SET vText = 'Sepa de VNL';
END IF;
IF NEW.hasCoreVnl AND !OLD.hasCoreVnl THEN
SET vText = 'Core de VNL';
END IF;
IF vText IS NOT NULL
THEN
INSERT INTO mail(sender, replyTo, `subject`, body)
SELECT
CONCAT(IF(ac.id,u.name, 'jgallego'), '@verdnatura.es'),
'administracion@verdnatura.es',
CONCAT('Cliente ', NEW.id),
CONCAT('Recibida la documentación: ', vText)
FROM worker w
LEFT JOIN account.user u ON w.userFk = u.id AND u.active
LEFT JOIN account.account ac ON ac.id = u.id
WHERE w.id = NEW.salesPersonFk;
END IF;
END$$
DELIMITER ;

View File

@ -62,7 +62,7 @@ BEGIN
UNION ALL UNION ALL
SELECT g.amount SELECT g.amount
FROM greuge g FROM greuge g
JOIN client c ON c.id = g.clientFk JOIN `client` c ON c.id = g.clientFk
WHERE g.greugeTypeFk = vManaGreugeType WHERE g.greugeTypeFk = vManaGreugeType
AND g.shipped > vFromDated AND g.shipped > vFromDated
AND g.shipped <= CURDATE() AND g.shipped <= CURDATE()

View File

@ -0,0 +1,97 @@
DROP procedure IF EXISTS `vn`.`clientPackagingOverstock`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`clientPackagingOverstock`(vClientFk INT, vGraceDays INT )
BEGIN
DROP TEMPORARY TABLE IF EXISTS tmp.clientPackagingOverstock;
CREATE TEMPORARY TABLE tmp.clientPackagingOverstock
ENGINE = MEMORY
SELECT itemFk,
sum(GotfromClient) - sum(SenttoClient) as devueltos,
sum(InvoicedtoClient) - sum(InvoicedfromClient) as facturados,
LEAST(
sum(GotfromClient) - sum(SenttoClient),
sum(InvoicedtoClient) - sum(InvoicedfromClient)
) as abonables
FROM
(
SELECT t.*,
IF(@month = month, 0, 1) monthEnd,
@month := month
FROM
(
SELECT x.id as ticketFk,
date(x.shipped) as shipped,
x.itemFk,
IFNULL(cast(sum(x.InvoicedtoClient) as DECIMAL(10,0)),0) InvoicedtoClient,
IFNULL(cast(sum(x.InvoicedfromClient) as DECIMAL(10,0)),0) InvoicedfromClient,
IFNULL(cast(sum(x.SenttoClient) as DECIMAL(10,0)),0) SenttoClient,
IFNULL(cast(sum(x.GotfromClient) as DECIMAL(10,0)),0) GotfromClient,
i.name as concept,
x.refFk as invoice,
month(shipped) month,
x.companyFk
FROM
(
SELECT t.id,
t.shipped,
IFNULL(pe.equivalentFk, s.itemFk) itemFk,
IF(s.quantity > 0, s.quantity, NULL) InvoicedtoClient,
IF(s.quantity < 0, -s.quantity, NULL) InvoicedfromClient,
NULL SenttoClient,
NULL GotfromClient,
t.refFk,
@month := 0 month,
t.companyFk
FROM sale s
JOIN ticket t on t.id = s.ticketFk
JOIN packaging p ON p.itemFk = s.itemFk
LEFT JOIN packageEquivalentItem pe ON pe.itemFk = s.itemFk
WHERE t.clientFk = vClientFk
AND t.shipped > '2017-11-30'
AND p.isPackageReturnable
UNION ALL
SELECT NULL,
'2017-11-30',
IFNULL(pe.equivalentFk, tps.itemFk) itemFk,
tps.sent InvoicedtoClient,
tps.returned InvoicedfromClient,
NULL SenttoClient,
NULL GotfromClient,
'Histórico',
NULL,
NULL
FROM ticketPackagingStartingStock tps
LEFT JOIN packageEquivalentItem pe ON pe.itemFk = tps.itemFk
WHERE tps.clientFk = vClientFk
AND tps.isForgetable = FALSE
UNION ALL
SELECT t.id,
t.shipped,
IFNULL(pe.equivalentFk, p.itemFk) itemFk,
NULL,
NULL,
IF(tp.quantity > 0 AND t.shipped <= TIMESTAMPADD(DAY, - vGraceDays, CURDATE()), tp.quantity, NULL) SenttoClient,
IF(tp.quantity < 0, -tp.quantity, NULL) GotfromClient,
NULL AS refFk,
NULL,
t.companyFk
FROM ticketPackaging tp
JOIN ticket t on t.id = tp.ticketFk
JOIN packaging p ON p.id = tp.packagingFk
LEFT JOIN packageEquivalentItem pe ON pe.itemFk = p.itemFk
WHERE t.clientFk = vClientFk
AND t.shipped > '2017-11-21' ) x
JOIN item i ON x.itemFk = i.id
GROUP BY x.id, x.itemFk
) t
ORDER BY itemFk, shipped DESC
) t2
GROUP BY itemFk;
END$$
DELIMITER ;

View File

@ -0,0 +1,132 @@
DROP procedure IF EXISTS `vn`.`clonTravelComplete`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`clonTravelComplete`(IN `vTravelFk` INT, IN `vDateStart` DATE, IN `vDateEnd` DATE, IN `vRef` VARCHAR(255))
BEGIN
DECLARE vTravelNew INT;
DECLARE vEntryNew INT;
DECLARE vDone BIT DEFAULT 0;
DECLARE vAuxEntryFk INT;
DECLARE vRsEntry CURSOR FOR
SELECT e.id
FROM entry e
JOIN travel t
ON t.id = e.travelFk
WHERE e.travelFk = vTravelFk;
DECLARE vRsBuy CURSOR FOR
SELECT b.*
FROM buy b
JOIN entry e
ON b.entryFk = e.id
WHERE e.travelFk = vTravelNew and b.entryFk=entryNew
ORDER BY e.id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
INSERT INTO travel (shipped,landed, warehouseInFk, warehouseOutFk, agencyFk, ref, isDelivered, isReceived, m3, kg)
SELECT vDateStart, vDateEnd,warehouseInFk, warehouseOutFk, agencyFk, vRef, isDelivered, isReceived, m3, kg
FROM travel
WHERE id = vTravelFk;
SET vTravelNew = LAST_INSERT_ID();
SET vDone = 0;
OPEN vRsEntry ;
FETCH vRsEntry INTO vAuxEntryFk;
WHILE NOT vDone DO
INSERT INTO entry (supplierFk,
ref,
isInventory,
isConfirmed,
isOrdered,
isRaid,
commission,
created,
evaNotes,
travelFk,
currencyFk,
companyFk,
gestDocFk,
invoiceInFk)
SELECT supplierFk,
ref,
isInventory,
isConfirmed,
isOrdered,
isRaid,
commission,
created,
evaNotes,
vTravelNew,
currencyFk,
companyFk,
gestDocFk,
invoiceInFk
FROM entry
WHERE id = vAuxEntryFk;
SET vEntryNew = LAST_INSERT_ID();
INSERT INTO buy (entryFk,
itemFk,
quantity,
buyingValue,
packageFk,
stickers,
freightValue,
packageValue,
comissionValue,
packing,
`grouping`,
groupingMode,
location,
price1,
price2,
price3,
minPrice,
producer,
printedStickers,
isChecked)
SELECT vEntryNew,
itemFk,
quantity,
buyingValue,
packageFk,
stickers,
freightValue,
packageValue,
comissionValue,
packing,
`grouping`,
groupingMode,
location,
price1,
price2,
price3,
minPrice,
producer,
printedStickers,
isChecked
FROM buy
WHERE entryFk = vAuxEntryFk;
FETCH vRsEntry INTO vAuxEntryFk;
END WHILE;
CLOSE vRsEntry;
COMMIT;
END$$
DELIMITER ;

View File

@ -0,0 +1,16 @@
DELIMITER $$
DROP TRIGGER IF EXISTS `vn`.`creditClassification_BEFORE_UPDATE` $$
CREATE DEFINER=`root`@`%` TRIGGER `vn`.`creditClassification_beforeUpdate` BEFORE UPDATE ON `creditClassification` FOR EACH ROW
BEGIN
IF NEW.client <> OLD.client THEN
CALL util.throw('NOT_ALLOWED_CHANGE_CLIENT');
END IF;
IF NEW.dateEnd IS NOT NULL AND OLD.dateEnd IS NULL THEN
UPDATE `client` c
SET creditInsurance = 0 WHERE c.id = NEW.client;
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,13 @@
DELIMITER $$
DROP TRIGGER IF EXISTS `vn`.`creditInsurance_AFTER_INSERT` $$
CREATE DEFINER=`root`@`%` TRIGGER `vn`.`creditInsurance_afterInsert` AFTER INSERT ON `creditInsurance` FOR EACH ROW
BEGIN
UPDATE `client` c
JOIN vn.creditClassification cc ON cc.client = c.id
SET creditInsurance = NEW.credit WHERE cc.id = NEW.creditClassification;
END$$
DELIMITER ;

View File

@ -0,0 +1,74 @@
DROP procedure IF EXISTS `vn`.`duaInvoiceInBooking`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`duaInvoiceInBooking`(vDuaFk INT)
BEGIN
DECLARE done BOOL DEFAULT FALSE;
DECLARE vInvoiceFk INT;
DECLARE vASIEN BIGINT DEFAULT 0;
DECLARE vCounter INT DEFAULT 0;
DECLARE rs CURSOR FOR
SELECT e.invoiceInFk
FROM entry e
JOIN duaEntry de ON de.entryFk = e.id
JOIN invoiceIn ii ON ii.id = e.invoiceInFk
WHERE de.duaFk = vDuaFk
AND de.customsValue
AND ii.isBooked = FALSE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN rs;
UPDATE invoiceIn ii
JOIN entry e ON e.invoiceInFk = ii.id
JOIN duaEntry de ON de.entryFk = e.id
JOIN dua d ON d.id = de.duaFk
SET ii.isBooked = TRUE,
ii.booked = IFNULL(ii.booked,d.booked),
ii.operated = IFNULL(ii.operated,d.operated),
ii.issued = IFNULL(ii.issued,d.issued),
ii.bookEntried = IFNULL(ii.bookEntried,d.bookEntried),
e.isConfirmed = TRUE
WHERE d.id = vDuaFk;
SELECT IFNULL(ASIEN,0) INTO vASIEN
FROM dua
WHERE id = vDuaFk;
FETCH rs INTO vInvoiceFk;
WHILE NOT done DO
CALL invoiceInBookingMain(vInvoiceFk);
IF vCounter > 0 OR vASIEN > 0 THEN
UPDATE XDiario x
JOIN config c ON c.ASIEN = x.ASIEN
SET x.ASIEN = vASIEN;
ELSE
SELECT ASIEN INTO vASIEN FROM config;
END IF;
SET vCounter = vCounter + 1;
FETCH rs INTO vInvoiceFk;
END WHILE;
CLOSE rs;
UPDATE dua
SET ASIEN = vASIEN
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

@ -0,0 +1,41 @@
DROP procedure IF EXISTS `vn`.`rangeDateInfo`;
DELIMITER $$
CREATE PROCEDURE `vn`.`rangeDateInfo` (vStarted DATE, vEnded DATE)
BEGIN
/**
* Crea una tabla temporal con las fechas
* desde una fecha inicial a una final
* @param vStarted fecha inicial
* @param vEnded fecha final
*/
DECLARE vDated DATE DEFAULT vStarted;
DROP TEMPORARY TABLE IF EXISTS tmp.rangeDate;
CREATE TEMPORARY TABLE tmp.rangeDate(
`dated` DATE,
`period` INT,
`month` INT,
`year` INT,
`day` INT,
`week` INT,
`yearMonth` INT
)
ENGINE = MEMORY;
WHILE vDated <= vEnded DO
INSERT INTO tmp.rangeDate
SET `dated` = vDated,
`period` = YEAR(vDated) * 100 + WEEK(vDated, 1),
`month` = MONTH(vDated),
`year` = YEAR(vDated),
`day` = DAY(vDated),
`week` = WEEK(vDated, 1),
`yearMonth` = YEAR(vDated) * 100 + MONTH(vDated);
SET vDated = DATE_ADD(vDated, INTERVAL 1 DAY);
END WHILE;
END$$
DELIMITER ;

View File

@ -1,4 +1,3 @@
USE `vn`;
ALTER TABLE `vn`.`ticketRequest` ALTER TABLE `vn`.`ticketRequest`
DROP FOREIGN KEY `fgnAtender`; DROP FOREIGN KEY `fgnAtender`;
@ -10,44 +9,12 @@ ADD CONSTRAINT `fgnAtender`
REFERENCES `vn`.`worker` (`id`) REFERENCES `vn`.`worker` (`id`)
ON UPDATE CASCADE; 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`; DROP TRIGGER IF EXISTS `vn`.`ticketRequest_beforeInsert`;
DELIMITER $$ DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` TRIGGER `vn`.`ticketRequest_beforeInsert` BEFORE INSERT ON `ticketRequest` FOR EACH ROW CREATE DEFINER=`root`@`%` TRIGGER `vn`.`ticketRequest_beforeInsert` BEFORE INSERT ON `ticketRequest` FOR EACH ROW
BEGIN BEGIN
IF NEW.ticketFk IS NULL THEN IF NEW.ticketFk IS NULL THEN
@ -68,7 +35,6 @@ DELIMITER ;
DROP TRIGGER IF EXISTS `vn`.`ticketRequest_beforeUpdate`; DROP TRIGGER IF EXISTS `vn`.`ticketRequest_beforeUpdate`;
DELIMITER $$ DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` TRIGGER `vn`.`ticketRequest_beforeUpdate` BEFORE UPDATE ON `ticketRequest` FOR EACH ROW CREATE DEFINER=`root`@`%` TRIGGER `vn`.`ticketRequest_beforeUpdate` BEFORE UPDATE ON `ticketRequest` FOR EACH ROW
BEGIN BEGIN
IF NEW.saleFk <> OLD.saleFk THEN IF NEW.saleFk <> OLD.saleFk THEN
@ -85,24 +51,4 @@ BEGIN
END$$ END$$
DELIMITER ; 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,41 @@
DROP procedure IF EXISTS `vn`.`timeControl_calculate`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`timeControl_calculate`(vDatedFrom DATETIME, vDatedTo DATETIME)
BEGIN
SET @vIsOdd := TRUE;
SET @vUser := NULL;
SET @vDated := NULL;
DROP TEMPORARY TABLE IF EXISTS tmp.timeControlCalculate;
CREATE TEMPORARY TABLE tmp.timeControlCalculate
SELECT userFk,
dated,
IF( timeWork >= 18000, @timeWork:=timeWork + 1200, @timeWork:=timeWork) timeWorkSeconds,
SEC_TO_TIME(@timeWork ) timeWorkSexagesimal,
@timeWork / 3600 timeWorkDecimal
FROM (SELECT SUM(timeWork) timeWork,
userFk,
dated
FROM (SELECT IF(@vUser = wtc.userFk, @vUser :=@vUser, @vUser := wtc.userFk ),
IF(@vIsOdd, @vIsOdd := FALSE, @vIsOdd := TRUE ),
IF(direction='in', @vIsOdd := TRUE, @vIsOdd := @vIsOdd ),
IF(@vIsOdd, @vLastTimed:=UNIX_TIMESTAMP(timed),@vLastTimed:=@vLastTimed),
IF(@vIsOdd, 0, UNIX_TIMESTAMP(timed)-@vLastTimed) timeWork,
IF(direction='in', @vDated := DATE(wtc.timed), @vDated :=@vDated) dated,
wtc.userFk,
wtc.timed timed,
direction
FROM workerTimeControl wtc
JOIN tmp.`user` w ON w.userFk = wtc.userFk
WHERE wtc.timed BETWEEN vDatedFrom AND vDatedTo
ORDER BY userFk, timed
) sub
GROUP BY userFk, dated
ORDER BY userFk, dated
)sub2;
END$$
DELIMITER ;

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,96 @@
DROP procedure IF EXISTS `vn`.`timeBusiness_calculate`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`timeBusiness_calculate`(vDatedFrom DATETIME, vDatedTo DATETIME)
BEGIN
/**
* Horas que debe trabajar un empleado según contrato y día.
* @param vDatedFrom workerTimeControl
* @param vDatedTo workerTimeControl
* @table tmp.user(userFk)
* @return tmp.timeBusinessCalculate
*/
DECLARE vHoursFullTime INT DEFAULT 40;
DROP TEMPORARY TABLE IF EXISTS tmp.timeBusinessCalculate;
DROP TEMPORARY TABLE IF EXISTS tmp.businessFullTime;
CALL rangeDateInfo(vDatedFrom, vDatedTo);
CREATE TEMPORARY TABLE tmp.timeBusinessCalculate
SELECT dated,
businessFk,
userFk,
departmentFk,
hourStart,
hourEnd,
timeWorkSeconds,
SEC_TO_TIME(timeWorkSeconds) timeWorkSexagesimal,
timeWorkSeconds / 3600 timeWorkDecimal,
timeWorkSeconds timeBusinessSeconds,
SEC_TO_TIME(timeWorkSeconds) timeBusinessSexagesimal,
timeWorkSeconds / 3600 timeBusinessDecimal,
type,
permissionrate,
hoursWeek
FROM(SELECT rd.dated,
b.business_id businessFk,
w.userFk,
bl.department_id departmentFk,
IF(cl.hours_week = vHoursFullTime, NULL, GROUP_CONCAT(DISTINCT LEFT(j.start,2) ORDER BY j.start ASC SEPARATOR '-')) hourStart ,
IF(cl.hours_week = vHoursFullTime, NULL, GROUP_CONCAT(DISTINCT LEFT(j.end,2) ORDER BY j.end ASC SEPARATOR '-')) hourEnd,
IF(cl.hours_week = vHoursFullTime, 0, IFNULL(SUM(TIME_TO_SEC(j.end)) - SUM(TIME_TO_SEC(j.start)),0)) timeWorkSeconds,
cs.type,
cs.permissionRate,
cl.hours_week hoursWeek
FROM tmp.rangeDate rd
LEFT JOIN postgresql.business b ON rd.dated BETWEEN b.date_start AND ifnull(b.date_end, vDatedTo )
LEFT JOIN postgresql.profile AS pr ON b.client_id = pr.profile_id
LEFT JOIN postgresql.person AS p ON pr.person_id = p.person_id
LEFT JOIN vn.worker AS w ON p.id_trabajador = w.id
JOIN tmp.`user` u ON u.userFK = w.userFK
JOIN postgresql.business_labour AS bl ON b.business_id = bl.business_id
LEFT JOIN postgresql.business_labour_payroll AS bp ON bl.business_id = bp.business_id
LEFT JOIN postgresql.professional_category AS pc ON bl.professional_category_id = pc.professional_category_id
LEFT JOIN postgresql.workcenter AS wc ON bl.workcenter_id = wc.workcenter_id
LEFT JOIN postgresql.calendar_labour_type AS cl ON bl.calendar_labour_type_id = cl.calendar_labour_type_id
LEFT JOIN postgresql.journey AS j ON j.business_id = b.business_id and j.day_id=WEEKDAY(rd.dated)+1
LEFT JOIN postgresql.calendar_employee ce ON ce.business_id=b.business_id and ce.date = rd.dated
LEFT JOIN postgresql.calendar_state cs ON cs.calendar_state_id = ce.calendar_state_id
WHERE rd.dated BETWEEN vDatedFrom AND vDatedTo
GROUP BY w.userFk,dated
)sub;
UPDATE tmp.timeBusinessCalculate t
SET t.timeWorkSeconds = vHoursFullTime / 5 * 3600,
t.timeWorkSexagesimal = SEC_TO_TIME( vHoursFullTime / 5 * 3600),
t.timeWorkDecimal = vHoursFullTime / 5,
t.timeBusinessSeconds = vHoursFullTime / 5 * 3600,
t.timeBusinessSexagesimal = SEC_TO_TIME( vHoursFullTime / 5 * 3600),
t.timeBusinessDecimal = vHoursFullTime / 5
WHERE DAYOFWEEK(t.dated) IN(2,3,4,5,6) AND hoursWeek = vHoursFullTime ;
UPDATE tmp.timeBusinessCalculate t
SET t.timeWorkSeconds = t.timeWorkSeconds - (t.timeWorkSeconds * permissionrate) ,
t.timeWorkSexagesimal = SEC_TO_TIME(t.timeWorkSeconds - (t.timeWorkSeconds * permissionrate)),
t.timeWorkDecimal = t.timeWorkDecimal - (t.timeWorkDecimal * permissionrate)
WHERE permissionrate <> 0;
UPDATE tmp.timeBusinessCalculate t
JOIN postgresql.calendar_labour cl ON cl.day = t.dated
JOIN postgresql.business_labour bl ON bl.business_id = t.businessFk AND bl.workcenter_id = cl.workcenter_id
SET t.timeWorkSeconds = 0,
t.timeWorkSexagesimal = 0,
t.timeWorkDecimal = 0,
t.permissionrate = 1,
t.type = 'Festivo'
WHERE t.type IS NULL;
DROP TEMPORARY TABLE IF EXISTS tmp.rangeDate;
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,86 @@
DROP procedure IF EXISTS `hedera`.`tpvTransaction_undo`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`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

@ -1,3 +0,0 @@
[mysqld]
innodb_log_file_size = 4M
innodb_autoextend_increment = 4

17
db/docker/docker-init.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
. /usr/local/bin/docker-entrypoint.sh
mysql_check_config "$@"
docker_setup_env "$@"
docker_create_db_directories
docker_verify_minimum_env
docker_init_database_dir "$@"
docker_temp_server_start "$@"
docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/*
mysql_expire_root_user
docker_temp_server_stop

10
db/docker/docker.cnf Normal file
View File

@ -0,0 +1,10 @@
[mysqld]
innodb_log_file_size = 4M
innodb_autoextend_increment = 4
innodb_page_size = 8K
innodb_default_row_format = COMPACT
log_bin_trust_function_creators = ON
datadir = /mysql-data
sql_mode = NO_ENGINE_SUBSTITUTION
innodb_temp_data_file_path = /tmp/ibtmp1:12M:autoextend
skip-log-bin

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,13 @@
-- FIXME: cuando se eliminen los procedimientos de la cache, se podra eliminar esta linea
CREATE SCHEMA IF NOT EXISTS `vn2008`;
CREATE SCHEMA IF NOT EXISTS `tmp`;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
ALTER TABLE `vn`.`itemTaxCountry` AUTO_INCREMENT = 1; ALTER TABLE `vn`.`itemTaxCountry` AUTO_INCREMENT = 1;
ALTER TABLE `vn`.`address` AUTO_INCREMENT = 1; ALTER TABLE `vn`.`address` AUTO_INCREMENT = 1;
ALTER TABLE `vn`.`zoneGeo` AUTO_INCREMENT = 1; ALTER TABLE `vn`.`zoneGeo` AUTO_INCREMENT = 1;
ALTER TABLE `vn`.`ticket` AUTO_INCREMENT = 1;
INSERT INTO `vn`.`ticketConfig` (`id`, `scopeDays`) INSERT INTO `vn`.`ticketConfig` (`id`, `scopeDays`)
VALUES VALUES
@ -14,10 +21,9 @@ INSERT INTO `vn`.`bionicConfig` (`generalInflationCoeficient`, `minimumDensityVo
VALUES VALUES
(1.30, 167.00, 138000, 71); (1.30, 167.00, 138000, 71);
INSERT INTO `account`.`user`(`id`,`name`, `nickname`, `password`,`role`,`active`,`email`, `lang`) 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' 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`) INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `userFk`, `bossFk`)
SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id, 9 SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id, 9
@ -261,7 +267,7 @@ INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `pr
(121, 'address 21', 'the bat cave', 'Silla', 46460, 1, 1111111111, 222222222, 1, 101, 2, NULL, NULL, 0, 0), (121, 'address 21', 'the bat cave', 'Silla', 46460, 1, 1111111111, 222222222, 1, 101, 2, NULL, NULL, 0, 0),
(122, 'address 22', 'NY roofs', 'Silla', 46460, 1, 1111111111, 222222222, 1, 102, 2, NULL, NULL, 0, 0), (122, 'address 22', 'NY roofs', 'Silla', 46460, 1, 1111111111, 222222222, 1, 102, 2, NULL, NULL, 0, 0),
(123, 'address 23', 'The phone box', 'Silla', 46460, 1, 1111111111, 222222222, 1, 103, 2, NULL, NULL, 0, 0), (123, 'address 23', 'The phone box', 'Silla', 46460, 1, 1111111111, 222222222, 1, 103, 2, NULL, NULL, 0, 0),
(124, 'address 24', 'Stark tower', 'Silla', 46460, 1, 1111111111, 222222222, 1, 104, 2, NULL, NULL, 0, 0), (124, 'address 24', 'Stark tower Silla', 'Silla', 46460, 1, 1111111111, 222222222, 1, 104, 2, NULL, NULL, 0, 0),
(125, 'address 25', 'The plastic cell', 'Silla', 46460, 1, 1111111111, 222222222, 1, 105, 2, NULL, NULL, 0, 0), (125, 'address 25', 'The plastic cell', 'Silla', 46460, 1, 1111111111, 222222222, 1, 105, 2, NULL, NULL, 0, 0),
(126, 'address 26', 'Many places', 'Silla', 46460, 1, 1111111111, 222222222, 1, 106, 2, NULL, NULL, 0, 0), (126, 'address 26', 'Many places', 'Silla', 46460, 1, 1111111111, 222222222, 1, 106, 2, NULL, NULL, 0, 0),
(127, 'address 27', 'Your pocket', 'Silla', 46460, 1, 1111111111, 222222222, 1, 107, 2, NULL, NULL, 0, 0), (127, 'address 27', 'Your pocket', 'Silla', 46460, 1, 1111111111, 222222222, 1, 107, 2, NULL, NULL, 0, 0),
@ -331,8 +337,8 @@ INSERT INTO `vn`.`clientObservation`(`id`, `clientFk`, `workerFk`, `text`, `crea
(6, 106, 5, 'My name is Legion, for we are many!', CURDATE()), (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()), (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()), (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()), (9, 109, 18, '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()); (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`) INSERT INTO `vn`.`observationType`(`id`,`description`)
VALUES VALUES
@ -361,7 +367,7 @@ INSERT INTO `vn`.`creditInsurance`(`id`, `creditClassification`, `credit`, `crea
(2, 2, 6000, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), NULL), (2, 2, 6000, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), NULL),
(3, 3, 10000, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), NULL); (3, 3, 10000, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), NULL);
INSERT INTO `vn2008`.`empresa_grupo`(`empresa_grupo_id`, `grupo`) INSERT INTO `vn`.`companyGroup`(`id`, `code`)
VALUES VALUES
(1, 'Wayne Industries'); (1, 'Wayne Industries');
@ -554,14 +560,18 @@ INSERT INTO `vn`.`stowaway`(`id`, `shipFk`, `created`)
VALUES VALUES
(12, 13, CURDATE()); (12, 13, CURDATE());
INSERT INTO `vn`.`vehicle`(`id`, `numberPlate`, `tradeMark`, `model`, `companyFk`, `warehouseFk`, `description`, `m3`, `isActive`) INSERT INTO `vn`.`deliveryPoint` (`id`, `name`, `ubication`)
VALUES VALUES
(1, '3333-BAT', 'WAYNE INDUSTRIES', 'BATMOBILE', 442, 1, 'The ultimate war machine', 50, 1), (1, 'Silla','46460 Av Espioca 100-Silla');
(2, '1111-IMK', 'STARK INDUSTRIES', 'MARK-III', 442, 1, 'Iron-Man Heavy Armor MARK-III', 18, 1),
(3, '2222-IMK', 'STARK INDUSTRIES', 'MARK-VI', 442, 1, 'Iron-Man Heavy Armor MARK-VI', 16, 1), INSERT INTO `vn`.`vehicle`(`id`, `numberPlate`, `tradeMark`, `model`, `companyFk`, `warehouseFk`, `description`, `m3`, `isActive`, `deliveryPointFk`)
(4, '3333-IMK', 'STARK INDUSTRIES', 'MARK-VII', 442, 1, 'Iron-Man Heavy Armor MARK-VII', 14, 1), VALUES
(5, '4444-IMK', 'STARK INDUSTRIES', 'MARK-XLII', 442, 1, 'Iron-Man Heavy Armor MARK-XLII', 13, 1), (1, '3333-BAT', 'WAYNE INDUSTRIES', 'BATMOBILE', 442, 1, 'The ultimate war machine', 50, 1, 1),
(6, '5555-IMK', 'STARK INDUSTRIES', 'MARK-XLV', 442, 1, 'Iron-Man Heavy Armor MARK-XLV', 12, 0); (2, '1111-IMK', 'STARK INDUSTRIES', 'MARK-III', 442, 1, 'Iron-Man Heavy Armor MARK-III', 18, 1, 1),
(3, '2222-IMK', 'STARK INDUSTRIES', 'MARK-VI', 442, 1, 'Iron-Man Heavy Armor MARK-VI', 16, 1, 1),
(4, '3333-IMK', 'STARK INDUSTRIES', 'MARK-VII', 442, 1, 'Iron-Man Heavy Armor MARK-VII', 14, 1, 1),
(5, '4444-IMK', 'STARK INDUSTRIES', 'MARK-XLII', 442, 1, 'Iron-Man Heavy Armor MARK-XLII', 13, 1, 1),
(6, '5555-IMK', 'STARK INDUSTRIES', 'MARK-XLV', 442, 1, 'Iron-Man Heavy Armor MARK-XLV', 12, 0, 1);
INSERT INTO `vn`.`config`(`id`, `mdbServer`, `fakeEmail`, `defaultersMaxAmount`, `inventoried`) INSERT INTO `vn`.`config`(`id`, `mdbServer`, `fakeEmail`, `defaultersMaxAmount`, `inventoried`)
VALUES VALUES
@ -601,16 +611,16 @@ INSERT INTO `vn`.`mandate`(`id`, `clientFk`, `companyFk`, `code`, `created`, `ma
VALUES VALUES
(1, 102, 442, '1-1', CURDATE(), 2); (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 VALUES
(1, 'Plant', 1, 'B92A26', 'icon-plant'), (1, 'Plant', 1, 'B92A26', 'icon-plant', 'plant'),
(2, 'Flower', 2, 'dcf711', 'icon-flower'), (2, 'Flower', 2, 'dcf711', 'icon-flower', 'flower'),
(3, 'Logistic', 0, 'b9f711', NULL), (3, 'Logistic', 0, 'b9f711', NULL, 'logistical'),
(4, 'Handmade', 1, NULL, 'icon-handmade'), (4, 'Handmade', 1, NULL, 'icon-handmade', 'handmade'),
(5, 'Artificial', 1, NULL, 'icon-artificial'), (5, 'Artificial', 1, NULL, 'icon-artificial', 'artificial'),
(6, 'Green', 1, NULL, 'icon-greenery'), (6, 'Green', 1, NULL, 'icon-greenery', 'greenery'),
(7, 'Accessories', 1, NULL, 'icon-accessory'), (7, 'Accessories', 1, NULL, 'icon-accessory', 'accessory'),
(8, 'Fruit', 1, NULL, 'icon-fruit'); (8, 'Fruit', 1, NULL, 'icon-fruit', 'fruit');
INSERT INTO `vn`.`itemType`(`id`, `code`, `name`, `categoryFk`, `life`,`workerFk`, `isPackaging`) INSERT INTO `vn`.`itemType`(`id`, `code`, `name`, `categoryFk`, `life`,`workerFk`, `isPackaging`)
VALUES VALUES
@ -885,6 +895,11 @@ INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
(32, 36, -92.324), (32, 36, -92.324),
(32, 39, 0.994); (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`) INSERT INTO `vn`.`saleTracking`(`saleFk`, `isChecked`, `created`, `originalQuantity`, `workerFk`, `actionFk`, `id`, `stateFk`)
VALUES VALUES
(1, 0, CURDATE(), 5, 55, 3, 1, 14), (1, 0, CURDATE(), 5, 55, 3, 1, 14),
@ -1356,6 +1371,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 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(19);
call vn.manaSpellersRequery(18); call vn.manaSpellersRequery(18);
@ -1464,7 +1480,7 @@ INSERT INTO `vn`.`receipt`(`id`, `invoiceFk`, `amountPaid`, `amountUnpaid`, `pay
(3, 'Cobro en efectivo', 300.00, 100.00, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 9, 1, 102, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 442, 0), (3, 'Cobro en efectivo', 300.00, 100.00, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 9, 1, 102, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 442, 0),
(4, 'Cobro en efectivo', 400.00, -50.00, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 9, 1, 103, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 442, 0); (4, 'Cobro en efectivo', 400.00, -50.00, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 9, 1, 103, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 442, 0);
INSERT INTO `vn2008`.`workerTeam`(`id`, `team`, `user`) INSERT INTO `vn`.`workerTeam`(`id`, `team`, `workerFk`)
VALUES VALUES
(1, 1, 9), (1, 1, 9),
(2, 1, 18), (2, 1, 18),
@ -1489,13 +1505,13 @@ INSERT INTO `vn`.`ticketServiceType`(`id`, `name`)
(4, 'Cargo FITOSANITARIO'), (4, 'Cargo FITOSANITARIO'),
(5, 'Documentos'); (5, 'Documentos');
INSERT INTO `vn`.`ticketService`(`id`, `description`, `quantity`, `price`, `taxClassFk`, `ticketFk`) INSERT INTO `vn`.`ticketService`(`id`, `description`, `quantity`, `price`, `taxClassFk`, `ticketFk`, `ticketServiceTypeFk`)
VALUES VALUES
(1, 'Documentos', 1, 2.00, 1, 1), (1, 'Documentos', 1, 2.00, 1, 1, 1),
(2, 'Porte Agencia', 1, 10.00, 1, 2), (2, 'Porte Agencia', 1, 10.00, 1, 2, 1),
(3, 'Documentos', 1, 5.50, 1, 11), (3, 'Documentos', 1, 5.50, 1, 11, 1),
(4, 'Documentos', 1, 2.00, 1, 9), (4, 'Documentos', 1, 2.00, 1, 9, 1),
(5, 'Documentos', 1, 2.00, 1, 8); (5, 'Documentos', 1, 2.00, 1, 8, 1);
INSERT INTO `pbx`.`sip`(`user_id`, `extension`) INSERT INTO `pbx`.`sip`(`user_id`, `extension`)
VALUES VALUES
@ -1570,9 +1586,9 @@ INSERT INTO `postgresql`.`calendar_employee` (`business_id`, `calendar_state_id`
(107, 1, DATE_ADD(CURDATE(), INTERVAL -12 DAY)), (107, 1, DATE_ADD(CURDATE(), INTERVAL -12 DAY)),
(107, 2, DATE_ADD(CURDATE(), INTERVAL -20 DAY)); (107, 2, DATE_ADD(CURDATE(), INTERVAL -20 DAY));
INSERT INTO `vn`.`smsConfig` (`id`, `uri`, `user`, `password`, `title`) INSERT INTO `vn`.`smsConfig` (`id`, `uri`, `title`)
VALUES VALUES
('1', 'https://websms.xtratelecom.es/api_php/server.wsdl', 'VERDINATURA', '182wbOKu', 'Verdnatura'); ('1', 'https://websms.xtratelecom.es/api_php/server.wsdl', 'Verdnatura');
INSERT INTO `vn`.`sharingClient`(`id`, `workerFk`, `started`, `ended`, `clientFk`) INSERT INTO `vn`.`sharingClient`(`id`, `workerFk`, `started`, `ended`, `clientFk`)
VALUES VALUES
@ -1869,7 +1885,8 @@ INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `wa
VALUES VALUES
(1, 14, '1.txt', 'text/plain', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', CURDATE()), (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()), (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`) INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`)
VALUES VALUES
@ -1880,6 +1897,10 @@ INSERT INTO `vn`.`clientDms`(`clientFk`, `dmsFk`)
(104, 2), (104, 2),
(104, 3); (104, 3);
INSERT INTO `vn`.`workerDocument`(`id`, `worker`, `document`)
VALUES
(1, 106, 4);
INSERT INTO `vn`.`device` (`sn`, `model`, `userFk`) INSERT INTO `vn`.`device` (`sn`, `model`, `userFk`)
VALUES VALUES
('aaa', 'android', '9'); ('aaa', 'android', '9');
@ -1916,7 +1937,6 @@ INSERT INTO `vn`.`userPhone`(`id`, `userFk`, `typeFk`, `phone`)
(22, 17, 'personalPhone', 623111111), (22, 17, 'personalPhone', 623111111),
(23, 18, 'personalPhone', 623111111), (23, 18, 'personalPhone', 623111111),
(24, 19, 'personalPhone', 623111111), (24, 19, 'personalPhone', 623111111),
(25, 20, 'personalPhone', 623111111),
(26, 21, 'personalPhone', 623111111), (26, 21, 'personalPhone', 623111111),
(27, 22, 'personalPhone', 623111111), (27, 22, 'personalPhone', 623111111),
(28, 30, 'personalPhone', 623111111), (28, 30, 'personalPhone', 623111111),

View File

@ -1,4 +1,3 @@
USE `vn2008`;
-- Import compiled functions -- Import compiled functions
CREATE AGGREGATE FUNCTION minacum RETURNS INT SONAME 'minacum.so'; 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() { dump_tables() {
SCHEMA=$1 SCHEMA=$1
echo "USE \`$SCHEMA\`;" >> "$DUMPED_FILE" 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" echo "" > "$DUMPED_FILE"
@ -48,22 +48,11 @@ TABLES=(
ticketUpdateAction ticketUpdateAction
state state
sample sample
department
) )
dump_tables ${TABLES[@]} dump_tables ${TABLES[@]}
TABLES=(
vn2008
time
accion_dits
businessReasonEnd
container
department
Grupos
iva_group_codigo
tarifa_componentes
tarifa_componentes_series
)
dump_tables ${TABLES[@]}
TABLES=( TABLES=(
bi bi

View File

@ -14,15 +14,93 @@ SCHEMAS=(
stock stock
util util
vn vn
vn2008
vncontrol vncontrol
) )
IGNORETABLES=(
--ignore-table=bi.last_Id_Cubo
--ignore-table=bi.v_clientes_jerarquia
--ignore-table=bi.v_ventas_contables
--ignore-table=bs.horasSilla
--ignore-table=bs.productionIndicators
--ignore-table=bs.VentasPorCliente
--ignore-table=bs.v_ventas
--ignore-table=edi.supplyOffer
--ignore-table=postgresql.currentWorkersStats
--ignore-table=vn.accounting__
--ignore-table=vn.agencyModeZone
--ignore-table=vn.agencyProvince
--ignore-table=vn.agencyWarehouse
--ignore-table=vn.awb
--ignore-table=vn.botanicExport__
--ignore-table=vn.clientDefaultCompany
--ignore-table=vn.color
--ignore-table=vn.comparative
--ignore-table=vn.comparativeFilter
--ignore-table=vn.coolerPath
--ignore-table=vn.coolerPathDetail
--ignore-table=vn.department__
--ignore-table=vn.doc
--ignore-table=vn.entity
--ignore-table=vn.especialPrice
--ignore-table=vn.exchangeInsurance
--ignore-table=vn.exchangeInsuranceInPrevious
--ignore-table=vn.exchangeReportSource
--ignore-table=vn.grant
--ignore-table=vn.grantGroup
--ignore-table=vn.invoiceCorrection__
--ignore-table=vn.invoiceIn
--ignore-table=vn.invoiceInAwb
--ignore-table=vn.invoiceInDueDay
--ignore-table=vn.invoiceInEntry
--ignore-table=vn.invoiceInIntrastat
--ignore-table=vn.invoiceInTax
--ignore-table=vn.itemTaxCountrySpain
--ignore-table=vn.mail__
--ignore-table=vn.manaSpellers
--ignore-table=vn.outgoingInvoiceKk
--ignore-table=vn.payment
--ignore-table=vn.paymentExchangeInsurance
--ignore-table=vn.payrollCenter
--ignore-table=vn.plantpassport
--ignore-table=vn.plantpassportAuthority
--ignore-table=vn.preparationException
--ignore-table=vn.priceFixed__
--ignore-table=vn.printer
--ignore-table=vn.printingQueue
--ignore-table=vn.printServerQueue__
--ignore-table=vn.promissoryNote
--ignore-table=vn.rate
--ignore-table=vn.referenceRate__
--ignore-table=vn.routesControl
--ignore-table=vn.salesToPrePrepare
--ignore-table=vn.specialPrice__
--ignore-table=vn.ticketDownBuffer
--ignore-table=vn.ticketeToPreparePrepared
--ignore-table=vn.ticketObservation__
--ignore-table=vn.ticketRequest__
--ignore-table=vn.ticketToPrepare
--ignore-table=vn.till__
--ignore-table=vn.time
--ignore-table=vn.travelThermograph__
--ignore-table=vn.travel_cloneWeekly
--ignore-table=vn.unary
--ignore-table=vn.unaryScan
--ignore-table=vn.unaryScanLine
--ignore-table=vn.unaryScanLineBuy
--ignore-table=vn.unaryScanLineExpedition
--ignore-table=vn.warehouseAlias__
--ignore-table=vn.warehouseJoined
--ignore-table=vn.workerTeam__
--ignore-table=vn.XDiario__
)
mysqldump \ mysqldump \
--defaults-file=config.production.ini \ --defaults-file=config.production.ini \
--default-character-set=utf8 \ --default-character-set=utf8 \
--column-statistics=0 \
--no-data --comments \ --no-data --comments \
--triggers --routines --events \ --triggers --routines --events \
--databases \ --databases \
${SCHEMAS[@]} \ ${SCHEMAS[@]} \
${IGNORETABLES[@]} \
> dump/structure.sql > dump/structure.sql

View File

@ -336,6 +336,7 @@ let actions = {
waitForLastSnackbar: function() { waitForLastSnackbar: function() {
return this.wait(500) return this.wait(500)
.waitForSpinnerLoad()
.waitForLastShape('vn-snackbar .shape .text'); .waitForLastShape('vn-snackbar .shape .text');
}, },

View File

@ -3,7 +3,7 @@ const config = require('./config.js');
let nightmare; let nightmare;
module.exports = function createNightmare(width = 1280, height = 720) { module.exports = function createNightmare(width = 1280, height = 800) {
if (nightmare) if (nightmare)
return nightmare; return nightmare;

View File

@ -44,7 +44,7 @@ export default {
}, },
clientDescriptor: { clientDescriptor: {
moreMenu: 'vn-client-descriptor vn-icon-menu[icon=more_vert]', moreMenu: 'vn-client-descriptor vn-icon-menu[icon=more_vert]',
simpleTicketButton: '.vn-drop-down.shown li' simpleTicketButton: '.vn-drop-down.shown li[name="Simple ticket"]'
}, },
clientBasicData: { clientBasicData: {
basicDataButton: 'vn-left-menu a[ui-sref="client.card.basicData"]', basicDataButton: 'vn-left-menu a[ui-sref="client.card.basicData"]',
@ -75,7 +75,8 @@ export default {
hasToInvoiceCheckbox: 'vn-check[label="Has to invoice"]', hasToInvoiceCheckbox: 'vn-check[label="Has to invoice"]',
invoiceByMailCheckbox: 'vn-check[label="Invoice by mail"]', invoiceByMailCheckbox: 'vn-check[label="Invoice by mail"]',
viesCheckbox: 'vn-check[label="Vies"]', viesCheckbox: 'vn-check[label="Vies"]',
saveButton: `button[type=submit]` saveButton: `button[type=submit]`,
watcher: 'vn-client-fiscal-data vn-watcher'
}, },
clientBillingData: { clientBillingData: {
payMethodAutocomplete: 'vn-client-billing-data vn-autocomplete[ng-model="$ctrl.client.payMethodFk"]', payMethodAutocomplete: 'vn-client-billing-data vn-autocomplete[ng-model="$ctrl.client.payMethodFk"]',
@ -91,7 +92,8 @@ export default {
newBankEntityBIC: '.vn-dialog.shown vn-textfield[label="Swift / BIC"] input', newBankEntityBIC: '.vn-dialog.shown vn-textfield[label="Swift / BIC"] input',
newBankEntityCode: '.vn-dialog.shown vn-textfield[label="Entity Code"] input', newBankEntityCode: '.vn-dialog.shown vn-textfield[label="Entity Code"] input',
acceptBankEntityButton: '.vn-dialog.shown button[response="accept"]', acceptBankEntityButton: '.vn-dialog.shown button[response="accept"]',
saveButton: `button[type=submit]` saveButton: `button[type=submit]`,
watcher: 'vn-client-billing-data vn-watcher'
}, },
clientAddresses: { clientAddresses: {
addressesButton: 'vn-left-menu a[ui-sref="client.card.address.index"]', addressesButton: 'vn-left-menu a[ui-sref="client.card.address.index"]',
@ -235,7 +237,7 @@ export default {
nameInput: 'vn-textfield[label="Name"] input', nameInput: 'vn-textfield[label="Name"] input',
relevancyInput: 'vn-input-number[ng-model="$ctrl.item.relevancy"] input', relevancyInput: 'vn-input-number[ng-model="$ctrl.item.relevancy"] input',
originAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.originFk"]', originAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.originFk"]',
expenceAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.expenceFk"]', expenseAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.expenseFk"]',
longNameInput: 'vn-textfield[ng-model="$ctrl.item.longName"] input', longNameInput: 'vn-textfield[ng-model="$ctrl.item.longName"] input',
isActiveCheckbox: 'vn-check[label="Active"]', isActiveCheckbox: 'vn-check[label="Active"]',
priceInKgCheckbox: 'vn-check[label="Price in kg"]', priceInKgCheckbox: 'vn-check[label="Price in kg"]',
@ -499,16 +501,17 @@ export default {
}, },
ticketService: { ticketService: {
addServiceButton: 'vn-ticket-service vn-icon-button[vn-tooltip="Add service"] > button', addServiceButton: 'vn-ticket-service vn-icon-button[vn-tooltip="Add service"] > button',
firstAddDescriptionButton: 'vn-ticket-service vn-icon-button[vn-tooltip="New service type"]', firstAddServiceTypeButton: 'vn-ticket-service vn-icon-button[vn-tooltip="New service type"]',
firstDescriptionAutocomplete: 'vn-ticket-service vn-autocomplete[ng-model="service.description"]', firstServiceTypeAutocomplete: 'vn-ticket-service vn-autocomplete[ng-model="service.ticketServiceTypeFk"]',
firstQuantityInput: 'vn-ticket-service vn-input-number[label="Quantity"] input', firstQuantityInput: 'vn-ticket-service vn-input-number[label="Quantity"] input',
firstPriceInput: 'vn-ticket-service vn-input-number[label="Price"] input', firstPriceInput: 'vn-ticket-service vn-input-number[label="Price"] input',
firstVatTypeAutocomplete: 'vn-ticket-service vn-autocomplete[label="Tax class"]', firstVatTypeAutocomplete: 'vn-ticket-service vn-autocomplete[label="Tax class"]',
fistDeleteServiceButton: 'vn-ticket-service form vn-horizontal:nth-child(1) vn-icon-button[icon="delete"]', fistDeleteServiceButton: 'vn-ticket-service form vn-horizontal:nth-child(1) vn-icon-button[icon="delete"]',
newDescriptionInput: '.vn-dialog.shown vn-textfield[ng-model="$ctrl.newServiceType.name"] input', newServiceTypeNameInput: '.vn-dialog.shown vn-textfield[ng-model="$ctrl.newServiceType.name"] input',
newServiceTypeExpenseAutocomplete: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.newServiceType.expenseFk"]',
serviceLine: 'vn-ticket-service > form > vn-card > vn-one:nth-child(2) > vn-horizontal', serviceLine: 'vn-ticket-service > form > vn-card > vn-one:nth-child(2) > vn-horizontal',
saveServiceButton: `button[type=submit]`, saveServiceButton: `button[type=submit]`,
saveDescriptionButton: '.vn-dialog.shown tpl-buttons > button' saveServiceTypeButton: '.vn-dialog.shown tpl-buttons > button'
}, },
createStateView: { createStateView: {
stateAutocomplete: 'vn-autocomplete[ng-model="$ctrl.stateFk"]', stateAutocomplete: 'vn-autocomplete[ng-model="$ctrl.stateFk"]',

View File

@ -307,6 +307,7 @@ describe('Client Edit fiscalData path', () => {
it('should navigate back to fiscal data to confirm invoice by address is now checked', async() => { it('should navigate back to fiscal data to confirm invoice by address is now checked', async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.clientFiscalData.fiscalDataButton) .waitToClick(selectors.clientFiscalData.fiscalDataButton)
.waitForWatcherData(selectors.clientFiscalData.watcher)
.checkboxState(selectors.clientFiscalData.invoiceByAddressCheckbox); .checkboxState(selectors.clientFiscalData.invoiceByAddressCheckbox);
expect(result).toBe('checked'); expect(result).toBe('checked');

View File

@ -62,8 +62,8 @@ describe('Client Edit billing data path', () => {
it(`should clear the BIC code field, update the IBAN to see how he BIC code autocompletes`, async() => { it(`should clear the BIC code field, update the IBAN to see how he BIC code autocompletes`, async() => {
const AutomaticCode = await nightmare const AutomaticCode = await nightmare
.clearInput(selectors.clientBillingData.IBANInput) .clearInput(selectors.clientBillingData.IBANInput)
.waitToClick(selectors.clientBillingData.clearswiftBicButton)
.write(selectors.clientBillingData.IBANInput, 'ES9121000418450200051332') .write(selectors.clientBillingData.IBANInput, 'ES9121000418450200051332')
.waitForTextInInput(`${selectors.clientBillingData.swiftBicAutocomplete} input`, 'caixesbb')
.waitToGetProperty(`${selectors.clientBillingData.swiftBicAutocomplete} input`, 'value'); .waitToGetProperty(`${selectors.clientBillingData.swiftBicAutocomplete} input`, 'value');
expect(AutomaticCode).toEqual('CAIXESBB Caixa Bank'); expect(AutomaticCode).toEqual('CAIXESBB Caixa Bank');
@ -71,6 +71,7 @@ describe('Client Edit billing data path', () => {
it(`should save the form with all its new data`, async() => { it(`should save the form with all its new data`, async() => {
const snackbarMessages = await nightmare const snackbarMessages = await nightmare
.waitForWatcherData(selectors.clientBillingData.watcher)
.waitToClick(selectors.clientBillingData.saveButton) .waitToClick(selectors.clientBillingData.saveButton)
.waitForSnackbar(); .waitForSnackbar();

View File

@ -99,6 +99,7 @@ describe('Client Add address path', () => {
it(`should click on the active checkbox and receive an error to save it because it is the default address`, async() => { it(`should click on the active checkbox and receive an error to save it because it is the default address`, async() => {
const result = await nightmare const result = await nightmare
.waitForWatcherData(selectors.clientAddresses.watcher)
.waitToClick(selectors.clientAddresses.activeCheckbox) .waitToClick(selectors.clientAddresses.activeCheckbox)
.waitToClick(selectors.clientAddresses.saveButton) .waitToClick(selectors.clientAddresses.saveButton)
.waitForLastSnackbar(); .waitForLastSnackbar();

View File

@ -57,6 +57,7 @@ describe('Client balance path', () => {
it('should check balance is now 0 and the company is now VNL becouse the user local settings were removed', async() => { it('should check balance is now 0 and the company is now VNL becouse the user local settings were removed', async() => {
let company = await nightmare let company = await nightmare
.waitForSpinnerLoad()
.waitToGetProperty(`${selectors.clientBalance.companyAutocomplete} input`, 'value'); .waitToGetProperty(`${selectors.clientBalance.companyAutocomplete} input`, 'value');
let firstBalanceLine = await nightmare let firstBalanceLine = await nightmare

View File

@ -27,7 +27,7 @@ describe('Item Edit basic data path', () => {
.clearInput(selectors.itemBasicData.relevancyInput) .clearInput(selectors.itemBasicData.relevancyInput)
.write(selectors.itemBasicData.relevancyInput, '1') .write(selectors.itemBasicData.relevancyInput, '1')
.autocompleteSearch(selectors.itemBasicData.originAutocomplete, 'Spain') .autocompleteSearch(selectors.itemBasicData.originAutocomplete, 'Spain')
.autocompleteSearch(selectors.itemBasicData.expenceAutocomplete, 'Alquiler VNH') .autocompleteSearch(selectors.itemBasicData.expenseAutocomplete, 'Alquiler VNH')
.clearInput(selectors.itemBasicData.longNameInput) .clearInput(selectors.itemBasicData.longNameInput)
.write(selectors.itemBasicData.longNameInput, 'RS Rose of Purity') .write(selectors.itemBasicData.longNameInput, 'RS Rose of Purity')
.waitToClick(selectors.itemBasicData.isActiveCheckbox) .waitToClick(selectors.itemBasicData.isActiveCheckbox)
@ -76,7 +76,7 @@ describe('Item Edit basic data path', () => {
it(`should confirm the item expence was edited`, async() => { it(`should confirm the item expence was edited`, async() => {
const result = await nightmare const result = await nightmare
.waitToGetProperty(`${selectors.itemBasicData.expenceAutocomplete} input`, 'value'); .waitToGetProperty(`${selectors.itemBasicData.expenseAutocomplete} input`, 'value');
expect(result).toEqual('Alquiler VNH'); expect(result).toEqual('Alquiler VNH');
}); });

View File

@ -33,6 +33,7 @@ describe('Ticket diary path', () => {
const url = await nightmare const url = await nightmare
.waitToClick(selectors.ticketSummary.firstSaleItemId) .waitToClick(selectors.ticketSummary.firstSaleItemId)
.waitToClick(selectors.ticketSummary.popoverDiaryButton) .waitToClick(selectors.ticketSummary.popoverDiaryButton)
.waitForURL('/diary')
.parsedUrl(); .parsedUrl();
expect(url.hash).toContain('/diary'); expect(url.hash).toContain('/diary');

View File

@ -15,10 +15,10 @@ describe('Ticket services path', () => {
it('should find the add descripton button disabled for this user role', async() => { it('should find the add descripton button disabled for this user role', async() => {
const result = await nightmare const result = await nightmare
.waitForClassPresent(selectors.ticketService.firstAddDescriptionButton, 'disabled') .waitForClassPresent(selectors.ticketService.firstAddServiceTypeButton, 'disabled')
.waitToClick(selectors.ticketService.addServiceButton) .waitToClick(selectors.ticketService.addServiceButton)
.wait(selectors.ticketService.firstAddDescriptionButton) .wait(selectors.ticketService.firstAddServiceTypeButton)
.isDisabled(selectors.ticketService.firstAddDescriptionButton); .isDisabled(selectors.ticketService.firstAddServiceTypeButton);
expect(result).toBeTruthy(); expect(result).toBeTruthy();
}, 100000); }, 100000);
@ -50,7 +50,7 @@ describe('Ticket services path', () => {
it('should click on the add button to prepare the form to create a new service', async() => { it('should click on the add button to prepare the form to create a new service', async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketService.addServiceButton) .waitToClick(selectors.ticketService.addServiceButton)
.isVisible(selectors.ticketService.firstDescriptionAutocomplete); .isVisible(selectors.ticketService.firstServiceTypeAutocomplete);
expect(result).toBeTruthy(); expect(result).toBeTruthy();
}); });
@ -63,27 +63,28 @@ describe('Ticket services path', () => {
expect(result).toEqual(`can't be blank`); expect(result).toEqual(`can't be blank`);
}); });
it('should click on the add new description to open the dialog', async() => { it('should click on the add new service type to open the dialog', async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketService.firstAddDescriptionButton) .waitToClick(selectors.ticketService.firstAddServiceTypeButton)
.wait('.vn-dialog.shown') .wait('.vn-dialog.shown')
.isVisible(selectors.ticketService.newDescriptionInput); .isVisible(selectors.ticketService.newServiceTypeNameInput);
expect(result).toBeTruthy(); expect(result).toBeTruthy();
}); });
it('should receive an error if description is empty on submit', async() => { it('should receive an error if service type is empty on submit', async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketService.saveDescriptionButton) .waitToClick(selectors.ticketService.saveServiceTypeButton)
.waitForLastSnackbar(); .waitForLastSnackbar();
expect(result).toEqual(`Name can't be empty`); expect(result).toEqual(`Name can't be empty`);
}); });
it('should create a new description then add price then create the service', async() => { it('should create a new service type then add price then create the service', async() => {
const result = await nightmare const result = await nightmare
.write(selectors.ticketService.newDescriptionInput, 'accurate description') .write(selectors.ticketService.newServiceTypeNameInput, 'Documentos')
.waitToClick(selectors.ticketService.saveDescriptionButton) .autocompleteSearch(selectors.ticketService.newServiceTypeExpenseAutocomplete, 'Retencion')
.waitToClick(selectors.ticketService.saveServiceTypeButton)
.write(selectors.ticketService.firstPriceInput, 999) .write(selectors.ticketService.firstPriceInput, 999)
.waitToClick(selectors.ticketService.saveServiceButton) .waitToClick(selectors.ticketService.saveServiceButton)
.waitForLastSnackbar(); .waitForLastSnackbar();
@ -94,9 +95,9 @@ describe('Ticket services path', () => {
it('should confirm the service description was created correctly', async() => { it('should confirm the service description was created correctly', async() => {
const result = await nightmare const result = await nightmare
.reloadSection('ticket.card.service') .reloadSection('ticket.card.service')
.waitToGetProperty(`${selectors.ticketService.firstDescriptionAutocomplete} input`, 'value'); .waitToGetProperty(`${selectors.ticketService.firstServiceTypeAutocomplete} input`, 'value');
expect(result).toEqual('accurate description'); expect(result).toEqual('Documentos');
}); });
it('should confirm the service quantity was created correctly', async() => { it('should confirm the service quantity was created correctly', async() => {

View File

@ -18,24 +18,11 @@ describe('Ticket create path', () => {
expect(url.hash).toEqual('#!/ticket/create'); expect(url.hash).toEqual('#!/ticket/create');
}); });
it('should attempt to create a ticket for a frozen client but fail', async() => { it('should succeed to create a ticket', async() => {
const result = await nightmare
.autocompleteSearch(selectors.createTicketView.clientAutocomplete, 'Bruce Banner')
.autocompleteSearch(selectors.createTicketView.addressAutocomplete, 'Bruce Banner')
.datePicker(selectors.createTicketView.deliveryDateInput, 1, null)
.autocompleteSearch(selectors.createTicketView.warehouseAutocomplete, 'Warehouse One')
.autocompleteSearch(selectors.createTicketView.agencyAutocomplete, 'Silla247')
.wait(1999)
.waitToClick(selectors.createTicketView.createButton)
.waitForLastSnackbar();
expect(result).toMatch(/You can't create a ticket for a inactive|frozen client/);
});
it('should succeed to create a ticket for a valid client', async() => {
const result = await nightmare const result = await nightmare
.autocompleteSearch(selectors.createTicketView.clientAutocomplete, 'Tony Stark') .autocompleteSearch(selectors.createTicketView.clientAutocomplete, 'Tony Stark')
.autocompleteSearch(selectors.createTicketView.addressAutocomplete, 'Tony Stark') .autocompleteSearch(selectors.createTicketView.addressAutocomplete, 'Tony Stark')
.datePicker(selectors.createTicketView.deliveryDateInput, 1, null)
.autocompleteSearch(selectors.createTicketView.warehouseAutocomplete, 'Warehouse One') .autocompleteSearch(selectors.createTicketView.warehouseAutocomplete, 'Warehouse One')
.autocompleteSearch(selectors.createTicketView.agencyAutocomplete, 'Silla247') .autocompleteSearch(selectors.createTicketView.agencyAutocomplete, 'Silla247')
.waitToClick(selectors.createTicketView.createButton) .waitToClick(selectors.createTicketView.createButton)

View File

@ -94,38 +94,4 @@ describe('Claim development', () => {
expect(worker).toEqual('deliveryNick'); expect(worker).toEqual('deliveryNick');
expect(redelivery).toEqual('Reparto'); expect(redelivery).toEqual('Reparto');
}); });
it('should delete the first development, add an empty one and save it', async() => {
const result = await nightmare
.waitToClick(selectors.claimDevelopment.firstDeleteDevelopmentButton)
.waitToClick(selectors.claimDevelopment.addDevelopmentButton)
.waitToClick(selectors.claimDevelopment.saveDevelopmentButton)
.waitForLastSnackbar();
expect(result).toEqual('Data saved!');
});
it('should confirm the second development was auto filled', async() => {
const reason = await nightmare
.reloadSection('claim.card.development')
.waitToGetProperty(`${selectors.claimDevelopment.secondClaimReasonAutocomplete} input`, 'value');
const result = await nightmare
.waitToGetProperty(`${selectors.claimDevelopment.secondClaimResultAutocomplete} input`, 'value');
const responsible = await nightmare
.waitToGetProperty(`${selectors.claimDevelopment.secondClaimResponsibleAutocomplete} input`, 'value');
const worker = await nightmare
.waitToGetProperty(`${selectors.claimDevelopment.secondClaimWorkerAutocomplete} input`, 'value');
const redelivery = await nightmare
.waitToGetProperty(`${selectors.claimDevelopment.secondClaimRedeliveryAutocomplete} input`, 'value');
expect(reason).toEqual('Prisas');
expect(result).toEqual('Otros daños');
expect(responsible).toEqual('Compradores');
expect(worker).toEqual('managerNick');
expect(redelivery).toEqual('Cliente');
});
}); });

View File

@ -1,3 +1,5 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
/** /**
* Returns a set of allowed values defined on table scheme * Returns a set of allowed values defined on table scheme
@ -7,7 +9,6 @@ module.exports = Self => {
Self.getSetValues = async function(column) { Self.getSetValues = async function(column) {
let model = this.app.models[this.modelName].definition; let model = this.app.models[this.modelName].definition;
let properties = model.properties; let properties = model.properties;
let columnName;
let tableName = this.modelName; let tableName = this.modelName;
let schema = null; let schema = null;
@ -17,35 +18,32 @@ module.exports = Self => {
schema = tableSplit.pop() || null; schema = tableSplit.pop() || null;
} }
if (properties[column]) { let property = properties[column];
columnName = column;
if (properties[column].mysql) if (!property)
columnName = properties[column].mysql.columnName; throw new UserError(`Column does not exist`);
}
let findColumn = Object.keys(properties).find(prop => { let columnName = property.mysql
return properties[prop].mysql && properties[prop].mysql.columnName === column; ? property.mysql.columnName
}); : column;
if (findColumn) let columnInfo = await this.rawSql(
columnName = properties[findColumn].mysql.columnName; `SELECT column_type columnType
FROM information_schema.columns
let type = await this.rawSql(
`SELECT DISTINCT column_type FROM information_schema.columns
WHERE table_name = ? WHERE table_name = ?
AND table_schema = IFNULL(?, DATABASE()) AND table_schema = IFNULL(?, DATABASE())
AND column_name = ?`, AND column_name = ?`,
[tableName, schema, columnName] [tableName, schema, columnName]
); );
if (!type) return; if (!columnInfo || !columnInfo[0])
throw new UserError(`Cannot fetch column values`);
let setValues; let setValues;
setValues = type[0].column_type; setValues = columnInfo[0].columnType
setValues = setValues.replace(/set\((.*)\)/i, '$1'); .replace(/^set\((.*)\)$/i, '$1')
setValues = setValues.replace(/'/g, ''); .replace(/'/g, '')
setValues = setValues.match(new RegExp(/(\w+)+/, 'ig')); .match(new RegExp(/(\w+)+/, 'ig'));
let values = []; let values = [];
setValues.forEach(setValue => { setValues.forEach(setValue => {

View File

@ -13,11 +13,4 @@ describe('Model getSetValues()', () => {
expect(result.length).toEqual(6); expect(result.length).toEqual(6);
expect(result[5].value).toEqual('TABLET_VN'); expect(result[5].value).toEqual('TABLET_VN');
}); });
it('should return an array of set values from table column source_app', async() => {
let result = await app.models.Order.getSetValues('source_app');
expect(result.length).toEqual(6);
expect(result[5].value).toEqual('TABLET_VN');
});
}); });

View File

@ -56,5 +56,6 @@
"Value has an invalid format": "Value has an invalid format", "Value has an invalid format": "Value has an invalid format",
"The postcode doesn't exists. Ensure you put the correct format": "The postcode doesn't exists. Ensure you put the correct format", "The postcode doesn't exists. Ensure you put the correct format": "The postcode doesn't exists. Ensure you put the correct format",
"Can't create stowaway for this ticket": "Can't create stowaway for this ticket", "Can't create stowaway for this ticket": "Can't create stowaway for this ticket",
"Has deleted the ticket id": "Has deleted the ticket id [#{{id}}]({{{url}}})" "Has deleted the ticket id": "Has deleted the ticket id [#{{id}}]({{{url}}})",
"Swift / BIC can't be empty": "Swift / BIC can't be empty"
} }

View File

@ -117,5 +117,6 @@
"You should specify a date": "Debes especificar una fecha", "You should specify a date": "Debes especificar una fecha",
"You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fín", "You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fín",
"Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fín", "Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fín",
"You should mark at least one week day": "Debes marcar al menos un día de la semana" "You should mark at least one week day": "Debes marcar al menos un día de la semana",
"Swift / BIC can't be empty": "Swift / BIC no puede estar vacío"
} }

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"> <vn-card class="summary">
<h5>#{{$ctrl.summary.id}} - {{$ctrl.summary.name}}</h5> <h5>#{{$ctrl.summary.id}} - {{$ctrl.summary.name}}</h5>
<vn-horizontal class="vn-pa-md"> <vn-horizontal class="vn-pa-md">
@ -34,14 +29,14 @@
<vn-horizontal class="vn-pa-md"> <vn-horizontal class="vn-pa-md">
<vn-auto> <vn-auto>
<h4 translate>Warehouses</h4> <h4 translate>Warehouses</h4>
<vn-table model="model"> <vn-table model="model" auto-load="false">
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
<vn-th>Name</vn-th> <vn-th>Name</vn-th>
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>
<vn-tbody> <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-td>{{zoneWarehouse.warehouse.name}}</vn-td>
</vn-tr> </vn-tr>
</vn-tbody> </vn-tbody>

View File

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

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 => { module.exports = Self => {
Self.remoteMethodCtx('removeFile', { Self.remoteMethodCtx('removeFile', {
description: 'Removes a ticket document', description: 'Removes a claim document',
accessType: 'WRITE', accessType: 'WRITE',
accepts: { accepts: {
arg: 'id', arg: 'id',

View File

@ -104,9 +104,6 @@ module.exports = Self => {
} }
} }
}, },
{
relation: 'claimDestination'
},
{ {
relation: 'claimReason' relation: 'claimReason'
}, },

View File

@ -11,6 +11,21 @@
"type": "Number", "type": "Number",
"id": true, "id": true,
"description": "Identifier" "description": "Identifier"
},
"claimFk": {
"required": true
},
"claimResponsibleFk": {
"required": true
},
"claimReasonFk": {
"required": true
},
"claimResultFk": {
"required": true
},
"claimRedeliveryFk": {
"required": true
} }
}, },
"relations": { "relations": {
@ -29,11 +44,6 @@
"model": "Worker", "model": "Worker",
"foreignKey": "workerFk" "foreignKey": "workerFk"
}, },
"claimDestination": {
"type": "belongsTo",
"model": "ClaimDestination",
"foreignKey": "claimDestinationFk"
},
"claimReason": { "claimReason": {
"type": "belongsTo", "type": "belongsTo",
"model": "ClaimReason", "model": "ClaimReason",

View File

@ -57,11 +57,11 @@
<span class="link" <span class="link"
vn-tooltip="Edit discount" vn-tooltip="Edit discount"
ng-click="$ctrl.showEditPopover($event, saleClaimed)"> ng-click="$ctrl.showEditPopover($event, saleClaimed)">
{{::saleClaimed.sale.discount}} % {{saleClaimed.sale.discount}} %
</span> </span>
</vn-td> </vn-td>
<vn-td number> <vn-td number>
{{::$ctrl.getSaleTotal(saleClaimed.sale) | currency: 'EUR':2}} {{$ctrl.getSaleTotal(saleClaimed.sale) | currency: 'EUR':2}}
</vn-td> </vn-td>
<vn-td shrink> <vn-td shrink>
<vn-icon-button <vn-icon-button
@ -125,8 +125,9 @@
<vn-popover <vn-popover
class="edit" class="edit"
vn-id="edit-popover" vn-id="edit-popover"
on-open="$ctrl.getManaSalespersonMana()" on-open="$ctrl.getSalespersonMana()"
on-close="$ctrl.mana = null"> on-close="$ctrl.mana = null">
<div class="discount-popover">
<vn-spinner <vn-spinner
ng-if="$ctrl.mana == null" ng-if="$ctrl.mana == null"
style="padding: 1em;" style="padding: 1em;"
@ -147,10 +148,11 @@
suffix="€"> suffix="€">
</vn-input-number> </vn-input-number>
<div class="simulator"> <div class="simulator">
<p class="simulatorTitle" translate>New price</p> <p class="simulatorTitle" translate>Total claimed price</p>
<p>{{$ctrl.newPrice | currency: 'EUR':2}} <p>{{$ctrl.newPrice | currency: 'EUR':2}}
</p> </p>
</div> </div>
</div> </div>
</div> </div>
</div>
</vn-popover> </vn-popover>

View File

@ -128,25 +128,30 @@ class Controller {
this.$.editPopover.show(); this.$.editPopover.show();
} }
getManaSalespersonMana() { getSalespersonMana() {
this.$http.get(`Tickets/${this.claim.ticketFk}/getSalesPersonMana`).then(res => { this.$http.get(`Tickets/${this.claim.ticketFk}/getSalesPersonMana`).then(res => {
this.mana = res.data; this.mana = res.data;
}); });
} }
updateDiscount() { updateDiscount() {
if (this.newDiscount != this.saleClaimed.sale.discount) { const claimedSale = this.saleClaimed.sale;
const params = {salesIds: [this.saleClaimed.sale.id], newDiscount: this.newDiscount}; if (this.newDiscount != claimedSale.discount) {
const query = `Tickets/${this.saleClaimed.sale.ticketFk}/updateDiscount`; const params = {salesIds: [claimedSale.id], newDiscount: this.newDiscount};
const query = `Tickets/${claimedSale.ticketFk}/updateDiscount`;
this.$http.post(query, params).then(() => { this.$http.post(query, params).then(() => {
this.vnApp.showSuccess(this.$translate.instant('Data saved!')); claimedSale.discount = this.newDiscount;
this.calculateTotals();
this.clearDiscount(); this.clearDiscount();
this.$.model.refresh();
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
}).catch(err => { }).catch(err => {
this.vnApp.showError(err.message); this.vnApp.showError(err.message);
}); });
} }
this.$.editPopover.hide();
} }
updateNewPrice() { updateNewPrice() {

View File

@ -29,6 +29,9 @@ describe('claim', () => {
hide: () => {}, hide: () => {},
show: () => {} show: () => {}
}; };
controller.$.editPopover = {
hide: () => {}
};
})); }));
describe('openAddSalesDialog()', () => { describe('openAddSalesDialog()', () => {
@ -110,16 +113,18 @@ describe('claim', () => {
spyOn(controller.vnApp, 'showSuccess'); spyOn(controller.vnApp, 'showSuccess');
spyOn(controller, 'calculateTotals');
spyOn(controller, 'clearDiscount'); spyOn(controller, 'clearDiscount');
spyOn(controller.$.model, 'refresh'); spyOn(controller.$.editPopover, 'hide');
$httpBackend.when('POST', 'Tickets/1/updateDiscount').respond({}); $httpBackend.when('POST', 'Tickets/1/updateDiscount').respond({});
controller.updateDiscount(); controller.updateDiscount();
$httpBackend.flush(); $httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!'); expect(controller.calculateTotals).toHaveBeenCalledWith();
expect(controller.clearDiscount).toHaveBeenCalledWith(); expect(controller.clearDiscount).toHaveBeenCalledWith();
expect(controller.$.model.refresh).toHaveBeenCalledWith(); expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
expect(controller.$.editPopover.hide).toHaveBeenCalledWith();
}); });
}); });

View File

@ -7,3 +7,4 @@ Claimable sales from ticket: Lineas reclamables del ticket
Detail: Detalles Detail: Detalles
Add sale item: Añadir artículo Add sale item: Añadir artículo
Insuficient permisos: Permisos insuficientes Insuficient permisos: Permisos insuficientes
Total claimed price: Precio total reclamado

View File

@ -1,28 +1,9 @@
@import "variables"; @import "variables";
vn-claim-detail { .vn-popover .discount-popover {
.vn-textfield { width: 16em;
margin: 0!important;
max-width: 100px; .header {
}
vn-dialog[vn-id=addSales] {
tpl-body {
width: 950px;
div {
div.buttons {
display: none;
}
vn-table{
min-width: 950px;
}
}
}
}
vn-popover.edit {
div.popover {
width: 200px;
}
vn-horizontal.header {
background-color: $color-main; background-color: $color-main;
color: $color-font-dark; color: $color-font-dark;
@ -31,7 +12,7 @@ vn-claim-detail {
margin: 0 auto; margin: 0 auto;
} }
} }
p.simulatorTitle { .simulatorTitle {
margin-bottom: 0px; margin-bottom: 0px;
font-size: 12px; font-size: 12px;
color: $color-main; color: $color-main;
@ -39,9 +20,8 @@ vn-claim-detail {
vn-label-value { vn-label-value {
padding-bottom: 20px; padding-bottom: 20px;
} }
div.simulator{ .simulator{
text-align: center; text-align: center;
} }
} }
}

View File

@ -49,7 +49,7 @@
data="claimReasons" data="claimReasons"
fields="['id', 'description']" fields="['id', 'description']"
show-field="description" show-field="description"
vn-acl="salesAssistant"> rule>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete
vn-one vn-one
@ -58,7 +58,7 @@
data="claimResults" data="claimResults"
fields="['id', 'description']" fields="['id', 'description']"
show-field="description" show-field="description"
vn-acl="salesAssistant"> rule>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete
vn-one vn-one
@ -67,7 +67,7 @@
data="claimResponsibles" data="claimResponsibles"
fields="['id', 'description']" fields="['id', 'description']"
show-field="description" show-field="description"
vn-acl="salesAssistant"> rule>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete
vn-one vn-one
@ -78,7 +78,7 @@
value-field="id" value-field="id"
where="{role: 'employee'}" where="{role: 'employee'}"
label="Worker" label="Worker"
vn-acl="salesAssistant"> rule>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete
vn-one vn-one
@ -87,15 +87,14 @@
data="claimRedeliveries" data="claimRedeliveries"
fields="['id', 'description']" fields="['id', 'description']"
show-field="description" show-field="description"
vn-acl="salesAssistant"> rule>
</vn-autocomplete> </vn-autocomplete>
<vn-icon-button <vn-icon-button
class="vn-my-md" class="vn-my-md"
vn-tooltip="Remove sale" vn-tooltip="Remove sale"
icon="delete" icon="delete"
ng-click="model.remove($index)" ng-click="model.remove($index)"
tabindex="-1" tabindex="-1">
vn-acl="salesAssistant">
</vn-icon-button> </vn-icon-button>
</vn-horizontal> </vn-horizontal>
</form> </form>
@ -104,8 +103,7 @@
vn-bind="+" vn-bind="+"
vn-tooltip="Add sale" vn-tooltip="Add sale"
icon="add_circle" icon="add_circle"
ng-click="model.insert()" ng-click="model.insert()">
vn-acl="salesAssistant">
</vn-icon-button> </vn-icon-button>
</vn-one> </vn-one>
</vn-vertical> </vn-vertical>
@ -113,8 +111,7 @@
<vn-button-bar> <vn-button-bar>
<vn-submit <vn-submit
label="Save" label="Save"
ng-click="$ctrl.onSubmit()" ng-click="$ctrl.onSubmit()">
vn-acl="salesAssistant">
</vn-submit> </vn-submit>
</vn-button-bar> </vn-button-bar>
</vn-vertical> </vn-vertical>

View File

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

View File

@ -20,7 +20,7 @@ module.exports = Self => {
Self.removeFile = async(ctx, id) => { Self.removeFile = async(ctx, id) => {
const models = Self.app.models; 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); 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'); let isSalesPerson = await app.models.Account.hasRole(result[0].id, 'salesPerson');
expect(result.length).toEqual(15); expect(result.length).toEqual(14);
expect(isSalesPerson).toBeTruthy(); expect(isSalesPerson).toBeTruthy();
}); });
@ -17,7 +17,7 @@ describe('Client activeWorkersWithRole', () => {
let isBuyer = await app.models.Account.hasRole(result[0].id, 'buyer'); let isBuyer = await app.models.Account.hasRole(result[0].id, 'buyer');
expect(result.length).toEqual(12); expect(result.length).toEqual(11);
expect(isBuyer).toBeTruthy(); expect(isBuyer).toBeTruthy();
}); });
}); });

View File

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

View File

@ -47,7 +47,14 @@ module.exports = Self => {
let xmlParsed; let xmlParsed;
let status; let status;
try { try {
if (process.env.NODE_ENV !== 'production') {
status = {
codigo: [200],
descripcion: ['Fake response']
};
} else {
[xmlResponse] = await soapClient.sendSMSAsync(params); [xmlResponse] = await soapClient.sendSMSAsync(params);
xmlResult = xmlResponse.result.$value; xmlResult = xmlResponse.result.$value;
xmlParsed = await new Promise((resolve, reject) => { xmlParsed = await new Promise((resolve, reject) => {
@ -58,6 +65,7 @@ module.exports = Self => {
}); });
}); });
[status] = xmlParsed['xtratelecom-sms-response'].sms; [status] = xmlParsed['xtratelecom-sms-response'].sms;
}
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }

View File

@ -32,43 +32,6 @@ describe('sms send()', () => {
let result = await app.models.Sms.send(ctx, 105, 'destination', 'My SMS Body'); let result = await app.models.Sms.send(ctx, 105, 'destination', 'My SMS Body');
expect(result.statusCode).toEqual(200); expect(result.statusCode).toEqual(200);
expect(result.status).toContain('Envio en procesamiento'); expect(result.status).toContain('Fake response');
});
it(`should throw if the response code isn't 200`, async() => {
let error;
const code = 400;
const smsConfig = await app.models.SmsConfig.findOne();
const soapClient = await soap.createClientAsync(smsConfig.uri);
spyOn(soap, 'createClientAsync').and.returnValue(soapClient);
spyOn(soapClient, 'sendSMSAsync').and.returnValue([{
result: {
$value:
`<xtratelecom-sms-response>
<sms>
<codigo>
${code}
</codigo>
<descripcion>
Envio en procesamiento
</descripcion>
<messageId>
1
</messageId>
</sms>
<procesoId>
444328681
</procesoId>
</xtratelecom-sms-response>`
}
}]);
let ctx = {req: {accessToken: {userId: 1}}};
try {
await app.models.Sms.send(ctx, 105, 'destination', 'My SMS Body');
} catch (err) {
error = err;
}
expect(error.message).toEqual(`We weren't able to send this SMS`);
}); });
}); });

View File

@ -1,5 +1,8 @@
module.exports = Self => { module.exports = Self => {
Self.validatesPresenceOf('name', { Self.validatesPresenceOf('name', {
message: 'Name cannot be blank' message: `Name cannot be blank`
});
Self.validatesPresenceOf('bic', {
message: `Swift / BIC can't be empty`
}); });
}; };

View File

@ -61,8 +61,8 @@
<vn-icon-button <vn-icon-button
vn-auto vn-auto
icon="add_circle" icon="add_circle"
ng-click="$ctrl.onAddEntityClick($event)"
vn-tooltip="New bank entity" vn-tooltip="New bank entity"
vn-dialog="bankEntityDialog"
vn-acl="salesAssistant"> vn-acl="salesAssistant">
</vn-icon-button> </vn-icon-button>
</append> </append>
@ -98,8 +98,7 @@
<!-- Create bank entity dialog --> <!-- Create bank entity dialog -->
<vn-dialog class="edit" <vn-dialog class="edit"
vn-id="bankEntityDialog" vn-id="bankEntityDialog"
on-open="$ctrl.onBankEntityOpen()" on-accept="$ctrl.onBankEntityAccept()">
on-response="$ctrl.onBankEntityResponse($response)">
<tpl-body> <tpl-body>
<h5 class="vn-py-sm" translate>New bank entity</h5> <h5 class="vn-py-sm" translate>New bank entity</h5>
<vn-horizontal> <vn-horizontal>

View File

@ -1,13 +1,7 @@
import ngModule from '../module'; import ngModule from '../module';
import Section from 'salix/components/section';
export default class Controller { export default class Controller extends Section {
constructor($scope, $http, vnApp, $translate) {
this.$scope = $scope;
this.$http = $http;
this.vnApp = vnApp;
this.$translate = $translate;
}
get client() { get client() {
return this._client; return this._client;
} }
@ -19,10 +13,6 @@ export default class Controller {
if (!value.bankEntityFk) if (!value.bankEntityFk)
this.autofillBic(); this.autofillBic();
this.newBankEntity = {
countryFk: Number.parseInt(value.countryFk)
};
} }
onSubmit() { onSubmit() {
@ -31,14 +21,14 @@ export default class Controller {
if (this.hasPaymethodChanges()) if (this.hasPaymethodChanges())
shouldNotify = true; shouldNotify = true;
this.$scope.watcher.submit().then(() => { this.$.watcher.submit().then(() => {
if (shouldNotify) if (shouldNotify)
this.vnApp.showMessage(this.$translate.instant('Notification sent!')); this.vnApp.showMessage(this.$t('Notification sent!'));
}); });
} }
hasPaymethodChanges() { hasPaymethodChanges() {
let orgData = this.$scope.watcher.orgData; let orgData = this.$.watcher.orgData;
let payMethod = orgData.payMethodFk != this.client.payMethodFk; let payMethod = orgData.payMethodFk != this.client.payMethodFk;
let iban = orgData.iban != this.client.iban; let iban = orgData.iban != this.client.iban;
@ -47,31 +37,17 @@ export default class Controller {
return payMethod || iban || dueDay; return payMethod || iban || dueDay;
} }
onBankEntityOpen() { onAddEntityClick(event) {
this.newBankEntity.name = ''; event.preventDefault();
this.newBankEntity.id = ''; this.newBankEntity = {
this.newBankEntity.bic = ''; countryFk: Number.parseInt(this.client.countryFk)
this.$scope.$apply(); };
this.$.bankEntityDialog.show();
} }
onBankEntityResponse(response) { onBankEntityAccept() {
if (response == 'accept') { return this.$http.post(`BankEntities`, this.newBankEntity)
try { .then(res => this.client.bankEntityFk = res.data.id);
if (!this.newBankEntity.name)
throw new Error(`Name can't be empty`);
if (!this.newBankEntity.bic)
throw new Error(`Swift / BIC can't be empty`);
this.$http.post(`BankEntities`, this.newBankEntity).then(response => {
if (response.data)
this.client.bankEntityFk = response.data.id;
});
} catch (e) {
this.vnApp.showError(this.$translate.instant(e.message));
return false;
}
}
return true;
} }
get ibanCountry() { get ibanCountry() {
@ -90,8 +66,7 @@ export default class Controller {
if (this.ibanCountry != 'ES') return; if (this.ibanCountry != 'ES') return;
let json = encodeURIComponent(JSON.stringify(filter)); this.$http.get(`BankEntities`, {filter}).then(response => {
this.$http.get(`BankEntities?filter=${json}`).then(response => {
const hasData = response.data && response.data[0]; const hasData = response.data && response.data[0];
if (hasData) if (hasData)
@ -101,7 +76,6 @@ export default class Controller {
}); });
} }
} }
Controller.$inject = ['$scope', '$http', 'vnApp', '$translate'];
ngModule.component('vnClientBillingData', { ngModule.component('vnClientBillingData', {
template: require('./index.html'), template: require('./index.html'),

View File

@ -10,12 +10,13 @@ describe('Client', () => {
beforeEach(ngModule('client')); beforeEach(ngModule('client'));
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _vnApp_) => { beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _vnApp_) => {
let $element = angular.element('<vn-client-billing-data></vn-client-billing-data>');
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
vnApp = _vnApp_; vnApp = _vnApp_;
$scope = $rootScope.$new(); $scope = $rootScope.$new();
$scope.watcher = {}; $scope.watcher = {};
spyOn(vnApp, 'showError'); spyOn(vnApp, 'showError');
controller = $componentController('vnClientBillingData', {$scope}); controller = $componentController('vnClientBillingData', {$element, $scope});
controller.client = {id: 101, name: 'Client name', payMethodFk: 4}; controller.client = {id: 101, name: 'Client name', payMethodFk: 4};
$scope.watcher.orgData = {id: 101, name: 'Client name', payMethodFk: 4}; $scope.watcher.orgData = {id: 101, name: 'Client name', payMethodFk: 4};
})); }));
@ -34,42 +35,7 @@ describe('Client', () => {
}); });
}); });
describe('onBankEntityOpen()', () => { describe('onBankEntityAccept()', () => {
it('should set reset the new bank entity properties', () => {
controller.newBankEntity.name = 'My new bank entity';
controller.newBankEntity.bic = 'ES123';
controller.onBankEntityOpen();
expect(controller.newBankEntity.name).toBe('');
expect(controller.newBankEntity.bic).toBe('');
});
});
describe('onBankEntityResponse()', () => {
it(`should throw an error if name property is empty`, () => {
controller.newBankEntity = {
name: '',
bic: 'ES123',
countryFk: 1,
id: 999
};
controller.onBankEntityResponse('accept');
expect(vnApp.showError).toHaveBeenCalledWith(`Name can't be empty`);
});
it(`should throw an error if bic property is empty`, () => {
controller.newBankEntity = {
name: 'My new bank entity',
bic: '',
countryFk: 1,
id: 999
};
controller.onBankEntityResponse('accept');
expect(vnApp.showError).toHaveBeenCalledWith(`Swift / BIC can't be empty`);
});
it('should request to create a new bank entity', () => { it('should request to create a new bank entity', () => {
let newBankEntity = { let newBankEntity = {
name: 'My new bank entity', name: 'My new bank entity',
@ -78,40 +44,49 @@ describe('Client', () => {
id: 999 id: 999
}; };
controller.newBankEntity = newBankEntity; controller.newBankEntity = newBankEntity;
$httpBackend.when('POST', 'BankEntities').respond('done'); $httpBackend.expectPOST('BankEntities', newBankEntity).respond({id: 999});
$httpBackend.expectPOST('BankEntities', newBankEntity); controller.onBankEntityAccept();
controller.onBankEntityResponse('accept');
$httpBackend.flush(); $httpBackend.flush();
expect(controller.client.bankEntityFk).toEqual(newBankEntity.id);
}); });
}); });
describe('autofillBic() should perform a GET query if client iban is specified and country code is "ES".', () => { describe('autofillBic()', () => {
it(`Should not define bankEntityFk property`, () => { it(`Should do nothing if there is not client`, () => {
controller.client.payMethodFk = 5; controller.client = undefined;
controller.client.iban = 'ES9121000418450200051332';
let expectedFilter = {where: {id: 2100}}; controller.autofillBic();
let json = encodeURIComponent(JSON.stringify(expectedFilter));
expect(controller.client).toBeUndefined();
});
it(`Should do nothing if the iban is not spanish`, () => {
controller.client.iban = 'FR9121000418450200051332';
$httpBackend.when('GET', `BankEntities?filter=${json}`).respond('done');
$httpBackend.expect('GET', `BankEntities?filter=${json}`);
controller.autofillBic(); controller.autofillBic();
$httpBackend.flush();
expect(controller.client.bankEntityFk).toBeUndefined(); expect(controller.client.bankEntityFk).toBeUndefined();
}); });
it(`Should define bankEntityFk property`, () => { it(`Should set the bankEntityId in the client`, () => {
controller.client.payMethodFk = 5; controller.client.iban = 'ES9121000418450200051332';
controller.client.iban = 'ES1501280010120123456789';
let expectedFilter = {where: {id: 128}};
let json = encodeURIComponent(JSON.stringify(expectedFilter));
$httpBackend.when('GET', `BankEntities?filter=${json}`).respond([{id: 128}]); $httpBackend.whenRoute('GET', `BankEntities`).respond([{id: 123}]);
$httpBackend.expect('GET', `BankEntities?filter=${json}`);
controller.autofillBic(); controller.autofillBic();
$httpBackend.flush(); $httpBackend.flush();
expect(controller.client.bankEntityFk).toEqual(128); expect(controller.client.bankEntityFk).toEqual(123);
});
it(`Should set clients bankEntityFk to null if no bank entity founds`, () => {
controller.client.iban = 'ES9121000418450200051332';
$httpBackend.whenRoute('GET', `BankEntities`).respond([]);
controller.autofillBic();
$httpBackend.flush();
expect(controller.client.bankEntityFk).toBeNull();
}); });
}); });

View File

@ -15,5 +15,4 @@ Received B2B VNL: Recibido B2B VNL
Save: Guardar Save: Guardar
New bank entity: Nueva entidad bancaria New bank entity: Nueva entidad bancaria
Name can't be empty: El nombre no puede quedar vacío Name can't be empty: El nombre no puede quedar vacío
Swift / BIC can't be empty: El Swift / BIC no puede quedar vacío
Entity Code: Código Entity Code: Código

View File

@ -68,3 +68,6 @@
</vn-quick-links> </vn-quick-links>
</div> </div>
</div> </div>
<!-- SMS Dialog -->
<vn-client-sms vn-id="sms" sms="$ctrl.newSMS"></vn-client-sms>
<!-- SMS Dialog -->

View File

@ -1,11 +1,13 @@
import ngModule from '../module'; import ngModule from '../module';
import Component from 'core/lib/component';
class Controller extends Component {
constructor($element, $) {
super($element, $);
class Controller {
constructor($http, $state) {
this.$state = $state;
this.$http = $http;
this.moreOptions = [ this.moreOptions = [
{callback: this.newTicket, name: 'Simple ticket'} {name: 'Simple ticket', callback: this.newTicket},
{name: 'Send SMS', callback: this.showSMSDialog},
]; ];
} }
@ -22,6 +24,9 @@ class Controller {
if (!value) return; if (!value) return;
if (this.$params.sendSMS)
this.showSMSDialog();
this._quicklinks = { this._quicklinks = {
btnOne: { btnOne: {
icon: 'icon-ticket', icon: 'icon-ticket',
@ -47,9 +52,20 @@ class Controller {
newTicket() { newTicket() {
this.$state.go('ticket.create', {clientFk: this.client.id}); this.$state.go('ticket.create', {clientFk: this.client.id});
} }
showSMSDialog() {
const phone = this.$params.phone || this.client.phone;
const message = this.$params.message || '';
this.newSMS = {
destinationFk: this.client.id,
destination: phone,
message: message
};
this.$.sms.open();
}
} }
Controller.$inject = ['$http', '$state']; Controller.$inject = ['$element', '$scope'];
ngModule.component('vnClientDescriptor', { ngModule.component('vnClientDescriptor', {
template: require('./index.html'), template: require('./index.html'),

View File

@ -56,7 +56,7 @@
"component": "vn-client-create", "component": "vn-client-create",
"description": "New client" "description": "New client"
}, { }, {
"url": "/:id", "url": "/:id?sendSMS&phone&message",
"state": "client.card", "state": "client.card",
"abstract": true, "abstract": true,
"component": "vn-client-card" "component": "vn-client-card"

View File

@ -56,7 +56,7 @@
<span <span
ng-click="$ctrl.showTicketDescriptor($event, ticket.id)" ng-click="$ctrl.showTicketDescriptor($event, ticket.id)"
class="link"> class="link">
{{ticket.id | zeroFill:6}} {{ticket.id}}
</span> </span>
</vn-td> </vn-td>
<vn-td> <vn-td>

View File

@ -46,7 +46,7 @@ module.exports = Self => {
}, },
{relation: 'intrastat'}, {relation: 'intrastat'},
{relation: 'itemBarcode'}, {relation: 'itemBarcode'},
{relation: 'expence'}, {relation: 'expense'},
{relation: 'origin'}, {relation: 'origin'},
{relation: 'taxes', {relation: 'taxes',
scope: { scope: {

View File

@ -1,5 +1,5 @@
{ {
"Expence": { "Expense": {
"dataSource": "vn" "dataSource": "vn"
}, },
"Genus": { "Genus": {

View File

@ -1,5 +1,5 @@
{ {
"name": "Expence", "name": "Expense",
"base": "VnModel", "base": "VnModel",
"options": { "options": {
"mysql": { "mysql": {

View File

@ -116,6 +116,12 @@
"hasKgPrice": { "hasKgPrice": {
"type": "Boolean", "type": "Boolean",
"description": "Price per Kg" "description": "Price per Kg"
},
"expenseFk": {
"type": "Number",
"mysql": {
"columnName": "expenceFk"
}
} }
}, },
"relations": { "relations": {
@ -144,10 +150,10 @@
"model": "Intrastat", "model": "Intrastat",
"foreignKey": "intrastatFk" "foreignKey": "intrastatFk"
}, },
"expence": { "expense": {
"type": "belongsTo", "type": "belongsTo",
"model": "Expence", "model": "Expense",
"foreignKey": "expenceFk" "foreignKey": "expenseFk"
}, },
"tags": { "tags": {
"type": "hasMany", "type": "hasMany",

View File

@ -1,7 +1,7 @@
<mg-ajax <mg-ajax
path="Items/{{patch.params.id}}" path="Items/{{patch.params.id}}"
options="vnPatch" options="vnPatch"
override="{filter: {include: [{relation: 'itemType'}, {relation: 'origin'}, {relation: 'ink'}, {relation: 'producer'}, {relation: 'expence'}]}}"> override="{filter: {include: [{relation: 'itemType'}, {relation: 'origin'}, {relation: 'ink'}, {relation: 'producer'}, {relation: 'expense'}]}}">
</mg-ajax> </mg-ajax>
<vn-watcher <vn-watcher
vn-id="watcher" vn-id="watcher"
@ -49,10 +49,10 @@
</tpl-item> </tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete vn-one <vn-autocomplete vn-one
url="Expences" url="Expenses"
label="Expence" label="Expense"
ng-model="$ctrl.item.expenceFk" ng-model="$ctrl.item.expenseFk"
initial-data="$ctrl.item.expence"> initial-data="$ctrl.item.expense">
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete vn-one <vn-autocomplete vn-one
url="Origins" url="Origins"

View File

@ -4,5 +4,5 @@ Full name calculates based on tags 1-3. Is not recommended to change it manually
basado en los tags 1-3. basado en los tags 1-3.
No se recomienda cambiarlo manualmente No se recomienda cambiarlo manualmente
Is active: Activo Is active: Activo
Expence: Gasto Expense: Gasto
Price in kg: Precio en kg Price in kg: Precio en kg

View File

@ -60,8 +60,8 @@
<vn-label-value label="Compression" <vn-label-value label="Compression"
value="{{$ctrl.summary.item.compression}}"> value="{{$ctrl.summary.item.compression}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Expence" <vn-label-value label="Expense"
value="{{$ctrl.summary.item.expence.name}}"> value="{{$ctrl.summary.item.expense.name}}">
</vn-label-value> </vn-label-value>
</vn-one> </vn-one>
<vn-one name="tags"> <vn-one name="tags">

View File

@ -0,0 +1,29 @@
module.exports = Self => {
Self.remoteMethod('getDeliveryPoint', {
description: 'get the deliveryPoint address ',
accessType: 'WRITE',
accepts: {
arg: 'vehicleId',
type: 'number',
required: true,
description: 'vehicle id asigned in the route',
http: {source: 'path'}
},
returns: {
type: 'String',
root: true
},
http: {
path: `/:vehicleId/getDeliveryPoint`
}
});
Self.getDeliveryPoint = async vehicleId => {
let vehicle = await Self.app.models.Vehicle.findById(vehicleId);
let deliveryPoint = await Self.app.models.DeliveryPoint.findById(vehicle.deliveryPointFk);
return deliveryPoint.ubication;
};
};

View File

@ -0,0 +1,13 @@
const app = require('vn-loopback/server/server');
describe('route getDeliveryPoint()', () => {
const routeId = 1;
const deliveryPointAddress = '46460 Av Espioca 100-Silla';
it('should get the delivery point addres of a route with assigned vehicle', async() => {
let route = await app.models.Route.findById(routeId);
let address = await app.models.Route.getDeliveryPoint(route.vehicleFk);
expect(address).toEqual(deliveryPointAddress);
});
});

View File

@ -7,5 +7,10 @@
}, },
"RouteLog": { "RouteLog": {
"dataSource": "vn" "dataSource": "vn"
},
"DeliveryPoint": {
"dataSource": "vn"
} }
} }

View File

@ -0,0 +1,22 @@
{
"name": "DeliveryPoint",
"base": "VnModel",
"options": {
"mysql": {
"table": "deliveryPoint"
}
},
"properties": {
"id": {
"type": "Number",
"id": true,
"description": "Identifier"
},
"name": {
"type": "String"
},
"ubication": {
"type": "String"
}
}
}

View File

@ -4,4 +4,5 @@ module.exports = Self => {
require('../methods/route/getTickets')(Self); require('../methods/route/getTickets')(Self);
require('../methods/route/guessPriority')(Self); require('../methods/route/guessPriority')(Self);
require('../methods/route/updateVolume')(Self); require('../methods/route/updateVolume')(Self);
require('../methods/route/getDeliveryPoint')(Self);
}; };

View File

@ -41,6 +41,11 @@
"type": "belongsTo", "type": "belongsTo",
"model": "Warehouse", "model": "Warehouse",
"foreignKey": "warehouseFk" "foreignKey": "warehouseFk"
},
"deliveryPoint": {
"type": "belongsTo",
"model": "DeliveryPoint",
"foreignKey": "deliveryPointFk"
} }
}, },
"scope": { "scope": {

View File

@ -7,8 +7,8 @@
</vn-crud-model> </vn-crud-model>
<vn-data-viewer model="model"> <vn-data-viewer model="model">
<form name="form"> <form name="form">
<vn-card class="vn-pa-lg"> <vn-card class="vn-pa-md">
<vn-tool-bar class="vn-mb-sm"> <vn-tool-bar>
<vn-button <vn-button
icon="icon-wand" icon="icon-wand"
ng-click="$ctrl.guessPriority()" ng-click="$ctrl.guessPriority()"
@ -18,14 +18,11 @@
disabled="!$ctrl.isChecked" disabled="!$ctrl.isChecked"
ng-click="$ctrl.goToBuscaman()" ng-click="$ctrl.goToBuscaman()"
vn-tooltip="Open buscaman" vn-tooltip="Open buscaman"
tooltip-position="up"
icon="icon-buscaman"> icon="icon-buscaman">
</vn-button> </vn-button>
</vn-tool-bar> </vn-tool-bar>
<vn-icon-button </vn-card>
vn-tooltip="Load more" <vn-card class="vn-mt-md">
ng-click="$ctrl.goToBuscaman()">
</vn-icon-button>
<vn-table model="model" auto-load="false"> <vn-table model="model" auto-load="false">
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
@ -36,12 +33,12 @@
</vn-th> </vn-th>
<vn-th>Order</vn-th> <vn-th>Order</vn-th>
<vn-th number>Ticket</vn-th> <vn-th number>Ticket</vn-th>
<vn-th>Client</vn-th> <vn-th expand>Client</vn-th>
<vn-th number shrink>Packages</vn-th> <vn-th number>Packages</vn-th>
<vn-th shrink></vn-th> <vn-th number></vn-th>
<vn-th shrink>Warehouse</vn-th> <vn-th>Warehouse</vn-th>
<vn-th expand>Postcode</vn-th> <vn-th>Postcode</vn-th>
<vn-th>Street</vn-th> <vn-th expand>Street</vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
</vn-tr> </vn-tr>
@ -53,11 +50,12 @@
ng-model="ticket.checked"> ng-model="ticket.checked">
</vn-check> </vn-check>
</vn-td> </vn-td>
<vn-td> <vn-td number>
<vn-input-number <vn-input-number
on-change="$ctrl.setPriority(ticket.id, ticket.priority)" on-change="$ctrl.setPriority(ticket.id, ticket.priority)"
ng-model="ticket.priority" ng-model="ticket.priority"
rule="Ticket"> rule="Ticket"
class="dense">
</vn-input-number> </vn-input-number>
</vn-td> </vn-td>
<vn-td number> <vn-td number>
@ -74,10 +72,10 @@
{{ticket.nickname}} {{ticket.nickname}}
</span> </span>
</vn-td> </vn-td>
<vn-td number shrink>{{ticket.packages}}</vn-td> <vn-td number>{{ticket.packages}}</vn-td>
<vn-td shrink>{{ticket.volume}}</vn-td> <vn-td number>{{ticket.volume}}</vn-td>
<vn-td shrink>{{ticket.warehouse.name}}</vn-td> <vn-td expand>{{ticket.warehouse.name}}</vn-td>
<vn-td number shrink>{{ticket.address.postalCode}}</vn-td> <vn-td>{{ticket.address.postalCode}}</vn-td>
<vn-td expand title="{{ticket.address.street}}">{{ticket.address.street}}</vn-td> <vn-td expand title="{{ticket.address.street}}">{{ticket.address.street}}</vn-td>
<vn-td shrink> <vn-td shrink>
<vn-icon-button <vn-icon-button

View File

@ -85,20 +85,26 @@ class Controller {
} }
goToBuscaman() { goToBuscaman() {
// firstAddress is a temporal variable, will be replaced with #1298 let query = `Routes/${this.route.vehicleFk}/getDeliveryPoint`;
let firstAddress = `46460 Av Espioca 100-46460 Silla`; let deliveryPointAddress;
let addresses = firstAddress; let addresses;
this.$http.get(query).then(response => {
deliveryPointAddress = response.data;
}).then(() => {
addresses = deliveryPointAddress;
let lines = this.getSelectedItems(this.tickets); let lines = this.getSelectedItems(this.tickets);
let url = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr='; let url = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=';
lines.forEach(line => { lines.forEach(line => {
addresses = addresses + '+to:' + line.address.postalCode + ' ' + line.address.street + '-' + line.address.postalCode + ' ' + line.address.city; addresses = addresses + '+to:' + line.address.postalCode + ' ' + line.address.city + ' ' + line.address.street;
}); });
window.open(url + addresses, '_blank'); window.open(url + addresses, '_blank');
});
} }
showDeleteConfirm(id) { showDeleteConfirm(id) {
this.selectedTicket = id; this.selectedTicket = id;
this.$.confirm.show(); this.$.confirm.show();

View File

@ -120,7 +120,11 @@ describe('Route', () => {
describe('goToBuscaman()', () => { describe('goToBuscaman()', () => {
it('should open buscaman with the given arguments', () => { it('should open buscaman with the given arguments', () => {
spyOn(window, 'open'); spyOn(window, 'open');
const expectedUrl = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=46460 Av Espioca 100-46460 Silla+to:n19 my street-n19 London'; const expectedUrl = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=46460 Av Espioca 100+to:n19 London my street';
controller.route = {vehicleFk: 1};
const url = `Routes/${controller.route.vehicleFk}/getDeliveryPoint`;
$httpBackend.expectGET(url).respond('46460 Av Espioca 100');
controller.tickets = [ controller.tickets = [
{ {
id: 1, id: 1,
@ -134,6 +138,7 @@ describe('Route', () => {
]; ];
controller.goToBuscaman(); controller.goToBuscaman();
$httpBackend.flush();
expect(window.open).toHaveBeenCalledWith(expectedUrl, '_blank'); expect(window.open).toHaveBeenCalledWith(expectedUrl, '_blank');
}); });

View File

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

Some files were not shown because too many files have changed in this diff Show More