This commit is contained in:
Juan Ferrer 2019-02-05 09:14:22 +01:00
commit 8f72fbad23
67 changed files with 906 additions and 511 deletions

View File

@ -37,6 +37,9 @@
}, },
"Vehicle": { "Vehicle": {
"dataSource": "vn" "dataSource": "vn"
},
"UserTableConfiguration": {
"dataSource": "vn"
} }
} }

View File

@ -0,0 +1,30 @@
{
"name": "UserTableConfiguration",
"base": "VnModel",
"options": {
"mysql": {
"table": "salix.userTableConfiguration"
}
},
"properties": {
"id": {
"id": true,
"type": "Number",
"required": true
},
"tableCode": {
"type": "String",
"required": true
},
"configuration": {
"type": "String"
}
},
"relations": {
"worker": {
"type": "belongsTo",
"model": "Worker",
"foreignKey": "workerFk"
}
}
}

View File

@ -190,6 +190,19 @@ let actions = {
}, done, selector); }, done, selector);
}, },
clickIfVisible: function(selector, done) {
this.wait(selector)
.isVisible(selector)
.then(visible => {
if (visible)
return this.click(selector);
throw new Error(`invisible selector: ${selector}`);
})
.then(done)
.catch(done);
},
countElement: function(selector, done) { countElement: function(selector, done) {
this.evaluate_now(selector => { this.evaluate_now(selector => {
return document.querySelectorAll(selector).length; return document.querySelectorAll(selector).length;

View File

@ -191,7 +191,8 @@ export default {
moreMenu: `vn-item-descriptor vn-icon-menu > div > vn-icon`, moreMenu: `vn-item-descriptor vn-icon-menu > div > vn-icon`,
moreMenuRegularizeButton: `vn-item-descriptor vn-icon-menu > div > vn-drop-down > vn-popover ul > li:nth-child(1)`, moreMenuRegularizeButton: `vn-item-descriptor vn-icon-menu > div > vn-drop-down > vn-popover ul > li:nth-child(1)`,
regularizeQuantityInput: `vn-item-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-textfield > div > div > div.infix > input`, regularizeQuantityInput: `vn-item-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-textfield > div > div > div.infix > input`,
regularizeWarehouseAutocomplete: 'vn-item-descriptor > vn-dialog vn-autocomplete[field="$ctrl.warehouseFk"]', regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[field="$ctrl.warehouseFk"]',
editButton: 'vn-item-card vn-item-descriptor vn-float-button[icon="edit"]',
regularizeSaveButton: `vn-item-descriptor > vn-dialog > div > form > div.buttons > tpl-buttons > button` regularizeSaveButton: `vn-item-descriptor > vn-dialog > div > form > div.buttons > tpl-buttons > button`
}, },
itemBasicData: { itemBasicData: {
@ -335,7 +336,7 @@ export default {
descriptorItemDiaryButton: `vn-item-descriptor .quicklinks.ng-scope > vn-horizontal > a > vn-icon > i`, descriptorItemDiaryButton: `vn-item-descriptor .quicklinks.ng-scope > vn-horizontal > a > vn-icon > i`,
newItemButton: 'vn-float-button[icon="add"]', newItemButton: 'vn-float-button[icon="add"]',
firstSaleText: `vn-table div > vn-tbody > vn-tr:nth-child(1)`, firstSaleText: `vn-table div > vn-tbody > vn-tr:nth-child(1)`,
firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(3) > img', firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img',
firstSaleZoomedImage: 'body > div > div > img', firstSaleZoomedImage: 'body > div > div > img',
firstSaleQuantity: `vn-textfield[model="sale.quantity"]:nth-child(1) input`, firstSaleQuantity: `vn-textfield[model="sale.quantity"]:nth-child(1) input`,
firstSaleQuantityClearInput: `vn-textfield[model="sale.quantity"] div.suffix > i`, firstSaleQuantityClearInput: `vn-textfield[model="sale.quantity"] div.suffix > i`,

View File

@ -163,6 +163,13 @@ describe('Item summary path', () => {
expect(url.hash).toContain('summary'); expect(url.hash).toContain('summary');
}); });
it(`should check the descritor edit button is not visible for employee`, async() => {
const visibleButton = await nightmare
.isVisible(selectors.itemDescriptor.editButton);
expect(visibleButton).toBeFalsy();
});
it(`should check the item summary shows fields from basic data section`, async() => { it(`should check the item summary shows fields from basic data section`, async() => {
const result = await nightmare const result = await nightmare
.waitForTextInElement(selectors.itemSummary.basicData, 'Object2 Gem2 3') .waitForTextInElement(selectors.itemSummary.basicData, 'Object2 Gem2 3')

View File

@ -11,6 +11,13 @@ describe('Item Edit basic data path', () => {
.accessToSection('item.card.data'); .accessToSection('item.card.data');
}); });
it(`should check the descritor edit button is visible for buyer`, async() => {
const visibleButton = await nightmare
.isVisible(selectors.itemDescriptor.editButton);
expect(visibleButton).toBeTruthy();
});
it(`should edit the item basic data`, async() => { it(`should edit the item basic data`, async() => {
const result = await nightmare const result = await nightmare
.clearInput(selectors.itemBasicData.nameInput) .clearInput(selectors.itemBasicData.nameInput)

View File

@ -14,10 +14,11 @@ describe('Ticket Create new tracking state path', () => {
it('should access to the create state view by clicking the create floating button', async() => { it('should access to the create state view by clicking the create floating button', async() => {
let url = await nightmare let url = await nightmare
.waitToClick(selectors.ticketTracking.createStateButton) .clickIfVisible(selectors.ticketTracking.createStateButton)
.wait(selectors.createStateView.stateAutocomplete) .wait(selectors.createStateView.stateAutocomplete)
.parsedUrl(); .parsedUrl();
expect(url.hash).toContain('tracking/edit'); expect(url.hash).toContain('tracking/edit');
}); });

View File

@ -62,7 +62,7 @@ describe('Ticket Edit sale path', () => {
it(`should click on the thumbnail image of the 1st sale and see the zoomed image`, async() => { it(`should click on the thumbnail image of the 1st sale and see the zoomed image`, async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketSales.firstSaleThumbnailImage) .clickIfVisible(selectors.ticketSales.firstSaleThumbnailImage)
.countElement(selectors.ticketSales.firstSaleZoomedImage); .countElement(selectors.ticketSales.firstSaleZoomedImage);
expect(result).toEqual(1); expect(result).toEqual(1);
@ -70,7 +70,8 @@ describe('Ticket Edit sale path', () => {
it(`should click on the zoomed image to close it`, async() => { it(`should click on the zoomed image to close it`, async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketSales.firstSaleZoomedImage) .wait(1000)
.clickIfVisible(selectors.ticketSales.firstSaleZoomedImage)
.countElement(selectors.ticketSales.firstSaleZoomedImage); .countElement(selectors.ticketSales.firstSaleZoomedImage);
expect(result).toEqual(0); expect(result).toEqual(0);
@ -94,15 +95,15 @@ describe('Ticket Edit sale path', () => {
it(`should click on the descriptor image of the 1st sale and see the zoomed image`, async() => { it(`should click on the descriptor image of the 1st sale and see the zoomed image`, async() => {
const result = await nightmare const result = await nightmare
.waitToClick('vn-item-descriptor img') .clickIfVisible('vn-item-descriptor img')
.countElement(selectors.ticketSales.firstSaleZoomedImage); .countElement(selectors.ticketSales.firstSaleZoomedImage);
expect(result).toEqual(1); expect(result).toEqual(1);
}); });
it(`should click on the zoomed image to close it`, async() => { it(`should now click on the zoomed image to close it`, async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketSales.firstSaleZoomedImage) .clickIfVisible(selectors.ticketSales.firstSaleZoomedImage)
.countElement(selectors.ticketSales.firstSaleZoomedImage); .countElement(selectors.ticketSales.firstSaleZoomedImage);
expect(result).toEqual(0); expect(result).toEqual(0);

View File

@ -1,7 +1,8 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/nightmare'; import createNightmare from '../../helpers/nightmare';
describe('Ticket descriptor path', () => { // #1051 Traducciones que fallan
xdescribe('Ticket descriptor path', () => {
const nightmare = createNightmare(); const nightmare = createNightmare();
beforeAll(() => { beforeAll(() => {

View File

@ -5,7 +5,7 @@
<vn-icon icon="keyboard_arrow_up" ng-if="item.childs.length" <vn-icon icon="keyboard_arrow_up" ng-if="item.childs.length"
ng-click="$ctrl.toggle(item, $event)"> ng-click="$ctrl.toggle(item, $event)">
</vn-icon> </vn-icon>
<vn-icon icon="keyboard_arrow_down" ng-if="!item.childs" <vn-icon icon="keyboard_arrow_down" ng-if="item.sons > 0 && !item.childs"
ng-click="$ctrl.toggle(item, $event)"> ng-click="$ctrl.toggle(item, $event)">
</vn-icon> </vn-icon>
</vn-auto> </vn-auto>

View File

@ -20,6 +20,7 @@ export default class Treeview extends Component {
refresh() { refresh() {
this.model.refresh().then(() => { this.model.refresh().then(() => {
this.data = this.model.data; this.data = this.model.data;
console.log(this.data);
this.repaintAll(); this.repaintAll();
}); });
} }

View File

@ -16,7 +16,7 @@ export default class Controller {
case 'search': case 'search':
return /^\d+$/.test(value) return /^\d+$/.test(value)
? {id: value} ? {id: value}
: {name: {regexp: value}}; : {name: {like: `%${value}%`}};
case 'warehouseFk': case 'warehouseFk':
case 'agencyModeFk': case 'agencyModeFk':
return {[param]: value}; return {[param]: value};

View File

@ -147,8 +147,8 @@ class Controller {
this.$scope.descriptor.ticketFk = sale.origin; this.$scope.descriptor.ticketFk = sale.origin;
this.$scope.descriptor.parent = event.target; this.$scope.descriptor.parent = event.target;
this.$scope.descriptor.show(); this.$scope.descriptor.show();
event.preventDefault(); event.preventDefault();
event.stopImmediatePropagation();
} }
showClientDescriptor(event, sale) { showClientDescriptor(event, sale) {
@ -157,8 +157,8 @@ class Controller {
this.$scope.clientDescriptor.clientFk = sale.clientFk; this.$scope.clientDescriptor.clientFk = sale.clientFk;
this.$scope.clientDescriptor.parent = event.target; this.$scope.clientDescriptor.parent = event.target;
this.$scope.clientDescriptor.show(); this.$scope.clientDescriptor.show();
event.preventDefault(); event.preventDefault();
event.stopImmediatePropagation();
} }
onDescriptorLoad() { onDescriptorLoad() {

View File

@ -20,7 +20,7 @@ class Controller {
let params = {id: this.possibleStowaways[index].id, shipFk: this.ticket.id}; let params = {id: this.possibleStowaways[index].id, shipFk: this.ticket.id};
this.$http.post(`/api/Stowaways/`, params) this.$http.post(`/api/Stowaways/`, params)
.then(() => { .then(() => {
this.card.reload(); this.cardReload();
this.vnApp.showSuccess(this.$translate.instant('Data saved!')); this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
}); });
} }
@ -40,9 +40,7 @@ ngModule.component('vnAddStowaway', {
template: require('./addStowaway.html'), template: require('./addStowaway.html'),
controller: Controller, controller: Controller,
bindings: { bindings: {
ticket: '<' ticket: '<',
}, cardReload: '&?'
require: {
card: '^vnTicketCard'
} }
}); });

View File

@ -100,6 +100,7 @@
show-field="id" show-field="id"
value-field="id" value-field="id"
vn-tooltip="Ship stowaways" vn-tooltip="Ship stowaways"
tooltip-position="up"
data="$ctrl.ticket.ship" data="$ctrl.ticket.ship"
on-change="$ctrl.goToTicket(value)"> on-change="$ctrl.goToTicket(value)">
</vn-button-menu> </vn-button-menu>
@ -152,5 +153,5 @@
question="You are going to delete this ticket" question="You are going to delete this ticket"
message="Continue anyway?"> message="Continue anyway?">
</vn-confirm> </vn-confirm>
<vn-add-stowaway vn-id="addStowaway" ticket="$ctrl.ticket"></vn-add-stowaway> <vn-add-stowaway vn-id="addStowaway" card-reload="$ctrl.cardReload()" ticket="$ctrl.ticket"></vn-add-stowaway>
<vn-remove-stowaway vn-id="removeStowaway" ticket="$ctrl.ticket"></vn-remove-stowaway> <vn-remove-stowaway vn-id="removeStowaway" card-reload="$ctrl.cardReload()" ticket="$ctrl.ticket"></vn-remove-stowaway>

View File

@ -11,7 +11,7 @@ class Controller {
this.moreOptions = [ this.moreOptions = [
{callback: this.showAddTurnDialog, name: 'Add turn', show: true}, {callback: this.showAddTurnDialog, name: 'Add turn', show: true},
{callback: this.showDeleteTicketDialog, name: 'Delete ticket', show: true}, {callback: this.showDeleteTicketDialog, name: 'Delete ticket', show: true},
{callback: this.showAddStowaway, name: 'Add stowaway', show: true}, {callback: this.showAddStowaway, name: 'Add stowaway', show: () => this.isTicketModule()},
{callback: this.showRemoveStowaway, name: 'Remove stowaway', show: () => this.shouldShowRemoveStowaway()}, {callback: this.showRemoveStowaway, name: 'Remove stowaway', show: () => this.shouldShowRemoveStowaway()},
/* callback: this.showChangeShipped, name: 'Change shipped hour', show: true} */ /* callback: this.showChangeShipped, name: 'Change shipped hour', show: true} */
]; ];
@ -37,8 +37,16 @@ class Controller {
} }
} }
isTicketModule() {
let path = this.$state.getCurrentPath();
if (path[1].state.name === 'ticket')
return true;
return false;
}
shouldShowRemoveStowaway() { shouldShowRemoveStowaway() {
if (!this._ticket) if (!this._ticket || !this.isTicketModule())
return false; return false;
return (this._ticket.stowaway || (this._ticket.ship && this._ticket.ship.length > 0)); return (this._ticket.stowaway || (this._ticket.ship && this._ticket.ship.length > 0));
@ -157,7 +165,8 @@ Controller.$inject = ['$state', '$scope', '$http', 'vnApp', '$translate'];
ngModule.component('vnTicketDescriptor', { ngModule.component('vnTicketDescriptor', {
template: require('./index.html'), template: require('./index.html'),
bindings: { bindings: {
ticket: '<' ticket: '<',
cardReload: '&'
}, },
controller: Controller controller: Controller
}); });

View File

@ -46,7 +46,7 @@ class Controller {
deleteStowaway(response) { deleteStowaway(response) {
if (response === 'ACCEPT') { if (response === 'ACCEPT') {
this.$http.delete(`/api/Stowaways/${this.stowawayToDelete.id}`).then(res => { this.$http.delete(`/api/Stowaways/${this.stowawayToDelete.id}`).then(res => {
this.card.reload(); this.cardReload();
this.vnApp.showSuccess(this.$translate.instant('Data saved!')); this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
}); });
} }
@ -72,9 +72,7 @@ ngModule.component('vnRemoveStowaway', {
template: require('./removeStowaway.html'), template: require('./removeStowaway.html'),
controller: Controller, controller: Controller,
bindings: { bindings: {
ticket: '<' ticket: '<',
}, cardReload: '&?'
require: {
card: '^vnTicketCard'
} }
}); });

View File

@ -19,9 +19,9 @@ class Controller {
} }
set order(value) { set order(value) {
this._order = value; if (!value.id || this._order) return;
if (!value.id) return; this._order = value;
this.$scope.$$postDigest(() => { this.$scope.$$postDigest(() => {
let category; let category;

View File

@ -20,6 +20,10 @@ module.exports = Self => {
Self.getPossibleStowaways = async ticketFk => { Self.getPossibleStowaways = async ticketFk => {
let ship = await Self.app.models.Ticket.findById(ticketFk); let ship = await Self.app.models.Ticket.findById(ticketFk);
if (!ship || !ship.shipped)
return [];
let lowestDate = new Date(ship.shipped.getTime()); let lowestDate = new Date(ship.shipped.getTime());
lowestDate.setHours(0, 0, -1, 0); lowestDate.setHours(0, 0, -1, 0);

View File

@ -1,6 +1,6 @@
<vn-main-block> <vn-main-block>
<vn-side-menu side="left"> <vn-side-menu side="left">
<vn-ticket-descriptor ticket="$ctrl.ticket"></vn-ticket-descriptor> <vn-ticket-descriptor ticket="$ctrl.ticket" card-reload="$ctrl.reload()"></vn-ticket-descriptor>
<vn-left-menu></vn-left-menu> <vn-left-menu></vn-left-menu>
</vn-side-menu> </vn-side-menu>
<div class="content-block" ui-view></div> <div class="content-block" ui-view></div>

View File

@ -1,5 +1,5 @@
.container { .container {
font-family: verdana, sans-serif; font-family: arial, sans-serif;
font-size: 16px; font-size: 16px;
zoom: 0.55 zoom: 0.55
} }
@ -33,9 +33,18 @@
float: left float: left
} }
.clearfix {
overflow: hidden;
display: block;
clear: both
}
.row { .row {
white-space: nowrap; margin-bottom: 15px;
margin-bottom: 15px overflow: hidden;
display: block;
clear: both;
width: 100%
} }
.row.small { .row.small {
@ -52,13 +61,36 @@
box-sizing: border-box box-sizing: border-box
} }
.row:last-child {
margin-bottom: 0
}
.row.inline .text {
display: table-cell;
margin-bottom: 0;
width: 30%
}
.row.inline .control {
display: table-cell;
padding-left: 20px;
font-weight: bold;
color: #000;
width: 70%
}
.row.inline .description {
position: static;
overflow: visible
}
.row .description { .row .description {
position: relative; position: relative;
padding-top: 2px; padding-top: 2px;
overflow: hidden;
font-size: 9px; font-size: 9px;
overflow: hidden;
display: block; display: block;
color: #999 clear: both
} }
.row .line { .row .line {
@ -78,42 +110,17 @@
float: left float: left
} }
.row:last-child {
margin-bottom: 0
}
.row.inline .text {
display: inline-block;
margin-bottom: 0;
width: 40%;
}
.row.inline .control {
display: inline-block;
font-weight: bold;
padding-left: 20px;
color: #000;
width: 60%
}
.row.inline .description {
position: static;
overflow: visible
}
.panel { .panel {
position: relative position: relative
} }
.panel .header { .panel .header {
background-color: #FFF; background-color: #FFF;
position:absolute;
left: 17.5px;
top: -12px;
padding: 2.5px 5px; padding: 2.5px 5px;
position: absolute;
font-weight: bold; font-weight: bold;
left: 17.5px;
top: -12px
} }
.panel .body { .panel .body {
@ -127,22 +134,27 @@
margin-top: 0 margin-top: 0
} }
.box { .field {
border-top: 1px solid #CCC;
border-right: 1px solid #CCC;
border-bottom: 1px solid #CCC; border-bottom: 1px solid #CCC;
font-weight: bold; border-left: 1px solid #CCC;
text-align: center; border-top: 1px solid #CCC;
padding-top: 4px;
width: 25px;
height: 21px;
color: #000;
float: left float: left
} }
.box.crossed { .field span {
font-weight: 100; border-right: 1px solid #CCC;
font-size: 16px -webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
display: table-cell;
vertical-align: middle;
text-align: center;
font-weight: bold
}
.field.square span {
height: 35.4px;
width: 35.4px
} }
.pull-left { .pull-left {
@ -153,53 +165,89 @@
float: right float: right
} }
.verticalText { .vertical-text {
-moz-transform: rotate(90deg); -moz-transform: rotate(90deg);
-webkit-transform: rotate(90deg); -webkit-transform: rotate(90deg);
transform: rotate(90deg); transform: rotate(90deg);
position: absolute; position: absolute;
text-align: center; text-align: center;
font-size: .65em; font-size: .65em;
right: -108px;
width: 200px; width: 200px;
border: 2px solid #000;
right: -110px;
top: 50% top: 50%
} }
vn-table { table {
border-collapse: collapse; border-collapse: collapse;
margin: 20px 0; border-spacing: 0;
display: table;
width: 100%;
} }
vn-thead { .row-oriented, .column-oriented {
text-align: left;
width: 100%
}
.row-oriented .description,
.column-oriented .description {
font-size: 0.6em;
color: #888;
padding: 0 !important
}
.row-oriented .description .line,
.column-oriented .description .line {
border-bottom: 1px solid #DDD;
border-right: 1px solid #DDD;
border-left: 1px solid #DDD;
margin-top: 10px;
color: #999;
padding: 5px
}
.row-oriented .description span,
.column-oriented .description span {
background-color: #FFF;
margin: -5px 0 0 50px;
display: block;
padding: 5px;
float: left
}
.column-oriented {
margin: 20px 0
}
.column-oriented tfoot {
border-top: 1px solid #808080;
}
.column-oriented td, .column-oriented th {
padding: 5px 10px
}
.column-oriented thead {
background-color: #c0c0c0
}
.column-oriented thead tr {
border-bottom: 1px solid #808080; border-bottom: 1px solid #808080;
border-top: 1px solid #808080; border-top: 1px solid #808080;
display: table-header-group background-color: #c0c0c0
} }
vn-tbody { .column-oriented tfoot tr:first-child td {
border-top: 3px solid #888888; padding-top: 20px !important;
display: table-row-group
} }
vn-tfoot { .panel .row-oriented td, .panel .row-oriented th {
border-top: 1px solid #808080; padding: 10px 0
display: table-footer-group
} }
vn-tr { .row-oriented > tbody > tr > td {
display: table-row width: 30%
} }
vn-th { .row-oriented > tbody > tr > th {
font-weight: bold padding-left: 30px;
} width: 70%
vn-td, vn-th {
vertical-align: middle;
display: table-cell;
text-align: left;
padding: 5px 0
} }

View File

@ -10,6 +10,14 @@
text-align: right text-align: right
} }
.gray { .font.gray {
color: #555 color: #555
} }
.font.light-gray {
color: #888
}
.font.small {
font-size: 0.65em
}

View File

@ -5,8 +5,9 @@
{"type": "email", "name": "letter-debtor-st"}, {"type": "email", "name": "letter-debtor-st"},
{"type": "email", "name": "letter-debtor-nd"}, {"type": "email", "name": "letter-debtor-nd"},
{"type": "email", "name": "claim-pickup-order"}, {"type": "email", "name": "claim-pickup-order"},
{"type": "report", "name": "delivery-note"}, {"type": "email", "name": "sepa-core"},
{"type": "report", "name": "invoice"}, {"type": "report", "name": "rpt-delivery-note"},
{"type": "report", "name": "rpt-invoice"},
{"type": "report", "name": "rpt-claim-pickup-order"}, {"type": "report", "name": "rpt-claim-pickup-order"},
{"type": "report", "name": "rpt-letter-debtor"}, {"type": "report", "name": "rpt-letter-debtor"},
{"type": "report", "name": "rpt-sepa-core"}, {"type": "report", "name": "rpt-sepa-core"},

View File

@ -107,7 +107,7 @@ module.exports = {
format: 'A4', format: 'A4',
border: '1.5cm', border: '1.5cm',
footer: { footer: {
height: '80px', height: '60px',
} }
}; };

View File

@ -26,7 +26,7 @@
<p>{{$t('sections.howToBuy.stock')}}</p> <p>{{$t('sections.howToBuy.stock')}}</p>
<p>{{$t('sections.howToBuy.delivery')}}</p> --> <p>{{$t('sections.howToBuy.delivery')}}</p> -->
</section> </section>
<email-footer></email-footer> <email-footer :locale="locale"></email-footer>
</section> </section>
</body> </body>
</html> </html>

View File

@ -30,6 +30,7 @@ module.exports = {
}); });
}, },
created() { created() {
if (this.locale)
this.$i18n.locale = this.locale; this.$i18n.locale = this.locale;
}, },
methods: { methods: {

View File

@ -62,7 +62,7 @@
</section> </section>
</p> </p>
</section> </section>
<email-footer></email-footer> <email-footer :locale="locale"></email-footer>
</section> </section>
</body> </body>
</html> </html>

View File

@ -19,6 +19,7 @@ module.exports = {
}); });
}, },
created() { created() {
if (this.locale)
this.$i18n.locale = this.locale; this.$i18n.locale = this.locale;
}, },
methods: { methods: {

View File

@ -1,3 +0,0 @@
.blue {
color: blue
}

View File

@ -1,4 +0,0 @@
<div>
<span class="red">{{$t('clientId')}}: {{ id1 }} {{ id2 }}</span>
<span class="blue">heey</span>
</div>

View File

@ -1,35 +0,0 @@
const database = require(`${appPath}/lib/database`);
const UserException = require(`${appPath}/lib/exceptions/userException`);
module.exports = {
name: 'delivery-note',
async asyncData(ctx, params) {
const promises = [];
const dataIndex = promises.push(this.methods.fetchData()) - 1;
const itemsIndex = promises.push(this.methods.fetchItems()) - 1;
return Promise.all(promises).then(result => {
const [[data]] = result[dataIndex];
const [[items]] = result[itemsIndex];
return {
id1: data.id,
id2: items.id,
};
});
},
data() {
return {
id: null,
};
},
methods: {
fetchData() {
return database.pool.query('SELECT 1 AS id');
},
fetchItems() {
return database.pool.query('SELECT 2 AS id');
},
},
};

View File

@ -1,8 +0,0 @@
module.exports = {
messages: {
es: {
clientId: 'Id cliente',
},
},
}
;

View File

@ -6,6 +6,9 @@ module.exports = {
}; };
}, },
created() { created() {
if (this.locale)
this.$i18n.locale = this.locale;
const embeded = []; const embeded = [];
this.files.map(file => { this.files.map(file => {
const src = this.isPreview ? `/api/${file}` : `cid:${file}`; const src = this.isPreview ? `/api/${file}` : `cid:${file}`;
@ -27,4 +30,5 @@ module.exports = {
], ],
}; };
}, },
props: ['locale']
}; };

View File

@ -19,5 +19,24 @@ module.exports = {
escrito al domicilio social de la entidad. La finalidad del fichero es la gestión administrativa, contabilidad, y facturación.`, escrito al domicilio social de la entidad. La finalidad del fichero es la gestión administrativa, contabilidad, y facturación.`,
}, },
}, },
/* fr: {
buttons: {
webAcccess: 'Visitez notre site web',
info: 'Ayúdanos a mejorar',
},
privacy: {
fiscalAddress: 'VERDNATURA LEVANTE SL, B97367486 Avda. Espioca, 100, 46460 Silla · www.verdnatura.es · clientes@verdnatura.es',
disclaimer: `- AVISO - Ce message est privé et confidentiel et doit être utilisé.
exclusivamente por la persona destinataria del mismo. Si has recibido este mensaje
por error, te rogamos lo comuniques al remitente y borres dicho mensaje y cualquier documento
adjunto que pudiera contener. Verdnatura Levante SL no renuncia a la confidencialidad ni a
ningún privilegio por causa de transmisión errónea o mal funcionamiento. Igualmente no se hace
responsable de los cambios, alteraciones, errores u omisiones que pudieran hacerse al mensaje una vez enviado.`,
law: `En cumplimiento de lo dispuesto en la Ley Orgánica 15/1999, de Protección de Datos de Carácter Personal,
te comunicamos que los datos personales que facilites se incluirán en ficheros automatizados de VERDNATURA LEVANTE S.L.,
pudiendo en todo momento ejercitar los derechos de acceso, rectificación, cancelación y oposición, comunicándolo por
escrito al domicilio social de la entidad. La finalidad del fichero es la gestión administrativa, contabilidad, y facturación.`,
},
}, */
}, },
}; };

View File

@ -52,7 +52,7 @@
</p> </p>
</section> </section>
<!-- Footer component --> <!-- Footer component -->
<email-footer></email-footer> <email-footer :locale="locale"></email-footer>
<!-- End footer component --> <!-- End footer component -->
</section> </section>
</body> </body>

View File

@ -30,6 +30,7 @@ module.exports = {
}); });
}, },
created() { created() {
if (this.locale)
this.$i18n.locale = this.locale; this.$i18n.locale = this.locale;
}, },
methods: { methods: {

View File

@ -35,7 +35,7 @@
</p> </p>
</section> </section>
<!-- Footer component --> <!-- Footer component -->
<email-footer></email-footer> <email-footer :locale="locale"></email-footer>
<!-- End footer component --> <!-- End footer component -->
</section> </section>
</body> </body>

View File

@ -31,6 +31,7 @@ module.exports = {
}); });
}, },
created() { created() {
if (this.locale)
this.$i18n.locale = this.locale; this.$i18n.locale = this.locale;
}, },
methods: { methods: {

View File

@ -38,7 +38,7 @@
<p>{{ $t('notifyAnError') }}</p> <p>{{ $t('notifyAnError') }}</p>
</section> </section>
<!-- Footer component --> <!-- Footer component -->
<email-footer></email-footer> <email-footer :locale="locale"></email-footer>
<!-- End footer component --> <!-- End footer component -->
</section> </section>
</body> </body>

View File

@ -13,7 +13,7 @@ module.exports = {
if (!params.clientFk) if (!params.clientFk)
throw new UserException('No client id specified'); throw new UserException('No client id specified');
return this.methods.fetchClientData(params.clientFk) return this.methods.fetchClient(params.clientFk)
.then(([result]) => { .then(([result]) => {
if (!result) if (!result)
throw new UserException('No client data found'); throw new UserException('No client data found');
@ -21,10 +21,11 @@ module.exports = {
}); });
}, },
created() { created() {
if (this.locale)
this.$i18n.locale = this.locale; this.$i18n.locale = this.locale;
}, },
methods: { methods: {
fetchClientData(clientFk) { fetchClient(clientFk) {
return database.pool.query(` return database.pool.query(`
SELECT SELECT
u.lang locale, u.lang locale,

View File

@ -49,7 +49,7 @@
</p> </p>
</section> </section>
<!-- Footer component --> <!-- Footer component -->
<email-footer></email-footer> <email-footer :locale="locale"></email-footer>
<!-- End footer component --> <!-- End footer component -->
</section> </section>
</body> </body>

View File

@ -1,6 +1,4 @@
const database = require(`${appPath}/lib/database`); const database = require(`${appPath}/lib/database`);
const emailHeader = require('../email-header');
const emailFooter = require('../email-footer');
const UserException = require(`${appPath}/lib/exceptions/userException`); const UserException = require(`${appPath}/lib/exceptions/userException`);
module.exports = { module.exports = {
@ -13,7 +11,7 @@ module.exports = {
if (!params.clientFk) if (!params.clientFk)
throw new UserException('No client id specified'); throw new UserException('No client id specified');
return this.methods.fetchClientData(params.clientFk) return this.methods.fetchClient(params.clientFk)
.then(([result]) => { .then(([result]) => {
if (!result) if (!result)
throw new UserException('No client data found'); throw new UserException('No client data found');
@ -21,6 +19,7 @@ module.exports = {
}); });
}, },
created() { created() {
if (this.locale)
this.$i18n.locale = this.locale; this.$i18n.locale = this.locale;
}, },
data() { data() {
@ -29,7 +28,7 @@ module.exports = {
}; };
}, },
methods: { methods: {
fetchClientData(clientFk) { fetchClient(clientFk) {
return database.pool.query(` return database.pool.query(`
SELECT SELECT
c.id, c.id,
@ -47,7 +46,7 @@ module.exports = {
}, },
}, },
components: { components: {
'email-header': emailHeader, 'email-header': require('../email-header'),
'email-footer': emailFooter, 'email-footer': require('../email-footer'),
}, },
}; };

View File

@ -1,13 +1,12 @@
footer { footer {
font-family: verdana, sans-serif; font-family: verdana, sans-serif;
font-size: 12px; font-size: 0.55em;
color: #555; color: #555;
zoom: 0.55 zoom: 0.65
} }
footer, footer p { footer, footer p {
text-align: center; text-align: center
font-size: 12px
} }
footer .page { footer .page {

View File

@ -1,4 +1,8 @@
module.exports = { module.exports = {
name: 'report-footer', name: 'report-footer',
props: ['leftText', 'centerText'] created() {
if (this.locale)
this.$i18n.locale = this.locale;
},
props: ['leftText', 'centerText', 'locale']
}; };

View File

@ -3,7 +3,7 @@ header {
padding-bottom: 10px; padding-bottom: 10px;
margin-bottom: 40px; margin-bottom: 40px;
text-align: center; text-align: center;
font-size: 12px; font-size: 0.65em;
color: #555 color: #555
} }

View File

@ -1,6 +1,9 @@
module.exports = { module.exports = {
name: 'report-header', name: 'report-header',
created() { created() {
if (this.locale)
this.$i18n.locale = this.locale;
const embeded = []; const embeded = [];
this.files.map(file => { this.files.map(file => {
embeded[file] = `file://${__dirname + file}`; embeded[file] = `file://${__dirname + file}`;
@ -12,4 +15,5 @@ module.exports = {
files: ['/assets/images/report-logo.svg'], files: ['/assets/images/report-logo.svg'],
}; };
}, },
props: ['locale']
}; };

View File

@ -9,7 +9,7 @@
font-size: 2em font-size: 2em
} }
vn-table { table.column-oriented {
margin-top: 50px !important margin-top: 50px !important
} }

View File

@ -8,18 +8,22 @@
<section class="size50"> <section class="size50">
<section class="size75"> <section class="size75">
<h1 class="title uppercase">{{$t('title')}}</h1> <h1 class="title uppercase">{{$t('title')}}</h1>
<section class="row inline small"> <table class="row-oriented">
<section class="text uppercase gray">{{$t('claimId')}}:</section> <tbody>
<section class="control">{{claimId}}</section> <tr>
</section> <td class="font gray uppercase">{{$t('claimId')}}</td>
<section class="row inline small"> <th>{{claimId}}</th>
<section class="text uppercase gray">{{$t('clientId')}}:</section> </tr>
<section class="control">{{clientId}}</section> <tr>
</section> <td class="font gray uppercase">{{$t('clientId')}}</td>
<section class="row inline small"> <th>{{clientId}}</th>
<section class="text uppercase gray">{{$t('date')}}:</section> </tr>
<section class="control">{{dated()}}</section> <tr>
</section> <td class="font gray uppercase">{{$t('date')}}</td>
<th>{{dated()}}</th>
</tr>
</tbody>
</table>
</section> </section>
</section> </section>
<section class="size50"> <section class="size50">
@ -41,24 +45,24 @@
</section> </section>
</section> </section>
<vn-table> <table class="column-oriented">
<vn-thead> <thead>
<vn-tr> <tr>
<vn-th>{{$t('reference')}}</vn-th> <th>{{$t('reference')}}</th>
<vn-th>{{$t('quantity')}}</vn-th> <th>{{$t('quantity')}}</th>
<vn-th>{{$t('claims')}}</vn-th> <th>{{$t('claims')}}</th>
<vn-th>{{$t('concept')}}</vn-th> <th>{{$t('concept')}}</th>
</vn-tr> </tr>
</vn-thead> </thead>
<vn-tbody> <tbody>
<vn-tr v-for="sale in sales" :key="sale.id"> <tr v-for="sale in sales" :key="sale.id">
<vn-td class="gray">{{sale.id}}</vn-td> <td class="font gray">{{sale.id}}</td>
<vn-td>{{sale.quantity}}</vn-td> <td>{{sale.quantity}}</td>
<vn-td>{{sale.claimQuantity}}</vn-td> <td>{{sale.claimQuantity}}</td>
<vn-td>{{sale.concept}}</vn-td> <td>{{sale.concept}}</td>
</vn-tr> </tr>
</vn-tbody> </tbody>
</vn-table> </table>
<section class="panel sign"> <section class="panel sign">
<section class="body centered"> <section class="body centered">
@ -71,7 +75,8 @@
<report-footer id="pageFooter" <report-footer id="pageFooter"
:left-text="$t('claim', [claimId])" :left-text="$t('claim', [claimId])"
:center-text="clientName"> :center-text="clientName"
:locale="locale">
</report-footer> </report-footer>
</section> </section>
</body> </body>

View File

@ -27,6 +27,7 @@ module.exports = {
}); });
}, },
created() { created() {
if (this.locale)
this.$i18n.locale = this.locale; this.$i18n.locale = this.locale;
}, },
methods: { methods: {

View File

@ -0,0 +1,7 @@
const CssReader = require(`${appPath}/lib/cssReader`);
module.exports = new CssReader([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/misc.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -0,0 +1,14 @@
.container {
color: #000
}
.title {
font-weight: 100;
margin-top: 0;
margin-bottom: 20px;
font-size: 2em
}
table.column-oriented {
margin-top: 50px !important
}

View File

@ -0,0 +1,86 @@
<!DOCTYPE html>
<html lang="es">
<body>
<section class="container">
<report-header></report-header>
<section class="main">
<section class="columns">
<section class="size50">
<section class="size75">
<h1 class="title uppercase">{{$t('title')}}</h1>
<table class="row-oriented">
<tbody>
<tr>
<td class="font gray uppercase">{{$t('clientId')}}</td>
<th>{{clientId}}</th>
</tr>
<tr>
<td class="font gray uppercase">{{$t('ticketId')}}</td>
<th>{{ticketId}}</th>
</tr>
<tr>
<td class="font gray uppercase">{{$t('date')}}</td>
<th>{{dated()}}</th>
</tr>
</tbody>
</table>
</section>
</section>
<section class="size50">
<section class="panel">
<section class="header">{{$t('clientData')}}</section>
<section class="body">
<h3 class="uppercase">{{clientName}}</h3>
<section>
{{street}}
</section>
<section>
{{postcode}}, {{city}} ({{province}})
</section>
<section>
{{country}}
</section>
</section>
</section>
</section>
</section>
<table class="column-oriented">
<thead>
<tr>
<th>{{$t('date')}}</th>
<th>{{$t('concept')}}</th>
<th class="number">{{$t('invoiced')}}</th>
<th class="number">{{$t('payed')}}</th>
<th class="number">{{$t('balance')}}</th>
</tr>
</thead>
<tbody>
<tr v-for="sale in sales" :key="sale.id">
<td>{{toISOString(sale.issued)}}</td>
<td>{{sale.ref}}</td>
<td class="number">{{sale.debtOut}}</td>
<td class="number">{{sale.debtIn}}</td>
<td class="number">{{a}}</td>
</tr>
</tbody>
<tfoot>
<!-- <tr>
<td></td>
<td></td>
<td class="number"><strong class="pull-left">Total</strong> {{getTotalDebtOut()}}</td>
<td class="number">{{getTotalDebtIn()}}</td>
<td class="number">{{totalBalance}}</td>
</tr> -->
</tfoot>
</table>
</section>
<report-footer id="pageFooter"
:left-text="$t('ticket', [clientId])"
:center-text="clientName"
:locale="locale">
</report-footer>
</section>
</body>
</html>

View File

@ -0,0 +1,72 @@
const strftime = require('strftime');
const database = require(`${appPath}/lib/database`);
const UserException = require(`${appPath}/lib/exceptions/userException`);
module.exports = {
name: 'rpt-delivery-note',
async asyncData(ctx, params) {
const promises = [];
const data = {};
if (!params.ticketFk)
throw new UserException('No ticket id specified');
promises.push(this.methods.fetchClient(params.ticketFk));
// promises.push(this.methods.fetchSales(params.ticketFk));
return Promise.all(promises).then(result => {
const [[client]] = result[0];
// const [[sales]] = result[1];
if (!client)
throw new UserException('No client data found');
Object.assign(data, client);
return data;
});
},
created() {
if (this.locale)
this.$i18n.locale = this.locale;
},
data() {
return {totalBalance: 0.00};
},
methods: {
fetchClient(ticketFk) {
return database.pool.query(
`SELECT
c.id clientId,
u.lang locale,
c.email AS recipient,
c.socialName AS clientName,
c.street,
c.postcode,
c.city,
c.fi,
p.name AS province,
ct.country
FROM ticket t
JOIN client c ON c.id = t.clientFk
JOIN account.user u ON u.id = c.id
JOIN country ct ON ct.id = c.countryFk
LEFT JOIN province p ON p.id = c.provinceFk
WHERE t.id = ?`, [ticketFk]);
},
fetchSales(clientFk, companyFk) {
return database.pool.query(
`CALL vn.clientGetDebtDiary(?, ?)`, [clientFk, companyFk]);
},
dated: () => {
return strftime('%d-%m-%Y', new Date());
},
toISOString: date => {
return strftime('%d-%m-%Y', date);
},
},
components: {
'report-header': require('../report-header'),
'report-footer': require('../report-footer'),
},
};

View File

@ -0,0 +1,16 @@
module.exports = {
messages: {
es: {
title: 'Albarán',
ticketId: 'Albarán',
clientId: 'Cliente',
clientData: 'Datos del cliente',
date: 'Fecha',
concept: 'Concepto',
invoiced: 'Facturado',
payed: 'Pagado',
balance: 'Saldo',
ticket: 'Albarán {0}'
},
},
};

View File

@ -9,6 +9,6 @@
font-size: 2em font-size: 2em
} }
vn-table { table.column-oriented {
margin-top: 50px !important margin-top: 50px !important
} }

View File

@ -8,14 +8,18 @@
<section class="size50"> <section class="size50">
<section class="size75"> <section class="size75">
<h1 class="title uppercase">{{$t('title')}}</h1> <h1 class="title uppercase">{{$t('title')}}</h1>
<section class="row inline small"> <table class="row-oriented">
<section class="text uppercase gray">{{$t('clientId')}}:</section> <tbody>
<section class="control">{{clientId}}</section> <tr>
</section> <td class="font gray uppercase">{{$t('clientId')}}</td>
<section class="row inline small"> <th>{{clientId}}</th>
<section class="text uppercase gray">{{$t('date')}}:</section> </tr>
<section class="control">{{dated()}}</section> <tr>
</section> <td class="font gray uppercase">{{$t('date')}}</td>
<th>{{dated()}}</th>
</tr>
</tbody>
</table>
</section> </section>
</section> </section>
<section class="size50"> <section class="size50">
@ -37,40 +41,41 @@
</section> </section>
</section> </section>
<vn-table> <table class="column-oriented">
<vn-thead> <thead>
<vn-tr> <tr>
<vn-th>{{$t('date')}}</vn-th> <th>{{$t('date')}}</th>
<vn-th>{{$t('concept')}}</vn-th> <th>{{$t('concept')}}</th>
<vn-th class="number">{{$t('invoiced')}}</vn-th> <th class="number">{{$t('invoiced')}}</th>
<vn-th class="number">{{$t('payed')}}</vn-th> <th class="number">{{$t('payed')}}</th>
<vn-th class="number">{{$t('balance')}}</vn-th> <th class="number">{{$t('balance')}}</th>
</vn-tr> </tr>
</vn-thead> </thead>
<vn-tbody> <tbody>
<vn-tr v-for="sale in sales" :key="sale.id"> <tr v-for="sale in sales" :key="sale.id">
<vn-td>{{toISOString(sale.issued)}}</vn-td> <td>{{toISOString(sale.issued)}}</td>
<vn-td>{{sale.ref}}</vn-td> <td>{{sale.ref}}</td>
<vn-td class="number">{{sale.debtOut}}</vn-td> <td class="number">{{sale.debtOut}}</td>
<vn-td class="number">{{sale.debtIn}}</vn-td> <td class="number">{{sale.debtIn}}</td>
<vn-td class="number">{{getBalance(sale)}}</vn-td> <td class="number">{{getBalance(sale)}}</td>
</vn-tr> </tr>
</vn-tbody> </tbody>
<vn-tfoot> <tfoot>
<vn-tr> <tr>
<vn-td></vn-td> <td></td>
<vn-td><strong class="pull-right">Total</strong></vn-td> <td></td>
<vn-td class="number">{{getTotalDebtOut()}}</vn-td> <td class="number"><strong class="pull-left">Total</strong> {{getTotalDebtOut()}}</td>
<vn-td class="number">{{getTotalDebtIn()}}</vn-td> <td class="number">{{getTotalDebtIn()}}</td>
<vn-td class="number">{{totalBalance}}</vn-td> <td class="number">{{totalBalance}}</td>
</vn-tr> </tr>
</vn-tfoot> </tfoot>
</vn-table> </table>
</section> </section>
<report-footer id="pageFooter" <report-footer id="pageFooter"
:left-text="$t('client', [clientId])" :left-text="$t('client', [clientId])"
:center-text="clientName"> :center-text="clientName"
:locale="locale">
</report-footer> </report-footer>
</section> </section>
</body> </body>

View File

@ -30,6 +30,7 @@ module.exports = {
}); });
}, },
created() { created() {
if (this.locale)
this.$i18n.locale = this.locale; this.$i18n.locale = this.locale;
}, },
data() { data() {

View File

@ -3,12 +3,21 @@
} }
.title { .title {
margin-bottom: 10px;
font-weight: 100; font-weight: 100;
margin-top: 0; font-size: 1.5em;
margin-bottom: 20px; margin-top: 0
font-size: 2em
} }
vn-table { .payment-type {
margin-top: 50px !important width: auto
} }
.payment-type th:nth-child(2), .payment-type th:nth-child(5) {
padding: 10px !important
}
.payment-type th:nth-child(3){
padding: 0 50px !important
}

View File

@ -4,266 +4,146 @@
<section class="container"> <section class="container">
<report-header></report-header> <report-header></report-header>
<section class="main"> <section class="main">
<h1 class="title centered">{{$t('title')}}</h1>
<section class="panel supplierPanel"> <section class="panel supplierPanel">
<section class="body"> <section class="body">
<section class="verticalText">{{$t('supplier.toCompleteBySupplier')}}</section> <section class="vertical-text">
<section class="row inline"> {{$t('supplier.toCompleteBySupplier')}}
<section class="text">{{$t('supplier.orderReference')}}</section>
<section class="control">{{mandateCode}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.identifier')}}</section>
<section class="control">ES89000B97367486</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.name')}}</section>
<section class="control">{{supplierName}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.street')}}</section>
<section class="control">{{supplierStreet}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.location')}}</section>
<section class="control">{{supplierPostCode}}, {{supplierCity}} ({{supplierProvince}})</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.country')}}</section>
<section class="control">{{supplierCountry}}</section>
</section> </section>
<table class="row-oriented">
<tbody>
<tr>
<td>{{$t('supplier.orderReference')}}</td>
<th>{{mandateCode}}</td>
</tr>
<tr>
<td>{{$t('supplier.identifier')}}</td>
<th>ES89000B97367486</th>
</tr>
<tr>
<td>{{$t('supplier.name')}}</td>
<th>{{supplierName}}</th>
</tr>
<tr>
<td>{{$t('supplier.street')}}</td>
<th>{{supplierStreet}}</th>
</tr>
<tr>
<td>{{$t('supplier.location')}}</td>
<th>{{supplierPostCode}}, {{supplierCity}} ({{supplierProvince}})</th>
</tr>
<tr>
<td>{{$t('supplier.country')}}</td>
<th>{{supplierCountry}}</th>
</tr>
</tbody>
</table>
</section> </section>
</section> </section>
<section class="panel supplierPanel"> <p class="font small light-gray">{{$t('description')}}</p>
<section class="body"> <p class="font small">
<section class="verticalText">{{$t('supplier.toCompleteBySupplier')}}</section> <strong>{{$t('documentCopy')}}</strong>
<section class="row inline"> </p>
<section class="text">{{$t('supplier.orderReference')}}</section>
<section class="control">{{mandateCode}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.identifier')}}</section>
<section class="control">ES89000B97367486</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.name')}}</section>
<section class="control">{{supplierName}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.street')}}</section>
<section class="control">{{supplierStreet}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.location')}}</section>
<section class="control">{{supplierPostCode}}, {{supplierCity}} ({{supplierProvince}})</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.country')}}</section>
<section class="control">{{supplierCountry}}</section>
</section>
</section>
</section>
<section class="panel supplierPanel">
<section class="body">
<section class="verticalText">{{$t('supplier.toCompleteBySupplier')}}</section>
<section class="row inline">
<section class="text">{{$t('supplier.orderReference')}}</section>
<section class="control">{{mandateCode}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.identifier')}}</section>
<section class="control">ES89000B97367486</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.name')}}</section>
<section class="control">{{supplierName}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.street')}}</section>
<section class="control">{{supplierStreet}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.location')}}</section>
<section class="control">{{supplierPostCode}}, {{supplierCity}} ({{supplierProvince}})</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.country')}}</section>
<section class="control">{{supplierCountry}}</section>
</section>
</section>
</section>
<section class="panel supplierPanel">
<section class="body">
<section class="verticalText">{{$t('supplier.toCompleteBySupplier')}}</section>
<section class="row inline">
<section class="text">{{$t('supplier.orderReference')}}</section>
<section class="control">{{mandateCode}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.identifier')}}</section>
<section class="control">ES89000B97367486</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.name')}}</section>
<section class="control">{{supplierName}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.street')}}</section>
<section class="control">{{supplierStreet}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.location')}}</section>
<section class="control">{{supplierPostCode}}, {{supplierCity}} ({{supplierProvince}})</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.country')}}</section>
<section class="control">{{supplierCountry}}</section>
</section>
</section>
</section>
<section class="panel supplierPanel">
<section class="body">
<section class="verticalText">{{$t('supplier.toCompleteBySupplier')}}</section>
<section class="row inline">
<section class="text">{{$t('supplier.orderReference')}}</section>
<section class="control">{{mandateCode}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.identifier')}}</section>
<section class="control">ES89000B97367486</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.name')}}</section>
<section class="control">{{supplierName}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.street')}}</section>
<section class="control">{{supplierStreet}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.location')}}</section>
<section class="control">{{supplierPostCode}}, {{supplierCity}} ({{supplierProvince}})</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.country')}}</section>
<section class="control">{{supplierCountry}}</section>
</section>
</section>
</section>
<section class="panel supplierPanel">
<section class="body">
<section class="verticalText">{{$t('supplier.toCompleteBySupplier')}}</section>
<section class="row inline">
<section class="text">{{$t('supplier.orderReference')}}</section>
<section class="control">{{mandateCode}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.identifier')}}</section>
<section class="control">ES89000B97367486</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.name')}}</section>
<section class="control">{{supplierName}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.street')}}</section>
<section class="control">{{supplierStreet}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.location')}}</section>
<section class="control">{{supplierPostCode}}, {{supplierCity}} ({{supplierProvince}})</section>
</section>
<section class="row inline">
<section class="text">{{$t('supplier.country')}}</section>
<section class="control">{{supplierCountry}}</section>
</section>
</section>
</section>
<!-- <p class="font small">{{$t('bodyDescription}}</p>
<p class="font small"><strong>{{$t('clientAdvice}}</strong></p>
<section class="panel"> <section class="panel">
<section class="verticalText">{{$t('toCompleteByClient}}</section> <section class="body">
<section class="row inline"> <section class="vertical-text">
<section class="text">{{$t('clientName}}</section> {{$t('client.toCompleteByClient')}}
<section class="control">{{clientName}}</section>
<section class="description">{{$t('accountHolder}}</section>
</section> </section>
<section class="row inline">
<section class="text">{{$t('clientStreet}}</section> <table class="row-oriented">
<section class="control">{{clientStreet}}</section> <tbody>
<tr>
<td>
{{$t('client.name')}}
<section class="description">{{$t('client.accountHolder')}}</section>
</td>
<th>{{clientName}}</td>
</tr>
<tr>
<td>{{$t('client.street')}}</td>
<th>{{clientStreet}}</td>
</tr>
<tr>
<td>{{$t('client.location')}}</td>
<th>{{clientPostCode}}, {{clientCity}} ({{clientProvince}})</td>
</tr>
<tr>
<td>{{$t('client.country')}}</td>
<th>{{clientCountry}}</td>
</tr>
<tr>
<td>{{$t('client.swift')}}</td>
<th>
<section class="field square">
<span v-for="i in 11"></span>
</section> </section>
<section class="row inline"> </td>
<section class="text">{{$t('clientLocation}}</section> </tr>
<section class="control">{{clientPostCode}}, {{clientCity}} ({{clientProvince}})</section> <tr>
<td colspan="2">{{$t('client.accountNumber')}}</td>
</tr>
<tr>
<td colspan="2">
<section class="field square">
<span>E</span>
<span>S</span>
<span v-for="i in 22"></span>
</section> </section>
<section class="row inline"> </td>
<section class="text">{{$t('clientCountry}}</section> </tr>
<section class="control">{{clientCountry}}</section> <tr>
<td class="description" colspan="2">
<section class="line">
<span>{{$t('client.accountNumberFormat')}}</span>
</section> </section>
<section class="row inline"> </td>
<section class="text font verticalAlign">{{$t('swift}}</section> </tr>
<section class="control"> <tr>
{{#swiftFields}} <td>{{$t('client.paymentType')}}</td>
<section class="box"></section> <th>
{{/swiftFields}} <table class="payment-type">
<tr>
<td>
<section class="field square">
<span class="crossed">X</span>
</section>
</td>
<th>{{$t('client.recurrent')}}</th>
<th>O</th>
<td>
<section class="field square">
<span></span>
</section>
</td>
<th>{{$t('client.unique')}}</th>
</tr>
</table>
</td>
</tr>
<tr>
<td>{{$t('client.signLocation')}}</td>
<th>{{dated()}}, {{supplierProvince}}</td>
</tr>
<tr>
<td>{{$t('client.sign')}}</td>
<th></td>
</tr>
</tbody>
</table>
</section> </section>
</section> </section>
<section class="row">
<section class="text">{{$t('accountNumber}}</section> <p class="font small">{{$t('mandatoryFields')}}</p>
<section class="control"> <p class="font small">{{$t('sendOrder')}}</p>
<section class="box">ES</section>
{{#accountNumberFields}}
<section class="box"></section>
{{/accountNumberFields}}
</section>
<section class="description">
<section class="line"><span>{{$t('accountNumberFormat}}</span></section>
</section>
</section>
<section class="row inline">
<section class="text font verticalAlign">{{$t('paymentType}}</section>
<section class="control">
<section class="columns">
<section class="size33">
<section class="size25">
<section class="box crossed">X</section>
</section>
<section class="size25 font verticalAlign">{{$t('recurrent}}</section>
</section>
<section class="size33 font centered">O</section>
<section class="size33">
<section class="size25">
<section class="box"></section>
</section>
<section class="size25 font verticalAlign">{{$t('unique}}</section>
</section>
</section>
</section>
</section>
<section class="row inline">
<section class="text">{{$t('signLocation}}</section>
<section class="control">{{currentDate}}, {{supplierProvince}}</section>
</section>
<section class="row inline">
<section class="text">{{$t('sign}}</section>
<section class="control"></section>
</section>
</section>
<p class="font small">{{$t('mandatoryFields}}</p>
<p class="font small">{{$t('sendOrder}}</p> -->
</section> </section>
<report-footer id="pageFooter" <report-footer id="pageFooter"
:left-text="$t('client', [clientId])" :left-text="$t('order', [mandateCode])"
:center-text="clientName"> :center-text="clientName"
:locale="locale">
</report-footer> </report-footer>
</section> </section>
</body> </body>

View File

@ -2,6 +2,15 @@ module.exports = {
messages: { messages: {
es: { es: {
title: 'Orden de domiciliación de adeudo SEPA CORE', title: 'Orden de domiciliación de adeudo SEPA CORE',
description: `Mediante la firma de esta orden de domiciliación, el deudor autoriza (A) al acreedor a enviar instrucciones
a la entidad del deudor para adeudar su cuenta y (B) a la entidad para efectuar los adeudos en su cuenta siguiendo las
instrucciones del acreedor.Como parte de sus derechos, el deudor está legitimado al reembolso por su entidad en los
términos y condiciones del contrato suscrito con la misma. La solicitud de reembolso deberá efectuarse dentro de las
ocho semanas que adeudo en cuenta. Puede obtener información adicional sobre sus derechos en su entidad financiera.`,
documentCopy: `Debe llevar a su Entidad Bancaria una copia
del documento firmado para que lo registre y evitar la devolución.`,
mandatoryFields: `TODOS LOS CAMPOS HAN DE SER CUMPLIMENTADOS OBLIGATORIAMENTE.`,
sendOrder: `UNA VEZ FIRMADA ESTA ORDEN DE DOMICILIACIÓN DEBE SER ENVIADA AL ACREEDOR PARA SU CUSTODIA Y ES RECOMENDABLE FACILITAR UNA COPIA A SU ENTIDAD BANCARIA.`,
supplier: { supplier: {
toCompleteBySupplier: 'A cumplimentar por el acreedor', toCompleteBySupplier: 'A cumplimentar por el acreedor',
orderReference: 'Referencia de la orden de domiciliación', orderReference: 'Referencia de la orden de domiciliación',
@ -9,11 +18,25 @@ module.exports = {
name: 'Nombre del acreedor', name: 'Nombre del acreedor',
street: 'Dirección', street: 'Dirección',
location: 'CP - Población - Provincia', location: 'CP - Población - Provincia',
country: 'País', country: 'País'
}, },
client: { client: {
toCompleteByClient: 'A cumplimentar por el deudor', toCompleteByClient: 'A cumplimentar por el deudor',
name: 'Nombre del deudor/es',
street: 'Dirección del deudor',
location: 'CP - Población - Provincia',
country: 'País del deudor',
swift: 'Swift BIC',
accountNumber: 'Número de cuenta - IBAN',
accountHolder: '(Titular/es de la cuenta de cargo)',
accountNumberFormat: 'En España el IBAN consta de 24 posiciones comenzando siempre por ES',
paymentType: 'Tipo de pago',
recurrent: 'Recurrente',
unique: 'Único',
signLocation: 'Fecha - Localidad',
sign: 'Firma del deudor y sello',
}, },
order: 'Ord. domiciliación {0}',
}, },
}, },
}; };

View File

@ -0,0 +1,6 @@
const CssReader = require(`${appPath}/lib/cssReader`);
module.exports = new CssReader([
`${appPath}/common/css/layout.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -0,0 +1,40 @@
body {
background-color: #EEE
}
.container {
max-width: 600px;
min-width: 320px;
margin: 0 auto;
color: #555
}
.main {
background-color: #FFF;
padding: 20px
}
.main a {
color: #8dba25
}
.main h1 {
color: #999
}
.main h3 {
font-size: 16px
}
.title {
background-color: #95d831;
text-transform: uppercase;
text-align: center;
padding: 35px 0
}
.title h1 {
font-size: 32px;
color: #333;
margin: 0
}

View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="es">
<head>
<title>{{ $t('subject') }}</title>
</head>
<body>
<section class="container">
<!-- Header component -->
<email-header></email-header>
<!-- End header component -->
<section class="main">
<!-- Title block -->
<div class="title">
<h1>{{ $t('title') }}</h1>
</div>
<!-- Title block end -->
<p>{{$t('description.dear')}},</p>
<p>{{$t('description.instructions')}}</p>
<p>{{$t('description.conclusion')}}</p>
</section>
<!-- Footer component -->
<email-footer></email-footer>
<!-- End footer component -->
</section>
</body>
</html>

49
print/report/sepa-core/index.js Executable file
View File

@ -0,0 +1,49 @@
const database = require(`${appPath}/lib/database`);
const reportEngine = require(`${appPath}/lib/reportEngine.js`);
const UserException = require(`${appPath}/lib/exceptions/userException`);
module.exports = {
name: 'sepa-core',
async asyncData(ctx, params) {
const promises = [];
const data = {
isPreview: ctx.method === 'GET',
};
if (!params.clientFk)
throw new UserException('No client id specified');
promises.push(reportEngine.toPdf('rpt-sepa-core', ctx));
promises.push(this.methods.fetchClient(params.clientFk));
return Promise.all(promises).then(result => {
const stream = result[0];
const [[client]] = result[1];
Object.assign(data, client);
Object.assign(data, {attachments: [{filename: 'rpt-sepa-core.pdf', content: stream}]});
return data;
});
},
created() {
if (this.locale)
this.$i18n.locale = this.locale;
},
methods: {
fetchClient(clientFk) {
return database.pool.query(`
SELECT
u.lang locale,
c.email recipient
FROM client c
JOIN account.user u ON u.id = c.id
WHERE c.id = ?`, [clientFk]);
},
},
components: {
'email-header': require('../email-header'),
'email-footer': require('../email-footer'),
},
};

View File

@ -0,0 +1,16 @@
module.exports = {
messages: {
es: {
subject: 'Solicitud de domiciliación bancaria',
title: 'Domiciliación SEPA CORE',
description: {
dear: 'Estimado cliente',
instructions: `Para poder tramitar tu solicitud de cambio de tu forma de pago a giro bancario,
te adjuntamos los documentos correspondientes a la ley de pago, que tienes que cumplimentar y enviarnos.`,
conclusion: 'Gracias por tu atención.'
},
},
},
};

View File

@ -0,0 +1,18 @@
CREATE TABLE `salix`.`userTableConfiguration` (
`id` INT NOT NULL AUTO_INCREMENT,
`workerFk` INT(11) NOT NULL,
`tableCode` VARCHAR(255) NOT NULL,
`configuration` TEXT NULL,
PRIMARY KEY (`id`));
ALTER TABLE `salix`.`userTableConfiguration`
ADD INDEX `fgn_worker_idx` (`workerFk` ASC);
ALTER TABLE `salix`.`userTableConfiguration`
ADD CONSTRAINT `fgn_worker`
FOREIGN KEY (`workerFk`)
REFERENCES `vn2008`.`Trabajadores` (`Id_Trabajador`)
ON DELETE CASCADE
ON UPDATE CASCADE;

View File

@ -0,0 +1,2 @@
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (144, 'Stowaway', '*', '*', 'ALLOW', 'ROLE', 'employee');
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (145, 'Ticket', 'getPossibleStowaways', 'READ', 'ALLOW', 'ROLE', 'employee');