diff --git a/back/methods/dms/specs/updateFile.spec.js b/back/methods/dms/specs/updateFile.spec.js
new file mode 100644
index 000000000..2945b1ac9
--- /dev/null
+++ b/back/methods/dms/specs/updateFile.spec.js
@@ -0,0 +1,22 @@
+const app = require('vn-loopback/server/server');
+
+describe('dms updateFile()', () => {
+ it(`should return an error for a user without enough privileges`, async() => {
+ let clientId = 101;
+ let companyId = 442;
+ let warehouseId = 1;
+ let dmsTypeId = 14;
+
+ let dmsId = 1;
+ let ctx = {req: {accessToken: {userId: clientId}}, args: {dmsTypeId: dmsTypeId}};
+
+ let error;
+ await app.models.Dms.updateFile(ctx, dmsId, warehouseId, companyId, dmsTypeId).catch(e => {
+ error = e;
+ }).finally(() => {
+ expect(error.message).toEqual(`You don't have enough privileges`);
+ });
+
+ expect(error).toBeDefined();
+ });
+});
diff --git a/back/methods/dms/updateFile.js b/back/methods/dms/updateFile.js
new file mode 100644
index 000000000..e502c7b94
--- /dev/null
+++ b/back/methods/dms/updateFile.js
@@ -0,0 +1,158 @@
+const UserError = require('vn-loopback/util/user-error');
+const fs = require('fs-extra');
+
+module.exports = Self => {
+ Self.remoteMethodCtx('updateFile', {
+ description: 'updates a file properties or file',
+ accessType: 'WRITE',
+ accepts: [{
+ arg: 'id',
+ type: 'Number',
+ description: 'The document id',
+ http: {source: 'path'}
+ },
+ {
+ arg: 'warehouseId',
+ type: 'Number',
+ description: 'The warehouse id'
+ }, {
+ arg: 'companyId',
+ type: 'Number',
+ description: 'The company id'
+ }, {
+ arg: 'dmsTypeId',
+ type: 'Number',
+ description: 'The dms type id'
+ }, {
+ arg: 'reference',
+ type: 'String'
+ }, {
+ arg: 'description',
+ type: 'String'
+ }, {
+ arg: 'hasFile',
+ type: 'Boolean',
+ description: 'True if has an attached file'
+ }],
+ returns: {
+ type: 'Object',
+ root: true
+ },
+ http: {
+ path: `/:id/updateFile`,
+ verb: 'POST'
+ }
+ });
+
+ Self.updateFile = async(ctx, id, warehouseId, companyId,
+ dmsTypeId, reference, description, hasFile, options) => {
+ const storageConnector = Self.app.dataSources.storage.connector;
+ const models = Self.app.models;
+ const fileOptions = {};
+
+ let tx;
+ let myOptions = {};
+
+ if (typeof options == 'object')
+ Object.assign(myOptions, options);
+
+ if (!myOptions.transaction) {
+ tx = await Self.beginTransaction({});
+ myOptions.transaction = tx;
+ }
+
+ try {
+ const hasWriteRole = await models.DmsType.hasWriteRole(ctx, dmsTypeId);
+ if (!hasWriteRole)
+ throw new UserError(`You don't have enough privileges`);
+
+ // Upload file to temporary path
+ const tempContainer = await getContainer('temp');
+ let files = [];
+ try {
+ const uploaded = await models.Container.upload(tempContainer.name, ctx.req, ctx.result, fileOptions);
+ files = Object.values(uploaded.files).map(file => {
+ return file[0];
+ });
+ } catch (err) {
+ if (err.message != 'No file content uploaded')
+ throw e;
+ }
+
+ const updatedDmsList = [];
+ for (const file of files) {
+ const updatedDms = await updateDms(id, dmsTypeId, companyId, warehouseId,
+ reference, description, hasFile, file.name, myOptions);
+
+ const pathHash = storageConnector.getPathHash(updatedDms.id);
+ const container = await getContainer(pathHash);
+
+ const originPath = `${tempContainer.client.root}/${tempContainer.name}/${file.name}`;
+ const destinationPath = `${container.client.root}/${pathHash}/${updatedDms.file}`;
+
+ fs.rename(originPath, destinationPath);
+
+ updatedDmsList.push(updatedDms);
+ }
+
+ if (tx) await tx.commit();
+ return updatedDmsList;
+ } catch (e) {
+ if (tx) await tx.rollback();
+ throw e;
+ }
+ };
+
+ async function updateDms(id, dmsTypeId, companyId, warehouseId,
+ reference, description, hasFile, fileName, myOptions) {
+ const storageConnector = Self.app.dataSources.storage.connector;
+ const dms = await Self.findById(id, null, myOptions);
+ const updatedDms = await dms.updateAttributes({
+ dmsTypeFk: dmsTypeId,
+ companyFk: companyId,
+ warehouseFk: warehouseId,
+ reference: reference,
+ description: description,
+ hasFile: hasFile
+ }, myOptions);
+
+ const oldExtension = storageConnector.getFileExtension(dms.file);
+ const newExtension = storageConnector.getFileExtension(fileName);
+
+ try {
+ if (oldExtension != newExtension) {
+ const pathHash = storageConnector.getPathHash(updatedDms.id);
+
+ await Self.app.models.Container.removeFile(pathHash, dms.file);
+ }
+ } catch (err) {}
+
+ fileName = `${updatedDms.id}.${newExtension}`;
+
+ return updatedDms.updateAttribute('file', fileName, myOptions);
+ }
+
+
+ /**
+ * Returns a container instance
+ * If doesn't exists creates a new one
+ *
+ * @param {String} name Container name
+ * @return {Object} Container instance
+ */
+ async function getContainer(name) {
+ const models = Self.app.models;
+ let container;
+ try {
+ container = await models.Container.getContainer(name);
+ } catch (err) {
+ if (err.code === 'ENOENT') {
+ container = await models.Container.createContainer({
+ name: name
+ });
+ } else throw err;
+ }
+
+ return container;
+ }
+};
diff --git a/back/methods/dms/uploadFile.js b/back/methods/dms/uploadFile.js
index 9ef60c005..5d4634aae 100644
--- a/back/methods/dms/uploadFile.js
+++ b/back/methods/dms/uploadFile.js
@@ -9,27 +9,25 @@ module.exports = Self => {
{
arg: 'warehouseId',
type: 'Number',
- description: ''
+ description: 'The warehouse id'
}, {
arg: 'companyId',
type: 'Number',
- description: ''
+ description: 'The company id'
}, {
arg: 'dmsTypeId',
type: 'Number',
- description: ''
+ description: 'The dms type id'
}, {
arg: 'reference',
- type: 'String',
- description: ''
+ type: 'String'
}, {
arg: 'description',
- type: 'String',
- description: ''
+ type: 'String'
}, {
arg: 'hasFile',
type: 'Boolean',
- description: ''
+ description: 'True if has an attached file'
}],
returns: {
type: 'Object',
diff --git a/back/models/dms.js b/back/models/dms.js
index d3471178b..9a06928db 100644
--- a/back/models/dms.js
+++ b/back/models/dms.js
@@ -2,4 +2,5 @@ module.exports = Self => {
require('../methods/dms/downloadFile')(Self);
require('../methods/dms/uploadFile')(Self);
require('../methods/dms/removeFile')(Self);
+ require('../methods/dms/updateFile')(Self);
};
diff --git a/front/core/components/table/style.scss b/front/core/components/table/style.scss
index 87af10834..7d985c437 100644
--- a/front/core/components/table/style.scss
+++ b/front/core/components/table/style.scss
@@ -141,6 +141,12 @@ vn-table {
background-color: $color-alert-medium;
}
+ & > vn-td vn-icon-menu {
+ display: inline-block;
+ color: $color-main;
+ padding: .25em
+ }
+
& > [actions] {
width: 1px;
diff --git a/loopback/server/boot/storage.js b/loopback/server/boot/storage.js
index d34804059..12662ab73 100644
--- a/loopback/server/boot/storage.js
+++ b/loopback/server/boot/storage.js
@@ -9,7 +9,7 @@ module.exports = app => {
};
storageConnector.getFileExtension = function(fileName) {
- return fileName.split('.').pop();
+ return fileName.split('.').pop().toLowerCase();
};
storageConnector.getPathHash = function(id) {
diff --git a/modules/client/front/dms/edit/index.html b/modules/client/front/dms/edit/index.html
new file mode 100644
index 000000000..65c280c5d
--- /dev/null
+++ b/modules/client/front/dms/edit/index.html
@@ -0,0 +1,63 @@
+