Merge branch 'dev' into 5834-billingDataAutoFillBic
gitea/salix/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Javier Segarra 2024-02-06 17:33:27 +01:00
commit 4d6e631fca
98 changed files with 18229 additions and 51300 deletions

View File

@ -13,7 +13,7 @@ RUN apt-get update \
graphicsmagick \ graphicsmagick \
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \ && apt-get install -y --no-install-recommends nodejs \
&& npm install -g npm@9.6.6 && corepack enable pnpm
# Puppeteer # Puppeteer
@ -39,12 +39,12 @@ RUN apt-get update \
WORKDIR /salix WORKDIR /salix
COPY print/package.json print/package-lock.json print/ COPY print/package.json print/pnpm-lock.yaml print/
RUN npm ci --no-audit --prefer-offline --omit=dev --prefix=print RUN pnpm install --prod --prefix=print
COPY package.json package-lock.json ./ COPY package.json pnpm-lock.yaml ./
COPY loopback/package.json loopback/ COPY loopback/package.json loopback/
RUN npm ci --no-audit --prefer-offline --omit=dev RUN pnpm install --prod
COPY loopback loopback COPY loopback loopback
COPY back back COPY back back

156
Jenkinsfile vendored
View File

@ -3,21 +3,11 @@
def PROTECTED_BRANCH def PROTECTED_BRANCH
def FROM_GIT def FROM_GIT
def RUN_TESTS def RUN_TESTS
def RUN_BUILD
pre: { node {
switch (env.BRANCH_NAME) { stage('Setup') {
case 'test':
env.NODE_ENV = 'test'
env.BACK_REPLICAS = 2
break
case 'master':
env.NODE_ENV = 'production'
env.BACK_REPLICAS = 4
break
default:
env.NODE_ENV = 'dev' env.NODE_ENV = 'dev'
env.BACK_REPLICAS = 1
}
PROTECTED_BRANCH = [ PROTECTED_BRANCH = [
'dev', 'dev',
@ -27,10 +17,32 @@ pre: {
FROM_GIT = env.JOB_NAME.startsWith('gitea/') FROM_GIT = env.JOB_NAME.startsWith('gitea/')
RUN_TESTS = !PROTECTED_BRANCH && FROM_GIT RUN_TESTS = !PROTECTED_BRANCH && FROM_GIT
RUN_BUILD = PROTECTED_BRANCH && FROM_GIT
// Uncomment to enable debugging // https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables
// https://loopback.io/doc/en/lb3/Setting-debug-strings.html#debug-strings-reference echo "NODE_NAME: ${env.NODE_NAME}"
//env.DEBUG = 'strong-remoting:shared-method' echo "WORKSPACE: ${env.WORKSPACE}"
configFileProvider([
configFile(fileId: 'salix.properties',
variable: 'PROPS_FILE')
]) {
def props = readProperties file: PROPS_FILE
props.each {key, value -> env."${key}" = value }
props.each {key, value -> echo "${key}: ${value}" }
}
if (PROTECTED_BRANCH) {
configFileProvider([
configFile(fileId: "salix.branch.${env.BRANCH_NAME}",
variable: 'BRANCH_PROPS_FILE')
]) {
def props = readProperties file: BRANCH_PROPS_FILE
props.each {key, value -> env."${key}" = value }
props.each {key, value -> echo "${key}: ${value}" }
}
}
}
} }
pipeline { pipeline {
agent any agent any
@ -47,20 +59,12 @@ pipeline {
stages { stages {
stage('Install') { stage('Install') {
environment { environment {
NODE_ENV = "" NODE_ENV = ''
} }
parallel { parallel {
stage('Backend') { stage('Back') {
steps { steps {
sh 'npm install --no-audit --prefer-offline' sh 'pnpm install --prefer-offline'
}
}
stage('Frontend') {
when {
expression { FROM_GIT }
}
steps {
sh 'npm install --no-audit --prefer-offline --prefix=front'
} }
} }
stage('Print') { stage('Print') {
@ -68,35 +72,99 @@ pipeline {
expression { FROM_GIT } expression { FROM_GIT }
} }
steps { steps {
sh 'npm install --no-audit --prefer-offline --prefix=print' sh 'pnpm install --prefer-offline --prefix=print'
}
}
stage('Front') {
when {
expression { FROM_GIT }
}
steps {
sh 'pnpm install --prefer-offline --prefix=front'
} }
} }
} }
} }
stage('Stack') {
environment {
TZ = 'Europe/Madrid'
}
parallel {
stage('Back') {
stages {
stage('Test') { stage('Test') {
when { when {
expression { RUN_TESTS } expression { RUN_TESTS }
} }
environment { environment {
NODE_ENV = "" NODE_ENV = ''
TZ = 'Europe/Madrid'
} }
parallel {
stage('Backend') {
steps { steps {
sh 'npm run test:back:ci' sh 'npm run test:back:ci'
} }
post {
always {
script {
try {
junit 'junitresults.xml'
junit 'junit.xml'
} catch (e) {
echo e.toString()
} }
stage('Frontend') {
steps {
sh 'jest --ci --reporters=default --reporters=jest-junit --maxWorkers=6'
} }
} }
} }
} }
stage('Build') { stage('Build') {
when { when {
expression { PROTECTED_BRANCH && FROM_GIT } expression { RUN_BUILD }
}
steps {
script {
def packageJson = readJSON file: 'package.json'
env.VERSION = packageJson.version
}
sh 'docker-compose build back'
}
}
}
}
stage('Front') {
when {
expression { FROM_GIT }
}
stages {
stage('Test') {
when {
expression { RUN_TESTS }
}
environment {
NODE_ENV = ''
}
steps {
sh 'jest --ci --reporters=default --reporters=jest-junit --maxWorkers=10'
}
}
stage('Build') {
when {
expression { RUN_BUILD }
}
steps {
script {
def packageJson = readJSON file: 'package.json'
env.VERSION = packageJson.version
}
sh 'gulp build'
sh 'docker-compose build front'
}
}
}
}
}
}
stage('Push') {
when {
expression { RUN_BUILD }
} }
environment { environment {
CREDENTIALS = credentials('docker-registry') CREDENTIALS = credentials('docker-registry')
@ -106,8 +174,8 @@ pipeline {
def packageJson = readJSON file: 'package.json' def packageJson = readJSON file: 'package.json'
env.VERSION = packageJson.version env.VERSION = packageJson.version
} }
sh 'gulp build' sh 'docker login --username $CREDENTIALS_USR --password $CREDENTIALS_PSW $REGISTRY'
dockerBuild() sh 'docker-compose push'
} }
} }
stage('Deploy') { stage('Deploy') {
@ -147,18 +215,6 @@ pipeline {
} }
} }
post { post {
always {
script {
if (RUN_TESTS) {
try {
junit 'junitresults.xml'
junit 'junit.xml'
} catch (e) {
echo e.toString()
}
}
}
}
success { success {
script { script {
if (env.BRANCH_NAME == 'master' && FROM_GIT) { if (env.BRANCH_NAME == 'master' && FROM_GIT) {

34
back/tests-helper.js Normal file
View File

@ -0,0 +1,34 @@
/* eslint-disable no-console */
const app = require('vn-loopback/server/server');
let dataSources = require('../loopback/server/datasources.json');
async function init() {
console.log('Initializing backend.');
dataSources = JSON.parse(JSON.stringify(dataSources));
Object.assign(dataSources.vn, {
host: process.env.DB_HOST,
port: process.env.DB_PORT
});
const bootOptions = {dataSources};
await new Promise((resolve, reject) => {
app.boot(bootOptions,
err => err ? reject(err) : resolve());
});
// FIXME: Workaround to wait for loopback to be ready
await app.models.Application.status();
}
async function deinit() {
console.log('Stopping backend.');
await app.disconnect();
}
module.exports = {
init,
deinit
};
if (require.main === module)
init();

View File

@ -2,29 +2,20 @@
const path = require('path'); const path = require('path');
const Myt = require('@verdnatura/myt/myt'); const Myt = require('@verdnatura/myt/myt');
const Run = require('@verdnatura/myt/myt-run'); const Run = require('@verdnatura/myt/myt-run');
let dataSources = require('../loopback/server/datasources.json'); const helper = require('./tests-helper');
let server; let server;
process.on('warning', warning => {
console.log(warning.name);
console.log(warning.message);
console.log(warning.stack);
});
process.on('SIGUSR2', rmServer);
process.on('exit', rmServer);
async function rmServer() {
if (!server) return;
await server.rm();
server = null;
}
async function test() {
console.log('Building and running DB container.');
const isCI = process.argv[2] === 'ci'; const isCI = process.argv[2] === 'ci';
const PARALLEL = false;
const TIMEOUT = 900000;
process.on('SIGINT', teardown);
process.on('exit', teardown);
process.on('uncaughtException', onError);
process.on('unhandledRejection', onError);
async function setup() {
console.log('Building and running DB container.');
const myt = new Myt(); const myt = new Myt();
await myt.init({ await myt.init({
@ -36,32 +27,57 @@ async function test() {
}); });
server = await myt.run(Run); server = await myt.run(Run);
await myt.deinit(); await myt.deinit();
const {dbConfig} = server; const {dbConfig} = server;
process.env.DB_HOST = dbConfig.host;
process.env.DB_PORT = dbConfig.port;
console.log('Initializing backend.'); if (!PARALLEL)
await helper.init();
}
dataSources = JSON.parse(JSON.stringify(dataSources)); async function teardown() {
Object.assign(dataSources.vn, { if (!server) return;
host: dbConfig.host,
port: dbConfig.port
});
const bootOptions = {dataSources}; if (!PARALLEL)
const app = require('vn-loopback/server/server'); await helper.deinit();
await new Promise((resolve, reject) => {
app.boot(bootOptions,
err => err ? reject(err) : resolve());
});
// FIXME: Workaround to wait for loopback to be ready
await app.models.Application.status();
console.log('Running tests.'); console.log('Stopping and removing DB container.');
await server.rm();
server = null;
}
async function onError(err) {
await teardown();
console.error(err);
}
async function test() {
let runner;
const config = {
globalSetup: setup,
globalSetupTimeout: TIMEOUT,
globalTeardown: teardown,
globalTeardownTimeout: TIMEOUT,
spec_dir: '.',
spec_files: [
'back/**/*[sS]pec.js',
'loopback/**/*[sS]pec.js',
'modules/*/back/**/*.[sS]pec.js'
],
helpers: []
};
if (PARALLEL) {
const ParallelRunner = require('jasmine/parallel');
runner = new ParallelRunner({numWorkers: 1});
config.helpers.push(`back/tests-helper.js`);
} else {
const Jasmine = require('jasmine'); const Jasmine = require('jasmine');
const jasmine = new Jasmine(); runner = new Jasmine();
const SpecReporter = require('jasmine-spec-reporter').SpecReporter; const SpecReporter = require('jasmine-spec-reporter').SpecReporter;
jasmine.addReporter(new SpecReporter({ runner.addReporter(new SpecReporter({
spec: { spec: {
displaySuccessful: isCI, displaySuccessful: isCI,
displayPending: isCI displayPending: isCI
@ -70,35 +86,17 @@ async function test() {
displayPending: false, displayPending: false,
} }
})); }));
}
if (isCI) { if (isCI) {
const JunitReporter = require('jasmine-reporters'); const JunitReporter = require('jasmine-reporters');
jasmine.addReporter(new JunitReporter.JUnitXmlReporter()); runner.addReporter(new JunitReporter.JUnitXmlReporter());
runner.jasmine.DEFAULT_TIMEOUT_INTERVAL = TIMEOUT;
jasmine.exitOnCompletion = true;
jasmine.jasmine.DEFAULT_TIMEOUT_INTERVAL = 900000;
} }
const backSpecs = [ // runner.loadConfigFile('back/jasmine.json');
'./back/**/*[sS]pec.js', runner.loadConfig(config);
'./loopback/**/*[sS]pec.js', await runner.execute();
'./modules/*/back/**/*.[sS]pec.js'
];
jasmine.loadConfig({
spec_dir: '.',
spec_files: backSpecs,
helpers: [],
});
await jasmine.execute();
console.log('Stopping.');
if (app) await app.disconnect();
await rmServer();
console.log('Tests ended.\n');
} }
test(); test();

View File

@ -73,9 +73,10 @@ INSERT INTO vn.cmr (id, truckPlate, observations, senderInstruccions, paymentIns
UPDATE `vn`.`claimRatio` SET `claimAmount` = '10' WHERE (`clientFk` = '1101'); UPDATE `vn`.`claimRatio` SET `claimAmount` = '10' WHERE (`clientFk` = '1101');
INSERT INTO `vn`.`agency` (`name`, `warehouseFk`, `warehouseAliasFk`, `isOwn`, `isAnyVolumeAllowed`) VALUES INSERT INTO `vn`.`agency` (`name`, `warehouseFk`, `isOwn`, `isAnyVolumeAllowed`)
('Agencia', '1', '1', '1', '1'), VALUES
('Otra agencia ', '1', '2', '0', '0'); ('Agencia', '1', '1', '1'),
('Otra agencia ', '1', '0', '0');
INSERT INTO `vn`.`expedition` (`agencyModeFk`, `ticketFk`, `isBox`, `counter`, `workerFk`, `externalId`, `packagingFk`, `hostFk`, `itemPackingTypeFk`, `hasNewRoute`) VALUES INSERT INTO `vn`.`expedition` (`agencyModeFk`, `ticketFk`, `isBox`, `counter`, `workerFk`, `externalId`, `packagingFk`, `hostFk`, `itemPackingTypeFk`, `hasNewRoute`) VALUES
('1', '1', 1, '1', '1', '1', '1', 'pc00', 'F', 0), ('1', '1', 1, '1', '1', '1', '1', 'pc00', 'F', 0),

View File

@ -174,20 +174,15 @@ INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`,
(19,'Francia', 1, 'FR', 1, 27, 4, 0, 1), (19,'Francia', 1, 'FR', 1, 27, 4, 0, 1),
(30,'Canarias', 1, 'IC', 1, 24, 4, 1, 2); (30,'Canarias', 1, 'IC', 1, 24, 4, 1, 2);
INSERT INTO `vn`.`warehouseAlias`(`id`, `name`) INSERT INTO `vn`.`warehouse`(`id`, `name`, `code`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`, `hasDms`, `hasComission`, `countryFk`, `hasProduction`, `isOrigin`, `isDestiny`)
VALUES VALUES
(1, 'Main Warehouse'), (1, 'Warehouse One', 'ALG', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
(2, 'Gotham'); (2, 'Warehouse Two', NULL, 1, 1, 1, 1, 0, 1, 13, 1, 1, 0),
(3, 'Warehouse Three', NULL, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0),
INSERT INTO `vn`.`warehouse`(`id`, `name`, `code`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`, `hasDms`, `hasComission`, `aliasFk`, `countryFk`, `hasProduction`) (4, 'Warehouse Four', NULL, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1),
VALUES (5, 'Warehouse Five', NULL, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0),
(1, 'Warehouse One', 'ALG', 1, 1, 1, 1, 1, 1, 2, 1, 1), (13, 'Inventory', 'inv', 1, 1, 1, 0, 0, 0, 1, 0, 0, 0),
(2, 'Warehouse Two', NULL, 1, 1, 1, 1, 0, 1, 2, 13, 1), (60, 'Algemesi', NULL, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0);
(3, 'Warehouse Three', NULL, 1, 1, 1, 1, 0, 0, 2, 1, 1),
(4, 'Warehouse Four', NULL, 1, 1, 1, 1, 0, 0, 2, 1, 1),
(5, 'Warehouse Five', NULL, 1, 1, 1, 1, 0, 0, 2, 1, 1),
(13, 'Inventory', 'inv', 1, 1, 1, 0, 0, 0, 2, 1, 0),
(60, 'Algemesi', NULL, 1, 1, 1, 0, 0, 0, 2, 1, 0);
INSERT INTO `vn`.`sectorType` (id,description) INSERT INTO `vn`.`sectorType` (id,description)
VALUES (1,'First type'); VALUES (1,'First type');
@ -271,18 +266,18 @@ INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
(3, 'PICKUP', 'Recogida'), (3, 'PICKUP', 'Recogida'),
(4, 'OTHER', 'Otros'); (4, 'OTHER', 'Otros');
INSERT INTO `vn`.`agency`(`id`, `name`, `warehouseFk`, `warehouseAliasFk`) INSERT INTO `vn`.`agency`(`id`, `name`, `warehouseFk`)
VALUES VALUES
(1, 'inhouse pickup' , 1, 1), (1, 'inhouse pickup' , 1),
(2, 'Super-Man delivery' , 1, 1), (2, 'Super-Man delivery' , 1),
(3, 'Teleportation device' , 1, 1), (3, 'Teleportation device' , 1),
(4, 'Entanglement' , 1, 1), (4, 'Entanglement' , 1),
(5, 'Quantum break device' , 1, 1), (5, 'Quantum break device' , 1),
(6, 'Walking' , 1, 1), (6, 'Walking' , 1),
(7, 'Gotham247' , 1, 1), (7, 'Gotham247' , 1),
(8, 'Gotham247Expensive' , 1, 1), (8, 'Gotham247Expensive' , 1),
(9, 'Refund' , 1, 1), (9, 'Refund' , 1),
(10, 'Other agency' , 1, 1); (10, 'Other agency' , 1);
UPDATE `vn`.`agencyMode` SET `id` = 1 WHERE `name` = 'inhouse pickup'; UPDATE `vn`.`agencyMode` SET `id` = 1 WHERE `name` = 'inhouse pickup';
UPDATE `vn`.`agencyMode` SET `id` = 2 WHERE `name` = 'Super-Man delivery'; UPDATE `vn`.`agencyMode` SET `id` = 2 WHERE `name` = 'Super-Man delivery';
@ -569,13 +564,13 @@ INSERT INTO `vn`.`supplierActivity`(`code`, `name`)
INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif`, `commission`, `created`, `isActive`, `street`, `city`, `provinceFk`, `postCode`, `payMethodFk`, `payDemFk`, `payDay`, `taxTypeSageFk`, `withholdingSageFk`, `transactionTypeSageFk`, `workerFk`, `supplierActivityFk`, `isPayMethodChecked`, `healthRegister`) INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif`, `commission`, `created`, `isActive`, `street`, `city`, `provinceFk`, `postCode`, `payMethodFk`, `payDemFk`, `payDay`, `taxTypeSageFk`, `withholdingSageFk`, `transactionTypeSageFk`, `workerFk`, `supplierActivityFk`, `isPayMethodChecked`, `healthRegister`)
VALUES VALUES
(1, 'Plants SL', 'Plants nick', 4100000001, 1, '06089160W', 0, util.VN_CURDATE(), 1, 'supplier address 1', 'PONTEVEDRA', 1, 15214, 1, 1, 15, 4, 1, 1, 18, 'flowerPlants', 1, '400664487V'), (1, 'PLANTS SL', 'Plants nick', 4100000001, 1, '06089160W', 0, util.VN_CURDATE(), 1, 'supplier address 1', 'PONTEVEDRA', 1, 15214, 1, 1, 15, 4, 1, 1, 18, 'flowerPlants', 1, '400664487V'),
(2, 'Farmer King', 'The farmer', 4000020002, 1, '87945234L', 0, util.VN_CURDATE(), 1, 'supplier address 2', 'GOTHAM', 2, 43022, 1, 2, 10, 93, 2, 8, 18, 'animals', 1, '400664487V'), (2, 'FARMER KING', 'The farmer', 4000020002, 1, '87945234L', 0, util.VN_CURDATE(), 1, 'supplier address 2', 'GOTHAM', 2, 43022, 1, 2, 10, 93, 2, 8, 18, 'animals', 1, '400664487V'),
(69, 'Packaging', 'Packaging nick', 4100000069, 1, '94935005K', 0, util.VN_CURDATE(), 1, 'supplier address 5', 'ASGARD', 3, 46600, 1, 1, 15, 4, 1, 1, 18, 'flowerPlants', 1, '400664487V'), (69, 'PACKAGING', 'Packaging nick', 4100000069, 1, '94935005K', 0, util.VN_CURDATE(), 1, 'supplier address 5', 'ASGARD', 3, 46600, 1, 1, 15, 4, 1, 1, 18, 'flowerPlants', 1, '400664487V'),
(442, 'Verdnatura Levante SL', 'Verdnatura', 5115000442, 1, '06815934E', 0, util.VN_CURDATE(), 1, 'supplier address 3', 'GOTHAM', 1, 43022, 1, 2, 15, 6, 9, 3, 18, 'complements', 1, '400664487V'), (442, 'VERDNATURA LEVANTE SL', 'Verdnatura', 5115000442, 1, '06815934E', 0, util.VN_CURDATE(), 1, 'supplier address 3', 'GOTHAM', 1, 43022, 1, 2, 15, 6, 9, 3, 18, 'complements', 1, '400664487V'),
(567, 'Holland', 'Holland nick', 4000020567, 1, '14364089Z', 0, util.VN_CURDATE(), 1, 'supplier address 6', 'ASGARD', 3, 46600, 1, 2, 10, 93, 2, 8, 18, 'animals', 1, '400664487V'), (567, 'HOLLAND', 'Holland nick', 4000020567, 1, '14364089Z', 0, util.VN_CURDATE(), 1, 'supplier address 6', 'ASGARD', 3, 46600, 1, 2, 10, 93, 2, 8, 18, 'animals', 1, '400664487V'),
(791, 'Bros SL', 'Bros nick', 5115000791, 1, '37718083S', 0, util.VN_CURDATE(), 1, 'supplier address 7', 'ASGARD', 3, 46600, 1, 2, 15, 6, 9, 3, 18, 'complements', 1, '400664487V'), (791, 'BROS SL', 'Bros nick', 5115000791, 1, '37718083S', 0, util.VN_CURDATE(), 1, 'supplier address 7', 'ASGARD', 3, 46600, 1, 2, 15, 6, 9, 3, 18, 'complements', 1, '400664487V'),
(1381, 'Ornamentales', 'Ornamentales', 7185001381, 1, '07972486L', 0, util.VN_CURDATE(), 1, 'supplier address 4', 'GOTHAM', 1, 43022, 1, 2, 15, 6, 9, 3, 18, 'complements', 1, '400664487V'); (1381, 'ORNAMENTALES', 'Ornamentales', 7185001381, 1, '07972486L', 0, util.VN_CURDATE(), 1, 'supplier address 4', 'GOTHAM', 1, 43022, 1, 2, 15, 6, 9, 3, 18, 'complements', 1, '400664487V');
INSERT INTO `vn`.`supplierAddress`(`id`, `supplierFk`, `nickname`, `street`, `provinceFk`, `postalCode`, `city`, `phone`, `mobile`) INSERT INTO `vn`.`supplierAddress`(`id`, `supplierFk`, `nickname`, `street`, `provinceFk`, `postalCode`, `city`, `phone`, `mobile`)
VALUES VALUES

View File

@ -20,16 +20,16 @@ BEGIN
c.movil, c.movil,
c.POBLACION poblacion, c.POBLACION poblacion,
p.`name` provincia, p.`name` provincia,
vn2008.red(f.futur) futur, ROUND(f.futur, 2) futur,
c.Credito credito, c.Credito credito,
pm.`name` forma_pago, pm.`name` forma_pago,
vn2008.red(c365 / 12) consumo_medio365, ROUND(c365 / 12, 2) consumo_medio365,
vn2008.red(c365) consumo365, ROUND(c365, 2) consumo365,
vn2008.red(CmLy.peso) peso_mes_año_pasado, ROUND(CmLy.peso, 2) peso_mes_año_pasado,
vn2008.red(CmLy.peso * 1.19) objetivo, ROUND(CmLy.peso * 1.19, 2) objetivo,
tr.CodigoTrabajador, tr.CodigoTrabajador,
vn2008.red(mes_actual.consumo) consumoMes, ROUND(mes_actual.consumo, 2) consumoMes,
vn2008.red(IFNULL(mes_actual.consumo, 0) - IFNULL(CmLy.peso * 1.19, 0)) como_lo_llevo, ROUND(IFNULL(mes_actual.consumo, 0) - IFNULL(CmLy.peso * 1.19, 0), 2) como_lo_llevo,
DATE(LastTicket) ultimo_ticket, DATE(LastTicket) ultimo_ticket,
dead.muerto, dead.muerto,
g.Greuge, g.Greuge,

View File

@ -5,7 +5,8 @@ proc: BEGIN
DECLARE vReserveDate DATETIME; DECLARE vReserveDate DATETIME;
DECLARE vParams CHAR(100); DECLARE vParams CHAR(100);
DECLARE vInventoryDate DATE; DECLARE vInventoryDate DATE;
DECLARE vIsLogifloraDay BOOLEAN; DECLARE vLifeScope DATE;
DECLARE vWarehouseFkInventory INT;
DECLARE EXIT HANDLER FOR SQLEXCEPTION DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN BEGIN
@ -26,43 +27,42 @@ proc: BEGIN
LEAVE proc; LEAVE proc;
END IF; END IF;
-- Invoca al procedimiento que genera el stock virtual de Logiflora, si coincide con la peticion de refresco del disponible
IF vn.isLogifloraDay(vDated, vWarehouse) THEN
-- CALL edi.floramondo_offerRefresh;
SET vIsLogifloraDay = TRUE;
ELSE
SET vIsLogifloraDay = FALSE;
END IF;
-- Calcula algunos parámetros necesarios -- Calcula algunos parámetros necesarios
SET vStartDate = TIMESTAMP(vDated, '00:00:00'); SET vStartDate = TIMESTAMP(vDated, '00:00:00');
SELECT inventoried INTO vInventoryDate FROM vn.config; SELECT inventoried INTO vInventoryDate FROM vn.config;
SELECT DATE_SUB(vStartDate, INTERVAL MAX(life) DAY) INTO vLifeScope FROM vn.itemType;
SELECT SUBTIME(util.VN_NOW(), reserveTime) INTO vReserveDate SELECT SUBTIME(util.VN_NOW(), reserveTime) INTO vReserveDate
FROM hedera.orderConfig; FROM hedera.orderConfig;
SELECT w.id INTO vWarehouseFkInventory
FROM vn.warehouse w
WHERE w.code = 'inv';
-- Calcula el ultimo dia de vida para cada producto -- Calcula el ultimo dia de vida para cada producto
DROP TEMPORARY TABLE IF EXISTS itemRange; DROP TEMPORARY TABLE IF EXISTS itemRange;
CREATE TEMPORARY TABLE itemRange CREATE TEMPORARY TABLE itemRange
(PRIMARY KEY (itemFk)) (PRIMARY KEY (itemFk))
ENGINE = MEMORY ENGINE = MEMORY
SELECT c.itemFk, SELECT i.id itemFk,
IF(it.life IS NULL, util.dayEnd(DATE_ADD(c.maxLanded, INTERVAL it.life DAY)) ended, it.life
NULL, FROM vn.item i
TIMESTAMP(TIMESTAMPADD(DAY, it.life, c.landing), '23:59:59')) ended LEFT JOIN (
FROM ( SELECT b.itemFk, MAX(t.landed) maxLanded
SELECT b.itemFk, MAX(t.landed) landing
FROM vn.buy b FROM vn.buy b
JOIN vn.entry e ON b.entryFk = e.id JOIN vn.entry e ON b.entryFk = e.id
JOIN vn.travel t ON t.id = e.travelFk JOIN vn.travel t ON t.id = e.travelFk
JOIN vn.warehouse w ON w.id = t.warehouseInFk JOIN vn.warehouse w ON w.id = t.warehouseInFk
WHERE t.landed BETWEEN vInventoryDate AND vStartDate JOIN vn.item i ON i.id = b.itemFk
JOIN vn.itemType it ON it.id = i.typeFk
WHERE t.landed BETWEEN vLifeScope AND vStartDate
AND t.warehouseInFk = vWarehouse AND t.warehouseInFk = vWarehouse
AND t.warehouseOutFk <> vWarehouseFkInventory
AND it.life
AND NOT e.isExcludedFromAvailable AND NOT e.isExcludedFromAvailable
GROUP BY b.itemFk GROUP BY b.itemFk
) c ) c ON i.id = c.itemFk
JOIN vn.item i ON i.id = c.itemFk
JOIN vn.itemType it ON it.id = i.typeFk JOIN vn.itemType it ON it.id = i.typeFk
HAVING ended >= vStartDate OR ended IS NULL; HAVING ended >= vStartDate OR life IS NULL;
-- Calcula el ATP -- Calcula el ATP
DELETE FROM available WHERE calc_id = vCalc; DELETE FROM available WHERE calc_id = vCalc;
@ -86,7 +86,7 @@ proc: BEGIN
WHERE i.landed >= vStartDate WHERE i.landed >= vStartDate
AND (ir.ended IS NULL OR i.landed <= ir.ended) AND (ir.ended IS NULL OR i.landed <= ir.ended)
AND i.warehouseInFk = vWarehouse AND i.warehouseInFk = vWarehouse
AND (ISNULL(wf.entryFk) OR vIsLogifloraDay) AND ISNULL(wf.entryFk)
UNION ALL UNION ALL
SELECT i.itemFk, i.shipped, i.quantity SELECT i.itemFk, i.shipped, i.quantity
FROM vn.itemEntryOut i FROM vn.itemEntryOut i

View File

@ -0,0 +1,32 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`intrastat_estimateNet`(
vSelf INT,
vStems INT
)
RETURNS double
DETERMINISTIC
BEGIN
/**
* Calcula un valor neto estimado en función de
* datos históricos de facturas intrastat.
*
* @param vSelf Id de intrastat
* @param vStems Número de unidades
* @return vNet
*/
DECLARE vNet DOUBLE;
SELECT ROUND(vStems / (SUM(average) / COUNT(average)), 2) INTO vNet
FROM (
SELECT *, stems / net average
FROM invoiceInIntrastat
WHERE intrastatFk = vSelf
AND net
AND stems > 0
ORDER BY dated DESC
LIMIT 20
) sub;
RETURN vNet/2;
END$$
DELIMITER ;

View File

@ -1,79 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`fustControl`(vFromDated DATE, vToDated DATE)
BEGIN
DECLARE vSijsnerClientFk INT DEFAULT 19752;
DECLARE vDateStart DATETIME;
DECLARE vDateEnd DATETIME;
SET vDateStart = vFromDated;
SET vDateEnd = util.Dayend(vToDated);
SELECT p.id FustCode,
CAST(sent.stucks AS DECIMAL(10,0)) FH,
CAST(tp.stucks AS DECIMAL(10,0)) Tickets,
CAST(-sj.stucks AS DECIMAL(10,0)) Sijsner,
CAST(IFNULL(sent.stucks,0) - IFNULL(tp.stucks,0) + IFNULL(sj.stucks,0) AS DECIMAL(10,0)) saldo
FROM vn.packaging p
LEFT JOIN (
SELECT FustCode, sum(fustQuantity) stucks
FROM (
SELECT IFNULL(pe.equivalentFk ,b.packagingFk) FustCode, s.quantity / b.packing AS fustQuantity
FROM vn.sale s
JOIN vn.ticket t ON t.id = s.ticketFk
JOIN vn.warehouse w ON w.id = t.warehouseFk
JOIN vn.warehouseAlias wa ON wa.id = w.aliasFk
JOIN cache.last_buy lb ON lb.item_id = s.itemFk AND lb.warehouse_id = t.warehouseFk
JOIN vn.buy b ON b.id = lb.buy_id
JOIN vn.packaging p ON p.id = b.packagingFk
LEFT JOIN vn.packageEquivalent pe ON pe.packagingFk = p.id
JOIN vn.address a ON a.id = t.addressFk
JOIN vn.province p2 ON p2.id = a.provinceFk
JOIN vn.country c ON c.id = p2.countryFk
WHERE t.shipped BETWEEN vDateStart AND vDateEnd
AND wa.name = 'VNH'
AND p.isPackageReturnable
AND c.country = 'FRANCIA') sub
GROUP BY FustCode) sent ON sent.FustCode = p.id
LEFT JOIN (
SELECT FustCode, sum(quantity) stucks
FROM (
SELECT IFNULL(pe.equivalentFk ,tp.packagingFk) FustCode, tp.quantity
FROM vn.ticketPackaging tp
JOIN vn.ticket t ON t.id = tp.ticketFk
JOIN vn.warehouse w ON w.id = t.warehouseFk
JOIN vn.warehouseAlias wa ON wa.id = w.aliasFk
JOIN vn.packaging p ON p.id = tp.packagingFk
LEFT JOIN vn.packageEquivalent pe ON pe.packagingFk = p.id
JOIN vn.address a ON a.id = t.addressFk
JOIN vn.province p2 ON p2.id = a.provinceFk
JOIN vn.country c ON c.id = p2.countryFk
WHERE t.shipped BETWEEN vDateStart AND vDateEnd
AND wa.name = 'VNH'
AND p.isPackageReturnable
AND c.country = 'FRANCIA'
AND t.clientFk != vSijsnerClientFk
AND tp.quantity > 0) sub
GROUP BY FustCode) tp ON tp.FustCode = p.id
LEFT JOIN (
SELECT FustCode, sum(quantity) stucks
FROM (
SELECT IFNULL(pe.equivalentFk ,tp.packagingFk) FustCode, tp.quantity
FROM vn.ticketPackaging tp
JOIN vn.ticket t ON t.id = tp.ticketFk
JOIN vn.warehouse w ON w.id = t.warehouseFk
JOIN vn.warehouseAlias wa ON wa.id = w.aliasFk
JOIN vn.packaging p ON p.id = tp.packagingFk
LEFT JOIN vn.packageEquivalent pe ON pe.packagingFk = p.id
WHERE t.shipped BETWEEN TIMESTAMPADD(DAY, 1, vDateStart ) AND TIMESTAMPADD(DAY, 1, vDateEnd )
AND wa.name = 'VNH'
AND p.isPackageReturnable
AND t.clientFk = vSijsnerClientFk) sub
GROUP BY FustCode) sj ON sj.FustCode = p.id
WHERE sent.stucks
OR tp.stucks
OR sj.stucks;
END$$
DELIMITER ;

View File

@ -1,36 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`fustControlDetail`(vFromDated DATE, vToDated DATE)
BEGIN
DECLARE vSijsnerClientFk INT DEFAULT 19752;
DECLARE vDateStart DATETIME;
DECLARE vDateEnd DATETIME;
SET vDateStart = vFromDated;
SET vDateEnd = util.Dayend(vToDated);
SELECT a.nickname shopName,
a.city ,
IFNULL(pe.equivalentFk ,tp.packagingFk) FustCode,
tp.quantity,
tp.ticketFk,
CONCAT('From ', vFromDated,' to ', vToDated) AS dateRange
FROM vn.ticketPackaging tp
JOIN vn.ticket t ON t.id = tp.ticketFk
JOIN vn.warehouse w ON w.id = t.warehouseFk
JOIN vn.warehouseAlias wa ON wa.id = w.aliasFk
JOIN vn.packaging p ON p.id = tp.packagingFk
LEFT JOIN vn.packageEquivalent pe ON pe.packagingFk = p.id
JOIN vn.address a ON a.id = t.addressFk
JOIN vn.province p2 ON p2.id = a.provinceFk
JOIN vn.country c ON c.id = p2.countryFk
WHERE t.shipped BETWEEN vFromDated AND util.dayend(vToDated)
AND wa.name = 'VNH'
AND p.isPackageReturnable
AND c.country = 'FRANCIA'
AND t.clientFk != vSijsnerClientFk
AND tp.quantity > 0;
END$$
DELIMITER ;

View File

@ -0,0 +1,234 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `sage`.`invoiceIn_add`(vInvoiceInFk INT, vXDiarioFk INT)
BEGIN
/**
* Traslada la info de contabilidad relacionada con las facturas recibidas
*
* @vInvoiceInFk Factura recibida
* @vXDiarioFk Id tabla XDiario
*/
DECLARE vInvoiceInOriginalFk INT;
DECLARE vDone BOOL DEFAULT FALSE;
DECLARE vBase DOUBLE;
DECLARE vVat DOUBLE;
DECLARE vRate DOUBLE;
DECLARE vTransactionCode INT;
DECLARE vCounter INT DEFAULT 0;
DECLARE vTransactionCodeOld INT;
DECLARE vTaxCode INT;
DECLARE vTaxCodeOld INT;
DECLARE vOperationCode VARCHAR(1);
DECLARE vIsIntracommunity BOOL DEFAULT FALSE;
DECLARE vSerialDua VARCHAR(1) DEFAULT 'D';
DECLARE vInvoiceTypeReceived VARCHAR(1);
DECLARE vInvoiceTypeInformative VARCHAR(1);
DECLARE vIsInformativeExportation BOOL DEFAULT FALSE;
DECLARE vCursor CURSOR FOR
SELECT it.taxableBase,
CAST((( it.taxableBase / 100) * t.PorcentajeIva) AS DECIMAL (10,2)),
t.PorcentajeIva,
it.transactionTypeSageFk,
it.taxTypeSageFk,
tty.isIntracommunity,
tt.ClaveOperacionDefecto
FROM vn.invoiceIn i
JOIN vn.invoiceInTax it ON it.InvoiceInFk = i.id
JOIN TiposIva t ON t.CodigoIva = it.taxTypeSageFk
JOIN taxType tty ON tty.id = t.CodigoIva
JOIN TiposTransacciones tt ON tt.CodigoTransaccion = it.transactionTypeSageFk
LEFT JOIN vn.dua d ON d.id = vInvoiceInFk
WHERE i.id = vInvoiceInFk
AND d.id IS NULL;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
DELETE FROM movContaIVA
WHERE id = vXDiarioFk;
SELECT codeSage INTO vInvoiceTypeReceived
FROM invoiceType WHERE code ='received';
SELECT codeSage INTO vInvoiceTypeInformative
FROM invoiceType WHERE code ='informative';
INSERT INTO movContaIVA(id, LibreA1)
VALUES (vXDiarioFk, vInvoiceInFk);
OPEN vCursor;
l: LOOP
FETCH vCursor INTO vBase,
vVat,
vRate,
vTransactionCode,
vTaxCode,
vIsIntracommunity,
vOperationCode;
IF vDone THEN
LEAVE l;
END IF;
SET vTransactionCodeOld = vTransactionCode;
SET vTaxCodeOld = vTaxCode;
IF vOperationCode IS NOT NULL THEN
UPDATE movContaIVA
SET ClaveOperacionFactura = vOperationCode
WHERE id = vXDiarioFk;
END IF;
SET vCounter = vCounter + 1;
CASE vCounter
WHEN 1 THEN
UPDATE movContaIVA
SET BaseIva1 = vBase,
PorIva1 = vRate,
CuotaIva1 = vVat,
CodigoTransaccion1 = vTransactionCode,
CodigoIva1 = vTaxCode
WHERE id = vXDiarioFk;
WHEN 2 THEN
UPDATE movContaIVA
SET BaseIva2 = vBase,
PorIva2 = vRate,
CuotaIva2 = vVat,
CodigoTransaccion2 = vTransactionCode,
CodigoIva2 = vTaxCode
WHERE id = vXDiarioFk;
WHEN 3 THEN
UPDATE movContaIVA
SET BaseIva3 = vBase,
PorIva3 = vRate,
CuotaIva3 = vVat,
CodigoTransaccion3 = vTransactionCode,
CodigoIva3 = vTaxCode
WHERE id = vXDiarioFk;
WHEN 4 THEN
UPDATE movContaIVA
SET BaseIva4 = vBase,
PorIva4 = vRate,
CuotaIva4 = vVat,
CodigoTransaccion4 = vTransactionCode,
CodigoIva4 = vTaxCode
WHERE id = vXDiarioFk;
ELSE
SELECT vXDiarioFk INTO vXDiarioFk;
END CASE;
IF vIsIntracommunity THEN
UPDATE movContaIVA
SET Intracomunitaria = TRUE
WHERE id = vXDiarioFk;
END IF;
SET vTransactionCodeOld = vTransactionCode;
SET vTaxCodeOld = vTaxCode;
END LOOP;
CLOSE vCursor;
SELECT d.ASIEN AND x.ASIEN IS NULL INTO vIsInformativeExportation
FROM vn.dua d
LEFT JOIN vn.XDiario x ON x.ASIEN = d.ASIEN
AND x.SERIE = vSerialDua COLLATE utf8mb3_unicode_ci
WHERE d.ASIEN = (
SELECT ASIEN
FROM vn.XDiario
WHERE id = vXDiarioFk)
LIMIT 1;
UPDATE movContaIVA mci
JOIN tmp.invoiceIn ii ON ii.id = vInvoiceInFk
JOIN vn.XDiario x ON x.id = mci.id
LEFT JOIN tmp.invoiceDua id ON id.id = mci.id
JOIN vn.supplier s ON s.id = ii.supplierFk
JOIN Naciones n ON n.countryFk = s.countryFk
SET mci.CodigoDivisa = ii.currencyFk,
mci.Año = YEAR(ii.issued),
mci.Serie = ii.serial,
mci.Factura = ii.id,
mci.FechaFactura = ii.issued,
mci.ImporteFactura = IFNULL(mci.BaseIva1, 0) + IFNULL(mci.CuotaIva1, 0) +
IFNULL(mci.BaseIva2, 0) + IFNULL(mci.CuotaIva2, 0) +
IFNULL(mci.BaseIva3, 0) + IFNULL(mci.CuotaIva3, 0) +
IFNULL(mci.BaseIva4, 0) + IFNULL(mci.CuotaIva4, 0),
mci.TipoFactura = IF(id.id,
IF( ii.serial = vSerialDua COLLATE utf8mb3_unicode_ci, vInvoiceTypeReceived, vInvoiceTypeInformative),
IF(vIsInformativeExportation,vInvoiceTypeInformative, vInvoiceTypeReceived)),
mci.CodigoCuentaFactura = x.SUBCTA,
mci.CifDni = IF(LEFT(TRIM(s.nif), 2) = n.SiglaNacion, SUBSTRING(TRIM(s.nif), 3), s.nif),
mci.Nombre = s.name,
mci.SiglaNacion = n.SiglaNacion,
mci.EjercicioFactura = YEAR(ii.issued),
mci.FechaOperacion = ii.issued,
mci.MantenerAsiento = TRUE,
mci.SuFacturaNo = ii.supplierRef,
mci.IvaDeducible1 = IF(id.id, FALSE, IF(IFNULL(mci.BaseIva1, FALSE) = FALSE, FALSE, ii.isVatDeductible)),
mci.IvaDeducible2 = IF(id.id, FALSE, IF(IFNULL(mci.BaseIva2, FALSE) = FALSE, FALSE, ii.isVatDeductible)),
mci.IvaDeducible3 = IF(id.id, FALSE, IF(IFNULL(mci.BaseIva3, FALSE) = FALSE, FALSE, ii.isVatDeductible)),
mci.IvaDeducible4 = IF(id.id, FALSE, IF(IFNULL(mci.BaseIva4, FALSE) = FALSE, FALSE, ii.isVatDeductible)),
mci.FechaFacturaOriginal = x.FECHA_EX
WHERE mci.id = vXDiarioFk;
-- RETENCIONES
UPDATE movContaIVA mci
JOIN vn.invoiceIn ii ON ii.id = vInvoiceInFk
JOIN vn.XDiario x ON x.id = mci.id
JOIN vn.supplier s ON s.id = supplierFk
JOIN vn.invoiceInTax iit ON iit.invoiceInFk = ii.id
JOIN vn.expense e ON e.id = iit.expenseFk
JOIN TiposRetencion t ON t.CodigoRetencion = ii.withholdingSageFk
LEFT JOIN tmp.invoiceDua id ON id.id = mci.id
JOIN (SELECT SUM(x2.BASEEURO) taxableBase, SUM(x2.EURODEBE) taxBase
FROM vn.XDiario x1
JOIN vn.XDiario x2 ON x1.ASIEN = x2.ASIEN
WHERE x2.BASEEURO <> 0
AND x1.id = vXDiarioFk
)sub
JOIN ClavesOperacion co ON co.Descripcion = 'Arrendamiento de locales de negocio'
SET mci.CodigoRetencion = t.CodigoRetencion,
mci.ClaveOperacionFactura = IF( t.Retencion = 'ARRENDAMIENTO Y SUBARRENDAMIENTO', co.ClaveOperacionFactura_, mci.ClaveOperacionFactura),
mci.BaseRetencion = IF (t.Retencion = 'ACTIVIDADES AGRICOLAS O GANADERAS', sub.taxableBase + sub.taxBase, sub.taxableBase),
mci.PorRetencion = t.PorcentajeRetencion,
mci.ImporteRetencion = iit.taxableBase * - 1
WHERE mci.id = vXDiarioFk
AND e.name = 'Retenciones'
AND id.id IS NULL;
SELECT correctedFk INTO vInvoiceInOriginalFk
FROM vn.invoiceInCorrection
WHERE correctingFk = vInvoiceInFk;
IF vInvoiceInOriginalFk THEN
UPDATE movContaIVA mci
JOIN vn.invoiceInRefund iir ON iir.invoiceInRefundFk = vInvoiceInFk
JOIN (SELECT issued,
SUM(sub.taxableBase) taxableBase,
SUM(ROUND((sub.taxableBase * sub.PorcentajeIva) / 100 , 2)) vat
FROM(SELECT issued,
SUM(iit.taxableBase) taxableBase,
ti.PorcentajeIva
FROM vn.invoiceIn i
JOIN vn.invoiceInTax iit ON iit.invoiceInFk = i.id
JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk
WHERE i.id = vInvoiceInOriginalFk
GROUP BY ti.CodigoIva)sub
)invoiceInOriginal
JOIN ClavesOperacion co ON co.Descripcion = 'Factura rectificativa'
SET mci.TipoRectificativa = iir.refundCategoryFk,
mci.ClaseAbonoRectificativas = iir.refundType,
mci.FechaFacturaOriginal = invoiceInOriginal.issued,
mci.FechaOperacion = invoiceInOriginal.issued,
mci.BaseImponibleOriginal = invoiceInOriginal.taxableBase,
mci.CuotaIvaOriginal = invoiceInOriginal.vat,
mci.ClaveOperacionFactura = co.ClaveOperacionFactura_
WHERE mci.id = vXDiarioFk;
END IF;
END$$
DELIMITER ;

View File

@ -8,16 +8,9 @@ BEGIN
* @param vItemFk Identificador de vn.item * @param vItemFk Identificador de vn.item
* @param vSectorFk Identificador de vn.sector * @param vSectorFk Identificador de vn.sector
*/ */
DECLARE vWarehouseAliasFk INT;
SELECT w.aliasFk INTO vWarehouseAliasFk
FROM vn.sector s
JOIN vn.warehouse w ON w.id = s.warehouseFk
WHERE s.id = vSectorFk;
SELECT ish.shelvingFk shelving, SELECT ish.shelvingFk shelving,
p.code parking, p.code parking,
sum(ish.visible) as stockTotal, SUM(ish.visible) stockTotal,
ish.created, ish.created,
p.pickingOrder p.pickingOrder
FROM vn.itemShelving ish FROM vn.itemShelving ish
@ -25,10 +18,12 @@ BEGIN
JOIN vn.parking p ON p.id = sh.parkingFk JOIN vn.parking p ON p.id = sh.parkingFk
JOIN vn.sector sc ON sc.id = p.sectorFk JOIN vn.sector sc ON sc.id = p.sectorFk
JOIN vn.warehouse w ON w.id = sc.warehouseFk JOIN vn.warehouse w ON w.id = sc.warehouseFk
WHERE w.aliasFk = vWarehouseAliasFk WHERE sc.id = vSectorFk
AND ish.visible > 0 AND ish.visible > 0
AND ish.itemFk = vItemFk AND ish.itemFk = vItemFk
GROUP BY ish.id GROUP BY ish.id
ORDER BY (sc.id = vSectorFk) DESC, sh.priority DESC, ish.created, p.pickingOrder; ORDER BY sh.priority DESC,
ish.created,
p.pickingOrder;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -1,7 +1,13 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingRadar`(vSectorFk INT) CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingRadar`(
vSectorFk INT
)
proc:BEGIN proc:BEGIN
/**
* Calcula la información detallada respecto un sector.
*
* @param vSectorFk Id de sector
*/
DECLARE vCalcVisibleFk INT; DECLARE vCalcVisibleFk INT;
DECLARE vCalcAvailableFk INT; DECLARE vCalcAvailableFk INT;
DECLARE hasFatherSector BOOLEAN; DECLARE hasFatherSector BOOLEAN;

View File

@ -1,12 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`warehouse_afterUpdate`
AFTER UPDATE ON `warehouse`
FOR EACH ROW
BEGIN
IF NEW.isFeedStock IS TRUE AND OLD.isFeedStock IS FALSE THEN
INSERT IGNORE INTO warehouseAlias(`name`) VALUES(NEW.`name`);
INSERT IGNORE INTO warehouseJoined(warehouseFk, warehouseAliasFk)
VALUES(NEW.id,LAST_INSERT_ID());
END IF;
END$$
DELIMITER ;

View File

@ -1,7 +1,7 @@
CREATE OR REPLACE DEFINER=`root`@`localhost` CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER SQL SECURITY DEFINER
VIEW `vn`.`itemShelvingAvailable` VIEW `vn`.`itemShelvingAvailable`
AS SELECT `s`.`id` AS `saleFk`, AS SELECT `s`.`id` `saleFk`,
`tst`.`updated` AS `Modificado`, `tst`.`updated` AS `Modificado`,
`s`.`ticketFk` AS `ticketFk`, `s`.`ticketFk` AS `ticketFk`,
0 AS `isPicked`, 0 AS `isPicked`,
@ -38,7 +38,7 @@ FROM (
) )
JOIN `vn`.`agencyMode` `am` ON(`am`.`id` = `t`.`agencyModeFk`) JOIN `vn`.`agencyMode` `am` ON(`am`.`id` = `t`.`agencyModeFk`)
) )
JOIN `vn`.`ticketStateToday` `tst` ON(`tst`.`ticket` = `t`.`id`) JOIN `vn`.`ticketStateToday` `tst` ON(`tst`.`ticketFk` = `t`.`id`)
) )
JOIN `vn`.`state` `st` ON(`st`.`id` = `tst`.`state`) JOIN `vn`.`state` `st` ON(`st`.`id` = `tst`.`state`)
) )

View File

@ -1,16 +1,15 @@
CREATE OR REPLACE DEFINER=`root`@`localhost` CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER SQL SECURITY DEFINER
VIEW `vn`.`ticketStateToday` VIEW `vn`.`ticketStateToday`
AS SELECT `ts`.`ticketFk` AS `ticket`, AS SELECT
`ts`.`ticketFk` AS `ticketFk`,
`ts`.`state` AS `state`, `ts`.`state` AS `state`,
`ts`.`productionOrder` AS `productionOrder`, `ts`.`productionOrder` AS `productionOrder`,
`ts`.`alertLevel` AS `alertLevel`, `ts`.`alertLevel` AS `alertLevel`,
`ts`.`userFk` AS `worker`, `ts`.`userFk` AS `userFk`,
`ts`.`code` AS `code`, `ts`.`code` AS `code`,
`ts`.`updated` AS `updated`, `ts`.`updated` AS `updated`,
`ts`.`isPicked` AS `isPicked` `ts`.`isPicked` AS `isPicked`
FROM ( FROM `ticketState` `ts`
`vn`.`ticketState` `ts` JOIN `ticket` `t` ON `t`.`id` = `ts`.`ticketFk`
JOIN `vn`.`ticket` `t` ON(`t`.`id` = `ts`.`ticketFk`) WHERE `t`.`shipped` BETWEEN `util`.`VN_CURDATE`() AND `MIDNIGHT`(`util`.`VN_CURDATE`());
)
WHERE `t`.`shipped` BETWEEN `util`.`VN_CURDATE`() AND `MIDNIGHT`(`util`.`VN_CURDATE`())

View File

@ -1,6 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn`.`warehouseJoined`
AS SELECT `wj`.`warehouse_id` AS `warehouseFk`,
`wj`.`warehouse_alias_id` AS `warehouseAliasFk`
FROM `vn2008`.`warehouse_joined` `wj`

View File

@ -9,12 +9,11 @@ CREATE OR REPLACE DEFINER=`root`@`localhost`
lhp.m3, lhp.m3,
dl.minSpeed dl.minSpeed
FROM ticket t FROM ticket t
JOIN ticketStateToday tst ON tst.ticket = t.id JOIN ticketStateToday tst ON tst.ticketFk = t.id
JOIN state s ON s.id = tst.state JOIN state s ON s.id = tst.state
JOIN saleVolume sv ON sv.ticketFk = t.id JOIN saleVolume sv ON sv.ticketFk = t.id
LEFT JOIN lastHourProduction lhp ON lhp.warehouseFk = t.warehouseFk LEFT JOIN lastHourProduction lhp ON lhp.warehouseFk = t.warehouseFk
JOIN warehouse w ON w.id = t.warehouseFk JOIN warehouse w ON w.id = t.warehouseFk
JOIN warehouseAlias wa ON wa.id = w.aliasFk
STRAIGHT_JOIN `zone` z ON z.id = t.zoneFk STRAIGHT_JOIN `zone` z ON z.id = t.zoneFk
LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk
AND zc.dated = util.VN_CURDATE() AND zc.dated = util.VN_CURDATE()

View File

@ -1,20 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn2008`.`intrastat_neto`(intINSTRASTAT INTEGER,intUNIDADES INTEGER)
RETURNS double
DETERMINISTIC
BEGIN
DECLARE n DOUBLE;
SELECT ROUND(intUNIDADES / (SUM(MEDIA) / COUNT(media)), 2) INTO n FROM
(SELECT *, unidades / neto MEDIA
FROM intrastat_data
WHERE intrastat_id = intINSTRASTAT AND neto
AND unidades > 0
ORDER BY odbc_date DESC
LIMIT 20) t;
-- JGF 01/06 per a evitar Kg en negatiu
RETURN n/2;
END$$
DELIMITER ;

View File

@ -1,14 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn2008`.`red`(intCANTIDAD DOUBLE)
RETURNS double
DETERMINISTIC
BEGIN
DECLARE n DOUBLE;
SET n = SIGN(intCANTIDAD) * TRUNCATE( (ABS(intCANTIDAD) * 100) + 0.5001 ,0) /100 ;
RETURN n;
END$$
DELIMITER ;

View File

@ -1,82 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`desglose_volume`(IN vAgencyFk INT)
BEGIN
DECLARE vStarted DATETIME DEFAULT TIMESTAMP(util.VN_CURDATE());
DECLARE vEnded DATETIME DEFAULT TIMESTAMP(util.VN_CURDATE(), '23:59:59');
DECLARE vIsHolland BOOL;
SELECT (wa.name = 'Holanda') INTO vIsHolland
FROM vn.agency a
JOIN vn.warehouseAlias wa ON wa.id = a.warehouseAliasFk
WHERE a.id = vAgencyFk;
IF vIsHolland THEN
DROP TEMPORARY TABLE IF EXISTS tmp.ticket_PackagingEstimated;
CREATE TEMPORARY TABLE tmp.ticket_PackagingEstimated
(
ticketFk INT PRIMARY KEY
,carros DECIMAL(5,1) DEFAULT 0
);
INSERT INTO tmp.ticket_PackagingEstimated(ticketFk, carros)
SELECT sv.ticketFk, ROUND(vc.dutchCompressionRate * sum(sv.volume) / vc.trolleyM3,0)
FROM vn.ticket t
JOIN vn.saleVolume sv ON sv.ticketFk = t.id
JOIN vn.agencyMode am ON am.id = t.agencyModeFk
JOIN vn.volumeConfig vc
WHERE t.shipped BETWEEN vStarted AND vEnded
AND am.agencyFk = vAgencyFk
GROUP BY t.id;
SELECT a.nickname Provincia,
count(*) expediciones,
0 Bultos,
sum(tpe.carros) Prevision
FROM vn.ticket t
JOIN vn.address a ON a.id = t.addressFk
JOIN tmp.ticket_PackagingEstimated tpe ON tpe.ticketFk = t.id
GROUP BY a.nickname;
ELSE
DROP TEMPORARY TABLE IF EXISTS tmp.ticket_PackagingEstimated;
CREATE TEMPORARY TABLE tmp.ticket_PackagingEstimated
(
ticketFk INT PRIMARY KEY
,boxes INT DEFAULT 0
);
INSERT INTO tmp.ticket_PackagingEstimated(ticketFk, boxes)
SELECT sv.ticketFk, CEIL(1000 * sum(sv.volume) / vc.standardFlowerBox)
FROM vn.ticket t
JOIN vn.saleVolume sv ON sv.ticketFk = t.id
JOIN vn.agencyMode am ON am.id = t.agencyModeFk
JOIN vn.volumeConfig vc
WHERE t.shipped BETWEEN vStarted AND vEnded
AND IFNULL(t.packages,0) = 0
AND am.agencyFk = vAgencyFk
GROUP BY t.id;
SELECT p.name Provincia,
count(*) expediciones,
sum(t.packages) Bultos,
sum(tpe.boxes) Prevision
FROM vn.ticket t
JOIN vn.address a ON a.id = t.addressFk
JOIN vn.province p ON a.provinceFk = p.id
JOIN vn.agencyMode am ON am.id = t.agencyModeFk
JOIN tmp.ticket_PackagingEstimated tpe ON tpe.ticketFk = t.id
WHERE t.warehouseFk = 60
AND t.shipped BETWEEN vStarted AND vEnded
AND am.agencyFk = vAgencyFk
GROUP BY p.name;
END IF;
SELECT * FROM tmp.ticket_PackagingEstimated;
DROP TEMPORARY TABLE tmp.ticket_PackagingEstimated;
END$$
DELIMITER ;

View File

@ -1,7 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`Articles_botanical`
AS SELECT `ab`.`itemFk` AS `Id_Article`,
`ab`.`genusFk` AS `genus_id`,
`ab`.`specieFk` AS `specie_id`
FROM `vn`.`itemBotanical` `ab`

View File

@ -1,8 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`Equipos`
AS SELECT `h`.`code` AS `alias`,
`h`.`description` AS `descripcion`,
`h`.`workerFk` AS `trabajador_id`,
`h`.`windowsSerial` AS `windowsSerial`
FROM `vn`.`host` `h`

View File

@ -1,6 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`Prioridades`
AS SELECT `qp`.`id` AS `Id_Prioridad`,
`qp`.`priority` AS `Prioridad`
FROM `vn`.`queuePriority` `qp`

View File

@ -4,7 +4,6 @@ CREATE OR REPLACE DEFINER=`root`@`localhost`
AS SELECT `a`.`id` AS `agency_id`, AS SELECT `a`.`id` AS `agency_id`,
`a`.`name` AS `name`, `a`.`name` AS `name`,
`a`.`warehouseFk` AS `warehouse_id`, `a`.`warehouseFk` AS `warehouse_id`,
`a`.`warehouseAliasFk` AS `warehouse_alias_id`,
`a`.`isOwn` AS `propios`, `a`.`isOwn` AS `propios`,
`a`.`workCenterFk` AS `workCenterFk` `a`.`workCenterFk` AS `workCenterFk`
FROM `vn`.`agency` `a` FROM `vn`.`agency` `a`

View File

@ -1,6 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`bionic_updating_options`
AS SELECT `t`.`id` AS `buo_id`,
`t`.`description` AS `description`
FROM `vn`.`ticketUpdateAction` `t`

View File

@ -1,6 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`businessReasonEnd`
AS SELECT `b`.`id` AS `id`,
`b`.`reason` AS `reason`
FROM `vn`.`businessReasonEnd` `b`

View File

@ -1,6 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`cl_dev`
AS SELECT `c`.`id` AS `id`,
`c`.`description` AS `devolucion`
FROM `vn`.`claimRedelivery` `c`

View File

@ -1,7 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`cl_est`
AS SELECT `c`.`id` AS `id`,
`c`.`description` AS `estado`,
`c`.`roleFk` AS `roleFk`
FROM `vn`.`claimState` `c`

View File

@ -1,7 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`deliveryPoint`
AS SELECT `dp`.`id` AS `id`,
`dp`.`name` AS `name`,
`dp`.`ubication` AS `ubication`
FROM `vn`.`deliveryPoint` `dp`

View File

@ -1,6 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`device_user`
AS SELECT `dpu`.`deviceProductionFk` AS `device_id`,
`dpu`.`userFk` AS `user_id`
FROM `vn`.`deviceProductionUser` `dpu`

View File

@ -1,10 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`edi_feature`
AS SELECT `edi`.`feature`.`item_id` AS `item_id`,
`edi`.`feature`.`feature_type_id` AS `feature_type_id`,
`edi`.`feature`.`feature_value` AS `feature_value`,
`edi`.`feature`.`entry_date` AS `entry_date`,
`edi`.`feature`.`expiry_date` AS `expiry_date`,
`edi`.`feature`.`change_date_time` AS `change_date_time`
FROM `edi`.`feature`

View File

@ -1,9 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`edi_genus`
AS SELECT `edi`.`genus`.`genus_id` AS `genus_id`,
`edi`.`genus`.`latin_genus_name` AS `latin_genus_name`,
`edi`.`genus`.`entry_date` AS `entry_date`,
`edi`.`genus`.`expiry_date` AS `expiry_date`,
`edi`.`genus`.`change_date_time` AS `change_date_time`
FROM `edi`.`genus`

View File

@ -1,11 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`edi_item_feature`
AS SELECT `edi`.`item_feature`.`item_id` AS `item_id`,
`edi`.`item_feature`.`presentation_order` AS `presentation_order`,
`edi`.`item_feature`.`feature` AS `feature`,
`edi`.`item_feature`.`regulation_type` AS `regulation_type`,
`edi`.`item_feature`.`entry_date` AS `entry_date`,
`edi`.`item_feature`.`expiry_date` AS `expiry_date`,
`edi`.`item_feature`.`change_date_time` AS `change_date_time`
FROM `edi`.`item_feature`

View File

@ -1,10 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`edi_plant`
AS SELECT `edi`.`plant`.`plant_id` AS `plant_id`,
`edi`.`plant`.`genus_id` AS `genus_id`,
`edi`.`plant`.`specie_id` AS `specie_id`,
`edi`.`plant`.`entry_date` AS `entry_date`,
`edi`.`plant`.`expiry_date` AS `expiry_date`,
`edi`.`plant`.`change_date_time` AS `change_date_time`
FROM `edi`.`plant`

View File

@ -1,10 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`edi_type`
AS SELECT `edi`.`type`.`type_id` AS `type_id`,
`edi`.`type`.`type_group_id` AS `type_group_id`,
`edi`.`type`.`description` AS `description`,
`edi`.`type`.`entry_date` AS `entry_date`,
`edi`.`type`.`expiry_date` AS `expiry_date`,
`edi`.`type`.`change_date_time` AS `change_date_time`
FROM `edi`.`type`

View File

@ -1,10 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`edi_value`
AS SELECT `edi`.`value`.`type_id` AS `type_id`,
`edi`.`value`.`type_value` AS `type_value`,
`edi`.`value`.`type_description` AS `type_description`,
`edi`.`value`.`entry_date` AS `entry_date`,
`edi`.`value`.`expiry_date` AS `expiry_date`,
`edi`.`value`.`change_date_time` AS `change_date_time`
FROM `edi`.`value`

View File

@ -1,9 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`escritos`
AS SELECT `s`.`id` AS `id`,
`s`.`code` AS `abrev`,
`s`.`description` AS `descripcion`,
`s`.`isVisible` AS `visible`,
`s`.`hasCompany` AS `hasCompany`
FROM `vn`.`sample` `s`

View File

@ -1,10 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`person_user`
AS SELECT `u`.`id` AS `id`,
`u`.`role` AS `mysql_user_id`,
`u`.`name` AS `name`,
`u`.`password` AS `password`,
`u`.`active` AS `active`,
`u`.`lastPassChange` AS `last_pass_change`
FROM `account`.`user` `u`

View File

@ -1,9 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`person_user_idtrabajador`
AS SELECT `t`.`Id_Trabajador` AS `Id_Trabajador`
FROM (
`vn2008`.`person_user` `p`
JOIN `vn2008`.`Trabajadores` `t` ON(`p`.`id` = `t`.`user_id`)
)
WHERE `t`.`user_id` = `account`.`myUser_getId`()

View File

@ -1,7 +0,0 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn2008`.`reference_min`
AS SELECT `rc`.`dated` AS `date`,
`rc`.`value` AS `rate`,
`rc`.`currencyFk` AS `moneda_id`
FROM `vn`.`referenceCurrent` `rc`

View File

@ -0,0 +1,4 @@
UPDATE salix.ACL
SET property='clone'
WHERE model = 'Sale'
AND property = 'refund'

View File

@ -0,0 +1,8 @@
ALTER TABLE vn.agency
CHANGE warehouseAliasFk warehouseAliasFk__ SMALLINT(5) UNSIGNED DEFAULT NULL NULL COMMENT '@deprecated 2024-01-23 refs #5167';
ALTER TABLE vn.warehouse
CHANGE aliasFk aliasFk__ SMALLINT(5) UNSIGNED DEFAULT NULL NULL COMMENT '@deprecated 2024-01-23 refs #5167';
RENAME TABLE vn.warehouseAlias TO vn.warehouseAlias__;
ALTER TABLE vn.warehouseAlias__ COMMENT='@deprecated 2024-01-23 refs #5167';

View File

@ -0,0 +1,4 @@
-- Place your SQL code here
UPDATE vn.supplier
SET name = UPPER(name),
nickname = UPPER(nickname);

View File

@ -0,0 +1 @@
REVOKE EXECUTE ON FUNCTION vn2008.red FROM hrBoss, salesPerson;

View File

@ -0,0 +1,4 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES
('InvoiceIn', 'corrective', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
('InvoiceInCorrection', '*', '*', 'ALLOW', 'ROLE', 'administrative');

View File

@ -0,0 +1,17 @@
CREATE TABLE IF NOT EXISTS `vn`.`invoiceInCorrection` (
`correctingFk` mediumint(8) UNSIGNED NOT NULL COMMENT 'Factura rectificativa',
`correctedFk` mediumint(8) UNSIGNED NOT NULL COMMENT 'Factura rectificada',
`cplusRectificationTypeFk` int(10) UNSIGNED NOT NULL,
`siiTypeInvoiceOutFk` int(10) UNSIGNED NOT NULL,
`invoiceCorrectionTypeFk` int(11) NOT NULL DEFAULT 3,
PRIMARY KEY (`correctingFk`),
KEY `invoiceInCorrection_correctedFk` (`correctedFk`),
KEY `invoiceInCorrection_cplusRectificationTypeFk` (`cplusRectificationTypeFk`),
KEY `invoiceInCorrection_siiTypeInvoiceOut` (`siiTypeInvoiceOutFk`),
KEY `invoiceInCorrection_invoiceCorrectionTypeFk` (`invoiceCorrectionTypeFk`),
CONSTRAINT `invoiceInCorrection_correctedFk` FOREIGN KEY (`correctedFk`) REFERENCES `invoiceIn` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `invoiceInCorrection_correctingFk` FOREIGN KEY (`correctingFk`) REFERENCES `invoiceIn` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `invoiceInCorrection_siiTypeInvoiceOut` FOREIGN KEY (`siiTypeInvoiceOutFk`) REFERENCES `siiTypeInvoiceOut` (`id`) ON UPDATE CASCADE,
CONSTRAINT `invoiceInCorrection_invoiceCorrectionTypeFk` FOREIGN KEY (`invoiceCorrectionTypeFk`) REFERENCES `invoiceCorrectionType` (`id`) ON UPDATE CASCADE,
CONSTRAINT `invoiceInCorrection_cplusRectificationTypeFk` FOREIGN KEY (`cplusRectificationTypeFk`) REFERENCES `cplusRectificationType` (`id`) ON UPDATE CASCADE
);

View File

@ -0,0 +1 @@
REVOKE SELECT ON TABLE vn2008.reference_min FROM logistic;

View File

@ -0,0 +1 @@
REVOKE SELECT ON TABLE vn2008.Articles_botanical FROM buyer, administrative;

View File

@ -24,7 +24,7 @@ describe('Supplier summary & descriptor path', () => {
it(`should confirm there's data on the summary header`, async() => { it(`should confirm there's data on the summary header`, async() => {
const result = await page.waitToGetProperty(selectors.supplierSummary.header, 'innerText'); const result = await page.waitToGetProperty(selectors.supplierSummary.header, 'innerText');
expect(result).toContain('Plants SL - 1'); expect(result).toContain('PLANTS SL - 1');
}); });
it(`should confirm there's data on the summary basic data`, async() => { it(`should confirm there's data on the summary basic data`, async() => {

View File

@ -24,7 +24,7 @@ describe('Supplier fiscal data path', () => {
country: null, country: null,
postcode: null, postcode: null,
city: 'Valencia', city: 'Valencia',
socialName: 'Farmer King SL', socialName: 'FARMER KING SL',
taxNumber: '12345678Z', taxNumber: '12345678Z',
account: '0123456789', account: '0123456789',
sageWithholding: 'retencion estimacion objetiva', sageWithholding: 'retencion estimacion objetiva',
@ -46,7 +46,7 @@ describe('Supplier fiscal data path', () => {
country: 'España', country: 'España',
postcode: '46000', postcode: '46000',
city: 'Valencia', city: 'Valencia',
socialName: 'Farmer King SL', socialName: 'FARMER KING SL',
taxNumber: '12345678Z', taxNumber: '12345678Z',
account: '0123456789', account: '0123456789',
sageWithholding: 'RETENCION ESTIMACION OBJETIVA', sageWithholding: 'RETENCION ESTIMACION OBJETIVA',

258
front/package-lock.json generated
View File

@ -1,258 +0,0 @@
{
"name": "salix-front",
"version": "1.0.0",
"lockfileVersion": 2,
"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",
"license": "MIT",
"dependencies": {
"@uirouter/core": "6.0.8"
},
"engines": {
"node": ">=4.0.0"
},
"peerDependencies": {
"angular": ">=1.2.0"
}
},
"node_modules/@uirouter/core": {
"version": "6.0.8",
"license": "MIT",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/angular": {
"version": "1.8.3",
"license": "MIT"
},
"node_modules/angular-animate": {
"version": "1.8.2",
"license": "MIT"
},
"node_modules/angular-moment": {
"version": "1.3.0",
"license": "MIT",
"dependencies": {
"moment": ">=2.8.0 <3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/angular-translate": {
"version": "2.19.1",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.1.tgz",
"integrity": "sha512-SrU40ndnL422vXiVoqVveCmSnCzMcIXxQgnl7Cv9krOKUg6B8KZK3ddYzidHR/rxVuySezYHNDgRvzQNKwAdNQ==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"dependencies": {
"angular": "^1.8.0"
},
"engines": {
"node": "*"
}
},
"node_modules/angular-translate-loader-partial": {
"version": "2.19.0",
"license": "MIT",
"dependencies": {
"angular-translate": "~2.19.0"
}
},
"node_modules/argparse": {
"version": "1.0.10",
"license": "MIT",
"dependencies": {
"sprintf-js": "~1.0.2"
}
},
"node_modules/croppie": {
"version": "2.6.5",
"license": "MIT"
},
"node_modules/esprima": {
"version": "4.0.1",
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/js-yaml": {
"version": "3.14.1",
"license": "MIT",
"dependencies": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/mg-crud": {
"version": "1.1.2",
"license": "MIT",
"dependencies": {
"angular": "^1.6.1"
}
},
"node_modules/moment": {
"version": "2.29.4",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/oclazyload": {
"version": "0.6.3",
"license": "MIT"
},
"node_modules/require-yaml": {
"version": "0.0.1",
"license": "BSD",
"dependencies": {
"js-yaml": ""
}
},
"node_modules/require-yaml/node_modules/argparse": {
"version": "2.0.1",
"license": "Python-2.0"
},
"node_modules/require-yaml/node_modules/js-yaml": {
"version": "4.1.0",
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"license": "BSD-3-Clause"
},
"node_modules/validator": {
"version": "6.3.0",
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
}
},
"dependencies": {
"@uirouter/angularjs": {
"version": "1.0.30",
"requires": {
"@uirouter/core": "6.0.8"
}
},
"@uirouter/core": {
"version": "6.0.8"
},
"angular": {
"version": "1.8.3"
},
"angular-animate": {
"version": "1.8.2"
},
"angular-moment": {
"version": "1.3.0",
"requires": {
"moment": ">=2.8.0 <3.0.0"
}
},
"angular-translate": {
"version": "2.19.1",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.1.tgz",
"integrity": "sha512-SrU40ndnL422vXiVoqVveCmSnCzMcIXxQgnl7Cv9krOKUg6B8KZK3ddYzidHR/rxVuySezYHNDgRvzQNKwAdNQ==",
"requires": {
"angular": "^1.8.0"
}
},
"angular-translate-loader-partial": {
"version": "2.19.0",
"requires": {
"angular-translate": "~2.19.0"
}
},
"argparse": {
"version": "1.0.10",
"requires": {
"sprintf-js": "~1.0.2"
}
},
"croppie": {
"version": "2.6.5"
},
"esprima": {
"version": "4.0.1"
},
"js-yaml": {
"version": "3.14.1",
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"mg-crud": {
"version": "1.1.2",
"requires": {
"angular": "^1.6.1"
}
},
"moment": {
"version": "2.29.4"
},
"oclazyload": {
"version": "0.6.3"
},
"require-yaml": {
"version": "0.0.1",
"requires": {
"js-yaml": ""
},
"dependencies": {
"argparse": {
"version": "2.0.1"
},
"js-yaml": {
"version": "4.1.0",
"requires": {
"argparse": "^2.0.1"
}
}
}
},
"sprintf-js": {
"version": "1.0.3"
},
"validator": {
"version": "6.3.0"
}
}
}

View File

@ -8,6 +8,7 @@
"type": "git", "type": "git",
"url": "https://gitea.verdnatura.es/verdnatura/salix" "url": "https://gitea.verdnatura.es/verdnatura/salix"
}, },
"packageManager": "pnpm@8.15.1",
"dependencies": { "dependencies": {
"@uirouter/angularjs": "^1.0.20", "@uirouter/angularjs": "^1.0.20",
"angular": "^1.7.5", "angular": "^1.7.5",

156
front/pnpm-lock.yaml Normal file
View File

@ -0,0 +1,156 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies:
'@uirouter/angularjs':
specifier: ^1.0.20
version: 1.1.0(@uirouter/core@6.1.0)(angular@1.8.3)
angular:
specifier: ^1.7.5
version: 1.8.3
angular-animate:
specifier: ^1.7.8
version: 1.8.3
angular-moment:
specifier: ^1.3.0
version: 1.3.0
angular-translate:
specifier: ^2.18.1
version: 2.19.1
angular-translate-loader-partial:
specifier: ^2.18.1
version: 2.19.1
croppie:
specifier: ^2.6.5
version: 2.6.5
js-yaml:
specifier: ^3.13.1
version: 3.14.1
mg-crud:
specifier: ^1.1.2
version: 1.1.2
oclazyload:
specifier: ^0.6.3
version: 0.6.3
require-yaml:
specifier: 0.0.1
version: 0.0.1
validator:
specifier: ^6.3.0
version: 6.3.0
packages:
/@uirouter/angularjs@1.1.0(@uirouter/core@6.1.0)(angular@1.8.3):
resolution: {integrity: sha512-AhgxXhMfN6FU2HxDQqwDPbzmd6kTgvYCgV/kgoCAXfxAH6cFQrifViToC90Wdg6djBynHwA3L/KYP+iOYHkw6A==}
engines: {node: '>=4.0.0'}
peerDependencies:
'@uirouter/core': ^6.0.8
angular: '>=1.2.0'
dependencies:
'@uirouter/core': 6.1.0
angular: 1.8.3
dev: false
/@uirouter/core@6.1.0:
resolution: {integrity: sha512-WFYh5NPAqRX4L2qlI4k62tgR6pxoqOBSW1CM1uBWCau4mAmgasYd5etJ9RoSJrSnCpCQ2km2Jltf0n5ql684MQ==}
engines: {node: '>=4.0.0'}
dev: false
/angular-animate@1.8.3:
resolution: {integrity: sha512-/LtTKvy5sD6MZbV0v+nHgOIpnFF0mrUp+j5WIxVprVhcrJriYpuCZf4S7Owj1o76De/J0eRzANUozNJ6hVepnQ==}
deprecated: For the actively supported Angular, see https://www.npmjs.com/package/@angular/core. AngularJS support has officially ended. For extended AngularJS support options, see https://goo.gle/angularjs-path-forward.
dev: false
/angular-moment@1.3.0:
resolution: {integrity: sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==}
engines: {node: '>=0.10.0'}
dependencies:
moment: 2.30.1
dev: false
/angular-translate-loader-partial@2.19.1:
resolution: {integrity: sha512-1rDe314zG09gwl/2qsLPwrxp5yehSsRi2vNJn/UwIJq20n0E0Fia/1K0nW9QAv67UFyvFuBOhl34n59I1qEHog==}
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
dependencies:
angular-translate: 2.19.1
dev: false
/angular-translate@2.19.1:
resolution: {integrity: sha512-SrU40ndnL422vXiVoqVveCmSnCzMcIXxQgnl7Cv9krOKUg6B8KZK3ddYzidHR/rxVuySezYHNDgRvzQNKwAdNQ==}
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
dependencies:
angular: 1.8.3
dev: false
/angular@1.8.3:
resolution: {integrity: sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw==}
deprecated: For the actively supported Angular, see https://www.npmjs.com/package/@angular/core. AngularJS support has officially ended. For extended AngularJS support options, see https://goo.gle/angularjs-path-forward.
dev: false
/argparse@1.0.10:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
dependencies:
sprintf-js: 1.0.3
dev: false
/argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: false
/croppie@2.6.5:
resolution: {integrity: sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ==}
dev: false
/esprima@4.0.1:
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
engines: {node: '>=4'}
hasBin: true
dev: false
/js-yaml@3.14.1:
resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
hasBin: true
dependencies:
argparse: 1.0.10
esprima: 4.0.1
dev: false
/js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
dependencies:
argparse: 2.0.1
dev: false
/mg-crud@1.1.2:
resolution: {integrity: sha512-mAR6t0aQHKnT0QHKHpLOi0kNPZfO36iMpIoiLjFHxuio6mIJyuveBJ4VNlNXJRxLh32/FLADEb41/sYo7QUKFw==}
dependencies:
angular: 1.8.3
dev: false
/moment@2.30.1:
resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
dev: false
/oclazyload@0.6.3:
resolution: {integrity: sha512-HpOSYUgjtt6sTB/C6+FWsExR+9HCnXKsUA96RWkDXfv11C8Cc9X2DlR0WIZwFIiG6FQU0pwB5dhoYyut8bFAOQ==}
dev: false
/require-yaml@0.0.1:
resolution: {integrity: sha512-M6eVEgLPRbeOhgSCnOTtdrOOEQzbXRchg24Xa13c39dMuraFKdI9emUo97Rih0YEFzSICmSKg8w4RQp+rd9pOQ==}
dependencies:
js-yaml: 4.1.0
dev: false
/sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
dev: false
/validator@6.3.0:
resolution: {integrity: sha512-BylxTwhqwjQI5MDJF7amCy/L0ejJO+74DvCsLV52Lq3+3bhVcVMKqNqOiNcQJm2G48u9EAcw4xFERAmFbwXM9Q==}
engines: {node: '>= 0.10'}
dev: false

View File

@ -22,7 +22,7 @@ module.exports = Self => {
}); });
const modelsLocale = new Map(); const modelsLocale = new Map();
const modulesDir = path.resolve(`${__dirname}/../../../../modules`); const modulesDir = path.resolve(`${process.cwd()}/modules`);
const modules = fs.readdirSync(modulesDir); const modules = fs.readdirSync(modulesDir);
for (const mod of modules) { for (const mod of modules) {

View File

@ -204,5 +204,8 @@
"Cannot past travels with entries": "Cannot past travels with entries", "Cannot past travels with entries": "Cannot past travels with entries",
"It was not able to remove the next expeditions:": "It was not able to remove the next expeditions: {{expeditions}}", "It was not able to remove the next expeditions:": "It was not able to remove the next expeditions: {{expeditions}}",
"Incorrect pin": "Incorrect pin.", "Incorrect pin": "Incorrect pin.",
"The notification subscription of this worker cant be modified": "The notification subscription of this worker cant be modified" "The notification subscription of this worker cant be modified": "The notification subscription of this worker cant be modified",
"Name should be uppercase": "Name should be uppercase",
"Fecha fuera de rango": "Fecha fuera de rango",
"There is no zone for these parameters 34": "There is no zone for these parameters 34"
} }

View File

@ -180,8 +180,7 @@
"New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*", "New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*",
"New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*", "New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*",
"Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío", "Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío",
"CountryFK cannot be empty": "El país no puede estar vacío", "This BIC already exist.": "Este BIC ya existe.",
"This BIC already exist": "Este BIC ya existe",
"That item doesn't exists": "Ese artículo no existe", "That item doesn't exists": "Ese artículo no existe",
"There's a new urgent ticket:": "Hay un nuevo ticket urgente:", "There's a new urgent ticket:": "Hay un nuevo ticket urgente:",
"Invalid account": "Cuenta inválida", "Invalid account": "Cuenta inválida",
@ -338,6 +337,7 @@
"You already have the mailAlias": "Ya tienes este alias de correo", "You already have the mailAlias": "Ya tienes este alias de correo",
"The alias cant be modified": "Este alias de correo no puede ser modificado", "The alias cant be modified": "Este alias de correo no puede ser modificado",
"No tickets to invoice": "No hay tickets para facturar", "No tickets to invoice": "No hay tickets para facturar",
"Name should be uppercase": "El nombre debe ir en mayúscula",
"Bank entity must be specified": "La entidad bancaria es obligatoria", "Bank entity must be specified": "La entidad bancaria es obligatoria",
"An email is necessary": "Es necesario un email" "An email is necessary": "Es necesario un email"
} }

View File

@ -1,4 +1,4 @@
const packageJson = require('../../../package.json'); const packageJson = require(`${process.cwd()}/package.json`);
module.exports = function(options) { module.exports = function(options) {
return function(req, res, next) { return function(req, res, next) {

View File

@ -28,7 +28,7 @@ module.exports = app;
let rootDir = __dirname; let rootDir = __dirname;
let lbDir = path.resolve(`${rootDir}/..`); let lbDir = path.resolve(`${rootDir}/..`);
let appDir = path.resolve(`${__dirname}/../..`); let appDir = process.cwd();
let localeDir = `${lbDir}/locale`; let localeDir = `${lbDir}/locale`;
let modulesDir = `${appDir}/modules`; let modulesDir = `${appDir}/modules`;
@ -80,13 +80,13 @@ app.boot = function(bootOptions, callback) {
`${__dirname}/model-config.json` `${__dirname}/model-config.json`
]; ];
let modelSources = [ let modelSources = [
`loopback/common/models`, `${lbDir}/common/models`,
`loopback/server/models`, `${lbDir}/server/models`,
`${__dirname}/../common/models` `${__dirname}/../common/models`
]; ];
let mixinDirs = [ let mixinDirs = [
`loopback/common/mixins`, `${lbDir}/common/mixins`,
`loopback/server/mixins`, `${lbDir}/server/mixins`,
`${__dirname}/../common/mixins` `${__dirname}/../common/mixins`
]; ];
let bootDirs = [ let bootDirs = [

View File

@ -2,13 +2,17 @@ module.exports = Self => {
Self.remoteMethodCtx('clone', { Self.remoteMethodCtx('clone', {
description: 'Clone the invoiceIn and as many invoiceInTax and invoiceInDueDay referencing it', description: 'Clone the invoiceIn and as many invoiceInTax and invoiceInDueDay referencing it',
accessType: 'WRITE', accessType: 'WRITE',
accepts: { accepts: [{
arg: 'id', arg: 'id',
type: 'number', type: 'number',
required: true, required: true,
description: 'The invoiceIn id', description: 'The invoiceIn id',
http: {source: 'path'} http: {source: 'path'}
}, }, {
arg: 'isRectification',
type: 'boolean',
description: 'Clone quantities in negative and clone Intrastat'
}],
returns: { returns: {
type: 'object', type: 'object',
root: true root: true
@ -19,7 +23,7 @@ module.exports = Self => {
} }
}); });
Self.clone = async(ctx, id, options) => { Self.clone = async(ctx, id, isRectification, options) => {
const models = Self.app.models; const models = Self.app.models;
let tx; let tx;
const myOptions = {}; const myOptions = {};
@ -45,14 +49,28 @@ module.exports = Self => {
'isVatDeductible', 'isVatDeductible',
'withholdingSageFk', 'withholdingSageFk',
'deductibleExpenseFk', 'deductibleExpenseFk',
] ],
include: [
{
relation: 'invoiceInTax',
},
{
relation: 'invoiceInDueDay',
},
{
relation: 'invoiceInIntrastat'
}
],
}, myOptions); }, myOptions);
const sourceInvoiceInTax = await models.InvoiceInTax.find({where: {invoiceInFk: id}}, myOptions); const invoiceInTax = sourceInvoiceIn.invoiceInTax();
const sourceInvoiceInDueDay = await models.InvoiceInDueDay.find({where: {invoiceInFk: id}}, myOptions); const invoiceInDueDay = sourceInvoiceIn.invoiceInDueDay();
const invoiceInIntrastat = sourceInvoiceIn.invoiceInIntrastat();
const issued = new Date(sourceInvoiceIn.issued); const issued = new Date(sourceInvoiceIn.issued);
issued.setMonth(issued.getMonth() + 1); issued.setMonth(issued.getMonth() + 1);
const clonedRef = sourceInvoiceIn.supplierRef + '(2)'; const totalCorrections = await models.InvoiceInCorrection.count({correctedFk: id}, myOptions);
const clonedRef = sourceInvoiceIn.supplierRef + `(${totalCorrections + 2})`;
const clone = await models.InvoiceIn.create({ const clone = await models.InvoiceIn.create({
serial: sourceInvoiceIn.serial, serial: sourceInvoiceIn.serial,
@ -68,18 +86,19 @@ module.exports = Self => {
const promises = []; const promises = [];
for (let tax of sourceInvoiceInTax) { for (let tax of invoiceInTax) {
promises.push(models.InvoiceInTax.create({ promises.push(models.InvoiceInTax.create({
invoiceInFk: clone.id, invoiceInFk: clone.id,
taxableBase: tax.taxableBase, taxableBase: isRectification ? -tax.taxableBase : tax.taxableBase,
expenseFk: tax.expenseFk, expenseFk: tax.expenseFk,
foreignValue: tax.foreignValue, foreignValue: isRectification ? -tax.foreignValue : tax.foreignValue,
taxTypeSageFk: tax.taxTypeSageFk, taxTypeSageFk: tax.taxTypeSageFk,
transactionTypeSageFk: tax.transactionTypeSageFk transactionTypeSageFk: tax.transactionTypeSageFk
}, myOptions)); }, myOptions));
} }
for (let dueDay of sourceInvoiceInDueDay) { if (!isRectification) {
for (let dueDay of invoiceInDueDay) {
const dueDated = dueDay.dueDated; const dueDated = dueDay.dueDated;
dueDated.setMonth(dueDated.getMonth() + 1); dueDated.setMonth(dueDated.getMonth() + 1);
@ -91,7 +110,20 @@ module.exports = Self => {
foreignValue: dueDated.foreignValue, foreignValue: dueDated.foreignValue,
}, myOptions)); }, myOptions));
} }
} else {
for (let intrastat of invoiceInIntrastat) {
promises.push(models.InvoiceInIntrastat.create({
invoiceInFk: clone.id,
net: -intrastat.net,
intrastatFk: intrastat.intrastatFk,
amount: -intrastat.amount,
stems: -intrastat.stems,
country: intrastat.countryFk,
dated: Date.vnNew(),
statisticalValue: intrastat.statisticalValue
}, myOptions));
}
}
await Promise.all(promises); await Promise.all(promises);
if (tx) await tx.commit(); if (tx) await tx.commit();

View File

@ -0,0 +1,58 @@
module.exports = Self => {
Self.remoteMethodCtx('corrective', {
description: 'Creates a rectificated invoice in',
accessType: 'WRITE',
accepts: [{
arg: 'id',
type: 'number'
}, {
arg: 'invoiceReason',
type: 'number',
}, {
arg: 'invoiceType',
type: 'number',
}, {
arg: 'invoiceClass',
type: 'number'
}],
returns: {
type: 'number',
root: true
},
http: {
path: '/corrective',
verb: 'POST'
}
});
Self.corrective = async(ctx, id, invoiceReason, invoiceType, invoiceClass, options) => {
const models = Self.app.models;
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const clone = await Self.clone(ctx, id, true, myOptions);
await models.InvoiceInCorrection.create({
correctingFk: clone.id,
correctedFk: id,
cplusRectificationTypeFk: invoiceType,
siiTypeInvoiceOutFk: invoiceClass,
invoiceCorrectionTypeFk: invoiceReason
}, myOptions);
if (tx) await tx.commit();
return clone.id;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -1,4 +1,3 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
const buildFilter = require('vn-loopback/util/filter').buildFilter; const buildFilter = require('vn-loopback/util/filter').buildFilter;
const mergeFilters = require('vn-loopback/util/filter').mergeFilters; const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
@ -80,6 +79,11 @@ module.exports = Self => {
type: 'boolean', type: 'boolean',
description: 'Whether the invoice is booked or not', description: 'Whether the invoice is booked or not',
}, },
{
arg: 'correctedFk',
type: 'number',
description: 'The corrected invoice',
}
], ],
returns: { returns: {
type: ['object'], type: ['object'],
@ -93,6 +97,7 @@ module.exports = Self => {
Self.filter = async(ctx, filter, options) => { Self.filter = async(ctx, filter, options) => {
const conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
const models = Self.app.models;
const args = ctx.args; const args = ctx.args;
const myOptions = {}; const myOptions = {};
@ -105,6 +110,14 @@ module.exports = Self => {
dateTo.setHours(23, 59, 0, 0); dateTo.setHours(23, 59, 0, 0);
} }
let correctings;
if (args.correctedFk) {
correctings = await models.InvoiceInCorrection.find({
fields: ['correctingFk'],
where: {correctedFk: args.correctedFk}
});
}
const where = buildFilter(ctx.args, (param, value) => { const where = buildFilter(ctx.args, (param, value) => {
switch (param) { switch (param) {
case 'search': case 'search':
@ -128,6 +141,8 @@ module.exports = Self => {
return {[`ii.${param}`]: value}; return {[`ii.${param}`]: value};
case 'awbCode': case 'awbCode':
return {'sub.code': value}; return {'sub.code': value};
case 'correctedFk':
return {'ii.id': {inq: correctings.map(x => x.correctingFk)}};
} }
}); });

View File

@ -2,50 +2,75 @@ const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context'); const LoopBackContext = require('loopback-context');
describe('invoiceIn clone()', () => { describe('invoiceIn clone()', () => {
beforeAll(async() => { let ctx;
const activeCtx = { let options;
accessToken: {userId: 9}, let tx;
http: {
beforeEach(async() => {
ctx = {
req: { req: {
accessToken: {userId: 1},
headers: {origin: 'http://localhost'} headers: {origin: 'http://localhost'}
} },
} args: {}
}; };
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx active: ctx.req
}); });
options = {transaction: tx};
tx = await models.Sale.beginTransaction({});
options.transaction = tx;
});
afterEach(async() => {
await tx.rollback();
}); });
it('should return the cloned invoiceIn and also clone invoiceInDueDays and invoiceInTaxes if there are any referencing the invoiceIn', async() => { it('should return the cloned invoiceIn and also clone invoiceInDueDays and invoiceInTaxes if there are any referencing the invoiceIn', async() => {
const userId = 1; const clone = await models.InvoiceIn.clone(ctx, 1, false, options);
const ctx = {
req: {
accessToken: {userId: userId},
headers: {origin: 'http://localhost:5000'},
}
};
const tx = await models.InvoiceIn.beginTransaction({});
const options = {transaction: tx};
try {
const clone = await models.InvoiceIn.clone(ctx, 1, options);
expect(clone.supplierRef).toEqual('1234(2)'); expect(clone.supplierRef).toEqual('1234(2)');
const invoiceIn = await models.InvoiceIn.findOne({
const invoiceInTaxes = await models.InvoiceInTax.find({where: {invoiceInFk: clone.id}}, options); include: [
{
expect(invoiceInTaxes.length).toEqual(2); relation: 'invoiceInTax',
},
const invoiceInDueDays = await models.InvoiceInDueDay.find({where: {invoiceInFk: clone.id}}, options); {
relation: 'invoiceInDueDay',
expect(invoiceInDueDays.length).toEqual(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
} }
], where: {
id: clone.id
}
}, options);
const invoiceInTax = invoiceIn.invoiceInTax();
const invoiceInDueDay = invoiceIn.invoiceInDueDay();
expect(invoiceInTax.length).toEqual(2);
expect(invoiceInDueDay.length).toEqual(2);
});
it('should return the cloned invoiceIn and also clone invoiceInIntrastat and invoiceInTaxes if it is rectificative', async() => {
const clone = await models.InvoiceIn.clone(ctx, 1, true, options);
expect(clone.supplierRef).toEqual('1234(2)');
const invoiceIn = await models.InvoiceIn.findOne({
include: [
{
relation: 'invoiceInTax',
},
{
relation: 'invoiceInIntrastat',
}
], where: {
id: clone.id
}
}, options);
const invoiceInTax = invoiceIn.invoiceInTax();
const invoiceInIntrastat = invoiceIn.invoiceInIntrastat();
expect(invoiceInTax.length).toEqual(2);
expect(invoiceInIntrastat.length).toEqual(2);
}); });
}); });

View File

@ -0,0 +1,49 @@
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('invoiceIn corrective()', () => {
let ctx;
let options;
let tx;
beforeEach(async() => {
ctx = {
req: {
accessToken: {userId: 9},
headers: {origin: 'http://localhost'}
},
args: {}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: ctx.req
});
options = {transaction: tx};
tx = await models.Sale.beginTransaction({});
options.transaction = tx;
});
afterEach(async() => {
await tx.rollback();
});
it('La función corrective debería devolver un id cuando se ejecuta correctamente', async() => {
const originalId = 1;
const invoiceReason = 3;
const invoiceType = 2;
const invoiceClass = 1;
const cloneId = await models.InvoiceIn.corrective(ctx,
originalId, invoiceReason, invoiceType, invoiceClass, options);
expect(cloneId).toBeDefined();
const correction = await models.InvoiceInCorrection.findOne({
where: {correctedFk: originalId, correctingFk: cloneId}
}, options);
expect(correction.cplusRectificationTypeFk).toEqual(invoiceType);
expect(correction.siiTypeInvoiceOutFk).toEqual(invoiceClass);
expect(correction.invoiceCorrectionTypeFk).toEqual(invoiceReason);
});
});

View File

@ -8,14 +8,14 @@ describe('InvoiceIn filter()', () => {
try { try {
const ctx = { const ctx = {
args: { args: {
search: 'Plants SL', search: 'PLANTS SL',
} }
}; };
const result = await models.InvoiceIn.filter(ctx, {}, options); const result = await models.InvoiceIn.filter(ctx, {}, options);
expect(result.length).toEqual(5); expect(result.length).toEqual(5);
expect(result[0].supplierName).toEqual('Plants SL'); expect(result[0].supplierName).toEqual('PLANTS SL');
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {

View File

@ -5,6 +5,9 @@
"InvoiceInConfig": { "InvoiceInConfig": {
"dataSource": "vn" "dataSource": "vn"
}, },
"InvoiceInCorrection": {
"dataSource": "vn"
},
"InvoiceInDueDay": { "InvoiceInDueDay": {
"dataSource": "vn" "dataSource": "vn"
}, },

View File

@ -0,0 +1,38 @@
{
"name": "InvoiceInCorrection",
"base": "VnModel",
"options": {
"mysql": {
"table": "invoiceInCorrection"
}
},
"properties": {
"correctingFk": {
"id": true,
"type": "number"
}
},
"relations": {
"invoiceIn": {
"type": "belongsTo",
"model": "InvoiceIn",
"foreignKey": "correctedFk"
},
"cplusRectificationType": {
"type": "belongsTo",
"model": "CplusRectificationType",
"foreignKey": "cplusRectificationTypeFk"
},
"invoiceCorrectionType": {
"type": "belongsTo",
"model": "InvoiceCorrectionType",
"foreignKey": "invoiceCorrectionTypeFk"
},
"siiTypeInvoiceOut": {
"type": "belongsTo",
"model": "SiiTypeInvoiceOut",
"foreignKey": "siiTypeInvoiceOutFk"
}
}
}

View File

@ -9,6 +9,8 @@ module.exports = Self => {
require('../methods/invoice-in/invoiceInPdf')(Self); require('../methods/invoice-in/invoiceInPdf')(Self);
require('../methods/invoice-in/invoiceInEmail')(Self); require('../methods/invoice-in/invoiceInEmail')(Self);
require('../methods/invoice-in/getSerial')(Self); require('../methods/invoice-in/getSerial')(Self);
require('../methods/invoice-in/corrective')(Self);
Self.rewriteDbError(function(err) { Self.rewriteDbError(function(err) {
if (err.code === 'ER_ROW_IS_REFERENCED_2' && err.sqlMessage.includes('vehicleInvoiceIn')) if (err.code === 'ER_ROW_IS_REFERENCED_2' && err.sqlMessage.includes('vehicleInvoiceIn'))
return new UserError(`This invoice has a linked vehicle.`); return new UserError(`This invoice has a linked vehicle.`);

View File

@ -103,6 +103,11 @@
"type": "belongsTo", "type": "belongsTo",
"model": "Dms", "model": "Dms",
"foreignKey": "dmsFk" "foreignKey": "dmsFk"
},
"invoiceInCorrection": {
"type": "hasOne",
"model": "InvoiceInCorrection",
"foreignKey": "correctedFk"
} }
} }
} }

View File

@ -17,6 +17,9 @@
}, },
"description": { "description": {
"type": "string" "type": "string"
},
"code": {
"type": "string"
} }
} }
} }

View File

@ -5,7 +5,7 @@ describe('Supplier getSummary()', () => {
const supplier = await app.models.Supplier.getSummary(1); const supplier = await app.models.Supplier.getSummary(1);
expect(supplier.id).toEqual(1); expect(supplier.id).toEqual(1);
expect(supplier.name).toEqual('Plants SL'); expect(supplier.name).toEqual('PLANTS SL');
expect(supplier.nif).toEqual('06089160W'); expect(supplier.nif).toEqual('06089160W');
expect(supplier.account).toEqual('4100000001'); expect(supplier.account).toEqual('4100000001');
expect(supplier.payDay).toEqual(15); expect(supplier.payDay).toEqual(15);

View File

@ -25,13 +25,13 @@ describe('Supplier newSupplier()', () => {
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
ctx.args = { ctx.args = {
name: 'newSupplier', name: 'NEWSUPPLIER',
nif: '12345678Z' nif: '12345678Z'
}; };
const result = await models.Supplier.newSupplier(ctx, options); const result = await models.Supplier.newSupplier(ctx, options);
expect(result.name).toEqual('newSupplier'); expect(result.name).toEqual('NEWSUPPLIER');
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
await tx.rollback(); await tx.rollback();

View File

@ -6,7 +6,7 @@ describe('Supplier updateFiscalData', () => {
const administrativeId = 5; const administrativeId = 5;
const employeeId = 1; const employeeId = 1;
const defaultData = { const defaultData = {
name: 'Plants SL', name: 'PLANTS SL',
nif: '06089160W', nif: '06089160W',
account: '4100000001', account: '4100000001',
sageTaxTypeFk: 4, sageTaxTypeFk: 4,
@ -56,7 +56,7 @@ describe('Supplier updateFiscalData', () => {
}); });
ctx.args = { ctx.args = {
name: 'Weapon Dealer', name: 'WEAPON DEALER',
nif: 'A68446004', nif: 'A68446004',
account: '4000000005', account: '4000000005',
sageTaxTypeFk: 5, sageTaxTypeFk: 5,
@ -72,7 +72,7 @@ describe('Supplier updateFiscalData', () => {
const result = await app.models.Supplier.updateFiscalData(ctx, supplierId); const result = await app.models.Supplier.updateFiscalData(ctx, supplierId);
expect(result.name).toEqual('Weapon Dealer'); expect(result.name).toEqual('WEAPON DEALER');
expect(result.nif).toEqual('A68446004'); expect(result.nif).toEqual('A68446004');
expect(result.account).toEqual('4000000005'); expect(result.account).toEqual('4000000005');
expect(result.sageTaxTypeFk).toEqual(5); expect(result.sageTaxTypeFk).toEqual(5);

View File

@ -129,7 +129,7 @@ describe('loopback model Supplier', () => {
const options = {transaction: tx}; const options = {transaction: tx};
try { try {
const newSupplier = await models.Supplier.create({name: 'Alfred Pennyworth'}, options); const newSupplier = await models.Supplier.create({name: 'ALFRED PENNYWORTH'}, options);
const fetchedSupplier = await models.Supplier.findById(newSupplier.id, null, options); const fetchedSupplier = await models.Supplier.findById(newSupplier.id, null, options);
expect(Number(fetchedSupplier.account)).toEqual(4100000000 + newSupplier.id); expect(Number(fetchedSupplier.account)).toEqual(4100000000 + newSupplier.id);

View File

@ -46,6 +46,12 @@ module.exports = Self => {
Self.validateAsync('postCode', hasValidPostcode, { Self.validateAsync('postCode', hasValidPostcode, {
message: `The postcode doesn't exist. Please enter a correct one` message: `The postcode doesn't exist. Please enter a correct one`
}); });
Self.validatesFormatOf('name', {
message: 'Name should be uppercase',
allowNull: false,
allowBlank: false,
with: /^[^a-z]*$/
});
async function hasValidPostcode(err, done) { async function hasValidPostcode(err, done) {
if (!this.postcode) if (!this.postcode)

View File

@ -12,7 +12,8 @@
<vn-textfield <vn-textfield
label="Supplier name" label="Supplier name"
ng-model="$ctrl.supplier.name" ng-model="$ctrl.supplier.name"
vn-focus> vn-focus
ng-keyup="$ctrl.supplier.name = $ctrl.supplier.name.toUpperCase()">
</vn-textfield> </vn-textfield>
</vn-horizontal> </vn-horizontal>
</vn-card> </vn-card>

View File

@ -1,4 +1,32 @@
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('clone', {
description: 'Clone sales and services provided',
accessType: 'WRITE',
accepts: [
{
arg: 'salesIds',
type: ['number'],
}, {
arg: 'servicesIds',
type: ['number']
}, {
arg: 'withWarehouse',
type: 'boolean',
required: true
}, {
arg: 'negative',
type: 'boolean'
}
],
returns: {
type: ['object'],
root: true
},
http: {
path: `/clone`,
verb: 'POST'
}
});
Self.clone = async(ctx, salesIds, servicesIds, withWarehouse, negative, options) => { Self.clone = async(ctx, salesIds, servicesIds, withWarehouse, negative, options) => {
const models = Self.app.models; const models = Self.app.models;
const myOptions = {}; const myOptions = {};

View File

@ -1,61 +0,0 @@
module.exports = Self => {
Self.remoteMethodCtx('refund', {
description: 'Create refund tickets with sales and services if provided',
accessType: 'WRITE',
accepts: [
{
arg: 'salesIds',
type: ['number'],
},
{
arg: 'servicesIds',
type: ['number']
},
{
arg: 'withWarehouse',
type: 'boolean',
required: true
}
],
returns: {
type: ['object'],
root: true
},
http: {
path: `/refund`,
verb: 'post'
}
});
Self.refund = async(ctx, salesIds, servicesIds, withWarehouse, options) => {
const models = Self.app.models;
const myOptions = {userId: ctx.req.accessToken.userId};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const refundsTicket = await models.Sale.clone(
ctx,
salesIds,
servicesIds,
withWarehouse,
true,
myOptions
);
if (tx) await tx.commit();
return refundsTicket;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -67,4 +67,34 @@ describe('Ticket cloning - clone function', () => {
expect(services.length).toBeGreaterThan(0); expect(services.length).toBeGreaterThan(0);
} }
}); });
it('should create a ticket without sales', async() => {
const servicesIds = [4];
const tickets = await models.Sale.clone(ctx, null, servicesIds, false, false, options);
const refundedTicket = await getTicketRefund(tickets[0].id, options);
expect(refundedTicket).toBeDefined();
}); });
});
async function getTicketRefund(id, options) {
return models.Ticket.findOne({
where: {
id
},
include: [
{
relation: 'ticketSales',
scope: {
include: {
relation: 'components'
}
}
},
{
relation: 'ticketServices',
}
]
}, options);
}

View File

@ -1,101 +0,0 @@
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('Sale refund()', () => {
const userId = 5;
const ctx = {req: {accessToken: userId}, args: {}};
const activeCtx = {
accessToken: {userId},
};
const servicesIds = [3];
const withWarehouse = true;
beforeEach(() => {
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
it('should create ticket with the selected lines', async() => {
const tx = await models.Sale.beginTransaction({});
const salesIds = [7, 8];
try {
const options = {transaction: tx};
const refundedTickets = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options);
expect(refundedTickets).toBeDefined();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should create one ticket for each unique ticketFk in the sales', async() => {
const tx = await models.Sale.beginTransaction({});
const salesIds = [6, 7];
try {
const options = {transaction: tx};
const ticketsBefore = await models.Ticket.find({}, options);
const tickets = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options);
const refundedTicket = await getTicketRefund(tickets[0].id, options);
const ticketsAfter = await models.Ticket.find({}, options);
const salesLength = refundedTicket.ticketSales().length;
const componentsLength = refundedTicket.ticketSales()[0].components().length;
expect(refundedTicket).toBeDefined();
expect(salesLength).toEqual(1);
expect(ticketsBefore.length).toEqual(ticketsAfter.length - 2);
expect(componentsLength).toEqual(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should create a ticket without sales', async() => {
const servicesIds = [4];
const tx = await models.Sale.beginTransaction({});
const options = {transaction: tx};
try {
const tickets = await models.Sale.refund(ctx, null, servicesIds, withWarehouse, options);
const refundedTicket = await getTicketRefund(tickets[0].id, options);
expect(refundedTicket).toBeDefined();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});
async function getTicketRefund(id, options) {
return models.Ticket.findOne({
where: {
id
},
include: [
{
relation: 'ticketSales',
scope: {
include: {
relation: 'components'
}
}
},
{
relation: 'ticketServices',
}
]
}, options);
}

View File

@ -108,6 +108,23 @@ module.exports = function(Self) {
await Self.rawSql('CALL invoiceOutBooking(?)', [resultInvoice.id], myOptions); await Self.rawSql('CALL invoiceOutBooking(?)', [resultInvoice.id], myOptions);
const client = await models.Client.findById(clientId,
{fields: ['hasElectronicInvoice', 'name', 'email']}, myOptions);
if (client.hasElectronicInvoice) {
const url = await models.Url.getUrl();
await models.NotificationQueue.create({
notificationFk: 'invoice-electronic',
authorFk: client.id,
params: JSON.stringify(
{
'name': client.name,
'email': client.email,
'ticketId': ticketsIds.join(','),
'url': url + 'ticket/index?q=' + encodeURIComponent(JSON.stringify({clientFk: clientId}))
})
}, myOptions);
}
if (tx) await tx.commit(); if (tx) await tx.commit();
return resultInvoice.id; return resultInvoice.id;

View File

@ -20,7 +20,7 @@ module.exports = Self => {
}, },
http: { http: {
path: `/refund`, path: `/refund`,
verb: 'post' verb: 'POST'
} }
}); });
@ -45,7 +45,7 @@ module.exports = Self => {
const services = await models.TicketService.find(filter, myOptions); const services = await models.TicketService.find(filter, myOptions);
const servicesIds = services.map(service => service.id); const servicesIds = services.map(service => service.id);
const refundedTickets = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, myOptions); const refundedTickets = await models.Sale.clone(ctx, salesIds, servicesIds, withWarehouse, true, myOptions);
if (tx) await tx.commit(); if (tx) await tx.commit();

View File

@ -9,7 +9,6 @@ module.exports = Self => {
require('../methods/sale/updateQuantity')(Self); require('../methods/sale/updateQuantity')(Self);
require('../methods/sale/updateConcept')(Self); require('../methods/sale/updateConcept')(Self);
require('../methods/sale/recalculatePrice')(Self); require('../methods/sale/recalculatePrice')(Self);
require('../methods/sale/refund')(Self);
require('../methods/sale/canEdit')(Self); require('../methods/sale/canEdit')(Self);
require('../methods/sale/usesMana')(Self); require('../methods/sale/usesMana')(Self);
require('../methods/sale/clone')(Self); require('../methods/sale/clone')(Self);

View File

@ -248,23 +248,6 @@ class Controller extends Section {
if (this.ticket.address.incotermsFk && !this.ticket.weight && !force) if (this.ticket.address.incotermsFk && !this.ticket.weight && !force)
return this.$.withoutWeightConfirmation.show(); return this.$.withoutWeightConfirmation.show();
const client = this.ticket.client;
if (client.hasElectronicInvoice) {
this.$http.post(`NotificationQueues`, {
notificationFk: 'invoice-electronic',
authorFk: client.id,
params: JSON.stringify(
{
'name': client.name,
'email': client.email,
'ticketId': this.id,
'url': window.location.href
})
}).then(() => {
this.vnApp.showSuccess(this.$t('Invoice sent'));
});
}
return this.$http.post(`Tickets/invoiceTicketsAndPdf`, {ticketsIds: [this.id]}) return this.$http.post(`Tickets/invoiceTicketsAndPdf`, {ticketsIds: [this.id]})
.then(() => this.reload()) .then(() => this.reload())
.then(() => this.vnApp.showSuccess(this.$t('Ticket invoiced'))); .then(() => this.vnApp.showSuccess(this.$t('Ticket invoiced')));

View File

@ -523,8 +523,8 @@ class Controller extends Section {
if (!sales) return; if (!sales) return;
const salesIds = sales.map(sale => sale.id); const salesIds = sales.map(sale => sale.id);
const params = {salesIds: salesIds, withWarehouse: withWarehouse}; const params = {salesIds: salesIds, withWarehouse: withWarehouse, negative: true};
const query = 'Sales/refund'; const query = 'Sales/clone';
this.$http.post(query, params).then(res => { this.$http.post(query, params).then(res => {
const [refundTicket] = res.data; const [refundTicket] = res.data;
this.vnApp.showSuccess(this.$t('The following refund ticket have been created', { this.vnApp.showSuccess(this.$t('The following refund ticket have been created', {

View File

@ -727,9 +727,10 @@ describe('Ticket', () => {
jest.spyOn(controller.$state, 'go'); jest.spyOn(controller.$state, 'go');
const params = { const params = {
salesIds: [1, 4], salesIds: [1, 4],
negative: true
}; };
const refundTicket = {id: 99}; const refundTicket = {id: 99};
$httpBackend.expect('POST', 'Sales/refund', params).respond(200, [refundTicket]); $httpBackend.expect('POST', 'Sales/clone', params).respond(200, [refundTicket]);
controller.createRefund(); controller.createRefund();
$httpBackend.flush(); $httpBackend.flush();

View File

@ -55,10 +55,10 @@ class Controller extends Section {
createRefund() { createRefund() {
if (!this.checkeds.length) return; if (!this.checkeds.length) return;
const params = {servicesIds: this.checkeds, withWarehouse: false}; const params = {servicesIds: this.checkeds, withWarehouse: false, negative: true};
const query = 'Sales/refund'; const query = 'Sales/clone';
this.$http.post(query, params).then(res => { this.$http.post(query, params).then(res => {
const refundTicket = res.data; const [refundTicket] = res.data;
this.vnApp.showSuccess(this.$t('The following refund ticket have been created', { this.vnApp.showSuccess(this.$t('The following refund ticket have been created', {
ticketId: refundTicket.id ticketId: refundTicket.id
})); }));

View File

@ -30,13 +30,12 @@ module.exports = Self => {
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
stmts.push(new ParameterizedSQL('CALL vn.subordinateGetList(?)', [userId])); stmts.push(new ParameterizedSQL('CALL vn.worker_getHierarchy(?)', [userId]));
const queryIndex = stmts.push('SELECT * FROM tmp.subordinate') - 1; const queryIndex = stmts.push('SELECT * FROM tmp.workerHierarchyList') - 1;
stmts.push('DROP TEMPORARY TABLE tmp.subordinate'); stmts.push('DROP TEMPORARY TABLE tmp.workerHierarchyList');
const sql = ParameterizedSQL.join(stmts, ';'); const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql, myOptions); const result = await conn.executeStmt(sql, myOptions);
return result[queryIndex]; return result[queryIndex];
}; };
}; };

47055
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,10 +11,13 @@
"engines": { "engines": {
"node": ">=20" "node": ">=20"
}, },
"packageManager": "pnpm@8.15.1",
"dependencies": { "dependencies": {
"axios": "^1.2.2", "axios": "^1.2.2",
"base64url": "^3.0.1", "base64url": "^3.0.1",
"body-parser": "^1.19.2",
"compression": "^1.7.3", "compression": "^1.7.3",
"ejs": "2.3.1",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"fs-extra": "^5.0.0", "fs-extra": "^5.0.0",
"ftps": "^1.2.0", "ftps": "^1.2.0",
@ -30,18 +33,22 @@
"loopback-boot": "3.3.1", "loopback-boot": "3.3.1",
"loopback-component-explorer": "^6.5.0", "loopback-component-explorer": "^6.5.0",
"loopback-component-storage": "3.6.1", "loopback-component-storage": "3.6.1",
"loopback-connector-mysql": "^6.2.0", "loopback-connector": "4.11.1",
"loopback-connector-mysql": "6.2.0",
"loopback-connector-remote": "^3.4.1", "loopback-connector-remote": "^3.4.1",
"loopback-context": "^3.5.2", "loopback-context": "^3.5.2",
"loopback-datasource-juggler": "3.36.1",
"md5": "^2.2.1", "md5": "^2.2.1",
"mysql": "2.18.1",
"node-ssh": "^11.0.0", "node-ssh": "^11.0.0",
"object.pick": "^1.3.0", "object.pick": "^1.3.0",
"puppeteer": "^21.10.0", "puppeteer": "^21.10.0",
"require-yaml": "0.0.1", "require-yaml": "0.0.1",
"smbhash": "0.0.1", "smbhash": "0.0.1",
"strong-error-handler": "^2.3.2", "strong-error-handler": "^2.3.2",
"vn-loopback": "file:./loopback", "vn-loopback": "link:./loopback",
"vn-print": "file:./print" "vn-print": "link:./print",
"xmldom": "^0.6.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.7.7", "@babel/core": "^7.7.7",
@ -74,11 +81,12 @@
"html-loader-jest": "^0.2.1", "html-loader-jest": "^0.2.1",
"html-webpack-plugin": "^5.5.1", "html-webpack-plugin": "^5.5.1",
"identity-obj-proxy": "^3.0.0", "identity-obj-proxy": "^3.0.0",
"jasmine": "^5.0.0", "jasmine": "^5.0.2",
"jasmine-reporters": "^2.4.0", "jasmine-reporters": "^2.4.0",
"jasmine-spec-reporter": "^7.0.0", "jasmine-spec-reporter": "^7.0.0",
"jest": "^26.0.1", "jest": "^26.0.1",
"jest-junit": "^8.0.0", "jest-junit": "^8.0.0",
"js-yaml": "^4.1.0",
"json-loader": "^0.5.7", "json-loader": "^0.5.7",
"merge-stream": "^1.0.1", "merge-stream": "^1.0.1",
"minimist": "^1.2.5", "minimist": "^1.2.5",

14432
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

2725
print/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,9 @@
"url": "https://git.verdnatura.es/salix" "url": "https://git.verdnatura.es/salix"
}, },
"license": "GPL-3.0", "license": "GPL-3.0",
"packageManager": "pnpm@8.15.1",
"dependencies": { "dependencies": {
"express": "4.14.0",
"fs-extra": "^7.0.1", "fs-extra": "^7.0.1",
"intl": "^1.2.5", "intl": "^1.2.5",
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",

2251
print/pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@ module.exports = {
required: true required: true
}, },
ticketId: { ticketId: {
type: [Number], type: [String],
required: true required: true
}, },
url: { url: {

View File

@ -15,7 +15,7 @@ SELECT pack.packages,
LEFT JOIN vn.province p ON p.id = c.provinceFk LEFT JOIN vn.province p ON p.id = c.provinceFk
JOIN vn.ticket t ON t.refFk = io.ref JOIN vn.ticket t ON t.refFk = io.ref
JOIN vn.address a ON a.id = t.addressFk JOIN vn.address a ON a.id = t.addressFk
LEFT JOIN vn.incoterms ic ON ic.code = a.incotermsFk JOIN vn.incoterms ic ON ic.code = a.incotermsFk
LEFT JOIN vn.customsAgent ca ON ca.id = a.customsAgentFk LEFT JOIN vn.customsAgent ca ON ca.id = a.customsAgentFk
JOIN vn.sale s ON s.ticketFk = t.id JOIN vn.sale s ON s.ticketFk = t.id
JOIN ( JOIN (

View File

@ -1,8 +1,5 @@
SELECT IF(incotermsFk IS NULL, FALSE, TRUE) AS hasIncoterms SELECT COUNT(*) AS hasIncoterms
FROM ticket t FROM invoiceOut io
JOIN invoiceOut io ON io.ref = t.refFk JOIN vn.invoiceOutSerial ios ON ios.code = io.serial
JOIN client c ON c.id = t.clientFk AND ios.taxAreaFk = 'WORLD'
JOIN address a ON a.id = t.addressFk WHERE io.ref = ?
WHERE t.refFk = ?
AND IF(c.hasToinvoiceByAddress = FALSE, c.defaultAddressFk, TRUE)
LIMIT 1