This commit is contained in:
Juan Ferrer 2019-01-29 16:38:11 +01:00
commit d46575a072
28 changed files with 112 additions and 94 deletions

View File

@ -1,4 +1,9 @@
<section class="ellipsize">
<vn-label></vn-label>
<span></span>
<vn-icon
ng-if="$ctrl.hasInfo"
vn-tooltip="{{$ctrl.info}}"
icon="info_outline">
</vn-icon>
</section>

View File

@ -2,9 +2,11 @@ import ngModule from '../../module';
import './style.scss';
export default class Controller {
constructor($element, $translate) {
constructor($element, $translate, $attrs) {
this.element = $element[0];
this._ = $translate;
this.hasInfo = Boolean($attrs.info);
this.info = $attrs.info || null;
}
set label(value) {
let label = this.element.querySelector('vn-label');
@ -24,7 +26,7 @@ export default class Controller {
return this._value;
}
}
Controller.$inject = ['$element', '$translate'];
Controller.$inject = ['$element', '$translate', '$attrs'];
ngModule.component('vnLabelValue', {
controller: Controller,

View File

@ -11,4 +11,10 @@ vn-label-value > section {
& > span {
color: $main-font-color;
}
& > vn-icon {
vertical-align: middle;
color: $secondary-font-color;
font-size: 1.2em
}
}

View File

@ -145,8 +145,9 @@ export default class ModelProxy extends DataModel {
});
return new Proxy(obj, {
set: (obj, prop, value) => {
let changed = prop.charAt(0) !== '$' && value !== obj[prop] && !obj.$isNew;
if (changed) {
let changed = prop.charAt(0) !== '$' && value !== obj[prop];
if (changed && !obj.$isNew) {
if (!obj.$oldData)
obj.$oldData = {};
if (!obj.$oldData[prop])
@ -159,7 +160,8 @@ export default class ModelProxy extends DataModel {
if (changed) {
this.emit('rowChange', {obj, prop, value});
this.emit('dataUpdate');
if (this.autoSave)
if (!obj.$isNew && this.autoSave)
this.save();
}
@ -173,10 +175,11 @@ export default class ModelProxy extends DataModel {
this.isChanged = false;
let data = this.proxiedData;
if (data)
if (data) {
for (let row of data)
row.$oldData = null;
}
}
/**
* Applies all changes made to the model into the original data source.
@ -186,18 +189,21 @@ export default class ModelProxy extends DataModel {
let orgData = this.orgData;
if (!data) return;
for (let row of data)
for (let row of data) {
if (row.$isNew) {
let orgRow = {};
for (let prop in row)
for (let prop in row) {
if (prop.charAt(0) !== '$')
orgRow[prop] = row[prop];
}
row.$orgIndex = orgData.push(orgRow) - 1;
row.$orgRow = orgRow;
row.$isNew = false;
} else if (row.$oldData)
} else if (row.$oldData) {
for (let prop in row.$oldData)
row.$orgRow[prop] = row[prop];
}
}
let removed = this.removed;

View File

@ -100,7 +100,7 @@ function backTest(done) {
nodemon({
exec: gulpBin,
args: ['dockerAndBackTest'],
args: ['backendUnitTest'],
watch: backSources,
done: done
});

View File

@ -29,5 +29,6 @@
"You can't make changes on the basic data of an confirmed order or with rows": "You can't make changes on the basic data of an confirmed order or with rows",
"You can't create a ticket for a inactive client": "You can't create a ticket for a inactive client",
"Worker cannot be blank": "Worker cannot be blank",
"You don't have enough privileges to change the state of this ticket": "You don't have enough privileges to change the state of this ticket"
"You don't have enough privileges to change the state of this ticket": "You don't have enough privileges to change the state of this ticket",
"You must delete the claim id %d first": "You must delete the claim id %d first"
}

View File

@ -38,7 +38,7 @@ module.exports = Self => {
stmts.push(new ParameterizedSQL(
`SELECT lft, rgt, depth + 1 INTO @lft, @rgt, @depth
FROM zoneTreeview WHERE id = ?`, [parentFk]));
FROM zoneGeo WHERE id = ?`, [parentFk]));
stmts.push(`DROP TEMPORARY TABLE IF EXISTS tChilds`);
@ -46,7 +46,7 @@ module.exports = Self => {
`CREATE TEMPORARY TABLE tChilds
ENGINE = MEMORY
SELECT id, lft, rgt
FROM zoneTreeview pt`);
FROM zoneGeo pt`);
stmt.merge(conn.makeSuffix(filter));
if (!filter.where) {
@ -63,7 +63,7 @@ module.exports = Self => {
ENGINE = MEMORY
SELECT t.id
FROM tChilds t
JOIN zoneTreeview zt
JOIN zoneGeo zt
ON zt.lft > t.lft AND zt.rgt < t.rgt
JOIN zoneIncluded zi
ON zi.geoFk = zt.id AND zi.zoneFk = ?
@ -80,7 +80,7 @@ module.exports = Self => {
ti.id IS NOT NULL hasCheckedChilds,
zi.geoFk IS NOT NULL AS selected,
zi.isIncluded AS excluded
FROM zoneTreeview pt
FROM zoneGeo pt
LEFT JOIN vn.zoneIncluded zi
ON zi.geoFk = pt.id AND zi.zoneFk = ?
JOIN tChilds c ON c.id = pt.id

View File

@ -24,20 +24,20 @@ module.exports = Self => {
Self.toggleIsIncluded = async(zoneFk, geoFk) => {
const models = Self.app.models;
const geo = await models.ZoneTreeview.findById(geoFk);
const geo = await models.ZoneGeo.findById(geoFk);
const isIncluded = await Self.findOne({
where: {zoneFk, geoFk}
});
const hasCheckedParents = await Self.rawSql(
`SELECT id
FROM vn.zoneTreeview zt
FROM vn.zoneGeo zt
JOIN vn.zoneIncluded zi ON zi.geoFk = zt.id
WHERE zt.lft < ? AND zt.rgt > ?`, [geo.lft, geo.rgt]
);
const hasCheckedChilds = await Self.rawSql(
`SELECT id
FROM vn.zoneTreeview zt
FROM vn.zoneGeo zt
JOIN vn.zoneIncluded zi ON zi.geoFk = zt.id
WHERE zt.lft > ? AND zt.rgt < ?`, [geo.lft, geo.rgt]
);

View File

@ -20,9 +20,6 @@
"ZoneIncluded": {
"dataSource": "vn"
},
"ZoneTreeview": {
"dataSource": "vn"
},
"LabourHoliday": {
"dataSource": "vn"
},

View File

@ -0,0 +1,3 @@
module.exports = Self => {
require('../methods/zone-geo/getLeaves')(Self);
};

View File

@ -19,6 +19,12 @@
},
"rgt": {
"type": "Number"
},
"depth": {
"type": "Number"
},
"sons": {
"type": "Number"
}
}
}

View File

@ -1,3 +0,0 @@
module.exports = Self => {
require('../methods/zone-treeview/getLeaves')(Self);
};

View File

@ -1,30 +0,0 @@
{
"name": "ZoneTreeview",
"base": "VnModel",
"options": {
"mysql": {
"table": "zoneTreeview"
}
},
"properties": {
"id": {
"id": true,
"type": "Number"
},
"name": {
"type": "String"
},
"lft": {
"type": "Number"
},
"rgt": {
"type": "Number"
},
"depth": {
"type": "Number"
},
"sons": {
"type": "Number"
}
}
}

View File

@ -1,6 +1,6 @@
<vn-crud-model
vn-id="model"
url="/agency/api/ZoneTreeviews/getLeaves"
url="/agency/api/ZoneGeos/getLeaves"
filter="::$ctrl.filter"
params="{zoneFk: $ctrl.$stateParams.id, parentFk: 1}">
</vn-crud-model>

View File

@ -24,7 +24,6 @@ describe('Update Claim', () => {
it('should throw error if isSaleAssistant is false and try to modify a forbidden field', async() => {
let params = {
id: newInstance.id,
ticketFk: 3,
clientFk: 101,
ticketCreated: newDate,
@ -40,7 +39,7 @@ describe('Update Claim', () => {
}
}
};
await app.models.Claim.updateClaim(ctx, params)
await app.models.Claim.updateClaim(ctx, newInstance.id, params)
.catch(e => {
error = e;
});
@ -50,7 +49,6 @@ describe('Update Claim', () => {
it('should throw error if isSaleAssistant is false and try to modify a valid field but a forbidden stated', async() => {
let params = {
id: newInstance.id,
ticketFk: 3,
clientFk: 101,
ticketCreated: newDate,
@ -65,7 +63,7 @@ describe('Update Claim', () => {
}
}
};
await app.models.Claim.updateClaim(ctx, params)
await app.models.Claim.updateClaim(ctx, newInstance.id, params)
.catch(e => {
error = e;
});
@ -75,7 +73,6 @@ describe('Update Claim', () => {
it('should change field observation', async() => {
let params = {
id: newInstance.id,
ticketCreated: newDate,
observation: 'another3'
};
@ -86,7 +83,7 @@ describe('Update Claim', () => {
}
}
};
await app.models.Claim.updateClaim(ctx, params);
await app.models.Claim.updateClaim(ctx, newInstance.id, params);
let claimUpdated = await app.models.Claim.findById(newInstance.id);
@ -95,7 +92,6 @@ describe('Update Claim', () => {
it('should change sensible fields as salesAssistant', async() => {
let params = {
id: newInstance.id,
ticketFk: 3,
clientFk: 101,
ticketCreated: newDate,
@ -112,7 +108,7 @@ describe('Update Claim', () => {
}
}
};
await app.models.Claim.updateClaim(ctx, params);
await app.models.Claim.updateClaim(ctx, newInstance.id, params);
let claimUpdated = await app.models.Claim.findById(newInstance.id);

View File

@ -7,6 +7,12 @@ module.exports = Self => {
description: 'Update a claim with privileges',
accessType: 'WRITE',
accepts: [{
arg: 'id',
type: 'string',
required: true,
description: 'Client id',
http: {source: 'path'}
}, {
arg: 'params',
type: 'object',
required: true,
@ -18,22 +24,21 @@ module.exports = Self => {
root: true
},
http: {
path: `/updateClaim`,
path: `/:id/updateClaim`,
verb: 'post'
}
});
Self.updateClaim = async(ctx, params) => {
Self.updateClaim = async(ctx, id, params) => {
let models = Self.app.models;
let isSalesAssistant;
let token = ctx.req.accessToken;
let currentUserId = token && token.userId;
let currentUserId = ctx.req.accessToken.userId;
isSalesAssistant = await models.Account.hasRole(currentUserId, 'salesAssistant');
if (!isSalesAssistant) {
let oldClaim = await models.Claim.findById(params.id);
let notModifiable = ['responsibility', 'isChargedToMana'];
let oldClaim = await models.Claim.findById(id);
let notModifiable = ['id', 'responsibility', 'isChargedToMana'];
let changedFields = diff(oldClaim, params);
let changedFieldsPicked = pick(changedFields, notModifiable);
let statesViables = ['Gestionado', 'Pendiente', 'Anulado'];
@ -45,6 +50,7 @@ module.exports = Self => {
throw new UserError(`You don't have enough privileges to change that field`);
}
return await Self.updateAll({id: params.id}, params);
let claim = await Self.findById(id);
return await claim.updateAttributes(params);
};
};

View File

@ -147,7 +147,7 @@ class Controller {
}
saveResponsibility(value) {
let query = `/claim/api/Claims/updateClaim`;
let query = `/api/Claims/${this.$stateParams.id}/updateClaim`;
this.$http.post(query, {responsibility: value}).then(() => {
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));

View File

@ -2,7 +2,7 @@
vn-id="watcher"
data="$ctrl.claim"
form="form"
url="/claim/api/Claims/updateClaim"
url="/api/Claims/{{$ctrl.$stateParams.id}}/updateClaim"
save="post">
</vn-watcher>
<form name="form" ng-submit="watcher.submit()" compact>

View File

@ -1,8 +1,17 @@
import ngModule from '../module';
import './style.scss';
class Controller {
constructor($stateParams) {
this.$stateParams = $stateParams;
}
}
Controller.$inject = ['$stateParams'];
ngModule.component('vnClaimBasicData', {
template: require('./index.html'),
controller: Controller,
bindings: {
claim: '<'
}

View File

@ -31,11 +31,13 @@ module.exports = function(Self) {
Self.addressesPropagateRe = async(id, data) => {
if (data.hasOwnProperty('isEqualizated')) {
let client = await Self.app.models.Client.findById(id);
if (client) {
await Self.app.models.Address.updateAll({clientFk: id}, data);
let client = await Self.app.models.Client.findById(id)
await client.updateAttributes({hasToInvoiceByAddress: false});
return true;
}
}
return false;
};
};

View File

@ -35,7 +35,7 @@ export default class Controller {
}
notifyChanges() {
this.$http.post(`/email/payment-update`, {clientFk: this.client.id}).then(
this.$http.post(`/api/email/payment-update`, {clientFk: this.client.id}).then(
() => this.vnApp.showMessage(this.$translate.instant('Notification sent!'))
);
}

View File

@ -6,21 +6,21 @@ class Controller {
this.filter = {
include: [
{
relation: "type",
relation: 'type',
scope: {
fields: ["code", "description"]
fields: ['code', 'description']
}
},
{
relation: "worker",
relation: 'worker',
scope: {
fields: ["firstName", "name"]
fields: ['firstName', 'name']
}
},
{
relation: "company",
relation: 'company',
scope: {
fields: ["code"]
fields: ['code']
}
}
]

View File

@ -168,22 +168,27 @@
<h4 translate>Financial information</h4>
<vn-label-value label="Risk"
value="{{$ctrl.summary.debt.debt | currency:'€':2}}"
ng-class="{alert: $ctrl.summary.debt.debt > $ctrl.summary.credit}">
ng-class="{alert: $ctrl.summary.debt.debt > $ctrl.summary.credit}"
info="Invoices minus payments plus orders not yet invoiced">
</vn-label-value>
<vn-label-value label="Credit"
value="{{$ctrl.summary.credit | currency:'€':2 }} "
ng-class="{alert: $ctrl.summary.credit > $ctrl.summary.creditInsurance ||
($ctrl.summary.credit && $ctrl.summary.creditInsurance == null)}">
($ctrl.summary.credit && $ctrl.summary.creditInsurance == null)}"
info="Verdnatura's maximum risk">
</vn-label-value>
<vn-label-value label="Secured credit"
value="{{$ctrl.summary.creditInsurance | currency:'€':2}} ({{$ctrl.summary.classifications[0].insurances[0].grade}})">
value="{{$ctrl.summary.creditInsurance | currency:'€':2}} ({{$ctrl.summary.classifications[0].insurances[0].grade}})"
info="Solunion's maximum risk">
</vn-label-value>
<vn-label-value label="Balance"
value="{{$ctrl.summary.sumRisk | currency:'€':2}}">
value="{{$ctrl.summary.sumRisk | currency:'€':2}}"
info="Invoices minus payments">
</vn-label-value>
<vn-label-value label="Balance due"
value="{{$ctrl.summary.defaulters[0].amount | currency:'€':2}}"
ng-class="{alert: $ctrl.summary.defaulters[0].amount}">
ng-class="{alert: $ctrl.summary.defaulters[0].amount}"
info="Deviated invoices minus payments">
</vn-label-value>
<vn-vertical ng-if="$ctrl.summary.recovery.started">
<vn-label-value label="Recovery since"

View File

@ -12,3 +12,8 @@ Rate: Tarifa
Business data: Datos comerciales
Recovery since: Recobro desde
Fiscal address: Dirección fiscal
Invoices minus payments plus orders not yet invoiced: Facturas menos recibos mas pedidos sin facturar
Verdnatura's maximum risk: Riesgo máximo asumido por Verdnatura
Solunion's maximum risk: Riesgo máximo asumido por Solunion
Invoices minus payments: Facturas menos recibos
Deviated invoices minus payments: Facturas fuera de plazo menos recibos

View File

@ -5,7 +5,6 @@
link="{itemFk: $ctrl.$stateParams.id}"
include="$ctrl.include"
order="priority ASC"
on-row-change="$ctrl.getSourceTable(obj)"
data="$ctrl.itemTags"
auto-load="true">
</vn-crud-model>
@ -30,6 +29,7 @@
initial-data="itemTag.tag"
field="itemTag.tagFk"
data="tags"
on-change="$ctrl.getSourceTable(tag)"
show-field="name"
vn-acl="buyer"
vn-focus>

View File

@ -30,7 +30,7 @@ class Controller {
getSourceTable(obj) {
let sourceTable;
this.sourceTables[obj.id] = {};
let tag = obj.tag;
let tag = obj.tag || obj.selection;
if (!tag || !tag.sourceTable && (tag.isFree === true || tag.isFree === undefined))
sourceTable = null;

View File

@ -58,6 +58,8 @@ Delay: Retraso
Code 100: Código 100
Invoice: Factura
Client card: Ficha del cliente
You are going to delete this ticket: Vas a borrar este ticket
Ticket deleted: Ticket borrado
#sections
List: Listado

View File

@ -16,8 +16,8 @@ module.exports = {
data() {
return {
files: [
'/assets/images/action.png',
'/assets/images/info.png',
/* '/assets/images/action.png',
'/assets/images/info.png', */
'/assets/images/facebook.png',
'/assets/images/twitter.png',
'/assets/images/youtube.png',