This commit is contained in:
Carlos Jimenez Ruiz 2019-06-19 14:42:59 +02:00
commit 73ccf9a107
38 changed files with 301 additions and 169 deletions

View File

@ -69,12 +69,22 @@ module.exports = Self => {
if (!hasWriteRole)
throw new UserError(`You don't have enough privileges`);
// Create final folder if not exists
const dmsType = await models.DmsType.findById(args.dmsTypeId);
await models.Container.getContainer(dmsType.path).catch(async err => {
if (err.code === 'ENOENT') {
await models.Container.createContainer({
name: dmsType.path
});
}
});
// Upload file to temporary path
const uploaded = await models.Container.upload('temp', ctx.req, ctx.result, fileOptions);
const files = Object.values(uploaded.files).map(file => {
return file[0];
});
const dmsType = await models.DmsType.findById(args.dmsTypeId);
const promises = [];
files.forEach(file => {

View File

@ -1,4 +0,0 @@
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='5';
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='12';
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='14';
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='13';

View File

@ -0,0 +1,24 @@
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='5';
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='12';
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='14';
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='13';
UPDATE `vn2008`.`gesttip` SET `code`='invoiceIn' WHERE `id`='1';
UPDATE `vn2008`.`gesttip` SET `code`='officialDoc' WHERE `id`='2';
UPDATE `vn2008`.`gesttip` SET `code`='hhrrData' WHERE `id`='3';
UPDATE `vn2008`.`gesttip` SET `code`='deliveryNote' WHERE `id`='4';
UPDATE `vn2008`.`gesttip` SET `code`='miscellaneous' WHERE `id`='5';
UPDATE `vn2008`.`gesttip` SET `code`='tests' WHERE `id`='6';
UPDATE `vn2008`.`gesttip` SET `code`='economicActivitiesTax' WHERE `id`='7';
UPDATE `vn2008`.`gesttip` SET `code`='fiscal' WHERE `id`='8';
UPDATE `vn2008`.`gesttip` SET `code`='vehicles' WHERE `id`='9';
UPDATE `vn2008`.`gesttip` SET `code`='templates' WHERE `id`='10';
UPDATE `vn2008`.`gesttip` SET `code`='contracts' WHERE `id`='11';
UPDATE `vn2008`.`gesttip` SET `code`='paymentsLaw' WHERE `id`='12';
UPDATE `vn2008`.`gesttip` SET `code`='trash' WHERE `id`='13';
UPDATE `vn2008`.`gesttip` SET `code`='ticket' WHERE `id`='14';
UPDATE `vn2008`.`gesttip` SET `code`='budgets' WHERE `id`='15';
UPDATE `vn2008`.`gesttip` SET `code`='logistics' WHERE `id`='16';
UPDATE `vn2008`.`gesttip` SET `code`='cmr' WHERE `id`='17';
UPDATE `vn2008`.`gesttip` SET `code`='dua' WHERE `id`='18';
UPDATE `vn2008`.`gesttip` SET `code`='fixedAssets' WHERE `id`='19';

View File

@ -332,9 +332,9 @@ INSERT INTO `vn`.`observationType`(`id`,`description`)
INSERT INTO `vn`.`addressObservation`(`id`,`addressFk`,`observationTypeFk`,`description`)
VALUES
(1, 1, 1, 'under the floor'),
(2, 1, 2, 'wears leather and goes out at night'),
(3, 1, 3, 'care with the dog');
(1, 121, 1, 'under the floor'),
(2, 121, 2, 'wears leather and goes out at night'),
(3, 121, 3, 'care with the dog');
INSERT INTO `vn`.`creditClassification`(`id`, `client`, `dateStart`, `dateEnd`)
VALUES

View File

@ -20,21 +20,27 @@ describe('last_buy_refresh()', () => {
let lastBuyTable = result[lastBuyTableIndex];
expect(lastBuyTable.length).toEqual(4);
expect(lastBuyTable.length).toEqual(6);
expect(lastBuyTable[0].item_id).toEqual(1);
expect(lastBuyTable[1].item_id).toEqual(2);
expect(lastBuyTable[2].item_id).toEqual(3);
expect(lastBuyTable[3].item_id).toEqual(4);
expect(lastBuyTable[4].item_id).toEqual(8);
expect(lastBuyTable[5].item_id).toEqual(9);
expect(lastBuyTable[0].warehouse_id).toEqual(1);
expect(lastBuyTable[1].warehouse_id).toEqual(1);
expect(lastBuyTable[2].warehouse_id).toEqual(1);
expect(lastBuyTable[3].warehouse_id).toEqual(1);
expect(lastBuyTable[4].warehouse_id).toEqual(1);
expect(lastBuyTable[5].warehouse_id).toEqual(1);
expect(lastBuyTable[1].buy_id).toEqual(4);
expect(lastBuyTable[0].buy_id).toEqual(3);
expect(lastBuyTable[2].buy_id).toEqual(5);
expect(lastBuyTable[3].buy_id).toEqual(6);
expect(lastBuyTable[3].buy_id).toEqual(8);
expect(lastBuyTable[4].buy_id).toEqual(6);
expect(lastBuyTable[5].buy_id).toEqual(7);
});
});

View File

@ -29,21 +29,27 @@ describe('buyUltimate()', () => {
let buyUltimateTable = result[buyUltimateTableIndex];
expect(buyUltimateTable.length).toEqual(4);
expect(buyUltimateTable.length).toEqual(6);
expect(buyUltimateTable[0].itemFk).toEqual(1);
expect(buyUltimateTable[1].itemFk).toEqual(2);
expect(buyUltimateTable[2].itemFk).toEqual(3);
expect(buyUltimateTable[3].itemFk).toEqual(4);
expect(buyUltimateTable[4].itemFk).toEqual(8);
expect(buyUltimateTable[5].itemFk).toEqual(9);
expect(buyUltimateTable[0].warehouseFk).toEqual(1);
expect(buyUltimateTable[1].warehouseFk).toEqual(1);
expect(buyUltimateTable[2].warehouseFk).toEqual(1);
expect(buyUltimateTable[3].warehouseFk).toEqual(1);
expect(buyUltimateTable[4].warehouseFk).toEqual(1);
expect(buyUltimateTable[5].warehouseFk).toEqual(1);
expect(buyUltimateTable[1].buyFk).toEqual(4);
expect(buyUltimateTable[0].buyFk).toEqual(3);
expect(buyUltimateTable[2].buyFk).toEqual(5);
expect(buyUltimateTable[3].buyFk).toEqual(6);
expect(buyUltimateTable[3].buyFk).toEqual(8);
expect(buyUltimateTable[4].buyFk).toEqual(6);
expect(buyUltimateTable[5].buyFk).toEqual(7);
});
});

