#5926 - Worker/PDA docuware #2482
|
@ -1,6 +1,67 @@
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
const env = process.env.NODE_ENV;
|
||||||
|
const {existsSync} = require('fs');
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
|
/**
|
||||||
|
* Returns templateJSON
|
||||||
|
*
|
||||||
|
* @param {object} config - The path for real config file
|
||||||
|
* @return {boolean} - The template parse
|
||||||
|
*/
|
||||||
|
Self.hasDeviceReady = config => {
|
||||||
|
let isDeviceConfigured = false;
|
||||||
|
|
||||||
|
if (!config)
|
||||||
|
config = existsSync(`../docuware.${env}.json`) ?? {};
|
||||||
|
|||||||
|
isDeviceConfigured = !!config?.device;
|
||||||
|
return isDeviceConfigured;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Returns templateJSON
|
||||||
|
*
|
||||||
|
* @param {string} fields - The config as template upload
|
||||||
|
* @return {object} - The template parse
|
||||||
|
*/
|
||||||
|
Self.buildTemplateJSON = fields => {
|
||||||
|
const templateJson = {
|
||||||
|
'Fields': []
|
||||||
|
};
|
||||||
|
|
||||||
|
templateJson.Fields = Object.keys(fields).map(fieldName => ({
|
||||||
|
'FieldName': fieldName,
|
||||||
|
'ItemElementName': fields[fieldName].type,
|
||||||
|
'Item': fields[fieldName].value
|
||||||
|
}));
|
||||||
|
|
||||||
|
return templateJson;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Returns upload options
|
||||||
|
*
|
||||||
|
* @param {string} value - The document value
|
||||||
|
* @param {Object} template - The config as template upload
|
||||||
|
* @param {string} fileName - The document fileName with extension
|
||||||
|
* @param {object} options - The options
|
||||||
|
* @return {object} - The options with headers
|
||||||
|
*/
|
||||||
|
Self.uploadOptions = async(value, template, fileName = '', options) => {
|
||||||
|
const FormData = require('form-data');
|
||||||
|
const data = new FormData();
|
||||||
|
const docuwareOptions = options ?? await Self.getOptions();
|
||||||
|
const templateJson = Self.buildTemplateJSON(template);
|
||||||
|
data.append('document', JSON.stringify(templateJson), 'schema.json');
|
||||||
|
data.append('file[]', value, fileName);
|
||||||
|
const uploadOptions = {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
'X-File-ModifiedDate': Date.vnNew(),
|
||||||
|
'Cookie': docuwareOptions.headers.headers.Cookie,
|
||||||
|
...data.getHeaders()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return {data, uploadOptions};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns basic headers
|
* Returns basic headers
|
||||||
*
|
*
|
||||||
|
@ -23,6 +84,27 @@ module.exports = Self => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the docuware id
|
||||||
|
*
|
||||||
|
* @param {object} filter - The filter to use in findOne method
|
||||||
|
* @return {object} - The doware record
|
||||||
|
*/
|
||||||
|
Self.getDocuware = async filter => {
|
||||||
|
return await Self.app.models.Docuware.findOne(filter);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Returns the base url
|
||||||
|
*
|
||||||
|
* @param {object} options - The docuware options
|
||||||
|
* @param {string} fileCabinetId - The fileCabinetId to use in findOne method
|
||||||
|
* @param {string} model - The model to use in findOne method
|
||||||
|
* @return {string} - The doware record
|
||||||
|
*/
|
||||||
|
Self.baseURL = (options, fileCabinetId, model) => {
|
||||||
|
return `${options.url}/FileCabinets/${fileCabinetId}/${model}`;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the dialog id
|
* Returns the dialog id
|
||||||
*
|
*
|
||||||
|
@ -32,10 +114,10 @@ module.exports = Self => {
|
||||||
* @return {number} - The fileCabinet id
|
* @return {number} - The fileCabinet id
|
||||||
*/
|
*/
|
||||||
Self.getDialog = async(code, action, fileCabinetId) => {
|
Self.getDialog = async(code, action, fileCabinetId) => {
|
||||||
if (!process.env.NODE_ENV)
|
if (!env && !Self.hasDeviceReady())
|
||||||
return Math.floor(Math.random() + 100);
|
return Math.floor(Math.random() + 100);
|
||||||
|
|
||||||
const docuwareInfo = await Self.app.models.Docuware.findOne({
|
const docuwareInfo = await Self.getDocuware({
|
||||||
where: {
|
where: {
|
||||||
code,
|
code,
|
||||||
action
|
action
|
||||||
|
@ -45,7 +127,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
const options = await Self.getOptions();
|
const options = await Self.getOptions();
|
||||||
|
|
||||||
const response = await axios.get(`${options.url}/FileCabinets/${fileCabinetId}/dialogs`, options.headers);
|
const response = await axios.get(Self.baseURL(options, fileCabinetId, 'dialog'), options.headers);
|
||||||
const dialogs = response.data.Dialog;
|
const dialogs = response.data.Dialog;
|
||||||
const dialogId = dialogs.find(dialogs => dialogs.DisplayName === docuwareInfo.dialogName).Id;
|
const dialogId = dialogs.find(dialogs => dialogs.DisplayName === docuwareInfo.dialogName).Id;
|
||||||
|
|
||||||
|
@ -59,7 +141,7 @@ module.exports = Self => {
|
||||||
* @return {number} - The fileCabinet id
|
* @return {number} - The fileCabinet id
|
||||||
*/
|
*/
|
||||||
Self.getFileCabinet = async code => {
|
Self.getFileCabinet = async code => {
|
||||||
if (!process.env.NODE_ENV)
|
if (!env && !Self.hasDeviceReady())
|
||||||
return Math.floor(Math.random() + 100);
|
return Math.floor(Math.random() + 100);
|
||||||
|
|
||||||
const options = await Self.getOptions();
|
const options = await Self.getOptions();
|
||||||
|
@ -85,14 +167,14 @@ module.exports = Self => {
|
||||||
* @return {object} - The data
|
* @return {object} - The data
|
||||||
*/
|
*/
|
||||||
Self.get = async(code, filter, parse) => {
|
Self.get = async(code, filter, parse) => {
|
||||||
if (!process.env.NODE_ENV) return;
|
if (!env && !Self.hasDeviceReady()) return;
|
||||||
|
|
||||||
const options = await Self.getOptions();
|
const options = await Self.getOptions();
|
||||||
const fileCabinetId = await Self.getFileCabinet(code);
|
const fileCabinetId = await Self.getFileCabinet(code);
|
||||||
const dialogId = await Self.getDialog(code, 'find', fileCabinetId);
|
const dialogId = await Self.getDialog(code, 'find', fileCabinetId);
|
||||||
|
|
||||||
const data = await axios.post(
|
const data = await axios.post(
|
||||||
`${options.url}/FileCabinets/${fileCabinetId}/Query/DialogExpression?dialogId=${dialogId}`,
|
`${Self.baseURL(options, fileCabinetId)}/Query/DialogExpression?dialogId=${dialogId}`,
|
||||||
filter,
|
filter,
|
||||||
options.headers
|
options.headers
|
||||||
);
|
);
|
||||||
|
@ -108,7 +190,7 @@ module.exports = Self => {
|
||||||
* @return {object} - The data
|
* @return {object} - The data
|
||||||
*/
|
*/
|
||||||
Self.getById = async(code, id, parse) => {
|
Self.getById = async(code, id, parse) => {
|
||||||
if (!process.env.NODE_ENV) return;
|
if (!env && !Self.hasDeviceReady()) return;
|
||||||
|
|
||||||
const docuwareInfo = await Self.app.models.Docuware.findOne({
|
const docuwareInfo = await Self.app.models.Docuware.findOne({
|
||||||
fields: ['findById'],
|
fields: ['findById'],
|
||||||
|
@ -129,6 +211,26 @@ module.exports = Self => {
|
||||||
return Self.get(code, filter, parse);
|
return Self.get(code, filter, parse);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute detete old docuware
|
||||||
|
*
|
||||||
|
* @param {string} id - The id
|
||||||
|
* @param {string} fileCabinet - The fieldCabinet
|
||||||
|
* @param {Object} template - The config
|
||||||
|
* @param {string} uri - The uri
|
||||||
|
* @param {Object} options - The options
|
||||||
|
*/
|
||||||
|
Self.deleteOld = async(id, fileCabinet, template, uri, options) => {
|
||||||
|
const docuwareOptions = options ?? await Self.getOptions();
|
||||||
|
template = template ?? {'ESTADO': {type: 'String', value: 'Pendiente eliminar'}};
|
||||||
|
const docuwareFile = await Self.checkFile(id, fileCabinet, false);
|
||||||
|
if (docuwareFile) {
|
||||||
|
const deleteJson = Self.buildTemplateJSON(template);
|
||||||
|
|
||||||
|
const deleteUri = `${uri}/${docuwareFile.id}/Fields`;
|
||||||
|
await axios.put(deleteUri, deleteJson, docuwareOptions.headers);
|
||||||
|
}
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Returns docuware data filtered
|
* Returns docuware data filtered
|
||||||
*
|
*
|
||||||
|
|
|
@ -4,7 +4,7 @@ const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethod('download', {
|
Self.remoteMethod('download', {
|
||||||
description: 'Download an docuware PDF',
|
description: 'Download a docuware PDF',
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [
|
accepts: [
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
const fileName = `filename="${id}.pdf"`;
|
const fileName = `filename="${id}.pdf"`;
|
||||||
const contentType = 'application/pdf';
|
const contentType = 'application/pdf';
|
||||||
const downloadUri = `${options.url}/FileCabinets/${fileCabinetId}/Documents/${docuwareFile.id}/FileDownload?targetFileType=Auto&keepAnnotations=false`;
|
const downloadUri = `${Self.baseURL(options, fileCabinetId)}Documents/${docuwareFile.id}/FileDownload?targetFileType=Auto&keepAnnotations=false`;
|
||||||
|
|
||||||
const stream = await axios.get(downloadUri, options.headers);
|
const stream = await axios.get(downloadUri, options.headers);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,29 @@
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const models = require('vn-loopback/server/server').models;
|
const {Docuware} = require('vn-loopback/server/server').models;
|
||||||
|
describe('hasDeviceReady()', () => {
|
||||||
|
it('should return true', async() => {
|
||||||
|
const result = await Docuware.hasDeviceReady({device: 'Tablet 1'});
|
||||||
|
|
||||||
|
expect(result).toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false', async() => {
|
||||||
|
const result = await Docuware.hasDeviceReady({device: null});
|
||||||
|
|
||||||
|
expect(result).toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not exists return false ', async() => {
|
||||||
|
const result = await Docuware.hasDeviceReady();
|
||||||
|
|
||||||
|
expect(result).toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Docuware core', () => {
|
describe('Docuware core', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
process.env.NODE_ENV = 'testing';
|
process.env.NODE_ENV = 'testing';
|
||||||
|
spyOn(Docuware, 'hasDeviceReady').and.returnValue(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
|
@ -12,7 +32,7 @@ describe('Docuware core', () => {
|
||||||
|
|
||||||
describe('getOptions()', () => {
|
describe('getOptions()', () => {
|
||||||
it('should return url and headers', async() => {
|
it('should return url and headers', async() => {
|
||||||
const result = await models.Docuware.getOptions();
|
const result = await Docuware.getOptions();
|
||||||
|
|
||||||
expect(result.url).toBeDefined();
|
expect(result.url).toBeDefined();
|
||||||
expect(result.headers).toBeDefined();
|
expect(result.headers).toBeDefined();
|
||||||
|
@ -32,16 +52,90 @@ describe('Docuware core', () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
spyOn(axios, 'get').and.returnValue(new Promise(resolve => resolve(dialogs)));
|
spyOn(axios, 'get').and.returnValue(new Promise(resolve => resolve(dialogs)));
|
||||||
const result = await models.Docuware.getDialog('deliveryNote', 'find', 'randomFileCabinetId');
|
const result = await Docuware.getDialog('deliveryNote', 'find', 'randomFileCabinetId');
|
||||||
|
|
||||||
expect(result).toEqual('getDialogTest');
|
expect(result).toEqual('getDialogTest');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('buildTemplateJSON()', () => {
|
||||||
|
it('should return buildTemplateJSON', async() => {
|
||||||
|
const config = {
|
||||||
|
'N__DOCUMENTO': {
|
||||||
|
type: 'string',
|
||||||
|
value: '12345'
|
||||||
|
},
|
||||||
|
'ESTADO': {
|
||||||
|
type: 'string',
|
||||||
|
value: 'Pendiente procesar'
|
||||||
|
},
|
||||||
|
'FIRMA_': {
|
||||||
|
type: 'string',
|
||||||
|
value: 'Si'
|
||||||
|
},
|
||||||
|
'FILTRO_TABLET': {
|
||||||
|
type: 'string',
|
||||||
|
value: 'Tablet123'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = await Docuware.buildTemplateJSON(config);
|
||||||
|
|
||||||
|
expect(result).toEqual({
|
||||||
|
'Fields': [
|
||||||
|
{
|
||||||
|
'FieldName': 'N__DOCUMENTO',
|
||||||
|
'ItemElementName': 'string',
|
||||||
|
'Item': '12345',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'FieldName': 'ESTADO',
|
||||||
|
'ItemElementName': 'string',
|
||||||
|
'Item': 'Pendiente procesar',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'FieldName': 'FIRMA_',
|
||||||
|
'ItemElementName': 'string',
|
||||||
|
'Item': 'Si',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'FieldName': 'FILTRO_TABLET',
|
||||||
|
'ItemElementName': 'string',
|
||||||
|
'Item': 'Tablet123',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('uploadOptions()', () => {
|
||||||
|
it('should return uploadOptions', async() => {
|
||||||
|
spyOn(Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
||||||
|
const {uploadOptions: result} = await Docuware.uploadOptions(1, {
|
||||||
|
'N__DOCUMENTO': {
|
||||||
|
type: 'string',
|
||||||
jsegarra marked this conversation as resolved
alexm
commented
Quitar? Quitar?
|
|||||||
|
value: '12345'
|
||||||
|
}}, 'test.pdf');
|
||||||
|
|
||||||
|
expect(result.headers.Cookie).toEqual(null);
|
||||||
|
expect(result.headers['Content-Type']).toEqual('multipart/form-data');
|
||||||
|
expect(result.headers['content-type']).toMatch(/^multipart\/form-data; boundary=/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('deleteOld()', () => {
|
||||||
|
it('should return deleteOld', async() => {
|
||||||
|
await Docuware.deleteOld(1, 'deliveryNote', {
|
||||||
|
'N__DOCUMENTO': {
|
||||||
|
type: 'string',
|
||||||
|
value: '12345'
|
||||||
|
}});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('getFileCabinet()', () => {
|
describe('getFileCabinet()', () => {
|
||||||
it('should return fileCabinetId', async() => {
|
it('should return fileCabinetId', async() => {
|
||||||
const code = 'deliveryNote';
|
const code = 'deliveryNote';
|
||||||
const docuwareInfo = await models.Docuware.findOne({
|
const docuwareInfo = await Docuware.findOne({
|
||||||
where: {
|
where: {
|
||||||
code
|
code
|
||||||
}
|
}
|
||||||
|
@ -57,7 +151,7 @@ describe('Docuware core', () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
spyOn(axios, 'get').and.returnValue(new Promise(resolve => resolve(dialogs)));
|
spyOn(axios, 'get').and.returnValue(new Promise(resolve => resolve(dialogs)));
|
||||||
const result = await models.Docuware.getFileCabinet(code);
|
const result = await Docuware.getFileCabinet(code);
|
||||||
|
|
||||||
expect(result).toEqual('getFileCabinetTest');
|
expect(result).toEqual('getFileCabinetTest');
|
||||||
});
|
});
|
||||||
|
@ -65,22 +159,22 @@ describe('Docuware core', () => {
|
||||||
|
|
||||||
describe('get()', () => {
|
describe('get()', () => {
|
||||||
it('should return data without parse', async() => {
|
it('should return data without parse', async() => {
|
||||||
spyOn(models.Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
spyOn(Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
||||||
spyOn(models.Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
spyOn(Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
||||||
const data = {
|
const data = {
|
||||||
data: {
|
data: {
|
||||||
id: 1
|
id: 1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
||||||
const result = await models.Docuware.get('deliveryNote');
|
const result = await Docuware.get('deliveryNote');
|
||||||
|
|
||||||
expect(result.id).toEqual(1);
|
expect(result.id).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return data with parse', async() => {
|
it('should return data with parse', async() => {
|
||||||
spyOn(models.Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
spyOn(Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
||||||
spyOn(models.Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
spyOn(Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
||||||
const data = {
|
const data = {
|
||||||
data: {
|
data: {
|
||||||
Items: [{
|
Items: [{
|
||||||
|
@ -109,7 +203,7 @@ describe('Docuware core', () => {
|
||||||
'secondRequiredField': 'name',
|
'secondRequiredField': 'name',
|
||||||
};
|
};
|
||||||
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
||||||
const [result] = await models.Docuware.get('deliveryNote', null, parse);
|
const [result] = await Docuware.get('deliveryNote', null, parse);
|
||||||
|
|
||||||
expect(result.id).toEqual(1);
|
expect(result.id).toEqual(1);
|
||||||
expect(result.name).toEqual('myName');
|
expect(result.name).toEqual('myName');
|
||||||
|
@ -119,15 +213,15 @@ describe('Docuware core', () => {
|
||||||
|
|
||||||
describe('getById()', () => {
|
describe('getById()', () => {
|
||||||
it('should return data', async() => {
|
it('should return data', async() => {
|
||||||
spyOn(models.Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
spyOn(Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
||||||
spyOn(models.Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
spyOn(Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
||||||
const data = {
|
const data = {
|
||||||
data: {
|
data: {
|
||||||
id: 1
|
id: 1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
||||||
const result = await models.Docuware.getById('deliveryNote', 1);
|
const result = await Docuware.getById('deliveryNote', 1);
|
||||||
|
|
||||||
expect(result.id).toEqual(1);
|
expect(result.id).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
const models = require('vn-loopback/server/server').models;
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('docuware upload()', () => {
|
describe('docuware upload()', () => {
|
||||||
const userId = 9;
|
const userId = 18;
|
||||||
const ticketIds = [10];
|
const ids = [10];
|
||||||
const ctx = {
|
const ctx = {
|
||||||
args: {ticketIds},
|
args: {ids},
|
||||||
req: {
|
req: {
|
||||||
getLocale: () => {
|
getLocale: () => {
|
||||||
return 'en';
|
return 'en';
|
||||||
|
@ -32,7 +32,7 @@ describe('docuware upload()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
const user = await models.UserConfig.findById(userId, null, options);
|
const user = await models.UserConfig.findById(userId, null, options);
|
||||||
await user.updateAttribute('tabletFk', 'Tablet1', options);
|
await user.updateAttribute('tabletFk', 'Tablet1', options);
|
||||||
await models.Docuware.upload(ctx, ticketIds, fileCabinetName, options);
|
await models.Docuware.upload(ctx, ids, fileCabinetName, options);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -50,7 +50,7 @@ describe('docuware upload()', () => {
|
||||||
let error;
|
let error;
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
await models.Docuware.upload(ctx, ticketIds, fileCabinetName, options);
|
await models.Docuware.upload(ctx, ids, fileCabinetName, options);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
const axios = require('axios');
|
|
||||||
const isProduction = require('vn-loopback/server/boot/isProduction');
|
const isProduction = require('vn-loopback/server/boot/isProduction');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
|
@ -8,9 +7,9 @@ module.exports = Self => {
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [
|
accepts: [
|
||||||
{
|
{
|
||||||
arg: 'ticketIds',
|
arg: 'ids',
|
||||||
type: ['number'],
|
type: ['number'],
|
||||||
description: 'The ticket ids',
|
description: 'The ids',
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -30,8 +29,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.upload = async function(ctx, ticketIds, fileCabinet, options) {
|
Self.upload = async function(ctx, ids, fileCabinet, options) {
|
||||||
delete ctx.args.ticketIds;
|
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const action = 'store';
|
const action = 'store';
|
||||||
|
|
||||||
|
@ -40,125 +38,33 @@ module.exports = Self => {
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const userConfig = await models.UserConfig.findById(ctx.req.accessToken.userId, {
|
const {tabletFk} = await models.UserConfig.findById(ctx.req.accessToken.userId, {
|
||||||
fields: ['tabletFk']
|
fields: ['tabletFk']
|
||||||
}, myOptions);
|
}, myOptions);
|
||||||
|
|
||||||
if (!userConfig?.tabletFk)
|
if (!tabletFk)
|
||||||
throw new UserError('This user does not have an assigned tablet');
|
throw new UserError('This user does not have an assigned tablet');
|
||||||
|
|
||||||
const docuwareOptions = await Self.getOptions();
|
const docuwareOptions = await Self.getOptions();
|
||||||
|
const docuware = await Self.getDocuware({where: {code: fileCabinet, action}});
|
||||||
|
const {modelFk} = docuware;
|
||||||
|
const modelIsValid = await Self.app.models.Module.findOne({where: {code: modelFk}});
|
||||||
|
|
||||||
|
if (!modelIsValid)
|
||||||
|
throw new UserError('This fileCabinet does not have an assigned module');
|
||||||
|
|
||||||
|
const model = modelFk.replace(/^.{1}/g, modelFk[0].toUpperCase());
|
||||||
|
|
||||||
const fileCabinetId = await Self.getFileCabinet(fileCabinet);
|
const fileCabinetId = await Self.getFileCabinet(fileCabinet);
|
||||||
const dialogId = await Self.getDialog(fileCabinet, action, fileCabinetId);
|
const dialogId = await Self.getDialog(fileCabinet, action, fileCabinetId);
|
||||||
|
|
||||||
const uploaded = [];
|
const uri = Self.baseURL(docuwareOptions, fileCabinetId, 'Documents');
|
||||||
for (id of ticketIds) {
|
|
||||||
// get delivery note
|
|
||||||
ctx.args.id = id;
|
|
||||||
const deliveryNote = await models.Ticket.deliveryNotePdf(ctx, {
|
|
||||||
id,
|
|
||||||
type: 'deliveryNote'
|
|
||||||
}, myOptions);
|
|
||||||
// get ticket data
|
|
||||||
const ticket = await models.Ticket.findById(id, {
|
|
||||||
include: [{
|
|
||||||
relation: 'client',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'name', 'fi']
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
// upload file
|
if (!isProduction(false) && !Self.hasDeviceReady())
|
||||||
const templateJson = {
|
|
||||||
'Fields': [
|
|
||||||
{
|
|
||||||
'FieldName': 'N__ALBAR_N',
|
|
||||||
'ItemElementName': 'string',
|
|
||||||
'Item': id,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'FieldName': 'CIF_PROVEEDOR',
|
|
||||||
'ItemElementName': 'string',
|
|
||||||
'Item': ticket.client().fi,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'FieldName': 'CODIGO_PROVEEDOR',
|
|
||||||
'ItemElementName': 'string',
|
|
||||||
'Item': ticket.client().id,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'FieldName': 'NOMBRE_PROVEEDOR',
|
|
||||||
'ItemElementName': 'string',
|
|
||||||
'Item': ticket.client().name + ' - ' + id,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'FieldName': 'FECHA_FACTURA',
|
|
||||||
'ItemElementName': 'date',
|
|
||||||
'Item': ticket.shipped,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'FieldName': 'TOTAL_FACTURA',
|
|
||||||
'ItemElementName': 'Decimal',
|
|
||||||
'Item': ticket.totalWithVat,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'FieldName': 'ESTADO',
|
|
||||||
'ItemElementName': 'string',
|
|
||||||
'Item': 'Pendiente procesar',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'FieldName': 'FIRMA_',
|
|
||||||
'ItemElementName': 'string',
|
|
||||||
'Item': 'Si',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'FieldName': 'FILTRO_TABLET',
|
|
||||||
'ItemElementName': 'string',
|
|
||||||
'Item': userConfig.tabletFk,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!isProduction(false))
|
|
||||||
throw new UserError('Action not allowed on the test environment');
|
throw new UserError('Action not allowed on the test environment');
|
||||||
|
const upload = {ctx, tabletFk, ids, myOptions, uri, fileCabinet, fileCabinetId, dialogId};
|
||||||
|
await Self.app.models[model].docuwareUpload(upload);
|
||||||
|
|
||||||
// delete old
|
// return models.TicketTracking.setDelivered(ctx, ids, myOptions);
|
||||||
const docuwareFile = await models.Docuware.checkFile(id, fileCabinet, false);
|
|
||||||
if (docuwareFile) {
|
|
||||||
const deleteJson = {
|
|
||||||
'Field': [{'FieldName': 'ESTADO', 'Item': 'Pendiente eliminar', 'ItemElementName': 'String'}]
|
|
||||||
};
|
|
||||||
const deleteUri = `${docuwareOptions.url}/FileCabinets/${fileCabinetId}/Documents/${docuwareFile.id}/Fields`;
|
|
||||||
await axios.put(deleteUri, deleteJson, docuwareOptions.headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uploadUri = `${docuwareOptions.url}/FileCabinets/${fileCabinetId}/Documents?StoreDialogId=${dialogId}`;
|
|
||||||
const FormData = require('form-data');
|
|
||||||
const data = new FormData();
|
|
||||||
|
|
||||||
data.append('document', JSON.stringify(templateJson), 'schema.json');
|
|
||||||
data.append('file[]', deliveryNote[0], 'file.pdf');
|
|
||||||
const uploadOptions = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data',
|
|
||||||
'X-File-ModifiedDate': Date.vnNew(),
|
|
||||||
'Cookie': docuwareOptions.headers.headers.Cookie,
|
|
||||||
...data.getHeaders()
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
await axios.post(uploadUri, data, uploadOptions);
|
|
||||||
} catch (err) {
|
|
||||||
const $t = ctx.req.__;
|
|
||||||
const message = $t('Failed to upload delivery note', {id});
|
|
||||||
if (uploaded.length)
|
|
||||||
await models.TicketTracking.setDelivered(ctx, uploaded, myOptions);
|
|
||||||
throw new UserError(message);
|
|
||||||
}
|
|
||||||
uploaded.push(id);
|
|
||||||
}
|
|
||||||
return models.TicketTracking.setDelivered(ctx, ticketIds, myOptions);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
},
|
},
|
||||||
"findById": {
|
"findById": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"modelFk": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
|
|
@ -2786,7 +2786,7 @@ INSERT INTO `bs`.`sale` (`saleFk`, `amount`, `dated`, `typeFk`, `clientFk`)
|
||||||
|
|
||||||
INSERT INTO `vn`.`docuwareConfig` (`id`, `url`)
|
INSERT INTO `vn`.`docuwareConfig` (`id`, `url`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'http://docuware.url/');
|
(1, 'http://docuware.url');
|
||||||
|
|
||||||
INSERT INTO `vn`.`calendarHolidaysName` (`id`, `name`)
|
INSERT INTO `vn`.`calendarHolidaysName` (`id`, `name`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -3141,6 +3141,11 @@ INSERT INTO `vn`.`docuwareTablet` (`tablet`,`description`)
|
||||||
('Tablet1','Jarvis tablet'),
|
('Tablet1','Jarvis tablet'),
|
||||||
('Tablet2','Avengers tablet');
|
('Tablet2','Avengers tablet');
|
||||||
|
|
||||||
|
-- Auto-generated SQL script #202406060955
|
||||||
|
INSERT INTO `vn`.`docuwareTablet` (`tablet`,`description`,`fileCabinet`)
|
||||||
|
VALUES ('Tablet4','Docuware Tablet','RRHH');
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`sms` (`id`, `senderFk`, `sender`, `destination`, `message`, `statusCode`, `status`, `created`)
|
INSERT INTO `vn`.`sms` (`id`, `senderFk`, `sender`, `destination`, `message`, `statusCode`, `status`, `created`)
|
||||||
VALUES (1, 66, '111111111', '0001111111111', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'OK', util.VN_CURDATE()),
|
VALUES (1, 66, '111111111', '0001111111111', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'OK', util.VN_CURDATE()),
|
||||||
(2, 66, '222222222', '0002222222222', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'PENDING', util.VN_CURDATE()),
|
(2, 66, '222222222', '0002222222222', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'PENDING', util.VN_CURDATE()),
|
||||||
|
@ -3884,6 +3889,41 @@ INSERT INTO vn.trainingCourse (workerFk,trainingCourseTypeFk,centerFk,started,en
|
||||||
(9,1,2,'2018-06-20 00:00:00.000','2020-06-24 00:00:00.000',1,0),
|
(9,1,2,'2018-06-20 00:00:00.000','2020-06-24 00:00:00.000',1,0),
|
||||||
(9,2,2,'2018-06-20 00:00:00.000','2020-06-24 00:00:00.000',1,1);
|
(9,2,2,'2018-06-20 00:00:00.000','2020-06-24 00:00:00.000',1,1);
|
||||||
|
|
||||||
|
|
||||||
|
-- Auto-generated SQL script #202405201318
|
||||||
|
UPDATE vn.userConfig
|
||||||
|
SET tabletFk='Tablet4'
|
||||||
|
WHERE userFk=5;
|
||||||
|
|
||||||
|
-- Auto-generated SQL script #202405201207
|
||||||
|
UPDATE vn.docuware
|
||||||
|
SET modelFk='ticket'
|
||||||
|
WHERE id=1;
|
||||||
|
UPDATE vn.docuware
|
||||||
|
SET modelFk='ticket'
|
||||||
|
WHERE id=2;
|
||||||
|
UPDATE vn.docuware
|
||||||
|
SET modelFk='worker'
|
||||||
|
WHERE id=3;
|
||||||
|
|
||||||
|
|
||||||
|
-- Auto-generated SQL script #202405201318
|
||||||
|
UPDATE vn.userConfig
|
||||||
|
SET tabletFk='Tablet1'
|
||||||
|
WHERE userFk=9;
|
||||||
|
|
||||||
|
-- Auto-generated SQL script #202405201207
|
||||||
|
UPDATE vn.docuware
|
||||||
|
SET modelFk='ticket'
|
||||||
|
WHERE id=1;
|
||||||
|
UPDATE vn.docuware
|
||||||
|
SET modelFk='ticket'
|
||||||
|
WHERE id=2;
|
||||||
|
UPDATE vn.docuware
|
||||||
|
SET modelFk='worker'
|
||||||
|
WHERE id=3;
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO vn.sectorCollection
|
INSERT INTO vn.sectorCollection
|
||||||
SET id = 2,
|
SET id = 2,
|
||||||
userFk = 18,
|
userFk = 18,
|
||||||
|
@ -3953,21 +3993,22 @@ INSERT INTO dipole.expedition_PrintOut (expeditionFk, ticketFk, addressFk, stree
|
||||||
truckName, clientFk, phone, province, agency, m3, workerCode, itemFk, quantity, longName, shelvingFk, comments)
|
truckName, clientFk, phone, province, agency, m3, workerCode, itemFk, quantity, longName, shelvingFk, comments)
|
||||||
VALUES(1, 1, 0, ' ', ' ', ' ', ' ', 0, '2001-01-01 00:00:00', 1, 0, ' ', ' ', 0, NULL, '', NULL, 0.000, NULL, 10, NULL, NULL, 'NCC', NULL);
|
VALUES(1, 1, 0, ' ', ' ', ' ', ' ', 0, '2001-01-01 00:00:00', 1, 0, ' ', ' ', 0, NULL, '', NULL, 0.000, NULL, 10, NULL, NULL, 'NCC', NULL);
|
||||||
|
|
||||||
INSERT INTO vn.accountDetail
|
INSERT INTO vn.accountDetail (id, value, accountDetailTypeFk, supplierAccountFk)
|
||||||
(id, value, accountDetailTypeFk, supplierAccountFk)
|
VALUES
|
||||||
VALUES
|
|
||||||
(21, 'ES12345B12345678', 3, 241),
|
(21, 'ES12345B12345678', 3, 241),
|
||||||
(35, 'ES12346B12345679', 3, 241);
|
(35, 'ES12346B12345679', 3, 241);
|
||||||
|
|
||||||
INSERT INTO vn.accountDetailType
|
INSERT INTO vn.accountDetailType (id, description, code)
|
||||||
(id, description, code)
|
VALUES
|
||||||
VALUES
|
(1, 'IBAN'),
|
||||||
(1, 'IBAN', 'iban'),
|
(2, 'SWIFT'),
|
||||||
(2, 'SWIFT', 'swift'),
|
(3, 'Referencia Remesas'),
|
||||||
(3, 'Referencia Remesas', 'remRef'),
|
(4, 'Referencia Transferencias'),
|
||||||
(4, 'Referencia Transferencias', 'trnRef'),
|
(5, 'Referencia Nominas'),
|
||||||
(5, 'Referencia Nominas', 'payRef'),
|
(6, 'ABA');
|
||||||
(6, 'ABA', 'aba');
|
|
||||||
|
INSERT INTO account.userConfig (userFk,warehouseFk,companyFk,darkMode,tabletFk)
|
||||||
|
VALUES (37,1,442,1,'Tablet4');
|
||||||
|
|
||||||
INSERT IGNORE INTO ormConfig
|
INSERT IGNORE INTO ormConfig
|
||||||
SET id =1,
|
SET id =1,
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
ALTER TABLE vn.docuware ADD modelFk VARCHAR(45) DEFAULT NULL NULL;
|
||||||
|
ALTER TABLE vn.docuware ADD CONSTRAINT docuware_module_FK FOREIGN KEY (modelFk) REFERENCES salix.module(code);
|
||||||
|
|
||||||
|
ALTER TABLE vn.docuwareTablet ADD fileCabinet varchar(100) NULL;
|
||||||
|
|
||||||
|
INSERT IGNORE INTO vn.docuware (code,fileCabinetName,`action`,dialogName,findById,dmsTypeFk,modelFk)
|
||||||
jsegarra marked this conversation as resolved
Outdated
alexm
commented
Quitar Quitar
|
|||||||
|
VALUES ('hr','RRHH','store','Archivar','N__DOCUMENTO',3,'worker');
|
||||||
|
|
||||||
|
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
|
||||||
|
VALUES ('Worker','signPdaPdf','READ','ALLOW','ROLE','hr');
|
||||||
|
|
||||||
|
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
|
||||||
jsegarra marked this conversation as resolved
alexm
commented
quitar quitar
|
|||||||
|
VALUES ('Docuware','upload','WRITE','ALLOW','ROLE','hr');
|
|
@ -0,0 +1,89 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
const {models} = require('vn-loopback/server/server');
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
const isProduction = require('vn-loopback/server/boot/isProduction');
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.docuwareUpload = async({ctx, tabletFk, ids: ticketIds, myOptions, uri, dialogId}) => {
|
||||||
|
const type = 'deliveryNote';
|
||||||
|
for (id of ticketIds) {
|
||||||
|
// get delivery note
|
||||||
|
ctx.args.id = id;
|
||||||
|
const deliveryNote = await models.Ticket.deliveryNotePdf(ctx, {
|
||||||
|
id,
|
||||||
|
type
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
// get ticket data
|
||||||
|
const ticket = await models.Ticket.findById(id, {
|
||||||
|
include: [{
|
||||||
|
relation: 'client',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name', 'fi']
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
// upload file
|
||||||
|
const configTemplate = {
|
||||||
|
'N__ALBAR_N': {
|
||||||
|
type: 'string',
|
||||||
|
value: id,
|
||||||
|
},
|
||||||
|
'CIF_PROVEEDOR': {
|
||||||
|
type: 'string',
|
||||||
|
value: ticket.client().fi,
|
||||||
|
},
|
||||||
|
'CODIGO_PROVEEDOR': {
|
||||||
|
type: 'string',
|
||||||
|
value: ticket.client().id,
|
||||||
|
},
|
||||||
|
'NOMBRE_PROVEEDOR': {
|
||||||
|
type: 'string',
|
||||||
|
value: ticket.client().name + ' - ' + id,
|
||||||
|
},
|
||||||
|
'FECHA_FACTURA': {
|
||||||
|
type: 'date',
|
||||||
|
value: ticket.shipped,
|
||||||
|
},
|
||||||
|
'TOTAL_FACTURA': {
|
||||||
|
type: 'Decimal',
|
||||||
|
value: ticket.totalWithVat,
|
||||||
|
},
|
||||||
|
'ESTADO': {
|
||||||
|
type: 'string',
|
||||||
|
value: 'Pendiente procesar',
|
||||||
|
},
|
||||||
|
'FIRMA_': {
|
||||||
|
type: 'string',
|
||||||
|
value: 'Si',
|
||||||
|
},
|
||||||
|
'FILTRO_TABLET': {
|
||||||
|
type: 'string',
|
||||||
|
value: tabletFk,
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isProduction(false) && !Self.hasDeviceReady())
|
||||||
|
throw new UserError('Action not allowed on the test environment');
|
||||||
|
|
||||||
|
// delete old
|
||||||
|
await models.Docuware.deleteOld(id, fileCabinet, uri);
|
||||||
|
|
||||||
|
const uploadUri = `${uri}?StoreDialogId=${dialogId}`;
|
||||||
|
const {data, uploadOptions} = models.Docuware.uploadOptions(deliveryNote[0], configTemplate, `${type}.pdf`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await axios.post(uploadUri, data, uploadOptions);
|
||||||
|
} catch (err) {
|
||||||
|
const $t = ctx.req.__;
|
||||||
|
const message = $t('Failed to upload delivery note', {id});
|
||||||
|
if (uploaded.length)
|
||||||
|
await models.TicketTracking.setDelivered(ctx, uploaded, myOptions);
|
||||||
|
throw new UserError(message);
|
||||||
|
}
|
||||||
|
uploaded.push(id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -45,5 +45,6 @@ module.exports = function(Self) {
|
||||||
require('../methods/ticket/invoiceTickets')(Self);
|
require('../methods/ticket/invoiceTickets')(Self);
|
||||||
require('../methods/ticket/invoiceTicketsAndPdf')(Self);
|
require('../methods/ticket/invoiceTicketsAndPdf')(Self);
|
||||||
require('../methods/ticket/docuwareDownload')(Self);
|
require('../methods/ticket/docuwareDownload')(Self);
|
||||||
|
require('../methods/ticket/docuwareUpload')(Self);
|
||||||
require('../methods/ticket/myLastModified')(Self);
|
require('../methods/ticket/myLastModified')(Self);
|
||||||
};
|
};
|
||||||
|
|
|
@ -324,7 +324,7 @@ class Controller extends Section {
|
||||||
if (!force)
|
if (!force)
|
||||||
return this.$.pdfToTablet.show();
|
return this.$.pdfToTablet.show();
|
||||||
|
|
||||||
return this.$http.post(`Docuwares/upload`, {fileCabinet: 'deliveryNote', ticketIds: [this.id]})
|
return this.$http.post(`Docuwares/upload`, {fileCabinet: 'deliveryNote', ids: [this.id]})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.vnApp.showSuccess(this.$t('PDF sent!'));
|
this.vnApp.showSuccess(this.$t('PDF sent!'));
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,12 +11,12 @@ export default class Controller extends Section {
|
||||||
|
|
||||||
sendDocuware() {
|
sendDocuware() {
|
||||||
const checkedTickets = this.checked;
|
const checkedTickets = this.checked;
|
||||||
let ticketIds = [];
|
let ids = [];
|
||||||
|
|
||||||
for (let ticket of checkedTickets)
|
for (let ticket of checkedTickets)
|
||||||
ticketIds.push(ticket.id);
|
ids.push(ticket.id);
|
||||||
|
|
||||||
return this.$http.post(`Docuwares/upload`, {fileCabinet: 'deliveryNote', ticketIds})
|
return this.$http.post(`Docuwares/upload`, {fileCabinet: 'deliveryNote', ids})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
let state = res.data;
|
let state = res.data;
|
||||||
for (let ticket of checkedTickets) {
|
for (let ticket of checkedTickets) {
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
const {models} = require('vn-loopback/server/server');
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
const isProduction = require('vn-loopback/server/boot/isProduction');
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.docuwareUpload = async({ctx, tabletFk, ids: id, myOptions, uri, fileCabinet, dialogId}) => {
|
||||||
|
const pdaId = id[0];
|
||||||
|
|
||||||
|
ctx.args.id = pdaId;
|
||||||
|
delete ctx.args.ids;
|
||||||
|
|
||||||
|
// upload file
|
||||||
|
const workerFk = await models.DeviceProductionUser.findOne(
|
||||||
|
{
|
||||||
|
fields: ['userFk'],
|
||||||
|
where: {deviceProductionFk: pdaId}
|
||||||
|
}
|
||||||
|
, myOptions);
|
||||||
|
|
||||||
|
const signPda = await models.Worker.signPdaPdf(ctx,
|
||||||
|
{pdaId, workerFk}
|
||||||
|
, myOptions);
|
||||||
|
|
||||||
|
const configTemplate = {
|
||||||
|
'N__DOCUMENTO': {
|
||||||
|
type: 'String',
|
||||||
|
value: pdaId
|
||||||
|
},
|
||||||
|
'ESTADO': {
|
||||||
|
type: 'String',
|
||||||
|
value: 'Pendiente procesar'
|
||||||
|
},
|
||||||
|
'FIRMA_': {
|
||||||
|
type: 'String',
|
||||||
|
value: 'Si'
|
||||||
|
},
|
||||||
|
'FILTRO_TABLET': {
|
||||||
|
type: 'String',
|
||||||
|
value: tabletFk
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isProduction(false) && !Self.hasDeviceReady())
|
||||||
|
throw new UserError('Action not allowed on the test environment');
|
||||||
|
|
||||||
|
// delete old
|
||||||
|
await models.Docuware.deleteOld(id, fileCabinet, uri);
|
||||||
|
|
||||||
|
const uploadUri = `${uri}?StoreDialogId=${dialogId}`;
|
||||||
|
const fileName = `assign${pdaId}Pda${workerFk}.pdf`;
|
||||||
|
const {data, uploadOptions} = await models.Docuware.uploadOptions(signPda[0], configTemplate, fileName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await axios.post(uploadUri, data, uploadOptions);
|
||||||
|
} catch (err) {
|
||||||
|
const $t = ctx.req.__;
|
||||||
|
const message = $t('Failed to upload delivery note', {id});
|
||||||
|
throw new UserError(message);
|
||||||
|
}
|
||||||
|
uploaded.push(id);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('signPdaPdf', {
|
||||||
|
description: 'Print pdf to sign PDA',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The pda id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The worker id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: [
|
||||||
|
{
|
||||||
|
arg: 'body',
|
||||||
|
type: 'file',
|
||||||
|
root: true
|
||||||
|
}, {
|
||||||
|
arg: 'Content-Type',
|
||||||
|
type: 'String',
|
||||||
|
http: {target: 'header'}
|
||||||
|
}, {
|
||||||
|
arg: 'Content-Disposition',
|
||||||
|
type: 'String',
|
||||||
|
http: {target: 'header'}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
http: {
|
||||||
|
path: '/:id/sign-pda-pdf',
|
||||||
|
verb: 'GET'
|
||||||
|
},
|
||||||
|
accessScopes: ['DEFAULT', 'read:multimedia']
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.signPdaPdf = (ctx, id) => Self.printReport(ctx, id, 'sign-pda');
|
||||||
|
};
|
|
@ -8,6 +8,7 @@ module.exports = Self => {
|
||||||
require('../methods/worker/createAbsence')(Self);
|
require('../methods/worker/createAbsence')(Self);
|
||||||
require('../methods/worker/deleteAbsence')(Self);
|
require('../methods/worker/deleteAbsence')(Self);
|
||||||
require('../methods/worker/updateAbsence')(Self);
|
require('../methods/worker/updateAbsence')(Self);
|
||||||
|
require('../methods/worker/docuwareUpload')(Self);
|
||||||
require('../methods/worker/active')(Self);
|
require('../methods/worker/active')(Self);
|
||||||
require('../methods/worker/activeWithRole')(Self);
|
require('../methods/worker/activeWithRole')(Self);
|
||||||
require('../methods/worker/activeWithInheritedRole')(Self);
|
require('../methods/worker/activeWithInheritedRole')(Self);
|
||||||
|
@ -17,6 +18,7 @@ module.exports = Self => {
|
||||||
require('../methods/worker/new')(Self);
|
require('../methods/worker/new')(Self);
|
||||||
require('../methods/worker/deallocatePDA')(Self);
|
require('../methods/worker/deallocatePDA')(Self);
|
||||||
require('../methods/worker/allocatePDA')(Self);
|
require('../methods/worker/allocatePDA')(Self);
|
||||||
|
require('../methods/worker/signPdaPdf')(Self);
|
||||||
require('../methods/worker/search')(Self);
|
require('../methods/worker/search')(Self);
|
||||||
require('../methods/worker/isAuthorized')(Self);
|
require('../methods/worker/isAuthorized')(Self);
|
||||||
require('../methods/worker/setPassword')(Self);
|
require('../methods/worker/setPassword')(Self);
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
const Stylesheet = require(`vn-print/core/stylesheet`);
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const vnPrintPath = path.resolve('print');
|
||||||
|
|
||||||
|
module.exports = new Stylesheet([
|
||||||
|
`${vnPrintPath}/common/css/spacing.css`,
|
||||||
|
`${vnPrintPath}/common/css/misc.css`,
|
||||||
|
`${vnPrintPath}/common/css/layout.css`,
|
||||||
|
`${vnPrintPath}/common/css/report.css`,
|
||||||
|
`${__dirname}/style.css`])
|
||||||
|
.mergeStyles();
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
.description strong {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-weight: 100;
|
||||||
|
color: #555
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-oriented {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-info {
|
||||||
|
font-size: 20px
|
||||||
|
}
|
||||||
|
.row-oriented > tbody > tr > th {
|
||||||
|
padding-left: 30px;
|
||||||
|
width: 20%
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-block {
|
||||||
|
font-size: 1.2em
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
reportName: pda
|
||||||
|
signNote: Recepción PDA
|
||||||
|
date: Fecha
|
||||||
|
deviceRecieved: He recibido de Verdnatura Levante SL, el terminal *{modelFk}* con nº de serie {serialNumber} junto con su funda y protector de pantalla para el desarrollo de mi actividad profesional.
|
||||||
|
pdaModel: PDA Modelo
|
||||||
|
pdaSerie: Serie PDA
|
||||||
|
sim: sim vodafone
|
||||||
|
pin: pin
|
||||||
|
puk: puk
|
||||||
|
label1: El terminal es propiedad de la empresa y debe ser utilizado exclusivamente para las funciones y aplicaciones determinadas por la empresa.
|
||||||
|
label2: Me comprometo a conservar el terminal con su batería, tarjeta SIM, funda y protector de pantalla, y en caso de finalizar mi relación de servicios con la empresa, realizar la devolución en el plazo máximo de 24 horas.
|
||||||
|
label3: Si el terminal fuese robado, perdido o dañado, me comprometo a abonar el importe íntegro del terminal o su reparación en el centro oficial , así como la funda y el protector de pantalla.
|
||||||
|
label4: La instalación de aplicaciones no autorizadas por la empresa, puedan provocar o no un daño al terminal o a la empresa por vulneración de datos, virus, etc, no está autorizado, bajo ningún concepto, el uso de accesorios no originales.
|
||||||
|
label5: La empresa prohibe el uso de accesorios no originales.
|
||||||
|
label6: Mediante este documento me comprometo a usar la funda, y protector de pantalla en todo momento para minimizar daños en el terminal.
|
||||||
|
sign1: Recibe, D/Dña
|
||||||
|
sign2: DNI
|
||||||
|
sign: FIRMA
|
|
@ -0,0 +1,18 @@
|
||||||
|
reportName: pda
|
||||||
|
signNote: Recepción PDA
|
||||||
|
date: Fecha
|
||||||
|
deviceRecieved: He recibido de Verdnatura Levante SL, el terminal *{modelFk}* con nº de serie {serialNumber} junto con su funda y protector de pantalla para el desarrollo de mi actividad profesional.
|
||||||
|
pdaModel: PDA Modelo
|
||||||
|
pdaSerie: Serie PDA
|
||||||
|
sim: sim vodafone
|
||||||
|
pin: pin
|
||||||
|
puk: puk
|
||||||
|
label1: El terminal es propiedad de la empresa y debe ser utilizado exclusivamente para las funciones y aplicaciones determinadas por la empresa.
|
||||||
|
label2: Me comprometo a conservar el terminal con su batería, tarjeta SIM, funda y protector de pantalla, y en caso de finalizar mi relación de servicios con la empresa, realizar la devolución en el plazo máximo de 24 horas.
|
||||||
|
label3: Si el terminal fuese robado, perdido o dañado, me comprometo a abonar el importe íntegro del terminal o su reparación en el centro oficial , así como la funda y el protector de pantalla.
|
||||||
|
label4: La instalación de aplicaciones no autorizadas por la empresa, puedan provocar o no un daño al terminal o a la empresa por vulneración de datos, virus, etc, no está autorizado, bajo ningún concepto, el uso de accesorios no originales.
|
||||||
|
label5: La empresa prohibe el uso de accesorios no originales.
|
||||||
|
label6: Mediante este documento me comprometo a usar la funda, y protector de pantalla en todo momento para minimizar daños en el terminal.
|
||||||
|
sign1: Recibe, D/Dña
|
||||||
|
sign2: DNI
|
||||||
|
sign: FIRMA
|
|
@ -0,0 +1,18 @@
|
||||||
|
reportName: pda
|
||||||
|
signNote: Recepción PDA
|
||||||
|
date: Fecha
|
||||||
|
deviceRecieved: He recibido de Verdnatura Levante SL, el terminal *{modelFk}* con nº de serie {serialNumber} junto con su funda y protector de pantalla para el desarrollo de mi actividad profesional.
|
||||||
|
pdaModel: PDA Modelo
|
||||||
|
pdaSerie: Serie PDA
|
||||||
|
sim: sim vodafone
|
||||||
|
pin: pin
|
||||||
|
puk: puk
|
||||||
|
label1: El terminal es propiedad de la empresa y debe ser utilizado exclusivamente para las funciones y aplicaciones determinadas por la empresa.
|
||||||
|
label2: Me comprometo a conservar el terminal con su batería, tarjeta SIM, funda y protector de pantalla, y en caso de finalizar mi relación de servicios con la empresa, realizar la devolución en el plazo máximo de 24 horas.
|
||||||
|
label3: Si el terminal fuese robado, perdido o dañado, me comprometo a abonar el importe íntegro del terminal o su reparación en el centro oficial , así como la funda y el protector de pantalla.
|
||||||
|
label4: La instalación de aplicaciones no autorizadas por la empresa, puedan provocar o no un daño al terminal o a la empresa por vulneración de datos, virus, etc, no está autorizado, bajo ningún concepto, el uso de accesorios no originales.
|
||||||
|
label5: La empresa prohibe el uso de accesorios no originales.
|
||||||
|
label6: Mediante este documento me comprometo a usar la funda, y protector de pantalla en todo momento para minimizar daños en el terminal.
|
||||||
|
sign1: Recibe, D/Dña
|
||||||
|
sign2: DNI
|
||||||
|
sign: FIRMA
|
|
@ -0,0 +1,18 @@
|
||||||
|
reportName: pda
|
||||||
|
signNote: Recepción PDA
|
||||||
|
date: Fecha
|
||||||
|
deviceRecieved: He recibido de Verdnatura Levante SL, el terminal *{modelFk}* con nº de serie {serialNumber} junto con su funda y protector de pantalla para el desarrollo de mi actividad profesional.
|
||||||
|
pdaModel: PDA Modelo
|
||||||
|
pdaSerie: Serie PDA
|
||||||
|
sim: sim vodafone
|
||||||
|
pin: pin
|
||||||
|
puk: puk
|
||||||
|
label1: El terminal es propiedad de la empresa y debe ser utilizado exclusivamente para las funciones y aplicaciones determinadas por la empresa.
|
||||||
|
label2: Me comprometo a conservar el terminal con su batería, tarjeta SIM, funda y protector de pantalla, y en caso de finalizar mi relación de servicios con la empresa, realizar la devolución en el plazo máximo de 24 horas.
|
||||||
|
label3: Si el terminal fuese robado, perdido o dañado, me comprometo a abonar el importe íntegro del terminal o su reparación en el centro oficial , así como la funda y el protector de pantalla.
|
||||||
|
label4: La instalación de aplicaciones no autorizadas por la empresa, puedan provocar o no un daño al terminal o a la empresa por vulneración de datos, virus, etc, no está autorizado, bajo ningún concepto, el uso de accesorios no originales.
|
||||||
|
label5: La empresa prohibe el uso de accesorios no originales.
|
||||||
|
label6: Mediante este documento me comprometo a usar la funda, y protector de pantalla en todo momento para minimizar daños en el terminal.
|
||||||
|
sign1: Recibe, D/Dña
|
||||||
|
sign2: DNI
|
||||||
|
sign: FIRMA
|
|
@ -0,0 +1,18 @@
|
||||||
|
reportName: pda
|
||||||
|
signNote: Recepción PDA
|
||||||
|
date: Fecha
|
||||||
|
deviceRecieved: He recibido de Verdnatura Levante SL, el terminal *{modelFk}* con nº de serie {serialNumber} junto con su funda y protector de pantalla para el desarrollo de mi actividad profesional.
|
||||||
|
pdaModel: PDA Modelo
|
||||||
|
pdaSerie: Serie PDA
|
||||||
|
sim: sim vodafone
|
||||||
|
pin: pin
|
||||||
|
puk: puk
|
||||||
|
label1: El terminal es propiedad de la empresa y debe ser utilizado exclusivamente para las funciones y aplicaciones determinadas por la empresa.
|
||||||
|
label2: Me comprometo a conservar el terminal con su batería, tarjeta SIM, funda y protector de pantalla, y en caso de finalizar mi relación de servicios con la empresa, realizar la devolución en el plazo máximo de 24 horas.
|
||||||
|
label3: Si el terminal fuese robado, perdido o dañado, me comprometo a abonar el importe íntegro del terminal o su reparación en el centro oficial , así como la funda y el protector de pantalla.
|
||||||
|
label4: La instalación de aplicaciones no autorizadas por la empresa, puedan provocar o no un daño al terminal o a la empresa por vulneración de datos, virus, etc, no está autorizado, bajo ningún concepto, el uso de accesorios no originales.
|
||||||
|
label5: La empresa prohibe el uso de accesorios no originales.
|
||||||
|
label6: Mediante este documento me comprometo a usar la funda, y protector de pantalla en todo momento para minimizar daños en el terminal.
|
||||||
|
sign1: Recibe, D/Dña
|
||||||
|
sign2: DNI
|
||||||
|
sign: FIRMA
|
|
@ -0,0 +1,48 @@
|
||||||
|
<report-body v-bind="$props">
|
||||||
|
<template v-slot:header>
|
||||||
|
<report-header v-bind="$props"> </report-header>
|
||||||
|
</template>
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="grid-block">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="body">
|
||||||
|
<span>{{$t('date')}}:{{formatDate(new Date(), '%d-%m-%Y')}}</span>
|
||||||
|
<p>
|
||||||
|
{{$t('deviceRecieved',{modelFk: device.modelFk, serialNumber: device.serialNumber})}}:
|
||||||
|
</p>
|
||||||
|
<p>{{$t('label1')}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{$t('label2')}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{$t('label3')}}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{$t('label4')}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{$t('label5')}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{$t('label6')}}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{$t('sign1')}} {{worker.firstName}} {{ worker.lastName}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{$t('sign2')}} {{worker.fi}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{$t('sign')}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template v-slot:footer>
|
||||||
|
<report-footer id="pageFooter" v-bind="$props"> </report-footer>
|
||||||
|
</template>
|
||||||
|
</report-body>
|
|
@ -0,0 +1,26 @@
|
||||||
|
const vnReport = require('../../../core/mixins/vn-report.js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'sign-pda',
|
||||||
|
mixins: [vnReport],
|
||||||
|
async serverPrefetch() {
|
||||||
|
this.device = await this.findOneFromDef('device', [this.id]);
|
||||||
|
this.worker = await this.findOneFromDef('worker', [this.workerFk]);
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
description: 'The device id'
|
||||||
|
},
|
||||||
|
workerFk: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
description: 'The worker id'
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1 @@
|
||||||
|
SELECT * FROM vn.deviceProduction WHERE id = ?
|
|
@ -0,0 +1 @@
|
||||||
|
SELECT * FROM vn.worker WHERE id = ?
|
Loading…
Reference in New Issue
Esto que es?
Es una funcionalidad que he hecho muy similar a print.development.json para que si existe algún archivo de configuración de tablet.
Esto es útil para hacer pruebas reales con la tablet 4 o con datos falsos