Merge branch 'dev' into 3536-DbUserSync
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
022c2cde3c
|
@ -0,0 +1,2 @@
|
|||
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
||||
VALUES('InvoiceInDueDay', '*', '*', 'ALLOW', 'ROLE', 'administrative');
|
|
@ -0,0 +1,248 @@
|
|||
DROP PROCEDURE IF EXISTS vn.invoiceInBookingMain;
|
||||
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`invoiceInBookingMain`(vInvoiceInId INT)
|
||||
BEGIN
|
||||
DECLARE vTotalAmount,vTotalAmountDivisa DECIMAL(10,2);
|
||||
DECLARE vBookNumber,vSerialNumber INT;
|
||||
DECLARE vRate DECIMAL(10,4);
|
||||
|
||||
CALL invoiceInBookingCommon(vInvoiceInId,vSerialNumber);
|
||||
|
||||
SELECT SUM(iit.taxableBase * IF( i.serial= 'R' AND ti.Iva <> 'HP DEVENGADO 21 ISP', 1 +(ti.PorcentajeIva/100),1)),
|
||||
SUM(iit.foreignValue * IF( i.serial= 'R', 1 + (ti.PorcentajeIva/100),1)),
|
||||
iit.taxableBase/iit.foreignValue
|
||||
INTO vTotalAmount, vTotalAmountDivisa, vRate
|
||||
FROM newInvoiceIn i
|
||||
JOIN invoiceInTax iit ON iit.invoiceInFk = i.id
|
||||
LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk;
|
||||
|
||||
CALL vn.ledger_next(vBookNumber);
|
||||
|
||||
-- Apunte del proveedor
|
||||
|
||||
INSERT INTO XDiario(ASIEN,
|
||||
FECHA,
|
||||
SUBCTA,
|
||||
EUROHABER,
|
||||
CONCEPTO,
|
||||
CAMBIO,
|
||||
HABERME,
|
||||
NFACTICK,
|
||||
CLAVE,
|
||||
empresa_id
|
||||
)
|
||||
SELECT
|
||||
vBookNumber,
|
||||
n.bookEntried,
|
||||
s.supplierAccount,
|
||||
vTotalAmount EUROHABER,
|
||||
n.conceptWithSupplier,
|
||||
vRate,
|
||||
vTotalAmountDivisa,
|
||||
n.invoicesCount,
|
||||
vInvoiceInId,
|
||||
n.companyFk
|
||||
FROM newInvoiceIn n
|
||||
JOIN newSupplier s;
|
||||
|
||||
-- Línea de Gastos
|
||||
INSERT INTO XDiario ( ASIEN,
|
||||
FECHA,
|
||||
SUBCTA,
|
||||
CONTRA,
|
||||
EURODEBE,
|
||||
EUROHABER,
|
||||
CONCEPTO,
|
||||
CAMBIO,
|
||||
DEBEME,
|
||||
HABERME,
|
||||
NFACTICK,
|
||||
empresa_id
|
||||
)
|
||||
SELECT vBookNumber ASIEN,
|
||||
n.bookEntried FECHA,
|
||||
IF(e.isWithheld , LPAD(RIGHT(s.supplierAccount,5),10,iit.expenceFk),iit.expenceFk) SUBCTA,
|
||||
s.supplierAccount CONTRA,
|
||||
IF(e.isWithheld AND iit.taxableBase < 0, NULL, ROUND(SUM(iit.taxableBase),2)) EURODEBE,
|
||||
IF(e.isWithheld AND iit.taxableBase < 0,ROUND(SUM(-iit.taxableBase),2),NULL) EUROHABER,
|
||||
n.conceptWithSupplier CONCEPTO,
|
||||
vRate,
|
||||
IF(e.isWithheld,NULL,ABS(ROUND(SUM(iit.foreignValue),2))) DEBEME,
|
||||
IF(e.isWithheld,ABS(ROUND(SUM(iit.foreignValue),2)),NULL) HABERME,
|
||||
n.invoicesCount NFACTICK,
|
||||
n.companyFk empresa_id
|
||||
FROM newInvoiceIn n
|
||||
JOIN newSupplier s
|
||||
JOIN invoiceInTax iit ON iit.invoiceInFk = n.id
|
||||
JOIN (SELECT * FROM expence e GROUP BY e.id)e ON e.id = iit.expenceFk
|
||||
WHERE e.name != 'Suplidos Transitarios nacionales'
|
||||
GROUP BY iit.expenceFk;
|
||||
|
||||
-- Líneas de IVA
|
||||
|
||||
INSERT INTO XDiario( ASIEN,
|
||||
FECHA,
|
||||
SUBCTA,
|
||||
CONTRA,
|
||||
EURODEBE,
|
||||
BASEEURO,
|
||||
CONCEPTO,
|
||||
FACTURA,
|
||||
IVA,
|
||||
AUXILIAR,
|
||||
SERIE,
|
||||
TIPOOPE,
|
||||
FECHA_EX,
|
||||
FECHA_OP,
|
||||
NFACTICK,
|
||||
FACTURAEX,
|
||||
L340,
|
||||
LRECT349,
|
||||
TIPOCLAVE,
|
||||
TIPOEXENCI,
|
||||
TIPONOSUJE,
|
||||
TIPOFACT,
|
||||
TIPORECTIF,
|
||||
TERIDNIF,
|
||||
TERNIF,
|
||||
TERNOM,
|
||||
FECREGCON,
|
||||
empresa_id
|
||||
)
|
||||
SELECT vBookNumber ASIEN,
|
||||
n.bookEntried FECHA,
|
||||
IF(n.expenceFkDeductible>0, n.expenceFkDeductible, ti.CuentaIvaSoportado) SUBCTA,
|
||||
s.supplierAccount CONTRA,
|
||||
SUM(ROUND(ti.PorcentajeIva * it.taxableBase / 100 /* + 0.0001*/ , 2)) EURODEBE,
|
||||
SUM(it.taxableBase) BASEEURO,
|
||||
GROUP_CONCAT(DISTINCT e.`name` SEPARATOR ', ') CONCEPTO,
|
||||
vSerialNumber FACTURA,
|
||||
ti.PorcentajeIva IVA,
|
||||
IF(isUeeMember AND eWithheld.id IS NULL,'','*') AUXILIAR,
|
||||
n.serial SERIE,
|
||||
ttr.ClaveOperacionDefecto,
|
||||
n.issued FECHA_EX,
|
||||
n.operated FECHA_OP,
|
||||
n.invoicesCount NFACTICK,
|
||||
n.supplierRef FACTURAEX,
|
||||
TRUE L340,
|
||||
(isSameCountry OR NOT isUeeMember) LRECT349,
|
||||
n.cplusTrascendency472Fk TIPOCLAVE,
|
||||
n.cplusTaxBreakFk TIPOEXENCI,
|
||||
n.cplusSubjectOpFk TIPONOSUJE,
|
||||
n.cplusInvoiceType472Fk TIPOFACT,
|
||||
n.cplusRectificationTypeFk TIPORECTIF,
|
||||
iis.cplusTerIdNifFk TERIDNIF,
|
||||
s.nif AS TERNIF,
|
||||
s.name AS TERNOM,
|
||||
n.booked FECREGCON,
|
||||
n.companyFk
|
||||
FROM newInvoiceIn n
|
||||
JOIN newSupplier s
|
||||
JOIN invoiceInTax it ON n.id = it.invoiceInFk
|
||||
JOIN sage.TiposIva ti ON ti.CodigoIva = it.taxTypeSageFk
|
||||
JOIN sage.TiposTransacciones ttr ON ttr.CodigoTransaccion = it.transactionTypeSageFk
|
||||
JOIN invoiceInSerial iis ON iis.code = n.serial
|
||||
JOIN (SELECT * FROM expence e GROUP BY e.id)e ON e.id = it.expenceFk
|
||||
LEFT JOIN (
|
||||
SELECT eWithheld.id
|
||||
FROM invoiceInTax hold
|
||||
JOIN expence eWithheld ON eWithheld.id = hold.expenceFk AND eWithheld.isWithheld
|
||||
WHERE hold.invoiceInFk = vInvoiceInId LIMIT 1
|
||||
) eWithheld ON TRUE
|
||||
WHERE it.taxTypeSageFk IS NOT NULL
|
||||
AND it.taxTypeSageFk NOT IN (22, 90)
|
||||
GROUP BY ti.PorcentajeIva, e.id;
|
||||
|
||||
-- Línea iva inversor sujeto pasivo
|
||||
|
||||
INSERT INTO XDiario( ASIEN,
|
||||
FECHA,
|
||||
SUBCTA,
|
||||
CONTRA,
|
||||
EUROHABER,
|
||||
BASEEURO,
|
||||
CONCEPTO,
|
||||
FACTURA,
|
||||
IVA,
|
||||
AUXILIAR,
|
||||
SERIE,
|
||||
TIPOOPE,
|
||||
FECHA_EX,
|
||||
FECHA_OP,
|
||||
NFACTICK,
|
||||
FACTURAEX,
|
||||
L340,
|
||||
LRECT349,
|
||||
TIPOCLAVE,
|
||||
TIPOEXENCI,
|
||||
TIPONOSUJE,
|
||||
TIPOFACT,
|
||||
TIPORECTIF,
|
||||
TERIDNIF,
|
||||
TERNIF,
|
||||
TERNOM,
|
||||
empresa_id
|
||||
)
|
||||
SELECT vBookNumber ASIEN,
|
||||
n.bookEntried FECHA,
|
||||
ti.CuentaIvaRepercutido SUBCTA,
|
||||
s.supplierAccount CONTRA,
|
||||
SUM(ROUND(ti.PorcentajeIva * it.taxableBase / 100,2)) EUROHABER,
|
||||
ROUND(SUM(it.taxableBase),2) BASEEURO,
|
||||
GROUP_CONCAT(DISTINCT e.`name` SEPARATOR ', ') CONCEPTO,
|
||||
vSerialNumber FACTURA,
|
||||
ti.PorcentajeIva IVA,
|
||||
'*' AUXILIAR,
|
||||
n.serial SERIE,
|
||||
ttr.ClaveOperacionDefecto,
|
||||
n.issued FECHA_EX,
|
||||
n.operated FECHA_OP,
|
||||
n.invoicesCount NFACTICK,
|
||||
n.supplierRef FACTURAEX,
|
||||
FALSE L340,
|
||||
(isSameCountry OR NOT isUeeMember) LRECT349,
|
||||
1 TIPOCLAVE,
|
||||
n.cplusTaxBreakFk TIPOEXENCI,
|
||||
n.cplusSubjectOpFk TIPONOSUJE,
|
||||
n.cplusInvoiceType472Fk TIPOFACT,
|
||||
n.cplusRectificationTypeFk TIPORECTIF,
|
||||
iis.cplusTerIdNifFk TERIDNIF,
|
||||
s.nif AS TERNIF,
|
||||
s.name AS TERNOM,
|
||||
n.companyFk
|
||||
FROM newInvoiceIn n
|
||||
JOIN newSupplier s
|
||||
JOIN invoiceInTax it ON n.id = it.invoiceInFk
|
||||
JOIN sage.TiposIva ti ON ti.CodigoIva = it.taxTypeSageFk
|
||||
JOIN sage.TiposTransacciones ttr ON ttr.CodigoTransaccion = it.transactionTypeSageFk
|
||||
JOIN invoiceInSerial iis ON iis.code = n.serial
|
||||
JOIN (SELECT * FROM expence e GROUP BY e.id)e ON e.id = it.expenceFk
|
||||
WHERE ti.Iva = 'HP DEVENGADO 21 ISP' OR MID(s.account, 4, 1) = '1'
|
||||
GROUP BY ti.PorcentajeIva, e.id;
|
||||
|
||||
-- Actualización del registro original
|
||||
UPDATE invoiceIn ii
|
||||
JOIN newInvoiceIn ni ON ii.id = ni.id
|
||||
SET ii.serialNumber = vSerialNumber,
|
||||
ii.isBooked = TRUE;
|
||||
|
||||
-- Problemas derivados de la precisión en los decimales al calcular los impuestos
|
||||
UPDATE XDiario
|
||||
SET EURODEBE = EURODEBE -
|
||||
(SELECT IF(ABS(sub.difference) = 0.01, sub.difference, 0)
|
||||
FROM(
|
||||
SELECT SUM(IFNULL(ROUND(EURODEBE, 2),0)) - SUM(IFNULL(ROUND(EUROHABER, 2), 0)) difference
|
||||
FROM XDiario
|
||||
WHERE ASIEN = vBookNumber
|
||||
)sub
|
||||
)
|
||||
WHERE ASIEN = vBookNumber
|
||||
AND EURODEBE <> 0
|
||||
ORDER BY id DESC
|
||||
LIMIT 1;
|
||||
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -8,7 +8,7 @@ ALTER TABLE `vn`.`ticket` AUTO_INCREMENT = 1;
|
|||
|
||||
INSERT INTO `salix`.`AccessToken` (`id`, `ttl`, `created`, `userId`)
|
||||
VALUES
|
||||
('TOTALLY_SECURE_TOKEN', '1209600', CURDATE(), 66);
|
||||
('DEFAULT_TOKEN', '1209600', CURDATE(), 66);
|
||||
|
||||
|
||||
INSERT INTO `vn`.`ticketConfig` (`id`, `scopeDays`)
|
||||
|
@ -455,7 +455,8 @@ INSERT INTO `vn`.`creditInsurance`(`id`, `creditClassification`, `credit`, `crea
|
|||
|
||||
INSERT INTO `vn`.`companyGroup`(`id`, `code`)
|
||||
VALUES
|
||||
(1, 'Wayne Industries');
|
||||
(1, 'wayneIndustries'),
|
||||
(2, 'Verdnatura');
|
||||
|
||||
INSERT INTO `vn`.`bankEntity`(`id`, `countryFk`, `name`, `bic`)
|
||||
VALUES
|
||||
|
@ -466,13 +467,13 @@ INSERT INTO `vn`.`supplierAccount`(`id`, `supplierFk`, `iban`, `bankEntityFk`)
|
|||
VALUES
|
||||
(241, 442, 'ES111122333344111122221111', 128);
|
||||
|
||||
INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`, `companyCode`, `sage200Company`, `expired`, `phytosanitary`)
|
||||
INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`, `companyCode`, `sage200Company`, `expired`, `companyGroupFk`, `phytosanitary`)
|
||||
VALUES
|
||||
(69 , 'CCs', NULL, 30, NULL, 0, NULL, NULL),
|
||||
(442 , 'VNL', 241, 30, 2 , 1, NULL, 'VNL Company - Plant passport'),
|
||||
(567 , 'VNH', NULL, 30, NULL, 4, NULL, 'VNH Company - Plant passport'),
|
||||
(791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30', NULL),
|
||||
(1381, 'ORN', NULL, 30, NULL, 7, NULL, 'ORN Company - Plant passport');
|
||||
(69 , 'CCs', NULL, 30, NULL, 0, NULL, 1, NULL),
|
||||
(442 , 'VNL', 241, 30, 2 , 1, NULL, 2, 'VNL Company - Plant passport'),
|
||||
(567 , 'VNH', NULL, 30, NULL, 4, NULL, 1, 'VNH Company - Plant passport'),
|
||||
(791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30', 1, NULL),
|
||||
(1381, 'ORN', NULL, 30, NULL, 7, NULL, 1, 'ORN Company - Plant passport');
|
||||
|
||||
INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`)
|
||||
VALUES
|
||||
|
@ -2352,7 +2353,7 @@ REPLACE INTO `vn`.`invoiceIn`(`id`, `serialNumber`,`serial`, `supplierFk`, `issu
|
|||
|
||||
INSERT INTO `vn`.`invoiceInDueDay`(`invoiceInFk`, `dueDated`, `bankFk`, `amount`)
|
||||
VALUES
|
||||
(1, CURDATE(), 1, 237),
|
||||
(1, CURDATE(), 1, 336.99),
|
||||
(1, CURDATE(), 1, 15.25),
|
||||
(2, CURDATE(), 1, 168),
|
||||
(2, CURDATE(), 1, 55.17),
|
||||
|
|
|
@ -1,183 +1,21 @@
|
|||
{
|
||||
"name": "salix-front",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "salix-front",
|
||||
"version": "1.0.0",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@uirouter/angularjs": "^1.0.20",
|
||||
"angular": "^1.7.5",
|
||||
"angular-animate": "^1.7.8",
|
||||
"angular-moment": "^1.3.0",
|
||||
"angular-translate": "^2.18.1",
|
||||
"angular-translate-loader-partial": "^2.18.1",
|
||||
"croppie": "^2.6.5",
|
||||
"js-yaml": "^3.13.1",
|
||||
"mg-crud": "^1.1.2",
|
||||
"oclazyload": "^0.6.3",
|
||||
"require-yaml": "0.0.1",
|
||||
"validator": "^6.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@uirouter/angularjs": {
|
||||
"version": "1.0.30",
|
||||
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz",
|
||||
"integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==",
|
||||
"dependencies": {
|
||||
"@uirouter/core": "6.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"angular": ">=1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@uirouter/core": {
|
||||
"version": "6.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz",
|
||||
"integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw==",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/angular": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.2.tgz",
|
||||
"integrity": "sha512-IauMOej2xEe7/7Ennahkbb5qd/HFADiNuLSESz9Q27inmi32zB0lnAsFeLEWcox3Gd1F6YhNd1CP7/9IukJ0Gw=="
|
||||
},
|
||||
"node_modules/angular-animate": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.8.2.tgz",
|
||||
"integrity": "sha512-Jbr9+grNMs9Kj57xuBU3Ju3NOPAjS1+g2UAwwDv7su1lt0/PLDy+9zEwDiu8C8xJceoTbmBNKiWGPJGBdCQLlA=="
|
||||
},
|
||||
"node_modules/angular-moment": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.3.0.tgz",
|
||||
"integrity": "sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==",
|
||||
"dependencies": {
|
||||
"moment": ">=2.8.0 <3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/angular-translate": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz",
|
||||
"integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==",
|
||||
"dependencies": {
|
||||
"angular": "^1.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/angular-translate-loader-partial": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz",
|
||||
"integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==",
|
||||
"dependencies": {
|
||||
"angular-translate": "~2.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"dependencies": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/croppie": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/croppie/-/croppie-2.6.5.tgz",
|
||||
"integrity": "sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ=="
|
||||
},
|
||||
"node_modules/esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
||||
"bin": {
|
||||
"esparse": "bin/esparse.js",
|
||||
"esvalidate": "bin/esvalidate.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"dependencies": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/mg-crud": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/mg-crud/-/mg-crud-1.1.2.tgz",
|
||||
"integrity": "sha1-p6AWGzWSPK7/8ZpIBpS2V1vDggw=",
|
||||
"dependencies": {
|
||||
"angular": "^1.6.1"
|
||||
}
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/oclazyload": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/oclazyload/-/oclazyload-0.6.3.tgz",
|
||||
"integrity": "sha1-Kjirv/QJDAihEBZxkZRbWfLoJ5w="
|
||||
},
|
||||
"node_modules/require-yaml": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz",
|
||||
"integrity": "sha1-LhsY2RPDuqcqWk03O28Tjd0sMr0=",
|
||||
"dependencies": {
|
||||
"js-yaml": ""
|
||||
}
|
||||
},
|
||||
"node_modules/sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||
},
|
||||
"node_modules/validator": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/validator/-/validator-6.3.0.tgz",
|
||||
"integrity": "sha1-R84j7Y1Ord+p1LjvAHG2zxB418g=",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@uirouter/angularjs": {
|
||||
"version": "1.0.30",
|
||||
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz",
|
||||
"integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==",
|
||||
"version": "1.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.29.tgz",
|
||||
"integrity": "sha512-RImWnBarNixkMto0o8stEaGwZmvhv5cnuOLXyMU2pY8MP2rgEF74ZNJTLeJCW14LR7XDUxVH8Mk8bPI6lxedmQ==",
|
||||
"requires": {
|
||||
"@uirouter/core": "6.0.8"
|
||||
"@uirouter/core": "6.0.7"
|
||||
}
|
||||
},
|
||||
"@uirouter/core": {
|
||||
"version": "6.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz",
|
||||
"integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw=="
|
||||
"version": "6.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.7.tgz",
|
||||
"integrity": "sha512-KUTJxL+6q0PiBnFx4/Z+Hsyg0pSGiaW5yZQeJmUxknecjpTbnXkLU8H2EqRn9N2B+qDRa7Jg8RcgeNDPY72O1w=="
|
||||
},
|
||||
"angular": {
|
||||
"version": "1.8.2",
|
||||
|
@ -198,19 +36,19 @@
|
|||
}
|
||||
},
|
||||
"angular-translate": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz",
|
||||
"integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==",
|
||||
"version": "2.18.4",
|
||||
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz",
|
||||
"integrity": "sha512-KohNrkH6J9PK+VW0L/nsRTcg5Fw70Ajwwe3Jbfm54Pf9u9Fd+wuingoKv+h45mKf38eT+Ouu51FPua8VmZNoCw==",
|
||||
"requires": {
|
||||
"angular": "^1.8.0"
|
||||
}
|
||||
},
|
||||
"angular-translate-loader-partial": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz",
|
||||
"integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==",
|
||||
"version": "2.18.4",
|
||||
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.18.4.tgz",
|
||||
"integrity": "sha512-bsjR+FbB0sdA2528E/ugwKdlPPQhA1looxLxI3otayBTFXBpED33besfSZhYAISLgNMSL038vSssfRUen9qD8w==",
|
||||
"requires": {
|
||||
"angular-translate": "~2.19.0"
|
||||
"angular-translate": "~2.18.4"
|
||||
}
|
||||
},
|
||||
"argparse": {
|
||||
|
@ -263,7 +101,22 @@
|
|||
"resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz",
|
||||
"integrity": "sha1-LhsY2RPDuqcqWk03O28Tjd0sMr0=",
|
||||
"requires": {
|
||||
"js-yaml": ""
|
||||
"js-yaml": "^4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"requires": {
|
||||
"argparse": "^2.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sprintf-js": {
|
||||
|
|
|
@ -210,6 +210,7 @@
|
|||
"Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio",
|
||||
"You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito",
|
||||
"You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente",
|
||||
"Amounts do not match": "Las cantidades no coinciden",
|
||||
"The PDF document does not exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'",
|
||||
"The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos",
|
||||
"You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días",
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('getTotals', {
|
||||
description: 'Return totals for an invoiceIn',
|
||||
accessType: 'READ',
|
||||
accepts: {
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'invoiceIn id',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
returns: {
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: '/:id/getTotals',
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.getTotals = async(id, options) => {
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const [result] = await Self.rawSql(`
|
||||
SELECT iit.*,
|
||||
SUM(iidd.amount) totalDueDay
|
||||
FROM vn.invoiceIn ii
|
||||
LEFT JOIN (SELECT SUM(iit.taxableBase) totalTaxableBase,
|
||||
SUM(iit.taxableBase * (1 + (ti.PorcentajeIva / 100))) totalVat
|
||||
FROM vn.invoiceInTax iit
|
||||
LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk
|
||||
WHERE iit.invoiceInFk = ?) iit ON TRUE
|
||||
LEFT JOIN vn.invoiceInDueDay iidd ON iidd.invoiceInFk = ii.id
|
||||
WHERE
|
||||
ii.id = ?`, [id, id]);
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('invoiceIn getTotals()', () => {
|
||||
it('should check that returns invoiceIn totals', async() => {
|
||||
const invoiceInId = 1;
|
||||
const tx = await models.InvoiceIn.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
||||
try {
|
||||
const invoiceIntotals = await models.InvoiceIn.getTotals(invoiceInId, options);
|
||||
|
||||
expect(typeof invoiceIntotals.totalTaxableBase).toBe('number');
|
||||
expect(invoiceIntotals.totalTaxableBase).toEqual(invoiceIntotals.totalDueDay);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('invoiceIn toBook()', () => {
|
||||
it('should check that invoiceIn is booked', async() => {
|
||||
const userId = 1;
|
||||
const ctx = {
|
||||
req: {
|
||||
|
||||
accessToken: {userId: userId},
|
||||
headers: {origin: 'http://localhost:5000'},
|
||||
}
|
||||
};
|
||||
const invoiceInId = 1;
|
||||
const tx = await models.InvoiceIn.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
||||
try {
|
||||
const invoiceInBefore = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||
|
||||
expect(invoiceInBefore.isBooked).toEqual(false);
|
||||
|
||||
await models.InvoiceIn.toBook(ctx, invoiceInId, options);
|
||||
|
||||
const invoiceIn = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||
|
||||
expect(invoiceIn.isBooked).toEqual(true);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
|
@ -20,6 +20,7 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
Self.summary = async(id, options) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
|
@ -85,25 +86,9 @@ module.exports = Self => {
|
|||
}
|
||||
]
|
||||
};
|
||||
let summaryObj = await models.InvoiceIn.findById(id, filter, myOptions);
|
||||
|
||||
let summaryObj = await Self.app.models.InvoiceIn.findById(id, filter, myOptions);
|
||||
|
||||
summaryObj.totals = await getTotals(id);
|
||||
summaryObj.totals = await models.InvoiceIn.getTotals(id, myOptions);
|
||||
return summaryObj;
|
||||
};
|
||||
|
||||
async function getTotals(invoiceInFk) {
|
||||
return (await Self.rawSql(`
|
||||
SELECT iit.*,
|
||||
SUM(iidd.amount) totalDueDay
|
||||
FROM vn.invoiceIn ii
|
||||
LEFT JOIN (SELECT SUM(iit.taxableBase) totalTaxableBase,
|
||||
SUM(iit.taxableBase * (1 + (ti.PorcentajeIva / 100))) totalVat
|
||||
FROM vn.invoiceInTax iit
|
||||
LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk
|
||||
WHERE iit.invoiceInFk = ?) iit ON TRUE
|
||||
LEFT JOIN vn.invoiceInDueDay iidd ON iidd.invoiceInFk = ii.id
|
||||
WHERE
|
||||
ii.id = ?`, [invoiceInFk, invoiceInFk]))[0];
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('toBook', {
|
||||
description: 'To book the invoiceIn',
|
||||
accessType: 'WRITE',
|
||||
accepts: {
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'The invoiceIn id',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
returns: {
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: '/:id/toBook',
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.toBook = async(ctx, id, options) => {
|
||||
let tx;
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
try {
|
||||
await Self.rawSql(`CALL vn.invoiceInBookingMain(?)`, [id], myOptions);
|
||||
if (tx) await tx.commit();
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -2,4 +2,6 @@ module.exports = Self => {
|
|||
require('../methods/invoice-in/filter')(Self);
|
||||
require('../methods/invoice-in/summary')(Self);
|
||||
require('../methods/invoice-in/clone')(Self);
|
||||
require('../methods/invoice-in/toBook')(Self);
|
||||
require('../methods/invoice-in/getTotals')(Self);
|
||||
};
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
<vn-descriptor-content module="invoiceIn" description="$ctrl.invoiceIn.supplierRef">
|
||||
<slot-menu>
|
||||
<vn-item
|
||||
ng-click="$ctrl.checkToBook()"
|
||||
vn-acl="administrative"
|
||||
ng-hide="$ctrl.invoiceIn.isBooked == true"
|
||||
translate>
|
||||
To book
|
||||
</vn-item>
|
||||
|
||||
<vn-item
|
||||
ng-click="deleteConfirmation.show()"
|
||||
vn-acl="invoicing"
|
||||
vn-acl="administrative"
|
||||
vn-acl-action="remove"
|
||||
name="deleteInvoice"
|
||||
translate>
|
||||
|
@ -10,7 +18,7 @@
|
|||
</vn-item>
|
||||
<vn-item
|
||||
ng-click="cloneConfirmation.show()"
|
||||
vn-acl="invoicing"
|
||||
vn-acl="administrative"
|
||||
name="cloneInvoice"
|
||||
translate>
|
||||
Clone Invoice
|
||||
|
@ -26,7 +34,7 @@
|
|||
</vn-label-value>
|
||||
<vn-label-value label="Supplier">
|
||||
<span ng-click="supplierDescriptor.show($event, $ctrl.invoiceIn.supplier.id)" class="link">
|
||||
{{$ctrl.invoiceIn.supplier.nickname}}
|
||||
{{$ctrl.invoiceIn.supplier.nickname}}
|
||||
</span>
|
||||
</vn-label-value>
|
||||
</div>
|
||||
|
@ -46,7 +54,9 @@
|
|||
icon="icon-invoice-in">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-confirm
|
||||
|
@ -62,3 +72,8 @@
|
|||
<vn-supplier-descriptor-popover
|
||||
vn-id="supplierDescriptor">
|
||||
</vn-supplier-descriptor-popover>
|
||||
<vn-confirm
|
||||
vn-id="confirm-toBookAnyway"
|
||||
message="Are you sure you want to book this invoice?"
|
||||
on-accept="$ctrl.onAcceptToBook()">
|
||||
</vn-confirm>
|
|
@ -51,6 +51,43 @@ class Controller extends Descriptor {
|
|||
return this.getData(`InvoiceIns/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
|
||||
checkToBook() {
|
||||
let message = '';
|
||||
const id = this.invoiceIn.id;
|
||||
this.$q.all([
|
||||
this.$http.get(`InvoiceIns/${this.id}/getTotals`)
|
||||
.then(res => {
|
||||
const taxableBaseNotEqualDueDay = res.data.totalDueDay != res.data.totalTaxableBase;
|
||||
const vatNotEqualDueDay = res.data.totalDueDay != res.data.totalVat;
|
||||
if (taxableBaseNotEqualDueDay && vatNotEqualDueDay)
|
||||
message += 'amountsDoNotMatch';
|
||||
}),
|
||||
this.$http.get('InvoiceInDueDays/count', {
|
||||
filter: {
|
||||
where: {
|
||||
invoiceInFk: id,
|
||||
dueDated: {gte: new Date()}
|
||||
}
|
||||
}})
|
||||
.then(res => {
|
||||
if (res.data)
|
||||
message += 'future payments';
|
||||
})
|
||||
|
||||
]).finally(() => {
|
||||
if (message.length)
|
||||
this.$.confirmToBookAnyway.show();
|
||||
else
|
||||
this.onAcceptToBook();
|
||||
});
|
||||
}
|
||||
|
||||
onAcceptToBook() {
|
||||
this.$http.post(`InvoiceIns/${this.id}/toBook`)
|
||||
.then(() => this.$state.reload())
|
||||
.then(() => this.vnApp.showSuccess(this.$t('InvoiceIn booked')));
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnInvoiceInDescriptor', {
|
||||
|
|
|
@ -8,19 +8,70 @@ describe('vnInvoiceInDescriptor', () => {
|
|||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnInvoiceInDescriptor', {$element: null});
|
||||
const $element = angular.element('<vn-invoice-in-descriptor></vn-invoice-in-descriptor>');
|
||||
|
||||
controller = $componentController('vnInvoiceInDescriptor', {$element});
|
||||
controller.invoiceIn = {id: 1};
|
||||
$httpBackend.when('GET', `InvoiceIns/${controller.invoiceIn.id}`).respond({id: 1});
|
||||
}));
|
||||
|
||||
describe('loadData()', () => {
|
||||
it(`should perform a get query to store the invoice in data into the controller`, () => {
|
||||
const id = 1;
|
||||
const response = {id: 1};
|
||||
expect(controller.invoiceIn).toEqual({id: 1});
|
||||
});
|
||||
});
|
||||
|
||||
$httpBackend.expectGET(`InvoiceIns/${id}`).respond(response);
|
||||
controller.id = id;
|
||||
describe('onAcceptToBook()', () => {
|
||||
it(`should perform a post query to book the invoice`, () => {
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
controller.$state.reload = jest.fn();
|
||||
|
||||
const id = 1;
|
||||
|
||||
$httpBackend.expectPOST(`InvoiceIns/${id}/toBook`).respond();
|
||||
controller.onAcceptToBook();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.invoiceIn).toEqual(response);
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('InvoiceIn booked');
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkToBook()', () => {
|
||||
it(`should show a warning before book`, () => {
|
||||
controller.$.confirmToBookAnyway = {show: () => {}};
|
||||
jest.spyOn(controller.$.confirmToBookAnyway, 'show');
|
||||
|
||||
const invoceInId = 1;
|
||||
const data = {
|
||||
totalDueDay: 'an amount',
|
||||
totalTaxableBase: 'distinct amount'
|
||||
};
|
||||
|
||||
$httpBackend.expectGET(`InvoiceIns/${invoceInId}/getTotals`).respond(data);
|
||||
$httpBackend.expectGET(`InvoiceInDueDays/count`).respond();
|
||||
|
||||
controller.checkToBook();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.confirmToBookAnyway.show).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it(`should call onAcceptToBook`, () => {
|
||||
controller.onAcceptToBook = jest.fn();
|
||||
|
||||
const invoceInId = 1;
|
||||
const data = {
|
||||
totalDueDay: 'same amount',
|
||||
totalTaxableBase: 'same amount'
|
||||
};
|
||||
|
||||
$httpBackend.expectGET(`InvoiceIns/${invoceInId}/getTotals`).respond(data);
|
||||
$httpBackend.expectGET(`InvoiceInDueDays/count`).respond();
|
||||
|
||||
controller.checkToBook();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.onAcceptToBook).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
InvoiceIn: Facturas recibidas
|
||||
Search invoices in by reference: Buscar facturas recibidas por referencia
|
||||
Entries list: Listado de entradas
|
||||
InvoiceIn deleted: Factura eliminada
|
||||
Remove tax: Quitar iva
|
||||
Add tax: Añadir iva
|
||||
Amounts do not match: La BI no coincide con el vencimiento ni con el total
|
||||
Due day: Vencimiento
|
||||
Entries list: Listado de entradas
|
||||
Foreign value: Divisa
|
||||
InvoiceIn: Facturas recibidas
|
||||
InvoiceIn cloned: Factura clonada
|
||||
InvoiceIn deleted: Factura eliminada
|
||||
Invoice list: Listado de facturas recibidas
|
||||
InvoiceIn booked: Factura contabilizada
|
||||
Remove tax: Quitar iva
|
||||
Sage tax: Sage iva
|
||||
Sage transaction: Sage transaccion
|
||||
Foreign value: Divisa
|
||||
Due day: Vencimiento
|
||||
Invoice list: Listado de facturas recibidas
|
||||
InvoiceIn cloned: Factura clonada
|
||||
Search invoices in by reference: Buscar facturas recibidas por referencia
|
||||
To book: Contabilizar
|
||||
|
||||
|
|
|
@ -80,9 +80,11 @@ module.exports = Self => {
|
|||
if (tx) await tx.commit();
|
||||
|
||||
response.data.pipe(fs.createWriteStream(fileSrc));
|
||||
}).catch(async() => {
|
||||
}).catch(async e => {
|
||||
if (fs.existsSync(fileSrc))
|
||||
await fs.unlink(fileSrc);
|
||||
|
||||
throw e;
|
||||
});
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
|
|
|
@ -1,24 +1,28 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
const got = require('got');
|
||||
const LoopBackContext = require('loopback-context');
|
||||
const fs = require('fs-extra');
|
||||
const axios = require('axios');
|
||||
|
||||
describe('InvoiceOut createPdf()', () => {
|
||||
const userId = 1;
|
||||
const ctx = {
|
||||
req: {
|
||||
|
||||
accessToken: {userId: userId},
|
||||
headers: {origin: 'http://localhost:5000'},
|
||||
}
|
||||
const activeCtx = {
|
||||
accessToken: {userId: userId, id: 'DEFAULT_TOKEN'},
|
||||
headers: {origin: 'http://localhost:5000'}
|
||||
};
|
||||
const ctx = {req: activeCtx};
|
||||
|
||||
it('should create a new PDF file and set true the hasPdf property', async() => {
|
||||
const invoiceId = 1;
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
active: activeCtx
|
||||
});
|
||||
const response = {
|
||||
pipe: () => {},
|
||||
on: () => {},
|
||||
data: {
|
||||
pipe: () => {},
|
||||
on: () => {},
|
||||
}
|
||||
};
|
||||
spyOn(got, 'stream').and.returnValue(response);
|
||||
spyOn(axios, 'get').and.returnValue(new Promise(resolve => resolve(response)));
|
||||
spyOn(models.InvoiceContainer, 'container').and.returnValue({
|
||||
client: {root: '/path'}
|
||||
});
|
||||
|
@ -32,9 +36,10 @@ describe('InvoiceOut createPdf()', () => {
|
|||
const options = {transaction: tx};
|
||||
|
||||
try {
|
||||
const result = await models.InvoiceOut.createPdf(ctx, invoiceId, options);
|
||||
await models.InvoiceOut.createPdf(ctx, invoiceId, options);
|
||||
const invoiceOut = await models.InvoiceOut.findById(invoiceId, null, options);
|
||||
|
||||
expect(result.hasPdf).toBe(true);
|
||||
expect(invoiceOut.hasPdf).toBe(true);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
|
|
@ -14,4 +14,4 @@ InvoiceOut booked: Factura asentada
|
|||
Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
|
||||
Regenerate PDF invoice: Regenerar PDF factura
|
||||
The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado
|
||||
The email can't be empty: El correo no puede estar vacío
|
||||
The email can't be empty: El correo no puede estar vacío
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,9 @@
|
|||
<header>
|
||||
<img v-bind:src="getReportSrc('report-logo.svg')" alt="Verdnatura"/>
|
||||
<img
|
||||
v-if="companyGroup == 'verdnatura'"
|
||||
v-bind:src="getReportSrc('report-logo.svg')"
|
||||
alt="Verdnatura"
|
||||
/>
|
||||
<section>
|
||||
{{companyName}}. {{company.street}}.
|
||||
{{company.postCode}} {{company.city}}.
|
||||
|
|
|
@ -10,9 +10,16 @@ module.exports = {
|
|||
},
|
||||
computed: {
|
||||
companyName() {
|
||||
if (!this.company.name) return;
|
||||
if (this.company.name)
|
||||
return this.company.name.toUpperCase();
|
||||
|
||||
return this.company.name.toUpperCase();
|
||||
return;
|
||||
},
|
||||
companyGroup() {
|
||||
if (this.company.groupName)
|
||||
return this.company.groupName.toLowerCase();
|
||||
|
||||
return;
|
||||
},
|
||||
companyPhone() {
|
||||
if (!this.company.phone) return;
|
||||
|
@ -30,8 +37,15 @@ module.exports = {
|
|||
methods: {
|
||||
getCompany(code) {
|
||||
return db.findOne(`
|
||||
SELECT s.name, s.street, s.postCode, s.city, s.phone
|
||||
SELECT
|
||||
s.name,
|
||||
s.street,
|
||||
s.postCode,
|
||||
s.city,
|
||||
s.phone,
|
||||
cg.code AS groupName
|
||||
FROM company c
|
||||
JOIN companyGroup cg ON cg.id = c.companyGroupFk
|
||||
JOIN supplier s ON s.id = c.id
|
||||
WHERE c.code = ?`, [code]);
|
||||
},
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue