This commit is contained in:
Vicente Falco 2018-02-25 10:59:33 +01:00
commit 268f4b3463
31 changed files with 75358 additions and 74326 deletions

2
Jenkinsfile vendored
View File

@ -9,7 +9,7 @@ env.TAG = "${env.BUILD_NUMBER}";
switch (branchName){
case branchTest:
env.NODE_ENV = "development";
env.NODE_ENV = "test";
break;
case branchProduction:
env.DOCKER_HOST = "tcp://172.16.255.29:2375";

View File

@ -11,7 +11,7 @@
<vn-vertical pad-medium>
<vn-title vn-one margin-large-bottom>Add Greuge</vn-title>
<vn-horizontal>
<vn-textfield vn-one margin-medium-right label="Amount" field="$ctrl.greuge.amount" type="number" step="1" vn-focus></vn-textfield>
<vn-textfield vn-one margin-medium-right label="Amount" field="$ctrl.greuge.amount" step="1" vn-focus></vn-textfield>
<vn-date-picker vn-one
label="Date"
model="$ctrl.greuge.shipped"

View File

@ -39,14 +39,14 @@ describe('Component vnDialog', () => {
describe('fireResponse()', () => {
it(`should call onResponse()`, () => {
let resposneRes;
let responseRes;
controller.onResponse = response => {
resposneRes = response;
responseRes = response;
return false;
};
let responseRet = controller.fireResponse('answer');
expect(resposneRes).toEqual({response: 'answer'});
expect(responseRes).toEqual({response: 'answer'});
expect(responseRet).toEqual(false);
});
});

View File

@ -52,6 +52,15 @@
},
"acl": ["buyer"]
},
{
"url" : "/tax",
"state": "item.card.tax",
"component": "vn-item-tax",
"menu": {
"description": "Tax",
"icon": "folder"
}
},
{
"url" : "/history",
"state": "item.card.history",

View File

@ -8,6 +8,7 @@ import './card/item-card';
import './descriptor/item-descriptor';
import './data/item-data';
import './tags/item-tags';
import './tax/item-tax';
import './history/item-history';
import './niche/item-niche';
import './botanical/item-botanical';

View File

@ -11,6 +11,7 @@ Basic data: Datos básicos
History: Historial
Item history: Historial del artículo
Item tags: Tags del artículo
Tax: IVA
Niche: Nicho
Picture: Foto
Barcode: Código barras
@ -21,4 +22,5 @@ Date: Fecha
Preview: Vista previa
Clone: Clonar
Do you want to clone this item?: ¿Desea clonar este artículo?
Yes, clone: Si, clonar
Yes, clone: Si, clonar
Value: Valor

View File

@ -3,11 +3,11 @@
<vn-vertical pad-large>
<vn-one margin-medium-top>
<vn-title>Item Niches</vn-title>
<vn-horizontal ng-repeat="niche in $ctrl.niches track by $index">
<vn-horizontal ng-repeat="itemNiche in $ctrl.niches track by $index">
<vn-autocomplete
vn-three
initial-data = "niche.warehouse"
field = "niche.warehouseFk"
initial-data = "itemNiche.warehouse"
field = "itemNiche.warehouseFk"
data = "$ctrl.warehouses"
show-field = "name"
value-field = "id"
@ -17,7 +17,8 @@
</vn-autocomplete>
<vn-textfield
vn-three label="code"
model="niche.code"
model="itemNiche.code"
rule="itemNiche.code"
vn-acl="buyer,replenisher">
</vn-textfield>
<vn-one pad-medium-top>
@ -34,7 +35,7 @@
margin-medium-left
orange
icon="add_circle"
ng-if = "niche.showAddIcon"
ng-if = "itemNiche.showAddIcon"
ng-click="$ctrl.addNiche()">
</vn-icon>
</vn-one>

View File

@ -86,6 +86,10 @@ export default class Controller {
}
});
if (this.$scope.form.$invalid) {
return this.vnApp.showMessage(this.$translate.instant('Some fields are invalid'));
}
if (repeatedWarehouse) {
return this.vnApp.showMessage(this.$translate.instant('The niche must be unique'));
}

View File