View File

@ -86,18 +86,20 @@ describe('ticket ticketCalculateClon()', () => {
stmt = new ParameterizedSQL('CALL vn.ticketCalculateClon(@result, ?)', [params.originalTicketId]);
stmts.push(stmt);
let orderIndex = stmts.push(`SELECT * FROM vn.orderTicket WHERE ticketFk = @result`) - 1;
stmts.push('ROLLBACK');
let sql = ParameterizedSQL.join(stmts, ';');
let result = await app.models.Ticket.rawStmt(sql);
let expectedOrder = 11;
let newestTicketIdInFixtures = 21;
let error;
expect(result[orderIndex][0].orderFk).toEqual(expectedOrder);
expect(result[orderIndex][0].ticketFk).toBeGreaterThan(newestTicketIdInFixtures);
try {
await app.models.Ticket.rawStmt(sql);
} catch (e) {
error = e;
}
expect(error).toBeDefined();
expect(error.statusCode).toBe(500);
expect(error.code).toBe('ER_SIGNAL_EXCEPTION');
});
});

View File

@ -14,8 +14,8 @@ describe('ticket ticketCreateWithUser()', () => {
shipped: today,
warehouseFk: 1,
companyFk: 442,
addressFk: 1,
agencyModeFk: 2,
addressFk: 121,
agencyModeFk: 1,
routeFk: null,
landed: today,
userId: 18
@ -64,8 +64,8 @@ describe('ticket ticketCreateWithUser()', () => {
shipped: today,
warehouseFk: 1,
companyFk: 442,
addressFk: 1,
agencyModeFk: 2,
addressFk: 121,
agencyModeFk: 1,
routeFk: null,
landed: today,
userId: 18
@ -91,7 +91,6 @@ describe('ticket ticketCreateWithUser()', () => {
let sql = ParameterizedSQL.join(stmts, ';');
let result = await app.models.Ticket.rawStmt(sql);
let firstTicketObservation = result[ticketObsevationsIndex][0];
let secondTicketObservation = result[ticketObsevationsIndex][1];
let thirdTicketObservation = result[ticketObsevationsIndex][2];
@ -116,7 +115,7 @@ describe('ticket ticketCreateWithUser()', () => {
warehouseFk: 1,
companyFk: 442,
addressFk: 0,
agencyModeFk: 2,
agencyModeFk: 1,
routeFk: null,
landed: today,
userId: 18
@ -162,8 +161,8 @@ describe('ticket ticketCreateWithUser()', () => {
shipped: today,
warehouseFk: 1,
companyFk: 442,
addressFk: 0,
agencyModeFk: 2,
addressFk: 121,
agencyModeFk: 1,
routeFk: null,
landed: today,
userId: 18
@ -186,7 +185,8 @@ describe('ticket ticketCreateWithUser()', () => {
params.userId
]);
stmts.push(stmt);
let ticket = stmts.push(`select @newTicketId`);
console.log('NUm ticket', ticket);
let ticketStateCodeIndex = stmts.push(`SELECT code FROM vn.ticketState WHERE ticketFk = @newTicketId`) - 1;
stmts.push('ROLLBACK');
@ -196,6 +196,6 @@ describe('ticket ticketCreateWithUser()', () => {
let ticketStateCode = result[ticketStateCodeIndex][0].code;
expect(ticketStateCode).toEqual('DELIVERED');
expect(ticketStateCode).toEqual('FREE');
});
});

View File

@ -28,6 +28,6 @@ describe('Worker pbx path', () => {
.waitToClick(selectors.workerPbx.saveButton)
.waitForLastSnackbar();
expect(result).toEqual('Data saved!');
expect(result).toEqual('Data saved! User must access web');
});
});

View File

@ -14,7 +14,10 @@
translate-attr="{title: 'Clear'}">
</vn-icon>
</div>
<label class="mdl-textfield__label" translate>{{::$ctrl.label}}</label>
<label class="mdl-textfield__label">
<span translate>{{::$ctrl.label}}</span>
<span translate ng-show="::$ctrl.required">(*)</span>
</label>
</div>
</div>
<vn-drop-down

View File

@ -294,6 +294,7 @@ ngModule.component('vnAutocomplete', {
label: '@',
field: '=?',
disabled: '<?',
required: '@?',
showField: '@?',
valueField: '@?',
initialData: '<?',

View File

@ -37,6 +37,10 @@ vn-autocomplete {
display: block;
}
}
label span:nth-child(2) {
color: $color-alert
}
}
ul.vn-autocomplete {

View File

@ -149,6 +149,10 @@ vn-textfield {
.infix.invalid + .underline {
background-color: #d50000;
}
label span:nth-child(2) {
color: $color-alert
}
}
vn-table {

View File

@ -14,7 +14,10 @@
ng-focus="$ctrl.hasFocus = true"
ng-blur="$ctrl.hasFocus = false"
tabindex="{{$ctrl.input.tabindex}}"/>
<label class="label" translate>{{::$ctrl.label}}</label>
<label class="label">
<span translate>{{::$ctrl.label}}</span>
<span translate ng-show="::$ctrl.required">(*)</span>
</label>
</div>
<div class="underline"></div>
<div class="selected underline"></div>

View File

@ -84,6 +84,7 @@ ngModule.component('vnTextfield', {
label: '@?',
name: '@?',
disabled: '<?',
required: '@?',
readonly: '<?',
rule: '@?',
type: '@?',

View File

@ -1,5 +1,5 @@
{
"PHONE_INVALID_FORMAT": "El formato del teléfono no es correcto",
"Phone format is invalid": "El formato del teléfono no es correcto",
"You are not allowed to change the credit": "No tienes privilegios para modificar el crédito",
"Unable to mark the equivalence surcharge": "No se puede marcar el recargo de equivalencia",
"The default consignee can not be unchecked": "No se puede desmarcar el consignatario predeterminado",
@ -73,12 +73,10 @@
"You cannot remove this department": "No puedes eliminar este departamento",
"The extension must be unique": "La extensión debe ser unica",
"The secret can't be blank": "La contraseña no puede estar en blanco",
"EXTENSION_INVALID_FORMAT": "La extensión es invalida",
"We weren't able to send this SMS": "No hemos podido enviar el SMS",
"This client can't be invoiced": "Este cliente no puede ser facturado",
"This ticket can't be invoiced": "Este ticket no puede ser facturado",
"That item is not available on that day": "El item no esta disponible para esa fecha",
"That item doesn't exists": "No existe el artículo",
"You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado",
"This ticket can not be modified": "Este ticket no puede ser modificado",
"The introduced hour already exists": "Esta hora ya ha sido introducida",
@ -90,5 +88,8 @@
"The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas",
"Please select at least one sale": "Por favor selecciona al menos una linea",
"All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket",
"NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada"
"NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada",
"That item doesn't exists": "El artículo no existe",
"NOT_ZONE_WITH_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada",
"Extension format is invalid": "El formato de la extensión es inválido"
}

View File

@ -31,7 +31,7 @@ describe('claimBeginning', () => {
expect(refundTicketSales.length).toEqual(2);
expect(refundTicketSales[0].quantity).toEqual(-5);
expect(refundTicketSales[1].quantity).toEqual(-4);
expect(refundTicketObservations[0].description).toEqual('Reclama ticket: 11');
expect(refundTicketObservations[3].description).toEqual('Reclama ticket: 11');
expect(refundTicketState.stateFk).toEqual(16);
expect(salesInsertedInClaimEnd[0].saleFk).toEqual(refundTicketSales[0].id);
expect(salesInsertedInClaimEnd[1].saleFk).toEqual(refundTicketSales[1].id);

View File

@ -146,9 +146,7 @@
</vn-input-number>
<div class="simulator">
<p class="simulatorTitle" translate>New price</p>
<p>{{($ctrl.saleClaimed.quantity * $ctrl.saleClaimed.sale.price) -
(($ctrl.newDiscount * ($ctrl.saleClaimed.quantity * $ctrl.saleClaimed.sale.price))/100)
| currency: 'EUR':2}}
<p>{{$ctrl.newPrice | currency: 'EUR':2}}
</p>
</div>
</div>

View File

@ -37,6 +37,15 @@ class Controller {
return this._salesClaimed;
}
get newDiscount() {
return this._newDiscount;
}
set newDiscount(value) {
this._newDiscount = value;
this.updateNewPrice();
}
openAddSalesDialog() {
this.getClaimableFromTicket();
this.$.addSales.show();
@ -140,6 +149,11 @@ class Controller {
}
}
updateNewPrice() {
this.newPrice = (this.saleClaimed.quantity * this.saleClaimed.sale.price) -
((this.newDiscount * (this.saleClaimed.quantity * this.saleClaimed.sale.price)) / 100);
}
clearDiscount() {
this.newDiscount = null;
}

View File

@ -95,10 +95,14 @@ describe('claim', () => {
describe('updateDiscount()', () => {
it('should perform a query if the new discount differs from the claim discount', () => {
controller.saleClaimed = {sale: {
discount: 5,
id: 7,
ticketFk: 1,
price: 2,
quantity: 10}};
controller.newDiscount = 10;
controller.saleClaimed = {sale: {discount: 5}};
controller.saleClaimed = {sale: {id: 7}};
controller.saleClaimed = {sale: {ticketFk: 1}};
spyOn(controller.vnApp, 'showSuccess');
spyOn(controller, 'clearDiscount');

View File

@ -0,0 +1,53 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => {
Self.remoteMethod('filter', {
description: 'Find all instances of the model matched by filter from the data source.',
accessType: 'READ',
accepts: [
{
arg: 'filter',
type: 'Object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
http: {source: 'query'}
}
],
returns: {
type: ['Object'],
root: true
},
http: {
path: `/filter`,
verb: 'GET'
}
});
Self.filter = async filter => {
let conn = Self.dataSource.connector;
let stmts = [];
let stmt;
filter.order = [
'c.defaultAddressFk DESC',
'a.isActive DESC',
'a.nickname ASC'
];
stmt = new ParameterizedSQL(
`SELECT a.*
FROM vn.address a
LEFT JOIN vn.client c ON c.defaultAddressFk = a.id`
);
stmt.merge(conn.makeSuffix(filter));
let itemsIndex = stmts.push(stmt) - 1;
let sql = ParameterizedSQL.join(stmts, ';');
let result = await conn.executeStmt(sql);
return itemsIndex === 0 ? result : result[itemsIndex];
};
};

View File

@ -5,6 +5,7 @@ let isMultiple = require('vn-loopback/util/hook').isMultiple;
module.exports = Self => {
// Methods
require('../methods/address/createDefaultAddress')(Self);
require('../methods/address/filter')(Self);
Self.validateAsync('isEqualizated', cannotHaveET, {
message: 'Cannot check Equalization Tax in this NIF/CIF'

View File

@ -0,0 +1,5 @@
module.exports = Self => {
Self.validatesPresenceOf('name', {
message: 'Name cannot be blank'
});
};

View File

@ -1,72 +1,74 @@
<vn-crud-model
vn-id="model"
url="/client/api/Addresses"
filter="::$ctrl.filter"
url="/client/api/Addresses/filter"
limit="10"
link="{clientFk: $ctrl.$stateParams.id}"
data="$ctrl.addresses"
auto-load="true">
auto-load="false">
</vn-crud-model>
<div compact>
<vn-card pad-large>
<vn-horizontal
ng-repeat="address in $ctrl.addresses"
class="pad-medium-top"
style="align-items: center;">
<vn-one
border-radius
class="pad-small border-solid"
ng-class="{
'item-hightlight': $ctrl.isDefaultAddress(address),
'item-disabled': !address.isActive && !$ctrl.isDefaultAddress(address)
}">
<vn-horizontal style="align-items: center;">
<vn-none pad-medium-h>
<vn-icon-button
icon="star"
ng-if="$ctrl.isDefaultAddress(address)">
</vn-icon-button>
<vn-icon-button
ng-if="!address.isActive"
icon="star_border"
vn-tooltip="Active first to set as default">
</vn-icon-button>
<vn-icon-button
ng-if="address.isActive && !$ctrl.isDefaultAddress(address)"
icon="star_border"
vn-tooltip="Set as default"
ng-click="$ctrl.setDefault(address)">
</vn-icon-button>
</vn-none>
<vn-one border-solid-right>
<vn-horizontal>
<vn-one>
<div><b>{{::address.nickname}}</b></div>
<div name="street">{{::address.street}}</div>
<div>{{::address.city}}, {{::address.province}}</div>
<div>{{::address.phone}}, {{::address.mobile}}</div>
</vn-one>
<vn-one>
<vn-check
vn-one label="Is equalizated"
field="address.isEqualizated"
disabled="true">
</vn-check>
</vn-one>
</vn-horizontal>
</vn-one>
<vn-vertical vn-one pad-medium-h>
<vn-one ng-repeat="observation in address.observations track by $index" ng-class="{'pad-small-top': $index}">
<b margin-medium-right>{{::observation.observationType.description}}:</b>
<span>{{::observation.description}}</span>
<vn-table model="model">
<vn-card pad-large>
<vn-horizontal
ng-repeat="address in $ctrl.addresses"
class="pad-medium-top"
style="align-items: center;">
<vn-one
border-radius
class="pad-small border-solid"
ng-class="{
'item-hightlight': $ctrl.isDefaultAddress(address),
'item-disabled': !address.isActive && !$ctrl.isDefaultAddress(address)
}">
<vn-horizontal style="align-items: center;">
<vn-none pad-medium-h>
<vn-icon-button
icon="star"
ng-if="$ctrl.isDefaultAddress(address)">
</vn-icon-button>
<vn-icon-button
ng-if="!address.isActive"
icon="star_border"
vn-tooltip="Active first to set as default">
</vn-icon-button>
<vn-icon-button
ng-if="address.isActive && !$ctrl.isDefaultAddress(address)"
icon="star_border"
vn-tooltip="Set as default"
ng-click="$ctrl.setDefault(address)">
</vn-icon-button>
</vn-none>
<vn-one border-solid-right>
<vn-horizontal>
<vn-one>
<div><b>{{::address.nickname}}</b></div>
<div name="street">{{::address.street}}</div>
<div>{{::address.city}}, {{::address.province}}</div>
<div>{{::address.phone}}, {{::address.mobile}}</div>
</vn-one>
<vn-one>
<vn-check
vn-one label="Is equalizated"
field="address.isEqualizated"
disabled="true">
</vn-check>
</vn-one>
</vn-horizontal>
</vn-one>
</vn-vertical>
<a pad-medium-h vn-tooltip="Edit address"
vn-auto ui-sref="client.card.address.edit({addressId: {{::address.id}}})">
<vn-icon-button icon="edit"></vn-icon-button>
</a>
</vn-horizontal>
</vn-one>
</vn-horizontal>
<vn-vertical vn-one pad-medium-h>
<vn-one ng-repeat="observation in address.observations track by $index" ng-class="{'pad-small-top': $index}">
<b margin-medium-right>{{::observation.observationType.description}}:</b>
<span>{{::observation.description}}</span>
</vn-one>
</vn-vertical>
<a pad-medium-h vn-tooltip="Edit address"
vn-auto ui-sref="client.card.address.edit({addressId: {{::address.id}}})">
<vn-icon-button icon="edit"></vn-icon-button>
</a>
</vn-horizontal>
</vn-one>
</vn-horizontal>
</vn-table>
</vn-card>
<vn-float-button
vn-bind="+"
@ -76,4 +78,5 @@
icon="add"
label="Add">
</vn-float-button>
<vn-pagination model="model"></vn-pagination>
</div>

View File

@ -5,30 +5,6 @@ class Controller {
this.$http = $http;
this.$scope = $scope;
this.$stateParams = $stateParams;
this.filter = {
include: {
observations: 'observationType'
},
order: ['isActive DESC', 'nickname ASC']
};
}
get client() {
return this._client;
}
set client(value) {
this._client = value;
this.sortAddresses();
}
get addresses() {
return this._addresses;
}
set addresses(value) {
this._addresses = value;
this.sortAddresses();
}
setDefault(address) {
@ -43,8 +19,8 @@ class Controller {
}
isDefaultAddress(address) {
if (!this.client) return;
return this.client.defaultAddressFk === address.id;
if (this.client)
return this.client.defaultAddressFk === address.id;
}
/**
@ -52,7 +28,7 @@ class Controller {
*/
sortAddresses() {
if (!this.client || !this.addresses) return;
this.$scope.model.data = this.addresses.sort((a, b) => {
this.addresses = this.addresses.sort((a, b) => {
return this.isDefaultAddress(b) - this.isDefaultAddress(a);
});
}

View File

@ -98,28 +98,33 @@
<vn-horizontal>
<vn-textfield vn-one
label="Name"
model="$ctrl.newBankEntity.name">
model="$ctrl.newBankEntity.name"
required="true">
</vn-textfield>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one
<vn-autocomplete vn-id="country" vn-one
label="Country"
field="$ctrl.newBankEntity.countryFk"
fields="['id', 'country', 'code']"
url="/client/api/Countries"
value-field="id"
show-field="country">
show-field="country"
required="true">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-textfield vn-one
label="Code"
model="$ctrl.newBankEntity.id">
label="Entity Code"
model="$ctrl.newBankEntity.id"
ng-show="country.selection.code === 'ES'">
</vn-textfield>
</vn-horizontal>
<vn-horizontal>
<vn-textfield vn-one
label="Swift / BIC"
model="$ctrl.newBankEntity.bic">
model="$ctrl.newBankEntity.bic"
required="true">
</vn-textfield>
</vn-horizontal>
</tpl-body>

View File

@ -59,8 +59,6 @@ export default class Controller {
try {
if (!this.newBankEntity.name)
throw new Error(`Name can't be empty`);
if (!this.newBankEntity.id)
throw new Error(`Code can't be empty`);
if (!this.newBankEntity.bic)
throw new Error(`Swift / BIC can't be empty`);

View File

@ -71,18 +71,6 @@ describe('Client', () => {
expect(vnApp.showError).toHaveBeenCalledWith(`Swift / BIC can't be empty`);
});
it(`should throw an error if id property is empty`, () => {
controller.newBankEntity = {
name: 'My new bank entity',
bic: 'ES123',
countryFk: 1,
id: null
};
controller.onBankEntityResponse('ACCEPT');
expect(vnApp.showError).toHaveBeenCalledWith(`Code can't be empty`);
});
it('should request to create a new bank entity', () => {
let newBankEntity = {
name: 'My new bank entity',

View File

@ -16,4 +16,4 @@ Save: Guardar
New bank entity: Nueva entidad bancaria
Name can't be empty: El nombre no puede quedar vacío
Swift / BIC can't be empty: El Swift / BIC no puede quedar vacío
Code: Código
Entity Code: Código

View File

@ -36,7 +36,7 @@ module.exports = Self => {
Self.download = async function(id) {
let file;
let env = process.env.NODE_ENV;
let [invoice] = await Self.rawSql(`SELECT hedera.invoiceGetPath(?) path`, [id]);
let [invoice] = await Self.rawSql(`SELECT invoiceOut_getPath(?) path`, [id]);
if (env && env != 'development') {
file = {

View File

@ -27,7 +27,8 @@
field="$ctrl.ticketRequest.quantity">
</vn-input-number>
<vn-input-number vn-one min="0"
label="Price"
label="Price"
step="0.01"
field="$ctrl.ticketRequest.price">
</vn-input-number>
</vn-horizontal>

View File

@ -13,8 +13,6 @@
</vn-input-number>
<div class="simulator">
<p class="simulatorTitle" translate>New price</p>
<p>{{($ctrl.edit[0].quantity * $ctrl.edit[0].price)
- (($ctrl.newDiscount * ($ctrl.edit[0].quantity * $ctrl.edit[0].price))/100)
| currency: 'EUR':2}}</p>
<p>{{$ctrl.newPrice | currency: 'EUR':2}}</p>
</div>
</div>

View File

@ -28,6 +28,20 @@ class Controller {
return this._bulk;
}
get newDiscount() {
return this._newDiscount;
}
set newDiscount(value) {
this._newDiscount = value;
this.updateNewPrice();
}
updateNewPrice() {
if (this.newDiscount && this.edit[0])
this.newPrice = (this.edit[0].quantity * this.edit[0].price) - ((this.newDiscount * (this.edit[0].quantity * this.edit[0].price)) / 100);
}
setNewDiscount() {
if (!this.newDiscount && this.edit[0])
this.newDiscount = this.edit[0].discount;

View File

@ -186,9 +186,7 @@
</vn-input-number>
<div class="simulator">
<p class="simulatorTitle" translate>New price</p>
<p>{{($ctrl.sale.quantity * $ctrl.editedPrice)
- (($ctrl.sale.discount * ($ctrl.sale.quantity * $ctrl.editedPrice))/100)
| currency: 'EUR':2}}</p>
<p>{{$ctrl.newPrice | currency: 'EUR':2}}</p>
</div>
</div>
</div>

View File

@ -21,16 +21,25 @@ class Controller {
this.imagesPath = '//verdnatura.es/vn-image-data/catalog';
}
get sales() {
return this._sales;
}
set sales(value) {
this._sales = value;
this.refreshTotal();
}
get sales() {
return this._sales;
get editedPrice() {
return this._editedPrice;
}
set editedPrice(value) {
this._editedPrice = value;
this.updateNewPrice();
}
refreshTotal() {
this.loadSubTotal();
this.loadVAT();
@ -270,6 +279,10 @@ class Controller {
this.$scope.editPricePopover.hide();
}
updateNewPrice() {
this.newPrice = this.sale.quantity * this.editedPrice - ((this.sale.discount * (this.sale.quantity * this.editedPrice)) / 100);
}
showEditPopover(event, sale) {
this.sale = sale;
this.edit = [{

View File

@ -16,4 +16,5 @@ User name: Usuario
Departments: Departamentos
Calendar: Calendario
Search workers by id, firstName, lastName or user name: Buscar trabajadores por el identificador, nombre, apellidos o nombre de usuario
Time control: Control de horario
Time control: Control de horario
Data saved! User must access web: ¡Datos guardados! El usuario deberá acceder con su contraseña a la web para que los cambios surtan efecto.

View File

@ -10,7 +10,6 @@
label="Extension"
model="$ctrl.worker.sip.extension">
</vn-textfield>
</vn-horizontal>
</vn-vertical>
</vn-card>

View File

@ -1,9 +1,11 @@
import ngModule from '../module';
class Controller {
constructor($scope, $http) {
constructor($scope, $http, vnApp, $translate) {
this.$scope = $scope;
this.$http = $http;
this.vnApp = vnApp;
this._ = $translate;
}
onSubmit() {
@ -15,12 +17,12 @@ class Controller {
this.$scope.watcher.check();
this.$http.patch('/api/Sips', params).then(() => {
this.$scope.watcher.updateOriginalData();
this.$scope.watcher.notifySaved();
this.vnApp.showSuccess(this._.instant('Data saved! User must access web'));
});
}
}
Controller.$inject = ['$scope', '$http'];
Controller.$inject = ['$scope', '$http', 'vnApp', '$translate'];
ngModule.component('vnWorkerPbx', {
template: require('./index.html'),