dms update files
gitea/salix/test This commit looks good
Details
gitea/salix/test This commit looks good
Details
This commit is contained in:
parent
88b698f3eb
commit
fefb389872
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
|
@ -9,27 +9,25 @@ module.exports = Self => {
|
||||||
{
|
{
|
||||||
arg: 'warehouseId',
|
arg: 'warehouseId',
|
||||||
type: 'Number',
|
type: 'Number',
|
||||||
description: ''
|
description: 'The warehouse id'
|
||||||
}, {
|
}, {
|
||||||
arg: 'companyId',
|
arg: 'companyId',
|
||||||
type: 'Number',
|
type: 'Number',
|
||||||
description: ''
|
description: 'The company id'
|
||||||
}, {
|
}, {
|
||||||
arg: 'dmsTypeId',
|
arg: 'dmsTypeId',
|
||||||
type: 'Number',
|
type: 'Number',
|
||||||
description: ''
|
description: 'The dms type id'
|
||||||
}, {
|
}, {
|
||||||
arg: 'reference',
|
arg: 'reference',
|
||||||
type: 'String',
|
type: 'String'
|
||||||
description: ''
|
|
||||||
}, {
|
}, {
|
||||||
arg: 'description',
|
arg: 'description',
|
||||||
type: 'String',
|
type: 'String'
|
||||||
description: ''
|
|
||||||
}, {
|
}, {
|
||||||
arg: 'hasFile',
|
arg: 'hasFile',
|
||||||
type: 'Boolean',
|
type: 'Boolean',
|
||||||
description: ''
|
description: 'True if has an attached file'
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'Object',
|
type: 'Object',
|
||||||
|
|
|
@ -2,4 +2,5 @@ module.exports = Self => {
|
||||||
require('../methods/dms/downloadFile')(Self);
|
require('../methods/dms/downloadFile')(Self);
|
||||||
require('../methods/dms/uploadFile')(Self);
|
require('../methods/dms/uploadFile')(Self);
|
||||||
require('../methods/dms/removeFile')(Self);
|
require('../methods/dms/removeFile')(Self);
|
||||||
|
require('../methods/dms/updateFile')(Self);
|
||||||
};
|
};
|
||||||
|
|
|
@ -141,6 +141,12 @@ vn-table {
|
||||||
background-color: $color-alert-medium;
|
background-color: $color-alert-medium;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& > vn-td vn-icon-menu {
|
||||||
|
display: inline-block;
|
||||||
|
color: $color-main;
|
||||||
|
padding: .25em
|
||||||
|
}
|
||||||
|
|
||||||
& > [actions] {
|
& > [actions] {
|
||||||
width: 1px;
|
width: 1px;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ module.exports = app => {
|
||||||
};
|
};
|
||||||
|
|
||||||
storageConnector.getFileExtension = function(fileName) {
|
storageConnector.getFileExtension = function(fileName) {
|
||||||
return fileName.split('.').pop();
|
return fileName.split('.').pop().toLowerCase();
|
||||||
};
|
};
|
||||||
|
|
||||||
storageConnector.getPathHash = function(id) {
|
storageConnector.getPathHash = function(id) {
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
<vn-watcher
|
||||||
|
vn-id="watcher"
|
||||||
|
data="$ctrl.dms">
|
||||||
|
</vn-watcher>
|
||||||
|
<form name="form" ng-submit="$ctrl.onSubmit()" margin-medium enctype="multipart/form-data">
|
||||||
|
<div compact>
|
||||||
|
<vn-card pad-large>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-one vn-focus
|
||||||
|
label="Reference"
|
||||||
|
field="$ctrl.dms.reference">
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Company"
|
||||||
|
field="$ctrl.dms.companyId"
|
||||||
|
url="/api/Companies"
|
||||||
|
show-field="code"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Warehouse"
|
||||||
|
field="$ctrl.dms.warehouseId"
|
||||||
|
url="/api/Warehouses"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Type"
|
||||||
|
field="$ctrl.dms.dmsTypeId"
|
||||||
|
url="/api/DmsTypes"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textarea vn-one required="true"
|
||||||
|
label="Description"
|
||||||
|
field="$ctrl.dms.description">
|
||||||
|
</vn-textarea>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-input-file vn-one
|
||||||
|
label="File"
|
||||||
|
model="$ctrl.dms.files"
|
||||||
|
on-change="$ctrl.onFileChange(files)"
|
||||||
|
accept=".pdf, .png, .jpg, .jpeg, application/zip, application/rar">
|
||||||
|
</vn-input-file>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-vertical>
|
||||||
|
<vn-check
|
||||||
|
label="Attached file"
|
||||||
|
field="$ctrl.dms.hasFile">
|
||||||
|
</vn-check>
|
||||||
|
</vn-vertical>
|
||||||
|
</vn-card>
|
||||||
|
<vn-button-bar>
|
||||||
|
<vn-submit label="Save"></vn-submit>
|
||||||
|
<vn-button ui-sref="client.card.dms.index" label="Cancel"></vn-button>
|
||||||
|
</vn-button-bar>
|
||||||
|
</div>
|
||||||
|
</form>
|
|
@ -0,0 +1,86 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
constructor($scope, $http, $state, $translate, vnApp) {
|
||||||
|
this.$ = $scope;
|
||||||
|
this.$http = $http;
|
||||||
|
this.$state = $state;
|
||||||
|
this.$stateParams = $state.params;
|
||||||
|
this.$translate = $translate;
|
||||||
|
this.vnApp = vnApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
get client() {
|
||||||
|
return this._client;
|
||||||
|
}
|
||||||
|
|
||||||
|
set client(value) {
|
||||||
|
this._client = value;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
this.setDefaultParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
setDefaultParams() {
|
||||||
|
const path = `/api/Dms/${this.$stateParams.dmsId}`;
|
||||||
|
this.$http.get(path).then(res => {
|
||||||
|
const dms = res.data && res.data;
|
||||||
|
this.dms = {
|
||||||
|
reference: dms.reference,
|
||||||
|
warehouseId: dms.warehouseFk,
|
||||||
|
companyId: dms.companyFk,
|
||||||
|
dmsTypeId: dms.dmsTypeFk,
|
||||||
|
description: dms.description,
|
||||||
|
hasFile: dms.hasFile,
|
||||||
|
files: []
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
const query = `/api/dms/${this.$stateParams.dmsId}/updateFile`;
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
url: query,
|
||||||
|
params: this.dms,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': undefined
|
||||||
|
},
|
||||||
|
transformRequest: files => {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++)
|
||||||
|
formData.append(files[i].name, files[i]);
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
},
|
||||||
|
data: this.dms.files
|
||||||
|
};
|
||||||
|
this.$http(options).then(res => {
|
||||||
|
if (res) {
|
||||||
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||||
|
this.$.watcher.updateOriginalData();
|
||||||
|
this.$state.go('client.card.dms.index');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileChange(files) {
|
||||||
|
if (files.length > 0) {
|
||||||
|
this.$.$applyAsync(() => {
|
||||||
|
this.dms.hasFile = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.$inject = ['$scope', '$http', '$state', '$translate', 'vnApp'];
|
||||||
|
|
||||||
|
ngModule.component('vnClientDmsEdit', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller,
|
||||||
|
bindings: {
|
||||||
|
client: '<'
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,60 @@
|
||||||
|
import './index';
|
||||||
|
|
||||||
|
describe('Client', () => {
|
||||||
|
describe('Component vnClientDmsCreate', () => {
|
||||||
|
let controller;
|
||||||
|
let $scope;
|
||||||
|
let $httpBackend;
|
||||||
|
let $httpParamSerializer;
|
||||||
|
|
||||||
|
beforeEach(ngModule('client'));
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$httpParamSerializer = _$httpParamSerializer_;
|
||||||
|
controller = $componentController('vnClientDmsCreate', {$scope});
|
||||||
|
controller._client = {id: 101, name: 'Bruce wayne'};
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('client() setter', () => {
|
||||||
|
it('should set the client data and then call setDefaultParams()', () => {
|
||||||
|
spyOn(controller, 'setDefaultParams');
|
||||||
|
controller.client = {
|
||||||
|
id: 15,
|
||||||
|
name: 'Bruce wayne'
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(controller.client).toBeDefined();
|
||||||
|
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setDefaultParams()', () => {
|
||||||
|
it('should perform a GET query and define the dms property on controller', () => {
|
||||||
|
const params = {filter: {
|
||||||
|
where: {code: 'paymentsLaw'}
|
||||||
|
}};
|
||||||
|
let serializedParams = $httpParamSerializer(params);
|
||||||
|
$httpBackend.when('GET', `/api/DmsTypes/findOne?${serializedParams}`).respond({id: 12, code: 'paymentsLaw'});
|
||||||
|
$httpBackend.expect('GET', `/api/DmsTypes/findOne?${serializedParams}`);
|
||||||
|
controller.setDefaultParams();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.dms).toBeDefined();
|
||||||
|
expect(controller.dms.reference).toEqual(101);
|
||||||
|
expect(controller.dms.dmsTypeId).toEqual(12);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onFileChange()', () => {
|
||||||
|
it('should set dms hasFile property to true if has any files', () => {
|
||||||
|
const files = [{id: 1, name: 'MyFile'}];
|
||||||
|
controller.onFileChange(files);
|
||||||
|
$scope.$apply();
|
||||||
|
|
||||||
|
expect(controller.dms.hasFile).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,3 @@
|
||||||
|
Edit file: Editar fichero
|
||||||
|
File: Fichero
|
||||||
|
Attached file: Fichero adjunto
|
|
@ -0,0 +1,7 @@
|
||||||
|
vn-ticket-request {
|
||||||
|
vn-textfield {
|
||||||
|
margin: 0!important;
|
||||||
|
max-width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
<vn-th field="dmsTypeFk" shrink>Type</vn-th>
|
<vn-th field="dmsTypeFk" shrink>Type</vn-th>
|
||||||
<vn-th field="reference">Reference</vn-th>
|
<vn-th field="reference">Reference</vn-th>
|
||||||
<vn-th>Description</vn-th>
|
<vn-th>Description</vn-th>
|
||||||
<vn-th field="hasFile" center>Attached file</vn-th>
|
<vn-th field="hasFile" center>Original</vn-th>
|
||||||
<vn-th shrink>File</vn-th>
|
<vn-th shrink>File</vn-th>
|
||||||
<vn-th>Employee</vn-th>
|
<vn-th shrink>Employee</vn-th>
|
||||||
<vn-th field="created">Created</vn-th>
|
<vn-th field="created">Created</vn-th>
|
||||||
<vn-th></vn-th>
|
<vn-th number></vn-th>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-thead>
|
</vn-thead>
|
||||||
<vn-tbody>
|
<vn-tbody>
|
||||||
|
@ -41,13 +41,13 @@
|
||||||
{{::document.dms.description}}
|
{{::document.dms.description}}
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td center>
|
<vn-td shrink center>
|
||||||
<vn-check disabled="true"
|
<vn-check disabled="true"
|
||||||
field="document.dms.hasFile">
|
field="document.dms.hasFile">
|
||||||
</vn-check>
|
</vn-check>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>{{::document.dms.file}}</vn-td>
|
<vn-td shrink>{{::document.dms.file}}</vn-td>
|
||||||
<vn-td>
|
<vn-td shrink>
|
||||||
<span class="link"
|
<span class="link"
|
||||||
ng-click="$ctrl.showWorkerDescriptor($event, document.dms.workerFk)">
|
ng-click="$ctrl.showWorkerDescriptor($event, document.dms.workerFk)">
|
||||||
{{::document.dms.worker.user.nickname | dashIfEmpty}}
|
{{::document.dms.worker.user.nickname | dashIfEmpty}}
|
||||||
|
@ -55,16 +55,21 @@
|
||||||
<vn-td>
|
<vn-td>
|
||||||
{{::document.dms.created | dateTime:'dd/MM/yyyy HH:mm'}}
|
{{::document.dms.created | dateTime:'dd/MM/yyyy HH:mm'}}
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td center shrink>
|
<vn-td number>
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
vn-tooltip="Download file"
|
vn-tooltip="Download file"
|
||||||
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}"
|
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}"
|
||||||
ng-show="document.hasFile">
|
ng-show="document.dms.hasFile">
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
icon="cloud_download"
|
icon="cloud_download"
|
||||||
title="{{'Download PDF' | translate}}">
|
title="{{'Download PDF' | translate}}">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
</a>
|
</a>
|
||||||
|
<vn-icon-button ui-sref="client.card.dms.edit({dmsId: {{::document.dmsFk}}})"
|
||||||
|
vn-tooltip="Edit file"
|
||||||
|
icon="edit"
|
||||||
|
title="{{'Edit file' | translate}}">
|
||||||
|
</vn-icon-button>
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
vn-tooltip="Remove file"
|
vn-tooltip="Remove file"
|
||||||
icon="delete"
|
icon="delete"
|
||||||
|
|
|
@ -38,3 +38,4 @@ import './sms';
|
||||||
import './postcode';
|
import './postcode';
|
||||||
import './dms/index';
|
import './dms/index';
|
||||||
import './dms/create';
|
import './dms/create';
|
||||||
|
import './dms/edit';
|
||||||
|
|
|
@ -336,6 +336,15 @@
|
||||||
"params": {
|
"params": {
|
||||||
"client": "$ctrl.client"
|
"client": "$ctrl.client"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/:dmsId/edit",
|
||||||
|
"state": "client.card.dms.edit",
|
||||||
|
"component": "vn-client-dms-edit",
|
||||||
|
"description": "Edit file",
|
||||||
|
"params": {
|
||||||
|
"client": "$ctrl.client"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
<vn-watcher
|
||||||
|
vn-id="watcher"
|
||||||
|
data="$ctrl.dms">
|
||||||
|
</vn-watcher>
|
||||||
|
<form name="form" ng-submit="$ctrl.onSubmit()" margin-medium enctype="multipart/form-data">
|
||||||
|
<div compact>
|
||||||
|
<vn-card pad-large>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-one vn-focus
|
||||||
|
label="Reference"
|
||||||
|
field="$ctrl.dms.reference">
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Company"
|
||||||
|
field="$ctrl.dms.companyId"
|
||||||
|
url="/api/Companies"
|
||||||
|
show-field="code"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Warehouse"
|
||||||
|
field="$ctrl.dms.warehouseId"
|
||||||
|
url="/api/Warehouses"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Type"
|
||||||
|
field="$ctrl.dms.dmsTypeId"
|
||||||
|
url="/api/DmsTypes"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textarea vn-one required="true"
|
||||||
|
label="Description"
|
||||||
|
field="$ctrl.dms.description">
|
||||||
|
</vn-textarea>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-input-file vn-one
|
||||||
|
label="File"
|
||||||
|
model="$ctrl.dms.files"
|
||||||
|
on-change="$ctrl.onFileChange(files)"
|
||||||
|
accept=".pdf, .png, .jpg, .jpeg, application/zip, application/rar">
|
||||||
|
</vn-input-file>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-vertical>
|
||||||
|
<vn-check
|
||||||
|
label="Attached file"
|
||||||
|
field="$ctrl.dms.hasFile">
|
||||||
|
</vn-check>
|
||||||
|
</vn-vertical>
|
||||||
|
</vn-card>
|
||||||
|
<vn-button-bar>
|
||||||
|
<vn-submit label="Save"></vn-submit>
|
||||||
|
<vn-button ui-sref="ticket.card.dms.index" label="Cancel"></vn-button>
|
||||||
|
</vn-button-bar>
|
||||||
|
</div>
|
||||||
|
</form>
|
|
@ -0,0 +1,86 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
constructor($scope, $http, $state, $translate, vnApp) {
|
||||||
|
this.$ = $scope;
|
||||||
|
this.$http = $http;
|
||||||
|
this.$state = $state;
|
||||||
|
this.$stateParams = $state.params;
|
||||||
|
this.$translate = $translate;
|
||||||
|
this.vnApp = vnApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
get ticket() {
|
||||||
|
return this._ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
set ticket(value) {
|
||||||
|
this._ticket = value;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
this.setDefaultParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
setDefaultParams() {
|
||||||
|
const path = `/api/Dms/${this.$stateParams.dmsId}`;
|
||||||
|
this.$http.get(path).then(res => {
|
||||||
|
const dms = res.data && res.data;
|
||||||
|
this.dms = {
|
||||||
|
reference: dms.reference,
|
||||||
|
warehouseId: dms.warehouseFk,
|
||||||
|
companyId: dms.companyFk,
|
||||||
|
dmsTypeId: dms.dmsTypeFk,
|
||||||
|
description: dms.description,
|
||||||
|
hasFile: dms.hasFile,
|
||||||
|
files: []
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
const query = `/api/dms/${this.$stateParams.dmsId}/updateFile`;
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
url: query,
|
||||||
|
params: this.dms,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': undefined
|
||||||
|
},
|
||||||
|
transformRequest: files => {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++)
|
||||||
|
formData.append(files[i].name, files[i]);
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
},
|
||||||
|
data: this.dms.files
|
||||||
|
};
|
||||||
|
this.$http(options).then(res => {
|
||||||
|
if (res) {
|
||||||
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||||
|
this.$.watcher.updateOriginalData();
|
||||||
|
this.$state.go('ticket.card.dms.index');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileChange(files) {
|
||||||
|
if (files.length > 0) {
|
||||||
|
this.$.$applyAsync(() => {
|
||||||
|
this.dms.hasFile = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.$inject = ['$scope', '$http', '$state', '$translate', 'vnApp'];
|
||||||
|
|
||||||
|
ngModule.component('vnTicketDmsEdit', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller,
|
||||||
|
bindings: {
|
||||||
|
ticket: '<'
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,60 @@
|
||||||
|
import './index';
|
||||||
|
|
||||||
|
describe('Client', () => {
|
||||||
|
describe('Component vnClientDmsCreate', () => {
|
||||||
|
let controller;
|
||||||
|
let $scope;
|
||||||
|
let $httpBackend;
|
||||||
|
let $httpParamSerializer;
|
||||||
|
|
||||||
|
beforeEach(ngModule('client'));
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$httpParamSerializer = _$httpParamSerializer_;
|
||||||
|
controller = $componentController('vnClientDmsCreate', {$scope});
|
||||||
|
controller._client = {id: 101, name: 'Bruce wayne'};
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('client() setter', () => {
|
||||||
|
it('should set the client data and then call setDefaultParams()', () => {
|
||||||
|
spyOn(controller, 'setDefaultParams');
|
||||||
|
controller.client = {
|
||||||
|
id: 15,
|
||||||
|
name: 'Bruce wayne'
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(controller.client).toBeDefined();
|
||||||
|
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setDefaultParams()', () => {
|
||||||
|
it('should perform a GET query and define the dms property on controller', () => {
|
||||||
|
const params = {filter: {
|
||||||
|
where: {code: 'paymentsLaw'}
|
||||||
|
}};
|
||||||
|
let serializedParams = $httpParamSerializer(params);
|
||||||
|
$httpBackend.when('GET', `/api/DmsTypes/findOne?${serializedParams}`).respond({id: 12, code: 'paymentsLaw'});
|
||||||
|
$httpBackend.expect('GET', `/api/DmsTypes/findOne?${serializedParams}`);
|
||||||
|
controller.setDefaultParams();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.dms).toBeDefined();
|
||||||
|
expect(controller.dms.reference).toEqual(101);
|
||||||
|
expect(controller.dms.dmsTypeId).toEqual(12);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onFileChange()', () => {
|
||||||
|
it('should set dms hasFile property to true if has any files', () => {
|
||||||
|
const files = [{id: 1, name: 'MyFile'}];
|
||||||
|
controller.onFileChange(files);
|
||||||
|
$scope.$apply();
|
||||||
|
|
||||||
|
expect(controller.dms.hasFile).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,3 @@
|
||||||
|
Edit file: Editar fichero
|
||||||
|
File: Fichero
|
||||||
|
Attached file: Fichero adjunto
|
|
@ -0,0 +1,7 @@
|
||||||
|
vn-ticket-request {
|
||||||
|
vn-textfield {
|
||||||
|
margin: 0!important;
|
||||||
|
max-width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -59,12 +59,17 @@
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
vn-tooltip="Download file"
|
vn-tooltip="Download file"
|
||||||
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}"
|
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}"
|
||||||
ng-show="document.hasFile">
|
ng-show="document.dms.hasFile">
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
icon="cloud_download"
|
icon="cloud_download"
|
||||||
title="{{'Download PDF' | translate}}">
|
title="{{'Download PDF' | translate}}">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
</a>
|
</a>
|
||||||
|
<vn-icon-button ui-sref="ticket.card.dms.edit({dmsId: {{::document.dmsFk}}})"
|
||||||
|
vn-tooltip="Edit file"
|
||||||
|
icon="edit"
|
||||||
|
title="{{'Edit file' | translate}}">
|
||||||
|
</vn-icon-button>
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
vn-tooltip="Remove file"
|
vn-tooltip="Remove file"
|
||||||
icon="delete"
|
icon="delete"
|
||||||
|
|
|
@ -33,3 +33,4 @@ import './log';
|
||||||
import './weekly';
|
import './weekly';
|
||||||
import './dms/index';
|
import './dms/index';
|
||||||
import './dms/create';
|
import './dms/create';
|
||||||
|
import './dms/edit';
|
||||||
|
|
|
@ -233,6 +233,15 @@
|
||||||
"params": {
|
"params": {
|
||||||
"ticket": "$ctrl.ticket"
|
"ticket": "$ctrl.ticket"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/:dmsId/edit",
|
||||||
|
"state": "ticket.card.dms.edit",
|
||||||
|
"component": "vn-ticket-dms-edit",
|
||||||
|
"description": "Edit file",
|
||||||
|
"params": {
|
||||||
|
"ticket": "$ctrl.ticket"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
Reference in New Issue