@ -1,5 +1,43 @@
<vn-card>
<vn-vertical pad-large>
<vn-title>Item tags</vn-title>
</vn-vertical>
</vn-card>
<vn-watcher
vn-id="watcher"
data="$ctrl.item"
form = "form">
</vn-watcher>
<form name="form" ng-submit="$ctrl.submit()">
<vn-card>
<vn-vertical pad-large>
<vn-title>Item tags</vn-title>
<mg-ajax path="/item/api/Tags" options="mgIndex as tags"></mg-ajax>
<vn-horizontal ng-repeat="itemTag in $ctrl.itemTags track by $index">
<vn-autocomplete
vn-one
initial-data = "itemTag.tag"
field = "itemTag.tagFk"
data = "tags.model"
show-field = "name"
label = "Tag">
</vn-autocomplete>
<vn-textfield vn-three label="Value" model="itemTag.value"></vn-textfield>
<vn-one pad-medium-top>
<vn-icon
pointer
medium-grey
icon="remove_circle_outline"
ng-click="$ctrl.removeItemTag($index)">
</vn-icon>
<vn-icon
pointer
margin-medium-left
orange
icon="add_circle"
ng-if = "itemTag.showAddIcon && tags.model.length > $ctrl.itemTags.length"
ng-click="$ctrl.addItemTag()">
</vn-icon>
</vn-one>
</vn-horizontal>
</vn-vertical>
</vn-card>
<vn-button-bar>
<vn-submit label="Save"></vn-submit>
</vn-button-bar>
</form>

View File

@ -1,5 +1,128 @@
import ngModule from '../module';
class ItemTags {
constructor($http, $scope, $translate, vnApp, params) {
this.$http = $http;
this.$scope = $scope;
this.$translate = $translate;
this.vnApp = vnApp;
this.itemId = params.id;
this.itemTags = [];
this.itemTagsRemoved = [];
this.oldItemTags = {};
}
_setIconAdd() {
if (this.itemTags.length) {
this.itemTags.map(element => {
element.showAddIcon = false;
return true;
});
this.itemTags[this.itemTags.length - 1].showAddIcon = true;
} else {
this.addItemTag();
}
}
_setDirtyForm() {
if (this.$scope.form) {
this.$scope.form.$setDirty();
}
}
_unsetDirtyForm() {
if (this.$scope.form) {
this.$scope.form.$setPristine();
}
}
removeItemTag(index) {
let item = this.itemTags[index];
if (item) {
this.itemTags.splice(index, 1);
this._setIconAdd();
if (item.id) {
this.itemTagsRemoved.push(item.id);
this._setDirtyForm();
}
}
}
addItemTag() {
this.itemTags.push({value: null, itemFk: this.item.id, tagFk: null, showAddIcon: true});
this._setIconAdd();
}
_setOlTags(itemTags) {
itemTags.map(tag => {
this.oldItemTags[tag.id] = Object.assign({}, tag);
return tag;
});
this._setIconAdd();
}
_getItemtags() {
let filter = {
where: {itemFk: this.itemId},
order: "priority ASC",
include: {relation: "tag"}
};
this.$http.get(`/item/api/ItemTags?filter=${JSON.stringify(filter)}`).then(response => {
this.itemTags = response.data;
this._setOlTags(response.data);
});
}
_equalItemTags(tagOld, tagNew) {
return tagOld.tagFk === tagNew.tagFk && tagOld.value === tagNew.value;
}
submit() {
let codes = [];
let repeatedItemTags = false;
let canSubmit;
let submitObj = {
delete: this.itemTagsRemoved,
create: [],
update: []
};
for (let i = 0; i < this.itemTags.length; i++) {
let itemTag = this.itemTags[i];
let isNewItemTag = itemTag.id === undefined;
if (itemTag.tagFk && codes.indexOf(itemTag.tagFk) !== -1) {
repeatedItemTags = true;
break;
}
if (itemTag.tagFk) codes.push(itemTag.tagFk);
if (isNewItemTag && itemTag.tagFk) {
submitObj.create.push(itemTag);
} else if (!isNewItemTag && !this._equalItemTags(this.oldItemTags[itemTag.id], itemTag)) {
submitObj.update.push(itemTag);
}
}
if (repeatedItemTags) {
return this.vnApp.showMessage(this.$translate.instant('The barcode must be unique'));
}
canSubmit = submitObj.update.length > 0 || submitObj.create.length > 0 || submitObj.delete.length > 0;
if (canSubmit) {
return this.$http.post(`/item/api/ItemTags/crudItemTags`, submitObj).then(() => {
this._getItemtags();
this._unsetDirtyForm();
});
}
this.vnApp.showMessage(this.$translate.instant('No changes to save'));
}
$onInit() {
this._getItemtags();
}
}
ItemTags.$inject = ['$http', '$scope', '$translate', 'vnApp', '$stateParams'];
ngModule.component('vnItemTags', {
template: require('./item-tags.html')
template: require('./item-tags.html'),
controller: ItemTags
});

