Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
8c84f006b0
|
@ -1,68 +0,0 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
|
||||||
|
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethod('addAlias', {
|
|
||||||
description: 'Add an alias if the user has the grant',
|
|
||||||
accessType: 'WRITE',
|
|
||||||
accepts: [
|
|
||||||
{
|
|
||||||
arg: 'ctx',
|
|
||||||
type: 'Object',
|
|
||||||
http: {source: 'context'}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
arg: 'id',
|
|
||||||
type: 'number',
|
|
||||||
required: true,
|
|
||||||
description: 'The user id',
|
|
||||||
http: {source: 'path'}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
arg: 'mailAlias',
|
|
||||||
type: 'number',
|
|
||||||
description: 'The new alias for user',
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
http: {
|
|
||||||
path: `/:id/addAlias`,
|
|
||||||
verb: 'POST'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.addAlias = async function(ctx, id, mailAlias, options) {
|
|
||||||
const models = Self.app.models;
|
|
||||||
const userId = ctx.req.accessToken.userId;
|
|
||||||
|
|
||||||
const myOptions = {};
|
|
||||||
|
|
||||||
if (typeof options == 'object')
|
|
||||||
Object.assign(myOptions, options);
|
|
||||||
|
|
||||||
const user = await Self.findById(userId, {fields: ['hasGrant']}, myOptions);
|
|
||||||
|
|
||||||
if (!user.hasGrant)
|
|
||||||
throw new UserError(`You don't have grant privilege`);
|
|
||||||
|
|
||||||
const account = await models.Account.findById(userId, {
|
|
||||||
fields: ['id'],
|
|
||||||
include: {
|
|
||||||
relation: 'aliases',
|
|
||||||
scope: {
|
|
||||||
fields: ['mailAlias']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
const aliases = account.aliases().map(alias => alias.mailAlias);
|
|
||||||
|
|
||||||
const hasAlias = aliases.includes(mailAlias);
|
|
||||||
if (!hasAlias)
|
|
||||||
throw new UserError(`You cannot assign an alias that you are not assigned to`);
|
|
||||||
|
|
||||||
return models.MailAliasAccount.create({
|
|
||||||
mailAlias: mailAlias,
|
|
||||||
account: id
|
|
||||||
}, myOptions);
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,55 +0,0 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
|
||||||
|
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethod('removeAlias', {
|
|
||||||
description: 'Remove alias if the user has the grant',
|
|
||||||
accessType: 'WRITE',
|
|
||||||
accepts: [
|
|
||||||
{
|
|
||||||
arg: 'ctx',
|
|
||||||
type: 'Object',
|
|
||||||
http: {source: 'context'}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
arg: 'id',
|
|
||||||
type: 'number',
|
|
||||||
required: true,
|
|
||||||
description: 'The user id',
|
|
||||||
http: {source: 'path'}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
arg: 'mailAlias',
|
|
||||||
type: 'number',
|
|
||||||
description: 'The alias to delete',
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
http: {
|
|
||||||
path: `/:id/removeAlias`,
|
|
||||||
verb: 'POST'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.removeAlias = async function(ctx, id, mailAlias, options) {
|
|
||||||
const models = Self.app.models;
|
|
||||||
const userId = ctx.req.accessToken.userId;
|
|
||||||
|
|
||||||
const myOptions = {};
|
|
||||||
|
|
||||||
if (typeof options == 'object')
|
|
||||||
Object.assign(myOptions, options);
|
|
||||||
|
|
||||||
const canRemoveAlias = await models.ACL.checkAccessAcl(ctx, 'VnUser', 'canRemoveAlias', 'WRITE');
|
|
||||||
|
|
||||||
if (userId != id && !canRemoveAlias) throw new UserError(`You don't have grant privilege`);
|
|
||||||
|
|
||||||
const mailAliasAccount = await models.MailAliasAccount.findOne({
|
|
||||||
where: {
|
|
||||||
mailAlias: mailAlias,
|
|
||||||
account: id
|
|
||||||
}
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
await mailAliasAccount.destroy(myOptions);
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -12,8 +12,6 @@ module.exports = function(Self) {
|
||||||
require('../methods/vn-user/privileges')(Self);
|
require('../methods/vn-user/privileges')(Self);
|
||||||
require('../methods/vn-user/validate-auth')(Self);
|
require('../methods/vn-user/validate-auth')(Self);
|
||||||
require('../methods/vn-user/renew-token')(Self);
|
require('../methods/vn-user/renew-token')(Self);
|
||||||
require('../methods/vn-user/addAlias')(Self);
|
|
||||||
require('../methods/vn-user/removeAlias')(Self);
|
|
||||||
|
|
||||||
Self.definition.settings.acls = Self.definition.settings.acls.filter(acl => acl.property !== 'create');
|
Self.definition.settings.acls = Self.definition.settings.acls.filter(acl => acl.property !== 'create');
|
||||||
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
|
||||||
VALUES
|
|
||||||
('VnUser', 'addAlias', 'WRITE', 'ALLOW', 'ROLE', 'employee');
|
|
||||||
|
|
||||||
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
|
||||||
VALUES
|
|
||||||
('VnUser', 'removeAlias', 'WRITE', 'ALLOW', 'ROLE', 'employee');
|
|
||||||
|
|
||||||
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
|
||||||
VALUES
|
|
||||||
('VnUser', 'canRemoveAlias', 'WRITE', 'ALLOW', 'ROLE', 'itManagement');
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
DELETE FROM `salix`.`ACL` WHERE model = 'MailAliasAccount';
|
||||||
|
|
||||||
|
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
||||||
|
VALUES
|
||||||
|
('MailAliasAccount', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('MailAliasAccount', 'create', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('MailAliasAccount', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('MailAliasAccount', 'canEditAlias', 'WRITE', 'ALLOW', 'ROLE', 'itManagement');
|
|
@ -0,0 +1,4 @@
|
||||||
|
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
||||||
|
VALUES
|
||||||
|
('WorkerDisableExcluded', '*', 'READ', 'ALLOW', 'ROLE', 'itManagement'),
|
||||||
|
('WorkerDisableExcluded', '*', 'WRITE', 'ALLOW', 'ROLE', 'itManagement');
|
|
@ -305,5 +305,6 @@
|
||||||
"The renew period has not been exceeded": "El periodo de renovación no ha sido superado",
|
"The renew period has not been exceeded": "El periodo de renovación no ha sido superado",
|
||||||
"Valid priorities": "Prioridades válidas: %d",
|
"Valid priorities": "Prioridades válidas: %d",
|
||||||
"Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}",
|
"Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}",
|
||||||
"You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado"
|
"You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado",
|
||||||
|
"This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.observe('before save', async ctx => {
|
||||||
|
const changes = ctx.currentInstance || ctx.instance;
|
||||||
|
|
||||||
|
await Self.hasGrant(ctx, changes.mailAlias);
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.observe('before delete', async ctx => {
|
||||||
|
const mailAliasAccount = await Self.findById(ctx.where.id);
|
||||||
|
|
||||||
|
await Self.hasGrant(ctx, mailAliasAccount.mailAlias);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if current user has
|
||||||
|
* grant to add/remove alias
|
||||||
|
*
|
||||||
|
* @param {Object} ctx - Request context
|
||||||
|
* @param {Interger} mailAlias - mailAlias id
|
||||||
|
* @return {Boolean} True for user with grant
|
||||||
|
*/
|
||||||
|
Self.hasGrant = async function(ctx, mailAlias) {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const accessToken = {req: {accessToken: ctx.options.accessToken}};
|
||||||
|
const userId = accessToken.req.accessToken.userId;
|
||||||
|
|
||||||
|
const canEditAlias = await models.ACL.checkAccessAcl(accessToken, 'MailAliasAccount', 'canEditAlias', 'WRITE');
|
||||||
|
if (canEditAlias) return true;
|
||||||
|
|
||||||
|
const user = await models.VnUser.findById(userId, {fields: ['hasGrant']});
|
||||||
|
if (!user.hasGrant)
|
||||||
|
throw new UserError(`You don't have grant privilege`);
|
||||||
|
|
||||||
|
const account = await models.Account.findById(userId, {
|
||||||
|
fields: ['id'],
|
||||||
|
include: {
|
||||||
|
relation: 'aliases',
|
||||||
|
scope: {
|
||||||
|
fields: ['mailAlias']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const aliases = account.aliases().map(alias => alias.mailAlias);
|
||||||
|
|
||||||
|
const hasAlias = aliases.includes(mailAlias);
|
||||||
|
if (!hasAlias)
|
||||||
|
throw new UserError(`You cannot assign/remove an alias that you are not assigned to`);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
};
|
|
@ -21,11 +21,12 @@ export default class Controller extends Section {
|
||||||
}
|
}
|
||||||
|
|
||||||
onAddClick() {
|
onAddClick() {
|
||||||
|
this.addData = {account: this.$params.id};
|
||||||
this.$.dialog.show();
|
this.$.dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
onAddSave() {
|
onAddSave() {
|
||||||
return this.$http.post(`VnUsers/${this.$params.id}/addAlias`, this.addData)
|
return this.$http.post(`MailAliasAccounts`, this.addData)
|
||||||
.then(() => this.refresh())
|
.then(() => this.refresh())
|
||||||
.then(() => this.vnApp.showSuccess(
|
.then(() => this.vnApp.showSuccess(
|
||||||
this.$t('Subscribed to alias!'))
|
this.$t('Subscribed to alias!'))
|
||||||
|
@ -33,12 +34,11 @@ export default class Controller extends Section {
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemove(row) {
|
onRemove(row) {
|
||||||
const params = {
|
return this.$http.delete(`MailAliasAccounts/${row.id}`)
|
||||||
mailAlias: row.mailAlias
|
.then(() => {
|
||||||
};
|
this.$.data.splice(this.$.data.indexOf(row), 1);
|
||||||
return this.$http.post(`VnUsers/${this.$params.id}/removeAlias`, params)
|
this.vnApp.showSuccess(this.$t('Unsubscribed from alias!'));
|
||||||
.then(() => this.refresh())
|
});
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,8 @@ describe('component vnUserAliases', () => {
|
||||||
describe('onAddSave()', () => {
|
describe('onAddSave()', () => {
|
||||||
it('should add the new row', () => {
|
it('should add the new row', () => {
|
||||||
controller.addData = {account: 1};
|
controller.addData = {account: 1};
|
||||||
controller.$params = {id: 1};
|
|
||||||
|
|
||||||
$httpBackend.expectPOST('VnUsers/1/addAlias').respond();
|
$httpBackend.expectPOST('MailAliasAccounts').respond();
|
||||||
$httpBackend.expectGET('MailAliasAccounts').respond('foo');
|
$httpBackend.expectGET('MailAliasAccounts').respond('foo');
|
||||||
controller.onAddSave();
|
controller.onAddSave();
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
|
@ -42,14 +41,12 @@ describe('component vnUserAliases', () => {
|
||||||
{id: 1, alias: 'foo'},
|
{id: 1, alias: 'foo'},
|
||||||
{id: 2, alias: 'bar'}
|
{id: 2, alias: 'bar'}
|
||||||
];
|
];
|
||||||
controller.$params = {id: 1};
|
|
||||||
|
|
||||||
$httpBackend.expectPOST('VnUsers/1/removeAlias').respond();
|
$httpBackend.expectDELETE('MailAliasAccounts/1').respond();
|
||||||
$httpBackend.expectGET('MailAliasAccounts').respond(controller.$.data[1]);
|
|
||||||
controller.onRemove(controller.$.data[0]);
|
controller.onRemove(controller.$.data[0]);
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
|
|
||||||
expect(controller.$.data).toEqual({id: 2, alias: 'bar'});
|
expect(controller.$.data).toEqual([{id: 2, alias: 'bar'}]);
|
||||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -70,11 +70,12 @@ module.exports = Self => {
|
||||||
c.creditInsurance,
|
c.creditInsurance,
|
||||||
d.defaulterSinced,
|
d.defaulterSinced,
|
||||||
cn.country,
|
cn.country,
|
||||||
|
c.countryFk,
|
||||||
pm.name payMethod
|
pm.name payMethod
|
||||||
FROM vn.defaulter d
|
FROM vn.defaulter d
|
||||||
JOIN vn.client c ON c.id = d.clientFk
|
JOIN vn.client c ON c.id = d.clientFk
|
||||||
JOIN vn.country cn ON cn.id = c.countryFk
|
JOIN vn.country cn ON cn.id = c.countryFk
|
||||||
JOIN vn.payMethod pm ON pm.id = c.payMethodFk
|
JOIN vn.payMethod pm ON pm.id = c.payMethodFk
|
||||||
LEFT JOIN vn.clientObservation co ON co.clientFk = c.id
|
LEFT JOIN vn.clientObservation co ON co.clientFk = c.id
|
||||||
LEFT JOIN account.user u ON u.id = c.salesPersonFk
|
LEFT JOIN account.user u ON u.id = c.salesPersonFk
|
||||||
LEFT JOIN account.user uw ON uw.id = co.workerFk
|
LEFT JOIN account.user uw ON uw.id = co.workerFk
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
"country": {
|
"country": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Country",
|
"model": "Country",
|
||||||
"foreignKey": "country"
|
"foreignKey": "countryFk"
|
||||||
},
|
},
|
||||||
"payMethod": {
|
"payMethod": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
|
@ -41,4 +41,4 @@
|
||||||
"foreignKey": "payMethod"
|
"foreignKey": "payMethod"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
<th field="salesPersonFk">
|
<th field="salesPersonFk">
|
||||||
<span translate>Comercial</span>
|
<span translate>Comercial</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="country">
|
<th field="countryFk">
|
||||||
<span translate>Country</span>
|
<span translate>Country</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="payMethod"
|
<th field="payMethod"
|
||||||
|
@ -132,7 +132,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{::defaulter.payMethod}}
|
{{::defaulter.payMethod}}
|
||||||
</td>
|
</td>
|
||||||
<td>{{::defaulter.amount | currency: 'EUR': 2}}</td>
|
<td>{{::defaulter.amount | currency: 'EUR': 2}}</td>
|
||||||
<td>
|
<td>
|
||||||
<span
|
<span
|
||||||
|
|
|
@ -31,10 +31,11 @@ export default class Controller extends Section {
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
field: 'country',
|
field: 'countryFk',
|
||||||
autocomplete: {
|
autocomplete: {
|
||||||
|
url: 'Countries',
|
||||||
showField: 'country',
|
showField: 'country',
|
||||||
valueField: 'country'
|
valueField: 'id'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
field: 'payMethodFk',
|
field: 'payMethodFk',
|
||||||
|
@ -167,7 +168,7 @@ export default class Controller extends Section {
|
||||||
case 'amount':
|
case 'amount':
|
||||||
case 'clientFk':
|
case 'clientFk':
|
||||||
case 'workerFk':
|
case 'workerFk':
|
||||||
case 'country':
|
case 'countryFk':
|
||||||
case 'payMethod':
|
case 'payMethod':
|
||||||
case 'salesPersonFk':
|
case 'salesPersonFk':
|
||||||
return {[`d.${param}`]: value};
|
return {[`d.${param}`]: value};
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
require('../methods/invoice-in/filter')(Self);
|
require('../methods/invoice-in/filter')(Self);
|
||||||
require('../methods/invoice-in/summary')(Self);
|
require('../methods/invoice-in/summary')(Self);
|
||||||
|
@ -7,4 +9,9 @@ module.exports = Self => {
|
||||||
require('../methods/invoice-in/invoiceInPdf')(Self);
|
require('../methods/invoice-in/invoiceInPdf')(Self);
|
||||||
require('../methods/invoice-in/invoiceInEmail')(Self);
|
require('../methods/invoice-in/invoiceInEmail')(Self);
|
||||||
require('../methods/invoice-in/getSerial')(Self);
|
require('../methods/invoice-in/getSerial')(Self);
|
||||||
|
Self.rewriteDbError(function(err) {
|
||||||
|
if (err.code === 'ER_ROW_IS_REFERENCED_2' && err.sqlMessage.includes('vehicleInvoiceIn'))
|
||||||
|
return new UserError(`This invoice has a linked vehicle.`);
|
||||||
|
return err;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -68,9 +68,9 @@ module.exports = Self => {
|
||||||
};
|
};
|
||||||
const country = await Self.app.models.Country.findOne(filter);
|
const country = await Self.app.models.Country.findOne(filter);
|
||||||
const code = country ? country.code.toLowerCase() : null;
|
const code = country ? country.code.toLowerCase() : null;
|
||||||
const countryCode = this.nif.toLowerCase().substring(0, 2);
|
const countryCode = this.nif?.toLowerCase().substring(0, 2);
|
||||||
|
|
||||||
if (!this.nif || !validateTin(this.nif, code) || (this.isVies && countryCode == code))
|
if (!validateTin(this.nif, code) || (this.isVies && countryCode == code))
|
||||||
err();
|
err();
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
async function hasSupplierSameName(err, done) {
|
async function hasSupplierSameName(err, done) {
|
||||||
if (!this.name || !this.countryFk) done();
|
if (!this.name || !this.countryFk) return done();
|
||||||
const supplier = await Self.app.models.Supplier.findOne(
|
const supplier = await Self.app.models.Supplier.findOne(
|
||||||
{
|
{
|
||||||
where: {
|
where: {
|
||||||
|
|
|
@ -141,6 +141,7 @@ describe('ticket filter()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the tickets that are not pending', async() => {
|
it('should return the tickets that are not pending', async() => {
|
||||||
|
pending('#6010 test intermitente');
|
||||||
const tx = await models.Ticket.beginTransaction({});
|
const tx = await models.Ticket.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -38,10 +38,12 @@ class Controller extends SearchPanel {
|
||||||
|
|
||||||
applyFilters(param) {
|
applyFilters(param) {
|
||||||
if (typeof this.filter.scopeDays === 'number') {
|
if (typeof this.filter.scopeDays === 'number') {
|
||||||
const shippedFrom = Date.vnNew();
|
const today = Date.vnNew();
|
||||||
|
const shippedFrom = new Date(today.getTime());
|
||||||
|
shippedFrom.setDate(today.getDate() - 30);
|
||||||
shippedFrom.setHours(0, 0, 0, 0);
|
shippedFrom.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
const shippedTo = new Date(shippedFrom.getTime());
|
const shippedTo = new Date(today.getTime());
|
||||||
shippedTo.setDate(shippedTo.getDate() + this.filter.scopeDays);
|
shippedTo.setDate(shippedTo.getDate() + this.filter.scopeDays);
|
||||||
shippedTo.setHours(23, 59, 59, 999);
|
shippedTo.setHours(23, 59, 59, 999);
|
||||||
Object.assign(this.filter, {shippedFrom, shippedTo});
|
Object.assign(this.filter, {shippedFrom, shippedTo});
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
data="absenceTypes"
|
data="absenceTypes"
|
||||||
auto-load="true">
|
auto-load="true">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<div ng-if="$ctrl.worker.hasWorkCenter">
|
<div ng-if="$ctrl.card.hasWorkCenter">
|
||||||
<div class="vn-w-lg">
|
<div class="vn-w-lg">
|
||||||
<vn-card class="vn-pa-sm calendars">
|
<vn-card class="vn-pa-sm calendars">
|
||||||
<vn-icon ng-if="::$ctrl.isSubordinate" icon="info" color-marginal
|
<vn-icon ng-if="::$ctrl.isSubordinate" icon="info" color-marginal
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
ng-if="!$ctrl.worker.hasWorkCenter"
|
ng-if="!$ctrl.card.hasWorkCenter"
|
||||||
class="bg-title"
|
class="bg-title"
|
||||||
translate>
|
translate>
|
||||||
Autonomous worker
|
Autonomous worker
|
||||||
|
@ -73,41 +73,39 @@
|
||||||
value-field="businessFk"
|
value-field="businessFk"
|
||||||
order="businessFk DESC"
|
order="businessFk DESC"
|
||||||
limit="5">
|
limit="5">
|
||||||
<tpl-item>
|
<tpl-item>
|
||||||
<div>#{{businessFk}}</div>
|
<div>#{{businessFk}}</div>
|
||||||
<div class="text-caption text-secondary">
|
<div class="text-caption text-secondary">
|
||||||
{{started | date: 'dd/MM/yyyy'}} - {{ended ? (ended | date: 'dd/MM/yyyy') : 'Indef.'}}
|
{{started | date: 'dd/MM/yyyy'}} - {{ended ? (ended | date: 'dd/MM/yyyy') : 'Indef.'}}
|
||||||
</div>
|
</div>
|
||||||
</tpl-item>
|
</tpl-item>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</div>
|
|
||||||
<div name="absenceTypes" class="input vn-py-md" style="overflow: hidden;">
|
|
||||||
<vn-chip ng-repeat="absenceType in absenceTypes" ng-class="::{'selectable': $ctrl.isSubordinate}"
|
|
||||||
ng-click="$ctrl.pick(absenceType)">
|
|
||||||
<vn-avatar
|
|
||||||
ng-style="{backgroundColor: absenceType.rgb}">
|
|
||||||
<vn-icon icon="check" ng-if="absenceType.id == $ctrl.absenceType.id"></vn-icon>
|
|
||||||
</vn-avatar>
|
|
||||||
{{absenceType.name}}
|
|
||||||
</vn-chip>
|
|
||||||
</div>
|
|
||||||
<div class="vn-py-md">
|
|
||||||
<vn-chip>
|
|
||||||
<vn-avatar class="festive">
|
|
||||||
</vn-avatar>
|
|
||||||
<span translate>Festive</span>
|
|
||||||
</vn-chip>
|
|
||||||
<vn-chip>
|
|
||||||
<vn-avatar class="today">
|
|
||||||
</vn-avatar>
|
|
||||||
<span translate>Current day</span>
|
|
||||||
</vn-chip>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div name="absenceTypes" class="input vn-py-md" style="overflow: hidden;">
|
||||||
|
<vn-chip ng-repeat="absenceType in absenceTypes" ng-class="::{'selectable': $ctrl.isSubordinate}" ng-click="$ctrl.pick(absenceType)">
|
||||||
|
<vn-avatar ng-style="{backgroundColor: absenceType.rgb}">
|
||||||
|
<vn-icon icon="check" ng-if="absenceType.id == $ctrl.absenceType.id"></vn-icon>
|
||||||
|
</vn-avatar>
|
||||||
|
{{absenceType.name}}
|
||||||
|
</vn-chip>
|
||||||
|
</div>
|
||||||
|
<div class="vn-py-md">
|
||||||
|
<vn-chip>
|
||||||
|
<vn-avatar class="festive">
|
||||||
|
</vn-avatar>
|
||||||
|
<span translate>Festive</span>
|
||||||
|
</vn-chip>
|
||||||
|
<vn-chip>
|
||||||
|
<vn-avatar class="today">
|
||||||
|
</vn-avatar>
|
||||||
|
<span translate>Current day</span>
|
||||||
|
</vn-chip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</vn-side-menu>
|
</vn-side-menu>
|
||||||
|
|
||||||
<vn-confirm
|
<vn-confirm
|
||||||
vn-id="confirm"
|
vn-id="confirm"
|
||||||
message="This item will be deleted"
|
message="This item will be deleted"
|
||||||
question="Are you sure you want to continue?">
|
question="Are you sure you want to continue?">
|
||||||
</vn-confirm>
|
</vn-confirm>
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ class Controller extends Section {
|
||||||
}
|
}
|
||||||
|
|
||||||
set businessId(value) {
|
set businessId(value) {
|
||||||
|
if (!this.card.hasWorkCenter) return;
|
||||||
|
|
||||||
this._businessId = value;
|
this._businessId = value;
|
||||||
if (value) {
|
if (value) {
|
||||||
this.refresh()
|
this.refresh()
|
||||||
|
@ -64,7 +66,7 @@ class Controller extends Section {
|
||||||
|
|
||||||
set worker(value) {
|
set worker(value) {
|
||||||
this._worker = value;
|
this._worker = value;
|
||||||
if (value && value.hasWorkCenter) {
|
if (value) {
|
||||||
this.getIsSubordinate();
|
this.getIsSubordinate();
|
||||||
this.getActiveContract();
|
this.getActiveContract();
|
||||||
}
|
}
|
||||||
|
@ -293,5 +295,8 @@ ngModule.vnComponent('vnWorkerCalendar', {
|
||||||
controller: Controller,
|
controller: Controller,
|
||||||
bindings: {
|
bindings: {
|
||||||
worker: '<'
|
worker: '<'
|
||||||
|
},
|
||||||
|
require: {
|
||||||
|
card: '^vnWorkerCard'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,6 +20,9 @@ describe('Worker', () => {
|
||||||
controller.absenceType = {id: 1, name: 'Holiday', code: 'holiday', rgb: 'red'};
|
controller.absenceType = {id: 1, name: 'Holiday', code: 'holiday', rgb: 'red'};
|
||||||
controller.$params.id = 1106;
|
controller.$params.id = 1106;
|
||||||
controller._worker = {id: 1106};
|
controller._worker = {id: 1106};
|
||||||
|
controller.card = {
|
||||||
|
hasWorkCenter: true
|
||||||
|
};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('year() getter', () => {
|
describe('year() getter', () => {
|
||||||
|
@ -74,7 +77,7 @@ describe('Worker', () => {
|
||||||
let yesterday = new Date(today.getTime());
|
let yesterday = new Date(today.getTime());
|
||||||
yesterday.setDate(yesterday.getDate() - 1);
|
yesterday.setDate(yesterday.getDate() - 1);
|
||||||
|
|
||||||
controller.worker = {id: 1107, hasWorkCenter: true};
|
controller.worker = {id: 1107};
|
||||||
|
|
||||||
expect(controller.getIsSubordinate).toHaveBeenCalledWith();
|
expect(controller.getIsSubordinate).toHaveBeenCalledWith();
|
||||||
expect(controller.getActiveContract).toHaveBeenCalledWith();
|
expect(controller.getActiveContract).toHaveBeenCalledWith();
|
||||||
|
|
|
@ -3,7 +3,7 @@ import ModuleCard from 'salix/components/module-card';
|
||||||
|
|
||||||
class Controller extends ModuleCard {
|
class Controller extends ModuleCard {
|
||||||
reload() {
|
reload() {
|
||||||
let filter = {
|
const filter = {
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
relation: 'user',
|
relation: 'user',
|
||||||
|
@ -32,13 +32,12 @@ class Controller extends ModuleCard {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$http.get(`Workers/${this.$params.id}`, {filter})
|
return Promise.all([
|
||||||
.then(res => this.worker = res.data)
|
this.$http.get(`Workers/${this.$params.id}`, {filter})
|
||||||
.then(() =>
|
.then(res => this.worker = res.data),
|
||||||
this.$http.get(`Workers/${this.$params.id}/activeContract`)
|
this.$http.get(`Workers/${this.$params.id}/activeContract`)
|
||||||
.then(res => {
|
.then(res => this.hasWorkCenter = res.data.workCenterFk)
|
||||||
if (res.data) this.worker.hasWorkCenter = res.data.workCenterFk;
|
]);
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
<slot-before>
|
<slot-before>
|
||||||
<div class="photo" text-center>
|
<div class="photo" text-center>
|
||||||
<img vn-id="photo"
|
<img vn-id="photo"
|
||||||
ng-src="{{$root.imagePath('user', '520x520', $ctrl.worker.id)}}"
|
ng-src="{{$root.imagePath('user', '520x520', $ctrl.worker.id)}}"
|
||||||
zoom-image="{{$root.imagePath('user', '1600x1600', $ctrl.worker.id)}}"
|
zoom-image="{{$root.imagePath('user', '1600x1600', $ctrl.worker.id)}}"
|
||||||
on-error-src/>
|
on-error-src/>
|
||||||
<vn-float-button ng-click="uploadPhoto.show('user', $ctrl.worker.id)"
|
<vn-float-button ng-click="uploadPhoto.show('user', $ctrl.worker.id)"
|
||||||
icon="edit"
|
icon="edit"
|
||||||
|
@ -15,39 +15,32 @@
|
||||||
</div>
|
</div>
|
||||||
</slot-before>
|
</slot-before>
|
||||||
<slot-menu>
|
<slot-menu>
|
||||||
<vn-item
|
<vn-item ng-click="$ctrl.handleExcluded()" translate>
|
||||||
ng-click="$ctrl.handleExcluded()"
|
{{$ctrl.workerExcluded
|
||||||
translate
|
? 'Click to allow the user to be disabled'
|
||||||
ng-if="!$ctrl.excluded">
|
: 'Click to exclude the user from getting disabled'}}
|
||||||
Click to exclude the user from getting disabled
|
</vn-item>
|
||||||
</vn-item>
|
|
||||||
<vn-item
|
|
||||||
ng-click="$ctrl.handleExcluded()"
|
|
||||||
translate
|
|
||||||
ng-if="$ctrl.excluded">
|
|
||||||
Click to allow the user to be disabled
|
|
||||||
</vn-item>
|
|
||||||
</slot-menu>
|
</slot-menu>
|
||||||
<slot-body>
|
<slot-body>
|
||||||
<div class="attributes">
|
<div class="attributes">
|
||||||
<vn-label-value
|
<vn-label-value
|
||||||
label="User"
|
label="User"
|
||||||
value="{{$ctrl.worker.user.name}}">
|
value="{{$ctrl.worker.user.name}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value
|
<vn-label-value
|
||||||
label="Email"
|
label="Email"
|
||||||
value="{{$ctrl.worker.user.emailUser.email}}">
|
value="{{$ctrl.worker.user.emailUser.email}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value
|
<vn-label-value
|
||||||
label="Department"
|
label="Department"
|
||||||
value="{{$ctrl.worker.department.department.name}}">
|
value="{{$ctrl.worker.department.department.name}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value
|
<vn-label-value
|
||||||
label="Phone"
|
label="Phone"
|
||||||
value="{{$ctrl.worker.phone}}">
|
value="{{$ctrl.worker.phone}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value
|
<vn-label-value
|
||||||
label="Extension"
|
label="Extension"
|
||||||
value="{{$ctrl.worker.sip.extension}}">
|
value="{{$ctrl.worker.sip.extension}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
</div>
|
</div>
|
||||||
|
@ -84,7 +77,7 @@
|
||||||
</vn-popup>
|
</vn-popup>
|
||||||
|
|
||||||
<!-- Upload photo dialog -->
|
<!-- Upload photo dialog -->
|
||||||
<vn-upload-photo
|
<vn-upload-photo
|
||||||
vn-id="uploadPhoto"
|
vn-id="uploadPhoto"
|
||||||
on-response="$ctrl.onUploadResponse()">
|
on-response="$ctrl.onUploadResponse()">
|
||||||
</vn-upload-photo>
|
</vn-upload-photo>
|
||||||
|
|
|
@ -18,28 +18,19 @@ class Controller extends Descriptor {
|
||||||
this.getIsExcluded();
|
this.getIsExcluded();
|
||||||
}
|
}
|
||||||
|
|
||||||
get excluded() {
|
|
||||||
return this.entity.excluded;
|
|
||||||
}
|
|
||||||
|
|
||||||
set excluded(value) {
|
|
||||||
this.entity.excluded = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
getIsExcluded() {
|
getIsExcluded() {
|
||||||
this.$http.get(`workerDisableExcludeds/${this.entity.id}/exists`).then(data => {
|
this.$http.get(`WorkerDisableExcludeds/${this.entity.id}/exists`).then(data => {
|
||||||
this.excluded = data.data.exists;
|
this.workerExcluded = data.data.exists;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleExcluded() {
|
handleExcluded() {
|
||||||
if (this.excluded) {
|
if (this.workerExcluded)
|
||||||
this.$http.delete(`workerDisableExcludeds/${this.entity.id}`);
|
this.$http.delete(`WorkerDisableExcludeds/${this.entity.id}`);
|
||||||
this.excluded = false;
|
else
|
||||||
} else {
|
this.$http.post(`WorkerDisableExcludeds`, {workerFk: this.entity.id, dated: new Date});
|
||||||
this.$http.post(`workerDisableExcludeds`, {workerFk: this.entity.id, dated: new Date});
|
|
||||||
this.excluded = true;
|
this.workerExcluded = !this.workerExcluded;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadData() {
|
loadData() {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
filter="::$ctrl.filter"
|
filter="::$ctrl.filter"
|
||||||
data="$ctrl.hours">
|
data="$ctrl.hours">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<div ng-if="$ctrl.worker.hasWorkCenter">
|
<div ng-if="$ctrl.card.hasWorkCenter">
|
||||||
<vn-card class="vn-pa-lg vn-w-lg">
|
<vn-card class="vn-pa-lg vn-w-lg">
|
||||||
<vn-table model="model" auto-load="false">
|
<vn-table model="model" auto-load="false">
|
||||||
<vn-thead>
|
<vn-thead>
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
</vn-button-bar>
|
</vn-button-bar>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
ng-if="!$ctrl.worker.hasWorkCenter"
|
ng-if="!$ctrl.card.hasWorkCenter"
|
||||||
class="bg-title"
|
class="bg-title"
|
||||||
translate>
|
translate>
|
||||||
Autonomous worker
|
Autonomous worker
|
||||||
|
@ -136,6 +136,7 @@
|
||||||
</vn-calendar>
|
</vn-calendar>
|
||||||
</div>
|
</div>
|
||||||
</vn-side-menu>
|
</vn-side-menu>
|
||||||
|
|
||||||
<vn-dialog
|
<vn-dialog
|
||||||
vn-id="addTimeDialog"
|
vn-id="addTimeDialog"
|
||||||
on-accept="$ctrl.addTime()"
|
on-accept="$ctrl.addTime()"
|
||||||
|
|
|
@ -141,6 +141,8 @@ class Controller extends Section {
|
||||||
]}
|
]}
|
||||||
};
|
};
|
||||||
this.$.model.applyFilter(filter, params).then(() => {
|
this.$.model.applyFilter(filter, params).then(() => {
|
||||||
|
if (!this.card.hasWorkCenter) return;
|
||||||
|
|
||||||
this.getWorkedHours(this.started, this.ended);
|
this.getWorkedHours(this.started, this.ended);
|
||||||
this.getAbsences();
|
this.getAbsences();
|
||||||
});
|
});
|
||||||
|
@ -151,7 +153,6 @@ class Controller extends Section {
|
||||||
}
|
}
|
||||||
|
|
||||||
getAbsences() {
|
getAbsences() {
|
||||||
if (!this.worker.hasWorkerCenter) return;
|
|
||||||
const fullYear = this.started.getFullYear();
|
const fullYear = this.started.getFullYear();
|
||||||
let params = {
|
let params = {
|
||||||
workerFk: this.$params.id,
|
workerFk: this.$params.id,
|
||||||
|
@ -486,5 +487,8 @@ ngModule.vnComponent('vnWorkerTimeControl', {
|
||||||
controller: Controller,
|
controller: Controller,
|
||||||
bindings: {
|
bindings: {
|
||||||
worker: '<'
|
worker: '<'
|
||||||
|
},
|
||||||
|
require: {
|
||||||
|
card: '^vnWorkerCard'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,9 +16,8 @@ describe('Component vnWorkerTimeControl', () => {
|
||||||
$scope = $rootScope.$new();
|
$scope = $rootScope.$new();
|
||||||
$element = angular.element('<vn-worker-time-control></vn-worker-time-control>');
|
$element = angular.element('<vn-worker-time-control></vn-worker-time-control>');
|
||||||
controller = $componentController('vnWorkerTimeControl', {$element, $scope});
|
controller = $componentController('vnWorkerTimeControl', {$element, $scope});
|
||||||
controller.worker = {
|
controller.card = {
|
||||||
hasWorkerCenter: true
|
hasWorkCenter: true
|
||||||
|
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -10,16 +10,17 @@ module.exports = {
|
||||||
|
|
||||||
async send(options) {
|
async send(options) {
|
||||||
options.from = `${config.app.senderName} <${config.app.senderEmail}>`;
|
options.from = `${config.app.senderName} <${config.app.senderEmail}>`;
|
||||||
if (!process.env.NODE_ENV)
|
const env = process.env.NODE_ENV;
|
||||||
options.to = config.app.senderEmail;
|
const canSend = env === 'production' || !env || options.force;
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production' && !options.force) {
|
if (!canSend || !config.smtp.auth.user) {
|
||||||
const notProductionError = {message: 'This not production, this email not sended'};
|
const notProductionError = {message: 'This not production, this email not sended'};
|
||||||
await this.mailLog(options, notProductionError);
|
await this.mailLog(options, notProductionError);
|
||||||
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config.smtp.auth.user)
|
if (!env)
|
||||||
return Promise.resolve(true);
|
options.to = config.app.senderEmail;
|
||||||
|
|
||||||
let res;
|
let res;
|
||||||
let error;
|
let error;
|
||||||
|
|
Loading…
Reference in New Issue