Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 5472-user_passExpired
gitea/salix/pipeline/head There was a failure building this commit
Details
gitea/salix/pipeline/head There was a failure building this commit
Details
This commit is contained in:
commit
91b0e3013a
|
@ -24,13 +24,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Added
|
||||
- (Tickets -> Crear Factura) Al facturar se envia automáticamente el pdf al cliente
|
||||
- (Artículos -> Histórico) Filtro para mostrar lo anterior al inventario
|
||||
|
||||
- (Trabajadores -> Nuevo trabajador) Permite elegir el método de pago
|
||||
|
||||
### Changed
|
||||
- (Trabajadores -> Nuevo trabajador) Los clientes se crean sin 'TR' pero se añade tipo de negocio 'Trabajador'
|
||||
|
||||
### Fixed
|
||||
- (Tickets -> Líneas) Se permite hacer split de líneas al mismo ticket
|
||||
- (Tickets -> Cambiar estado) Ahora muestra la lista completa de todos los estados
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
LOAD DATA LOCAL INFILE ?
|
||||
INTO TABLE `edi`.`item`
|
||||
CHARACTER SET ascii
|
||||
FIELDS TERMINATED BY ';'
|
||||
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9, @col10, @col11, @col12)
|
||||
SET
|
||||
id = @col2,
|
||||
SET id = @col2,
|
||||
product_name = @col4,
|
||||
name = @col5,
|
||||
plant_id = @col7,
|
||||
|
@ -11,3 +11,4 @@ LOAD DATA LOCAL INFILE ?
|
|||
entry_date = STR_TO_DATE(@col10, '%Y%m%d'),
|
||||
expiry_date = IFNULL(NULL,STR_TO_DATE(@col11, '%Y%m%d')),
|
||||
change_date_time = STR_TO_DATE(@col12, '%Y%m%d%H%i')
|
||||
|
|
@ -3,236 +3,237 @@ const path = require('path');
|
|||
const fs = require('fs-extra');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('updateData', {
|
||||
description: 'Updates schema data from external provider',
|
||||
accessType: 'WRITE',
|
||||
returns: {
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/updateData`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
Self.remoteMethodCtx('updateData', {
|
||||
description: 'Updates schema data from external provider',
|
||||
accessType: 'WRITE',
|
||||
returns: {
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/updateData`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.updateData = async() => {
|
||||
const models = Self.app.models;
|
||||
Self.updateData = async() => {
|
||||
const models = Self.app.models;
|
||||
|
||||
// Get files checksum
|
||||
const tx = await Self.beginTransaction({});
|
||||
// Get files checksum
|
||||
const tx = await Self.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const files = await Self.rawSql('SELECT name, checksum, keyValue FROM edi.fileConfig', null, options);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const files = await Self.rawSql('SELECT name, checksum, keyValue FROM edi.fileConfig', null, options);
|
||||
|
||||
const updatableFiles = [];
|
||||
for (const file of files) {
|
||||
const fileChecksum = await getChecksum(file);
|
||||
const updatableFiles = [];
|
||||
for (const file of files) {
|
||||
const fileChecksum = await getChecksum(file);
|
||||
|
||||
if (file.checksum != fileChecksum) {
|
||||
updatableFiles.push({
|
||||
name: file.name,
|
||||
checksum: fileChecksum
|
||||
});
|
||||
} else
|
||||
console.debug(`File already updated, skipping...`);
|
||||
}
|
||||
if (file.checksum != fileChecksum) {
|
||||
updatableFiles.push({
|
||||
name: file.name,
|
||||
checksum: fileChecksum
|
||||
});
|
||||
} else
|
||||
console.debug(`File already updated, skipping...`);
|
||||
}
|
||||
|
||||
if (updatableFiles.length === 0)
|
||||
return false;
|
||||
if (updatableFiles.length === 0)
|
||||
return false;
|
||||
|
||||
// Download files
|
||||
const container = await models.TempContainer.container('edi');
|
||||
const tempPath = path.join(container.client.root, container.name);
|
||||
// Download files
|
||||
const container = await models.TempContainer.container('edi');
|
||||
const tempPath = path.join(container.client.root, container.name);
|
||||
|
||||
let remoteFile;
|
||||
let tempDir;
|
||||
let tempFile;
|
||||
let remoteFile;
|
||||
let tempDir;
|
||||
let tempFile;
|
||||
|
||||
const fileNames = updatableFiles.map(file => file.name);
|
||||
const fileNames = updatableFiles.map(file => file.name);
|
||||
|
||||
const tables = await Self.rawSql(`
|
||||
SELECT fileName, toTable, file
|
||||
FROM edi.tableConfig
|
||||
WHERE file IN (?)`, [fileNames], options);
|
||||
const tables = await Self.rawSql(`
|
||||
SELECT fileName, toTable, file
|
||||
FROM edi.tableConfig
|
||||
WHERE file IN (?)`, [fileNames], options);
|
||||
|
||||
for (const table of tables) {
|
||||
const fileName = table.file;
|
||||
for (const table of tables) {
|
||||
const fileName = table.file;
|
||||
|
||||
remoteFile = `codes/${fileName}.ZIP`;
|
||||
tempDir = `${tempPath}/${fileName}`;
|
||||
tempFile = `${tempPath}/${fileName}.zip`;
|
||||
remoteFile = `codes/${fileName}.ZIP`;
|
||||
tempDir = `${tempPath}/${fileName}`;
|
||||
tempFile = `${tempPath}/${fileName}.zip`;
|
||||
|
||||
try {
|
||||
await fs.readFile(tempFile);
|
||||
} catch (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
console.debug(`Downloading file ${fileName}...`);
|
||||
const downloadOutput = await downloadFile(remoteFile, tempFile);
|
||||
if (downloadOutput.error)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
try {
|
||||
await fs.readFile(tempFile);
|
||||
} catch (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
console.debug(`Downloading file ${fileName}...`);
|
||||
const downloadOutput = await downloadFile(remoteFile, tempFile);
|
||||
if (downloadOutput.error)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
await extractFile(fileName, tempFile, tempDir);
|
||||
await extractFile(fileName, tempFile, tempDir);
|
||||
|
||||
console.debug(`Updating table ${table.toTable}...`);
|
||||
await dumpData(tempDir, table, options);
|
||||
}
|
||||
console.debug(`Updating table ${table.toTable}...`);
|
||||
await dumpData(tempDir, table, options);
|
||||
}
|
||||
|
||||
// Update files checksum
|
||||
for (const file of updatableFiles) {
|
||||
console.log(`Updating file ${file.name} checksum...`);
|
||||
await Self.rawSql(`
|
||||
UPDATE edi.fileConfig
|
||||
SET checksum = ?
|
||||
WHERE name = ?`,
|
||||
[file.checksum, file.name], options);
|
||||
}
|
||||
// Update files checksum
|
||||
for (const file of updatableFiles) {
|
||||
console.log(`Updating file ${file.name} checksum...`);
|
||||
await Self.rawSql(`
|
||||
UPDATE edi.fileConfig
|
||||
SET checksum = ?
|
||||
WHERE name = ?`,
|
||||
[file.checksum, file.name], options);
|
||||
}
|
||||
|
||||
await tx.commit();
|
||||
await tx.commit();
|
||||
|
||||
// Clean files
|
||||
try {
|
||||
console.debug(`Cleaning files...`);
|
||||
await fs.remove(tempPath);
|
||||
} catch (error) {
|
||||
if (error.code !== 'ENOENT')
|
||||
throw e;
|
||||
}
|
||||
// Clean files
|
||||
try {
|
||||
console.debug(`Cleaning files...`);
|
||||
await fs.remove(tempPath);
|
||||
} catch (error) {
|
||||
if (error.code !== 'ENOENT')
|
||||
throw e;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
await tx.rollback();
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
return true;
|
||||
} catch (error) {
|
||||
await tx.rollback();
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
let ftpClient;
|
||||
async function getFtpClient() {
|
||||
if (!ftpClient) {
|
||||
const [ftpConfig] = await Self.rawSql('SELECT host, user, password FROM edi.ftpConfig');
|
||||
console.debug(`Openning FTP connection to ${ftpConfig.host}...\n`);
|
||||
let ftpClient;
|
||||
async function getFtpClient() {
|
||||
if (!ftpClient) {
|
||||
const [ftpConfig] = await Self.rawSql('SELECT host, user, password FROM edi.ftpConfig');
|
||||
console.debug(`Openning FTP connection to ${ftpConfig.host}...\n`);
|
||||
|
||||
const FtpClient = require('ftps');
|
||||
const FtpClient = require('ftps');
|
||||
|
||||
ftpClient = new FtpClient({
|
||||
host: ftpConfig.host,
|
||||
username: ftpConfig.user,
|
||||
password: ftpConfig.password,
|
||||
procotol: 'ftp'
|
||||
});
|
||||
}
|
||||
ftpClient = new FtpClient({
|
||||
host: ftpConfig.host,
|
||||
username: ftpConfig.user,
|
||||
password: ftpConfig.password,
|
||||
procotol: 'ftp',
|
||||
additionalLftpCommands: 'set ssl:verify-certificate no'
|
||||
});
|
||||
}
|
||||
|
||||
return ftpClient;
|
||||
}
|
||||
return ftpClient;
|
||||
}
|
||||
|
||||
async function getChecksum(file) {
|
||||
const ftpClient = await getFtpClient();
|
||||
console.debug(`Checking checksum for file ${file.name}...`);
|
||||
async function getChecksum(file) {
|
||||
const ftpClient = await getFtpClient();
|
||||
console.debug(`Checking checksum for file ${file.name}...`);
|
||||
|
||||
ftpClient.cat(`codes/${file.name}.txt`);
|
||||
ftpClient.cat(`codes/${file.name}.TXT`);
|
||||
|
||||
const response = await new Promise((resolve, reject) => {
|
||||
ftpClient.exec((err, response) => {
|
||||
if (err || response.error) {
|
||||
console.debug(`Error downloading checksum file... ${response.error}`);
|
||||
return reject(err);
|
||||
}
|
||||
const response = await new Promise((resolve, reject) => {
|
||||
ftpClient.exec((err, response) => {
|
||||
if (err || response.error) {
|
||||
console.debug(`Error downloading checksum file... ${response.error}`);
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
|
||||
if (response && response.data) {
|
||||
const fileContents = response.data;
|
||||
const rows = fileContents.split('\n');
|
||||
const row = rows[4];
|
||||
const columns = row.split(/\s+/);
|
||||
if (response && response.data) {
|
||||
const fileContents = response.data;
|
||||
const rows = fileContents.split('\n');
|
||||
const row = rows[4];
|
||||
const columns = row.split(/\s+/);
|
||||
|
||||
let fileChecksum;
|
||||
if (file.keyValue)
|
||||
fileChecksum = columns[1];
|
||||
let fileChecksum;
|
||||
if (file.keyValue)
|
||||
fileChecksum = columns[1];
|
||||
|
||||
if (!file.keyValue)
|
||||
fileChecksum = columns[0];
|
||||
if (!file.keyValue)
|
||||
fileChecksum = columns[0];
|
||||
|
||||
return fileChecksum;
|
||||
}
|
||||
}
|
||||
return fileChecksum;
|
||||
}
|
||||
}
|
||||
|
||||
async function downloadFile(remoteFile, tempFile) {
|
||||
const ftpClient = await getFtpClient();
|
||||
async function downloadFile(remoteFile, tempFile) {
|
||||
const ftpClient = await getFtpClient();
|
||||
|
||||
ftpClient.get(remoteFile, tempFile);
|
||||
ftpClient.get(remoteFile, tempFile);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
ftpClient.exec((err, response) => {
|
||||
if (err || response.error) {
|
||||
console.debug(`Error downloading file... ${response.error}`);
|
||||
return reject(err);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
ftpClient.exec((err, response) => {
|
||||
if (err || response.error) {
|
||||
console.debug(`Error downloading file... ${response.error}`);
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function extractFile(fileName, tempFile, tempDir) {
|
||||
const JSZip = require('jszip');
|
||||
async function extractFile(fileName, tempFile, tempDir) {
|
||||
const JSZip = require('jszip');
|
||||
|
||||
try {
|
||||
await fs.mkdir(tempDir);
|
||||
console.debug(`Extracting file ${fileName}...`);
|
||||
} catch (error) {
|
||||
if (error.code !== 'EEXIST')
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
await fs.mkdir(tempDir);
|
||||
console.debug(`Extracting file ${fileName}...`);
|
||||
} catch (error) {
|
||||
if (error.code !== 'EEXIST')
|
||||
throw e;
|
||||
}
|
||||
|
||||
const fileStream = await fs.readFile(tempFile);
|
||||
if (fileStream) {
|
||||
const zip = new JSZip();
|
||||
const zipContents = await zip.loadAsync(fileStream);
|
||||
const fileStream = await fs.readFile(tempFile);
|
||||
if (fileStream) {
|
||||
const zip = new JSZip();
|
||||
const zipContents = await zip.loadAsync(fileStream);
|
||||
|
||||
if (!zipContents) return;
|
||||
if (!zipContents) return;
|
||||
|
||||
const fileNames = Object.keys(zipContents.files);
|
||||
const fileNames = Object.keys(zipContents.files);
|
||||
|
||||
for (const fileName of fileNames) {
|
||||
const fileContent = await zip.file(fileName).async('nodebuffer');
|
||||
const dest = path.join(tempDir, fileName);
|
||||
await fs.writeFile(dest, fileContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const fileName of fileNames) {
|
||||
const fileContent = await zip.file(fileName).async('nodebuffer');
|
||||
const dest = path.join(tempDir, fileName);
|
||||
await fs.writeFile(dest, fileContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function dumpData(tempDir, table, options) {
|
||||
const toTable = table.toTable;
|
||||
const baseName = table.fileName;
|
||||
async function dumpData(tempDir, table, options) {
|
||||
const toTable = table.toTable;
|
||||
const baseName = table.fileName;
|
||||
|
||||
console.log(`Emptying table ${toTable}...`);
|
||||
const tableName = `edi.${toTable}`;
|
||||
await Self.rawSql(`DELETE FROM ??`, [tableName]);
|
||||
console.log(`Emptying table ${toTable}...`);
|
||||
const tableName = `edi.${toTable}`;
|
||||
await Self.rawSql(`DELETE FROM ??`, [tableName]);
|
||||
|
||||
const dirFiles = await fs.readdir(tempDir);
|
||||
const files = dirFiles.filter(file => file.startsWith(baseName));
|
||||
const dirFiles = await fs.readdir(tempDir);
|
||||
const files = dirFiles.filter(file => file.startsWith(baseName));
|
||||
|
||||
for (const file of files) {
|
||||
console.log(`Dumping data from file ${file}...`);
|
||||
for (const file of files) {
|
||||
console.log(`Dumping data from file ${file}...`);
|
||||
|
||||
const templatePath = path.join(__dirname, `./sql/${toTable}.sql`);
|
||||
const sqlTemplate = await fs.readFile(templatePath, 'utf8');
|
||||
const filePath = path.join(tempDir, file);
|
||||
const templatePath = path.join(__dirname, `./sql/${toTable}.sql`);
|
||||
const sqlTemplate = await fs.readFile(templatePath, 'utf8');
|
||||
const filePath = path.join(tempDir, file);
|
||||
|
||||
await Self.rawSql(sqlTemplate, [filePath], options);
|
||||
await Self.rawSql(`
|
||||
UPDATE edi.tableConfig
|
||||
SET updated = ?
|
||||
WHERE fileName = ?
|
||||
`, [Date.vnNew(), baseName], options);
|
||||
}
|
||||
await Self.rawSql(sqlTemplate, [filePath], options);
|
||||
await Self.rawSql(`
|
||||
UPDATE edi.tableConfig
|
||||
SET updated = ?
|
||||
WHERE fileName = ?
|
||||
`, [Date.vnNew(), baseName], options);
|
||||
}
|
||||
|
||||
console.log(`Updated table ${toTable}\n`);
|
||||
}
|
||||
console.log(`Updated table ${toTable}\n`);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -56,8 +56,6 @@ CREATE TABLE `vn`.`collectionWagonTicket` (
|
|||
|
||||
ALTER TABLE `vn`.`wagon` ADD `typeFk` int(11) unsigned NOT NULL;
|
||||
ALTER TABLE `vn`.`wagon` ADD `label` int(11) unsigned NOT NULL;
|
||||
ALTER TABLE `vn`.`wagon` ADD CONSTRAINT `wagon_type` FOREIGN KEY (`typeFk`) REFERENCES `wagonType` (`id`) ON UPDATE CASCADE;
|
||||
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES
|
||||
('WagonType', '*', '*', 'ALLOW', 'ROLE', 'productionAssi'),
|
||||
|
@ -70,3 +68,4 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri
|
|||
('WagonType', 'createWagonType', '*', 'ALLOW', 'ROLE', 'productionAssi'),
|
||||
('WagonType', 'deleteWagonType', '*', 'ALLOW', 'ROLE', 'productionAssi'),
|
||||
('WagonType', 'editWagonType', '*', 'ALLOW', 'ROLE', 'productionAssi');
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE `vn`.`wagon` ADD CONSTRAINT `wagon_type` FOREIGN KEY (`typeFk`) REFERENCES `wagonType` (`id`) ON UPDATE CASCADE;
|
|
@ -1,7 +1,7 @@
|
|||
ALTER TABLE `vn`.`workerConfig` ADD payMethodFk tinyint(3) unsigned NULL;
|
||||
ALTER TABLE `vn`.`workerConfig` ADD CONSTRAINT workerConfig_FK FOREIGN KEY (roleFk) REFERENCES account.`role`(id) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE `vn`.`workerConfig` ADD CONSTRAINT workerConfig_FK_1 FOREIGN KEY (payMethodFk) REFERENCES `vn`.`payMethod`(id) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
-- Cuando se apruebe el PR quitar y poner en redmine para hacerse manualmente
|
||||
|
||||
UPDATE `vn`.`workerConfig`
|
||||
SET payMethodFk = 4
|
||||
WHERE id=1;
|
||||
|
|
|
@ -61950,7 +61950,6 @@ BEGIN
|
|||
* @vWarehouseFk almacen donde buscar
|
||||
* @vDate Si la fecha es null, muestra el histórico desde el inventario. Si la fecha no es null, muestra histórico desde la fecha pasada.
|
||||
*/
|
||||
|
||||
DECLARE vDateInventory DATETIME;
|
||||
DECLARE vInvCalculated INT;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ services:
|
|||
- node.role == worker
|
||||
resources:
|
||||
limits:
|
||||
memory: 4G
|
||||
memory: 8G
|
||||
configs:
|
||||
datasources:
|
||||
external: true
|
||||
|
|
|
@ -150,10 +150,10 @@ export default class Controller extends Section {
|
|||
if (value == null || value == '') return null;
|
||||
switch (prop) {
|
||||
case 'search':
|
||||
const or = [{changedModelId: value}];
|
||||
if (!/^[0-9]+$/.test(value))
|
||||
or.push({changedModelValue: {like: `%${value}%`}});
|
||||
return {or};
|
||||
if (/^[0-9]+$/.test(value))
|
||||
return {changedModelId: value};
|
||||
else
|
||||
return {changedModelValue: {like: `%${value}%`}};
|
||||
case 'changes':
|
||||
return {or: [
|
||||
{oldInstance: {like: `%${value}%`}},
|
||||
|
|
|
@ -15,3 +15,7 @@ columns:
|
|||
image: image
|
||||
hasGrant: has grant
|
||||
userFk: user
|
||||
recoverPass: recover password
|
||||
role: role
|
||||
sync: pending sync
|
||||
lastPassChange: password changed
|
||||
|
|
|
@ -15,3 +15,7 @@ columns:
|
|||
image: imagen
|
||||
hasGrant: puede delegar
|
||||
userFk: usuario
|
||||
recoverPass: recuperar contraseña
|
||||
role: rol
|
||||
sync: Pendiente de sincronizar
|
||||
lastPassChange: contraseña modificada
|
||||
|
|
|
@ -59,6 +59,12 @@ module.exports = function(Self) {
|
|||
fields: ['id', 'name']
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'businessType',
|
||||
scope: {
|
||||
fields: ['description']
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'account',
|
||||
scope: {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "payMethod"
|
||||
"table": "payMethod"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
{{$ctrl.client.salesPersonUser.name}}
|
||||
</span>
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Business type"
|
||||
value="{{$ctrl.client.businessType.description}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
<div class="icons">
|
||||
<vn-icon
|
||||
|
|
|
@ -8,3 +8,4 @@ Client invoices list: Listado de facturas del cliente
|
|||
Pay method: Forma de pago
|
||||
Unpaid Dated: "Fecha: {{dated | date:'dd/MM/yyyy'}}"
|
||||
Unpaid Amount: "Importe: {{amount | currency: 'EUR':2}}"
|
||||
Business type: Tipo de negocio
|
|
@ -1,4 +1,4 @@
|
|||
name: botanical
|
||||
name: botanical data
|
||||
columns:
|
||||
itemFk: item
|
||||
genusFk: genus
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
name: botánico
|
||||
name: datos botánicos
|
||||
columns:
|
||||
itemFk: artículo
|
||||
genusFk: género
|
||||
|
|
|
@ -35,7 +35,7 @@ columns:
|
|||
packingOut: packing out
|
||||
hasMinPrice: has min price
|
||||
isFragile: fragile
|
||||
isFloramondo: is floramondo
|
||||
isFloramondo: floramondo
|
||||
packingShelve: packing shelve
|
||||
isLaid: laid
|
||||
inkFk: ink
|
||||
|
|
|
@ -35,7 +35,7 @@ columns:
|
|||
packingOut: empaquetar
|
||||
hasMinPrice: tiene precio mínimo
|
||||
isFragile: frágil
|
||||
isFloramondo: es floramondo
|
||||
isFloramondo: floramondo
|
||||
packingShelve: estantería embalaje
|
||||
isLaid: puesto
|
||||
inkFk: tinta
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
name: shelving
|
||||
columns:
|
||||
id: id
|
||||
code: code
|
||||
parkingFk: parking
|
||||
isPrinted: printed
|
||||
priority: priority
|
||||
parked: parked
|
||||
userFk: user
|
||||
isSpam: SPAM
|
||||
isRecyclable: recyclable
|
|
@ -0,0 +1,11 @@
|
|||
name: estantería
|
||||
columns:
|
||||
id: id
|
||||
code: código
|
||||
parkingFk: parking
|
||||
isPrinted: impreso
|
||||
priority: prioridad
|
||||
parked: aparcado
|
||||
userFk: usuario
|
||||
isSpam: SPAM
|
||||
isRecyclable: reciclable
|
|
@ -12,3 +12,5 @@ columns:
|
|||
hostFk: PC
|
||||
isBox: box
|
||||
itemPackingTypeFk: packing type
|
||||
externalId: external id
|
||||
stateTypeFk: status
|
||||
|
|
|
@ -12,3 +12,5 @@ columns:
|
|||
hostFk: PC
|
||||
isBox: caja
|
||||
itemPackingTypeFk: tipo empaquetado
|
||||
externalId: id externo
|
||||
stateTypeFk: estado
|
||||
|
|
|
@ -4,9 +4,20 @@ columns:
|
|||
companyCodeFk: company
|
||||
started: started
|
||||
ended: ended
|
||||
workerBusiness: business
|
||||
reasonEndFk: ending reason
|
||||
payedHolidays: payed holidays
|
||||
occupationCodeFk: occupation
|
||||
workerFk: worker
|
||||
notes: notes
|
||||
departmentFk: department
|
||||
workerBusinessProfessionalCategoryFk: professional category
|
||||
calendarTypeFk: calendar type
|
||||
isHourlyLabor: hourly labor
|
||||
workcenterFk: workcenter
|
||||
rate: rate
|
||||
workerBusinessCategoryFk: category
|
||||
workerBusinessTypeFk: type
|
||||
amount: amount
|
||||
workerBusinessAgreementFk: agreement
|
||||
basicSalary: salary
|
||||
|
|
|
@ -4,9 +4,20 @@ columns:
|
|||
companyCodeFk: empresa
|
||||
started: iniciado
|
||||
ended: finalizado
|
||||
workerBusiness: negocio
|
||||
reasonEndFk: motivo finalización
|
||||
payedHolidays: vacaciones pagadas
|
||||
occupationCodeFk: ocupación
|
||||
workerFk: trabajador
|
||||
notes: notas
|
||||
departmentFk: departamento
|
||||
workerBusinessProfessionalCategoryFk: categoría profesional
|
||||
calendarTypeFk: tipo calendario
|
||||
isHourlyLabor: horario laboral
|
||||
workcenterFk: centro de trabajo
|
||||
rate: tarifa
|
||||
workerBusinessCategoryFk: categoría
|
||||
workerBusinessTypeFk: tipo
|
||||
amount: salario
|
||||
workerBusinessAgreementFk: acuerdo
|
||||
basicSalary: salario base
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: document
|
||||
columns:
|
||||
id: id
|
||||
dmsFk: dms
|
||||
workerFk: worker
|
||||
worker: worker
|
||||
document: document
|
||||
isReadableByWorker: readable by worker
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: documento
|
||||
columns:
|
||||
id: id
|
||||
dmsFk: dms
|
||||
workerFk: trabajador
|
||||
isReadableByWorker: legible por trabajador
|
||||
worker: trabajador
|
||||
document: documento
|
||||
isReadableByWorker: accesible por trabajador
|
||||
|
|
|
@ -1,20 +1,32 @@
|
|||
name: worker
|
||||
columns:
|
||||
id: id
|
||||
code: code
|
||||
firstName: first name
|
||||
lastName: last name
|
||||
sub: buyer number
|
||||
photo: photo
|
||||
phone: phone
|
||||
mobileExtension: mobile extension
|
||||
userFk: user
|
||||
bossFk: boss
|
||||
fiDueDate: FI due date
|
||||
hasMachineryAuthorized: machinery authorized
|
||||
seniority: seniority
|
||||
isTodayRelative: today relative
|
||||
isF11Allowed: F11 allowed
|
||||
sectorFk: sector
|
||||
maritalStatus: marital status
|
||||
labelerFk: labeler
|
||||
originCountryFk: origin country
|
||||
educationLevelFk: education level
|
||||
SSN: SSN
|
||||
labelerFk: labeler
|
||||
mobileExtension: mobile extension
|
||||
code: code
|
||||
fi: fiscal identifier
|
||||
birth: birth date
|
||||
isDisable: disabled
|
||||
isFreelance: freelance
|
||||
isSsDiscounted: SS discounted
|
||||
sex: sex
|
||||
businessFk: current contract
|
||||
balance: balance
|
||||
locker: locker
|
||||
workerFk: worker
|
||||
sectorFk: sector
|
||||
|
||||
|
||||
|
|
|
@ -1,20 +1,32 @@
|
|||
name: trabajador
|
||||
columns:
|
||||
id: id
|
||||
code: código
|
||||
firstName: nombre
|
||||
lastName: apellido
|
||||
sub: número comprador
|
||||
photo: foto
|
||||
phone: teléfono
|
||||
mobileExtension: extensión móvil
|
||||
userFk: usuario
|
||||
bossFk: jefe
|
||||
fiDueDate: caducidad DNI
|
||||
hasMachineryAuthorized: maquinaria autorizada
|
||||
seniority: antigüedad
|
||||
isTodayRelative: relativo hoy
|
||||
isF11Allowed: F11 autorizado
|
||||
sectorFk: sector
|
||||
maritalStatus: estado civil
|
||||
labelerFk: etiquetadora
|
||||
originCountryFk: país origen
|
||||
educationLevelFk: nivel educativo
|
||||
SSN: SSN
|
||||
labelerFk: etiquetadora
|
||||
mobileExtension: extensión móvil
|
||||
code: código
|
||||
locker: casillero
|
||||
workerFk: trabajador
|
||||
sectorFk: sector
|
||||
|
||||
|
||||
fi: identificador fiscal
|
||||
birth: nacimiento
|
||||
isDisable: deshabilitado
|
||||
isFreelance: autónomo
|
||||
isSsDiscounted: descuento SS
|
||||
sex: sexo
|
||||
businessFk: contrato actual
|
||||
balance: saldo
|
||||
locker: taquilla
|
||||
|
|
|
@ -230,21 +230,21 @@ module.exports = Self => {
|
|||
}, myOptions);
|
||||
} else {
|
||||
const weekDay = day.dated.getDay();
|
||||
const journeys = await models.Journey.find({
|
||||
const journeys = await models.BusinessSchedule.find({
|
||||
where: {
|
||||
business_id: day.businessFk,
|
||||
day_id: weekDay
|
||||
businessFk: day.businessFk,
|
||||
weekday: weekDay
|
||||
}
|
||||
}, myOptions);
|
||||
|
||||
let timeTableDecimalInSeconds = 0;
|
||||
for (let journey of journeys) {
|
||||
const start = Date.vnNew();
|
||||
const [startHours, startMinutes, startSeconds] = getTime(journey.start);
|
||||
const [startHours, startMinutes, startSeconds] = getTime(journey.started);
|
||||
start.setHours(startHours, startMinutes, startSeconds, 0);
|
||||
|
||||
const end = Date.vnNew();
|
||||
const [endHours, endMinutes, endSeconds] = getTime(journey.end);
|
||||
const [endHours, endMinutes, endSeconds] = getTime(journey.ended);
|
||||
end.setHours(endHours, endMinutes, endSeconds, 0);
|
||||
|
||||
const result = (end - start) / 1000;
|
||||
|
@ -255,7 +255,7 @@ module.exports = Self => {
|
|||
const timeTableDecimal = timeTableDecimalInSeconds / 3600;
|
||||
if (day.timeWorkDecimal == timeTableDecimal) {
|
||||
const timed = new Date(day.dated);
|
||||
const [startHours, startMinutes, startSeconds] = getTime(journey.start);
|
||||
const [startHours, startMinutes, startSeconds] = getTime(journey.started);
|
||||
await models.WorkerTimeControl.create({
|
||||
userFk: day.workerFk,
|
||||
timed: timed.setHours(startHours, startMinutes, startSeconds),
|
||||
|
@ -263,7 +263,7 @@ module.exports = Self => {
|
|||
isSendMail: true
|
||||
}, myOptions);
|
||||
|
||||
const [endHours, endMinutes, endSeconds] = getTime(journey.end);
|
||||
const [endHours, endMinutes, endSeconds] = getTime(journey.ended);
|
||||
await models.WorkerTimeControl.create({
|
||||
userFk: day.workerFk,
|
||||
timed: timed.setHours(endHours, endMinutes, endSeconds),
|
||||
|
@ -276,7 +276,7 @@ module.exports = Self => {
|
|||
});
|
||||
if (journey == minStart) {
|
||||
const timed = new Date(day.dated);
|
||||
const [startHours, startMinutes, startSeconds] = getTime(journey.start);
|
||||
const [startHours, startMinutes, startSeconds] = getTime(journey.started);
|
||||
await models.WorkerTimeControl.create({
|
||||
userFk: day.workerFk,
|
||||
timed: timed.setHours(startHours, startMinutes, startSeconds),
|
||||
|
@ -304,7 +304,7 @@ module.exports = Self => {
|
|||
});
|
||||
if (journey == minStart) {
|
||||
const timed = new Date(day.dated);
|
||||
const [startHours, startMinutes, startSeconds] = getTime(journey.start);
|
||||
const [startHours, startMinutes, startSeconds] = getTime(journey.started);
|
||||
await models.WorkerTimeControl.create({
|
||||
userFk: day.workerFk,
|
||||
timed: timed.setHours(startHours + 1, startMinutes, startSeconds),
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
"AbsenceType": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"BusinessSchedule": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Calendar": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
|
@ -38,9 +41,6 @@
|
|||
"EducationLevel": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Journey": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"ProfileType":{
|
||||
"dataSource": "vn"
|
||||
},
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
{
|
||||
"name": "Journey",
|
||||
"name": "BusinessSchedule",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "postgresql.journey"
|
||||
"table": "businessSchedule"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"journey_id": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "number"
|
||||
},
|
||||
"day_id": {
|
||||
"weekday": {
|
||||
"type": "number"
|
||||
},
|
||||
"start": {
|
||||
"started": {
|
||||
"type": "date"
|
||||
},
|
||||
"end": {
|
||||
"ended": {
|
||||
"type": "date"
|
||||
},
|
||||
"business_id": {
|
||||
"businessFk": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
|
@ -72,7 +72,7 @@
|
|||
"state": "worker.card.workerLog",
|
||||
"component": "vn-worker-log",
|
||||
"description": "Log",
|
||||
"acl": ["salesAssistant"]
|
||||
"acl": ["hr"]
|
||||
}, {
|
||||
"url": "/note",
|
||||
"state": "worker.card.note",
|
||||
|
|
Loading…
Reference in New Issue