View File

@ -0,0 +1,24 @@
<form name="form" ng-submit="$ctrl.submit()">
<vn-card>
<vn-vertical pad-large>
<vn-title>Item tax</vn-title>
<vn-horizontal ng-repeat="tax in $ctrl.taxes track by $index">
<vn-textfield vn-one
label="Country"
model="tax.country.country"
disabled="true">
</vn-textfield>
<vn-autocomplete vn-one
label="Class"
field="tax.taxClassFk"
data="$ctrl.classes"
value-field="id"
show-field="description">
</vn-autocomplete>
</vn-horizontal>
</vn-vertical>
</vn-card>
<vn-button-bar>
<vn-submit label="Save"></vn-submit>
</vn-button-bar>
</form>

View File

@ -0,0 +1,43 @@
import ngModule from '../module';
export default class Controller {
constructor($stateParams, $http) {
this.$http = $http;
this.$stateParams = $stateParams;
let filter = {
fields: ['id', 'countryFk', 'taxClassFk'],
include: [{
relation: 'country',
scope: {fields: ['country']}
}]
};
let urlFilter = encodeURIComponent(JSON.stringify(filter));
let url = `/item/api/Items/${$stateParams.id}/taxes?filter=${urlFilter}`;
$http.get(url).then(json => {
this.taxes = json.data;
});
$http.get(`/item/api/TaxClasses`).then(json => {
this.classes = json.data;
});
}
submit() {
let data = [];
for (let tax of this.taxes)
data.push({id: tax.id, taxClassFk: tax.taxClassFk});
let url = `/item/api/Items/${this.$stateParams.id}/updateTaxes`;
this.$http.post(url, data);
}
}
Controller.$inject = ['$stateParams', '$http'];
ngModule.component('vnItemTax', {
template: require('./item-tax.html'),
controller: Controller,
bindings: {
item: '<'
}
});

View File

@ -137,6 +137,8 @@ export default {
createItemButton: `${components.vnFloatButton}`,
searchResult: `${components.vnItemProduct} > vn-horizontal > vn-one`,
searchResultPreviewButton: `${components.vnItemProduct}:nth-child(1) > vn-horizontal > vn-horizontal > vn-one:nth-child(2) > vn-icon > i`,
searchResultCloneButton: `${components.vnItemProduct} > vn-horizontal > vn-horizontal > vn-one:nth-child(1) > vn-icon > i`,
acceptClonationAlertButton: `vn-dialog.ng-isolate-scope.vn-dialog.shown > div > form > div.buttons > tpl-buttons > button:nth-child(2)`,
searchItemInput: `${components.vnTextfield}`,
searchButton: `${components.vnSearchBar} > vn-icon-button > button`,
closeItemSummaryPreview: 'body > vn-app > vn-vertical > vn-vertical > ui-view > vn-item-list:nth-child(1) > div > vn-dialog > div > button > vn-icon'

View File

@ -14,7 +14,7 @@ describe('Item summary path', () => {
});
});
it('should search for the item Gem of Mind', () => {
it('should search for the item Gem of Time', () => {
return nightmare
.wait(selectors.itemsIndex.searchResult)
.type(selectors.itemsIndex.searchItemInput, 'Gem of Time')

View File

@ -0,0 +1,52 @@
import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/helpers';
describe('Item clone path', () => {
const nightmare = createNightmare();
it('should access to the items index by clicking the items button', () => {
return nightmare
.click(selectors.moduleAccessView.itemsSectionButton)
.wait(selectors.itemsIndex.createItemButton)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/item/list');
});
});
it('should search for the item Iron Patriot', () => {
return nightmare
.wait(selectors.itemsIndex.searchResult)
.type(selectors.itemsIndex.searchItemInput, 'Iron Patriot')
.click(selectors.itemsIndex.searchButton)
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
.countSearchResults(selectors.itemsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
});
it(`should clone the Iron Patriot`, () => {
return nightmare
.waitForTextInElement(selectors.itemsIndex.searchResult, 'Iron Patriot')
.click(selectors.itemsIndex.searchResultCloneButton)
.waitToClick(selectors.itemsIndex.acceptClonationAlertButton)
.waitForURL('tags')
.parsedUrl()
.then(url => {
expect(url.hash).toContain('tags');
});
});
it('should search for the item Iron Patriot and find two', () => {
return nightmare
.wait(selectors.itemsIndex.searchResult)
.type(selectors.itemsIndex.searchItemInput, 'Iron Patriot')
.click(selectors.itemsIndex.searchButton)
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 2)
.countSearchResults(selectors.itemsIndex.searchResult)
.then(result => {
expect(result).toEqual(2);
});
});
});

File diff suppressed because it is too large Load Diff

View File

@ -1,96 +1,92 @@
USE `account`;
-- MySQL dump 10.13 Distrib 5.7.17, for Win64 (x86_64)
--
-- Host: db.verdnatura.es Database: account
-- ------------------------------------------------------
-- Server version 5.6.25-4-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Dumping data for table `role`
--
LOCK TABLES `role` WRITE;
/*!40000 ALTER TABLE `role` DISABLE KEYS */;
INSERT INTO `role` VALUES (0,'root','Rol con todos los privilegios',0,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(1,'employee','Empleado básico',1,'2017-05-19 07:04:58','2017-11-29 10:06:31'),(2,'customer','Privilegios básicos de un cliente',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(3,'agency','Consultar tablas de predicciones de bultos',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(5,'administrative','Tareas relacionadas con la contabilidad',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(6,'guest','Privilegios para usuarios sin cuenta',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(9,'developer','Desarrolladores del sistema',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(11,'account','Privilegios relacionados con el login',0,'2017-05-19 07:04:58','2017-09-20 17:06:35'),(13,'teamBoss','Jefe de departamento',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(14,'manageEmployee','Privilegios para gestión de empleados',0,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(15,'logistic','Departamento de compras, responsables de la logistica',1,'2017-05-19 07:04:58','2018-02-12 10:50:10'),(16,'logisticBoss','Jefe del departamento de logística',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(17,'adminBoss','Jefe del departamento de administración',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(18,'salesPerson','Departamento de ventas',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(19,'salesBoss','Jefe del departamento de ventas',1,'2017-05-19 07:04:58','2017-08-16 12:38:27'),(20,'manager','Departamento de gerencia',1,'2017-06-01 14:57:02','2017-06-01 14:57:51'),(21,'salesAssistant','Jefe auxiliar de ventas',1,'2017-08-16 12:40:52','2017-08-16 12:40:52'),(22,'teamManager','Jefe de departamento con privilegios de auxiliar de venta.',1,'2017-09-07 09:08:12','2017-09-07 09:08:12'),(30,'financialBoss','Director finaciero',1,'2017-09-21 11:05:36','2017-09-21 11:05:36'),(31,'freelancer','Trabajadores por cuenta ajena',1,'2017-10-10 12:57:26','2017-10-10 12:59:27'),(32,'ett','Trabajadores de empresa temporal',1,'2017-10-10 12:58:58','2017-10-10 12:59:20'),(33,'invoicing','Personal con acceso a facturación',0,'2018-01-29 16:43:34','2018-01-29 16:43:34'),(34,'agencyAdmin','Gestión administrativa de agencias',1,'2018-01-29 16:44:39','2018-01-29 16:44:39'),(35,'buyer','Departamento de compras',1,'2018-02-12 10:35:42','2018-02-12 10:35:42'),(36,'replenisher','Trabajador en la camara',1,'2018-02-16 14:07:10','2018-02-16 14:08:11');
/*!40000 ALTER TABLE `role` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping data for table `roleRole`
--
LOCK TABLES `roleRole` WRITE;
/*!40000 ALTER TABLE `roleRole` DISABLE KEYS */;
INSERT INTO `roleRole` VALUES (0,0),(0,1),(0,2),(0,3),(0,5),(0,6),(0,9),(0,11),(0,13),(0,14),(0,15),(0,16),(0,17),(0,18),(0,19),(0,20),(0,21),(0,22),(0,30),(0,31),(0,32),(0,33),(0,34),(0,35),(0,36),(1,1),(1,2),(1,3),(1,6),(1,11),(2,2),(2,6),(2,11),(3,3),(3,6),(3,11),(5,1),(5,2),(5,3),(5,5),(5,6),(5,11),(5,13),(5,14),(5,18),(5,19),(5,21),(5,33),(6,6),(9,0),(9,1),(9,2),(9,3),(9,5),(9,6),(9,9),(9,11),(9,13),(9,14),(9,15),(9,16),(9,17),(9,18),(9,19),(9,20),(9,21),(9,22),(9,30),(9,31),(9,32),(9,33),(9,34),(9,35),(9,36),(11,6),(11,11),(13,1),(13,2),(13,3),(13,6),(13,11),(13,13),(13,14),(14,14),(15,1),(15,2),(15,3),(15,6),(15,11),(15,15),(15,35),(16,1),(16,2),(16,3),(16,6),(16,11),(16,13),(16,14),(16,15),(16,16),(16,35),(17,1),(17,2),(17,3),(17,5),(17,6),(17,11),(17,13),(17,14),(17,17),(17,18),(17,19),(17,20),(17,21),(17,33),(18,1),(18,2),(18,3),(18,6),(18,11),(18,18),(19,1),(19,2),(19,3),(19,6),(19,11),(19,13),(19,14),(19,18),(19,19),(19,21),(20,1),(20,2),(20,3),(20,6),(20,11),(20,13),(20,14),(20,20),(21,1),(21,2),(21,3),(21,6),(21,11),(21,13),(21,14),(21,18),(21,21),(22,1),(22,2),(22,3),(22,6),(22,11),(22,13),(22,14),(22,18),(22,21),(22,22),(30,1),(30,2),(30,3),(30,5),(30,6),(30,11),(30,13),(30,14),(30,18),(30,19),(30,20),(30,21),(30,22),(30,30),(30,33),(31,1),(31,2),(31,3),(31,6),(31,11),(31,31),(32,1),(32,2),(32,3),(32,6),(32,11),(32,32),(33,33),(34,1),(34,2),(34,3),(34,6),(34,11),(34,33),(34,34),(35,1),(35,2),(35,3),(35,6),(35,11),(35,35),(36,1),(36,2),(36,3),(36,6),(36,11),(36,36);
/*!40000 ALTER TABLE `roleRole` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping data for table `roleInherit`
--
LOCK TABLES `roleInherit` WRITE;
/*!40000 ALTER TABLE `roleInherit` DISABLE KEYS */;
INSERT INTO `roleInherit` VALUES (9,0),(5,1),(13,1),(18,1),(31,1),(32,1),(34,1),(35,1),(36,1),(1,2),(5,2),(1,3),(17,5),(30,5),(11,6),(1,11),(2,11),(3,11),(16,13),(17,13),(19,13),(20,13),(21,13),(22,13),(5,14),(13,14),(16,15),(21,18),(5,19),(17,20),(30,20),(19,21),(22,21),(30,22),(5,33),(34,33),(15,35);
/*!40000 ALTER TABLE `roleInherit` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2018-02-20 14:01:13
USE `salix`;
-- MySQL dump 10.13 Distrib 5.7.17, for Win64 (x86_64)
--
-- Host: db.verdnatura.es Database: salix
-- ------------------------------------------------------
-- Server version 5.6.25-4-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Dumping data for table `ACL`
--
LOCK TABLES `ACL` WRITE;
/*!40000 ALTER TABLE `ACL` DISABLE KEYS */;
INSERT INTO `ACL` VALUES (1,'Account','*','*','ALLOW','ROLE','employee'),(3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(7,'Client','*','*','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','employee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','employee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','employee'),(18,'State','*','READ','ALLOW','ROLE','employee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','employee'),(28,'ClientObservation','*','READ','ALLOW','ROLE','employee'),(30,'GreugeType','*','READ','ALLOW','ROLE','employee'),(31,'Mandate','*','READ','ALLOW','ROLE','employee'),(32,'MandateType','*','READ','ALLOW','ROLE','employee'),(33,'Company','*','READ','ALLOW','ROLE','employee'),(34,'Greuge','*','READ','ALLOW','ROLE','employee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(48,'ItemNiche','*','READ','ALLOW','ROLE','employee'),(49,'ItemNiche','*','WRITE','ALLOW','ROLE','buyer'),(50,'ItemNiche','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(52,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW ','ROLE','buyer');
/*!40000 ALTER TABLE `ACL` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2018-02-20 14:01:13
USE `account`;
-- MySQL dump 10.16 Distrib 10.1.29-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: db.verdnatura.es Database: account
-- ------------------------------------------------------
-- Server version 5.6.25-4-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Dumping data for table `role`
--
LOCK TABLES `role` WRITE;
/*!40000 ALTER TABLE `role` DISABLE KEYS */;
INSERT INTO `role` VALUES (0,'root','Rol con todos los privilegios',0,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(1,'employee','Empleado básico',1,'2017-05-19 07:04:58','2017-11-29 10:06:31'),(2,'customer','Privilegios básicos de un cliente',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(3,'agency','Consultar tablas de predicciones de bultos',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(5,'administrative','Tareas relacionadas con la contabilidad',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(6,'guest','Privilegios para usuarios sin cuenta',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(9,'developer','Desarrolladores del sistema',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(11,'account','Privilegios relacionados con el login',0,'2017-05-19 07:04:58','2017-09-20 17:06:35'),(13,'teamBoss','Jefe de departamento',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(15,'logistic','Departamento de compras, responsables de la logistica',1,'2017-05-19 07:04:58','2018-02-12 10:50:10'),(16,'logisticBoss','Jefe del departamento de logística',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(17,'adminBoss','Jefe del departamento de administración',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(18,'salesPerson','Departamento de ventas',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(19,'salesBoss','Jefe del departamento de ventas',1,'2017-05-19 07:04:58','2017-08-16 12:38:27'),(20,'manager','Departamento de gerencia',1,'2017-06-01 14:57:02','2017-06-01 14:57:51'),(21,'salesAssistant','Jefe auxiliar de ventas',1,'2017-08-16 12:40:52','2017-08-16 12:40:52'),(22,'teamManager','Jefe de departamento con privilegios de auxiliar de venta.',1,'2017-09-07 09:08:12','2017-09-07 09:08:12'),(30,'financialBoss','Director finaciero',1,'2017-09-21 11:05:36','2017-09-21 11:05:36'),(31,'freelancer','Trabajadores por cuenta ajena',1,'2017-10-10 12:57:26','2017-10-10 12:59:27'),(32,'ett','Trabajadores de empresa temporal',1,'2017-10-10 12:58:58','2017-10-10 12:59:20'),(33,'invoicing','Personal con acceso a facturación',0,'2018-01-29 16:43:34','2018-01-29 16:43:34'),(34,'agencyBoss','Jefe/a del departamento de agencias',1,'2018-01-29 16:44:39','2018-02-23 07:58:53'),(35,'buyer','Departamento de compras',1,'2018-02-12 10:35:42','2018-02-12 10:35:42'),(36,'replenisher','Trabajador en la camara',1,'2018-02-16 14:07:10','2018-02-16 14:08:11'),(37,'hr','Gestor/a de recursos humanos',1,'2018-02-22 17:34:53','2018-02-22 17:34:53'),(38,'hrBoss','Jefe/a de recursos humanos',1,'2018-02-22 17:35:09','2018-02-22 17:35:09');
/*!40000 ALTER TABLE `role` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping data for table `roleRole`
--
LOCK TABLES `roleRole` WRITE;
/*!40000 ALTER TABLE `roleRole` DISABLE KEYS */;
INSERT INTO `roleRole` VALUES (0,0),(0,1),(0,2),(0,3),(0,5),(0,6),(0,9),(0,11),(0,13),(0,15),(0,16),(0,17),(0,18),(0,19),(0,20),(0,21),(0,22),(0,30),(0,31),(0,32),(0,33),(0,34),(0,35),(0,36),(0,37),(0,38),(1,1),(1,2),(1,3),(1,6),(1,11),(2,2),(2,6),(2,11),(3,3),(3,6),(3,11),(5,1),(5,2),(5,3),(5,5),(5,6),(5,11),(5,13),(5,18),(5,19),(5,21),(5,33),(6,6),(9,0),(9,1),(9,2),(9,3),(9,5),(9,6),(9,9),(9,11),(9,13),(9,15),(9,16),(9,17),(9,18),(9,19),(9,20),(9,21),(9,22),(9,30),(9,31),(9,32),(9,33),(9,34),(9,35),(9,36),(9,37),(9,38),(11,6),(11,11),(13,1),(13,2),(13,3),(13,6),(13,11),(13,13),(15,1),(15,2),(15,3),(15,6),(15,11),(15,15),(15,35),(16,1),(16,2),(16,3),(16,6),(16,11),(16,13),(16,15),(16,16),(16,35),(17,1),(17,2),(17,3),(17,5),(17,6),(17,11),(17,13),(17,17),(17,18),(17,19),(17,20),(17,21),(17,33),(17,37),(18,1),(18,2),(18,3),(18,6),(18,11),(18,18),(19,1),(19,2),(19,3),(19,6),(19,11),(19,13),(19,18),(19,19),(19,21),(20,1),(20,2),(20,3),(20,6),(20,11),(20,13),(20,20),(21,1),(21,2),(21,3),(21,6),(21,11),(21,13),(21,18),(21,21),(22,1),(22,2),(22,3),(22,6),(22,11),(22,13),(22,18),(22,21),(22,22),(30,1),(30,2),(30,3),(30,5),(30,6),(30,11),(30,13),(30,18),(30,19),(30,20),(30,21),(30,22),(30,30),(30,33),(31,1),(31,2),(31,3),(31,6),(31,11),(31,31),(32,1),(32,2),(32,3),(32,6),(32,11),(32,32),(33,33),(34,1),(34,2),(34,3),(34,6),(34,11),(34,13),(34,33),(34,34),(35,1),(35,2),(35,3),(35,6),(35,11),(35,35),(36,1),(36,2),(36,3),(36,6),(36,11),(36,36),(37,1),(37,2),(37,3),(37,6),(37,11),(37,37),(38,1),(38,2),(38,3),(38,6),(38,11),(38,37),(38,38);
/*!40000 ALTER TABLE `roleRole` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping data for table `roleInherit`
--
LOCK TABLES `roleInherit` WRITE;
/*!40000 ALTER TABLE `roleInherit` DISABLE KEYS */;
INSERT INTO `roleInherit` VALUES (9,0),(5,1),(13,1),(18,1),(31,1),(32,1),(34,1),(35,1),(36,1),(37,1),(1,2),(5,2),(1,3),(17,5),(30,5),(11,6),(1,11),(2,11),(3,11),(16,13),(17,13),(19,13),(20,13),(21,13),(22,13),(34,13),(16,15),(21,18),(5,19),(17,20),(30,20),(19,21),(22,21),(30,22),(5,33),(34,33),(15,35),(17,37),(38,37);
/*!40000 ALTER TABLE `roleInherit` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2018-02-23 9:05:51
USE `salix`;
-- MySQL dump 10.16 Distrib 10.1.29-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: db.verdnatura.es Database: salix
-- ------------------------------------------------------
-- Server version 5.6.25-4-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Dumping data for table `ACL`
--
LOCK TABLES `ACL` WRITE;
/*!40000 ALTER TABLE `ACL` DISABLE KEYS */;
INSERT INTO `ACL` VALUES (1,'Account','*','*','ALLOW','ROLE','employee'),(3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(7,'Client','*','*','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','employee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','employee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','employee'),(18,'State','*','READ','ALLOW','ROLE','employee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','employee'),(28,'ClientObservation','*','READ','ALLOW','ROLE','employee'),(30,'GreugeType','*','READ','ALLOW','ROLE','employee'),(31,'Mandate','*','READ','ALLOW','ROLE','employee'),(32,'MandateType','*','READ','ALLOW','ROLE','employee'),(33,'Company','*','READ','ALLOW','ROLE','employee'),(34,'Greuge','*','READ','ALLOW','ROLE','employee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(48,'ItemNiche','*','READ','ALLOW','ROLE','employee'),(49,'ItemNiche','*','WRITE','ALLOW','ROLE','buyer'),(50,'ItemNiche','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(52,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW','ROLE','buyer');
/*!40000 ALTER TABLE `ACL` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2018-02-23 9:05:51

View File

@ -2,11 +2,11 @@ INSERT INTO `util`.`config` ( `dbVersion`, `hasTriggersDisabled`, `environment`)
VALUES ('1.0.0', '0', 'development');
INSERT INTO `account`.`user`(`name`,`password`,`role`,`active`,`email`)
SELECT name,'ac754a330530832ba1bf7687f577da91',id,1,CONCAT(name,'@verdnatura.es')
SELECT name, MD5('nightmare'), id, 1, CONCAT(name, '@verdnatura.es')
FROM `account`.`role`;
INSERT INTO `vn`.`worker`(`workerCode`, `firstName`, `name`, `userFk`)
SELECT UPPER(LPAD(role, 3, '0')),name,name,id
SELECT UPPER(LPAD(role, 3, '0')), name, name, id
FROM `vn`.`user`;
INSERT INTO `account`.`user`(`id`,`name`,`password`,`role`,`active`,`email`)

View File

@ -1,3 +1,6 @@
/*
-- ERROR 1091 (42000) at line 1: Can't DROP 'Articles_nichos_fk'; check that column/key exists
ALTER TABLE `vn2008`.`Articles_nicho`
DROP FOREIGN KEY `Articles_nichos_fk`;
ALTER TABLE `vn2008`.`Articles_nicho`
@ -11,6 +14,4 @@ ADD CONSTRAINT `Articles_nichos_fk`
REFERENCES `vn2008`.`Articles` (`Id_Article`)
ON DELETE CASCADE
ON UPDATE CASCADE;
*/

View File

@ -1,2 +1,6 @@
/*
-- ERROR 1061 (42000) at line 1: Duplicate key name 'Id_Article_UNIQUE'
ALTER TABLE `vn2008`.`Articles_nicho`
ADD UNIQUE INDEX `Id_Article_UNIQUE` (`Id_Article` ASC, `warehouse_id` ASC);
*/

4
services/db/export-data.cmd Normal file → Executable file
View File

@ -1,5 +1,5 @@
echo USE `account`; > 02-dumpedFixtures.sql
echo "USE \`account\`;" > 02-dumpedFixtures.sql
mysqldump --defaults-file=connect.ini --no-create-info account role roleRole roleInherit >> 02-dumpedFixtures.sql
echo USE `salix`; >> 02-dumpedFixtures.sql
echo "USE \`salix\`;" >> 02-dumpedFixtures.sql
mysqldump --defaults-file=connect.ini --no-create-info salix ACL >> 02-dumpedFixtures.sql

View File

@ -0,0 +1,36 @@
module.exports = Self => {
Self.remoteMethod('crudItemTags', {
description: 'create, update or delete itemTags',
accessType: 'WRITE',
accepts: [
{
arg: 'itemtags',
type: 'Object',
require: true,
description: 'object with itemTags to create, update or delete, Example: {create: [], update: [], delete: []}',
http: {source: 'body'}
}
],
http: {
path: `/crudItemTags`,
verb: 'post'
}
});
Self.crudItemTags = itemtags => {
let promises = [];
if (itemtags.delete && itemtags.delete.length) {
promises.push(Self.destroyAll({id: {inq: itemtags.delete}}));
}
if (itemtags.create.length) {
promises.push(Self.create(itemtags.create));
}
if (itemtags.update.length) {
itemtags.update.forEach(itemtag => {
promises.push(Self.upsert(itemtag));
});
}
return Promise.all(promises);
};
};

View File

@ -0,0 +1,38 @@
module.exports = Self => {
Self.remoteMethod('updateTaxes', {
description: 'Updates the item taxes',
accessType: 'WRITE',
accepts: [{
arg: 'id',
type: 'number',
required: true,
description: 'The item id',
http: {source: 'path'}
}, {
arg: 'niches',
type: ['object'],
required: true,
description: 'The list of taxes to update',
http: {source: 'body'}
}],
returns: {
type: 'boolean',
root: true
},
http: {
path: `/:id/updateTaxes`,
verb: 'post'
}
});
Self.updateTaxes = async (id, taxes) => {
let promises = [];
for (let tax of taxes)
promises.push(Self.app.models.ItemTaxCountry.updateAll(
{id: tax.id},
{taxClassFk: tax.taxClassFk}
));
await Promise.all(promises);
return true;
};
};

View File

@ -22,7 +22,8 @@
"warehouse": {
"type": "belongsTo",
"model": "Warehouse",
"foreignKey": "warehouseFk"
"foreignKey": "warehouseFk",
"required": true
}
}
}

View File

@ -0,0 +1,3 @@
module.exports = function(Self) {
require('../methods/item/crudItemTags.js')(Self);
};

View File

@ -0,0 +1,36 @@
{
"name": "ItemTaxCountry",
"base": "VnModel",
"options": {
"mysql": {
"table": "itemTaxCountry"
}
},
"properties": {
"id": {
"type": "Number",
"id": true,
"description": "Identifier"
},
"effectived": {
"type": "Boolean"
}
},
"relations": {
"item": {
"type": "belongsTo",
"model": "Item",
"foreignKey": "itemFk"
},
"country": {
"type": "belongsTo",
"model": "Country",
"foreignKey": "countryFk"
},
"taxClass": {
"type": "belongsTo",
"model": "TaxClass",
"foreignKey": "taxClassFk"
}
}
}

View File

@ -1,6 +1,7 @@
module.exports = function(Self) {
require('../methods/item/filter.js')(Self);
require('../methods/item/clone.js')(Self);
require('../methods/item/updateTaxes.js')(Self);
Self.validatesPresenceOf('name', {message: 'Cannot be blank'});
Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'});

View File

@ -85,6 +85,11 @@
"model": "ItemBarcode",
"foreignKey": "itemFk"
},
"taxes": {
"type": "hasMany",
"model": "ItemTaxCountry",
"foreignKey": "itemFk"
},
"itemNiche": {
"type": "hasMany",
"model": "ItemNiche",

View File

@ -50,6 +50,9 @@
"ItemPlacement": {
"dataSource": "vn"
},
"ItemTaxCountry": {
"dataSource": "vn"
},
"Warehouse": {
"dataSource": "vn"
},

View File

@ -4,5 +4,6 @@
"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",
"Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado",
"El método de pago seleccionado requiere que se especifique el IBAN": "El método de pago seleccionado requiere que se especifique el IBAN"
"El método de pago seleccionado requiere que se especifique el IBAN": "El método de pago seleccionado requiere que se especifique el IBAN",
"can't be blank": "can't be blank"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 11 KiB