Merge branch 'dev' of http://git.verdnatura.es/salix into dev
|
@ -1,5 +1,5 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
import './style.scss';
|
|
||||||
export default class Controller {
|
export default class Controller {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.client = null;
|
this.client = null;
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
vn-main-block {
|
|
||||||
display:block;
|
|
||||||
max-width: 1920px;
|
|
||||||
width:100%;
|
|
||||||
margin: 0 auto;
|
|
||||||
|
|
||||||
.left-block {
|
|
||||||
min-width: 18em;
|
|
||||||
padding-left: 1em;
|
|
||||||
padding-bottom: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,7 +12,7 @@ export default class App {
|
||||||
this.$rootScope = $rootScope;
|
this.$rootScope = $rootScope;
|
||||||
}
|
}
|
||||||
show(message) {
|
show(message) {
|
||||||
if (this.snackbar) this.snackbar.show({message: message});
|
if (this.snackbar) this.snackbar.show({message: message, timeout: 400});
|
||||||
}
|
}
|
||||||
showMessage(message) {
|
showMessage(message) {
|
||||||
this.show(message);
|
this.show(message);
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import {module} from '../module';
|
||||||
|
|
||||||
|
const isFullEmpty = item => {
|
||||||
|
return (!item && item !== 0) || (typeof item === 'object' && !Object.keys(item).length);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default isFullEmpty;
|
||||||
|
export const NAME = 'isFullEmpty';
|
||||||
|
module.value(NAME, isFullEmpty);
|
|
@ -7,13 +7,18 @@ vn-textfield {
|
||||||
width: auto;
|
width: auto;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
right: -6px;
|
right: -6px;
|
||||||
margin: 22px 0px;
|
margin: 21px 0px;
|
||||||
background: transparent;
|
background: white;
|
||||||
|
opacity: 1;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
|
color: #aaa;
|
||||||
}
|
}
|
||||||
.material-icons {
|
.material-icons {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
.material-icons:hover {
|
||||||
|
color: rgba(0,0,0, .87);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@ import Component from '../lib/component';
|
||||||
import getModifiedData from '../lib/modified';
|
import getModifiedData from '../lib/modified';
|
||||||
import copyObject from '../lib/copy';
|
import copyObject from '../lib/copy';
|
||||||
import isEqual from '../lib/equals';
|
import isEqual from '../lib/equals';
|
||||||
|
import isFullEmpty from '../lib/fullEmpty';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that checks for changes on a specific model property and
|
* Component that checks for changes on a specific model property and
|
||||||
|
@ -95,7 +96,7 @@ export default class Watcher extends Component {
|
||||||
let changedData = getModifiedData(this.data, this.orgData);
|
let changedData = getModifiedData(this.data, this.orgData);
|
||||||
|
|
||||||
if (this.save) {
|
if (this.save) {
|
||||||
this.save.model = changedData;
|
this.save.model = this.copyInNewObject(changedData);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.save.accept().then(
|
this.save.accept().then(
|
||||||
json => this.writeData({data: json}, resolve),
|
json => this.writeData({data: json}, resolve),
|
||||||
|
@ -154,7 +155,7 @@ export default class Watcher extends Component {
|
||||||
if (data && typeof data === 'object') {
|
if (data && typeof data === 'object') {
|
||||||
Object.keys(data).forEach(
|
Object.keys(data).forEach(
|
||||||
val => {
|
val => {
|
||||||
if (data[val] !== "" && data[val] !== undefined && data[val] !== null) {
|
if (!isFullEmpty(data[val])) {
|
||||||
if (typeof data[val] === 'object') {
|
if (typeof data[val] === 'object') {
|
||||||
newCopy[val] = this.copyInNewObject(data[val]);
|
newCopy[val] = this.copyInNewObject(data[val]);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './src/item';
|
|
@ -0,0 +1,49 @@
|
||||||
|
{
|
||||||
|
"module": "item",
|
||||||
|
"name": "Items",
|
||||||
|
"icon": "/static/images/icon_item.png",
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"url": "/item",
|
||||||
|
"state": "item",
|
||||||
|
"abstract": true,
|
||||||
|
"component": "ui-view"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/list",
|
||||||
|
"state": "item.index",
|
||||||
|
"component": "vn-item-list"
|
||||||
|
}, {
|
||||||
|
"url": "/create",
|
||||||
|
"state": "item.create",
|
||||||
|
"component": "vn-item-create"
|
||||||
|
}, {
|
||||||
|
"url": "/:id",
|
||||||
|
"state": "item.card",
|
||||||
|
"abstract": true,
|
||||||
|
"component": "vn-item-card"
|
||||||
|
}, {
|
||||||
|
"url" : "/data",
|
||||||
|
"state": "item.card.data",
|
||||||
|
"component": "vn-item-data",
|
||||||
|
"params": {
|
||||||
|
"item": "$ctrl.item"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"description": "Basic data",
|
||||||
|
"icon": "folder"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"url" : "/image",
|
||||||
|
"state": "item.card.image",
|
||||||
|
"component": "vn-item-image",
|
||||||
|
"params": {
|
||||||
|
"item": "$ctrl.item"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"description": "Images",
|
||||||
|
"icon": "image"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<vn-main-block>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-auto class="left-block">
|
||||||
|
<vn-card margin-medium-v>
|
||||||
|
<a class="item-product-link pad-large text-center" ui-sref="item.index">
|
||||||
|
<b>{{$ctrl.item.name}}</b>
|
||||||
|
<img ng-src="http://verdnatura.es/vn-image-data/catalog/200x200/{{$ctrl.item.image}}" />
|
||||||
|
</a>
|
||||||
|
</vn-card>
|
||||||
|
<vn-left-menu></vn-left-menu>
|
||||||
|
</vn-auto>
|
||||||
|
<vn-one>
|
||||||
|
<vn-vertical margin-medium ui-view></vn-vertical>
|
||||||
|
</vn-one>
|
||||||
|
</vn-horizontal>
|
||||||
|
</vn-main-block>
|
|
@ -0,0 +1,32 @@
|
||||||
|
import ngModule from '../module';
|
||||||
|
|
||||||
|
class ItemCard {
|
||||||
|
constructor($http, $state) {
|
||||||
|
this.$http = $http;
|
||||||
|
this.$state = $state;
|
||||||
|
this.item = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
$onInit() {
|
||||||
|
let filter = {
|
||||||
|
include: [
|
||||||
|
{relation: "itemType"},
|
||||||
|
{relation: "origin"},
|
||||||
|
{relation: "ink"},
|
||||||
|
{relation: "producer"},
|
||||||
|
{relation: "intrastat"}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
this.$http.get(`/item/api/Items/${this.$state.params.id}?filter=${JSON.stringify(filter)}`).then(
|
||||||
|
res => {
|
||||||
|
this.item = res.data;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ItemCard.$inject = ['$http', '$state'];
|
||||||
|
|
||||||
|
ngModule.component('vnItemCard', {
|
||||||
|
template: require('./item-card.html'),
|
||||||
|
controller: ItemCard
|
||||||
|
});
|
|
@ -0,0 +1,66 @@
|
||||||
|
<mg-ajax path="/item/api/Items" options="vnPost"></mg-ajax>
|
||||||
|
<vn-watcher
|
||||||
|
vn-id="watcher"
|
||||||
|
data="$ctrl.item"
|
||||||
|
form="form"
|
||||||
|
save="post">
|
||||||
|
</vn-watcher>
|
||||||
|
<form name="form" ng-submit="$ctrl.onSubmit()" margin-medium>
|
||||||
|
<div style="max-width: 70em; margin: 0 auto;">
|
||||||
|
<vn-card>
|
||||||
|
<vn-vertical pad-large>
|
||||||
|
<vn-title>Create item</vn-title>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-one label="Size" field="$ctrl.item.size" vn-focus></vn-textfield>
|
||||||
|
<vn-textfield vn-five label="Category" field="$ctrl.item.category"></vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-one label="Stems" field="$ctrl.item.stems"></vn-textfield>
|
||||||
|
<vn-textfield vn-five label="Description" field="$ctrl.item.description"></vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/ItemTypes"
|
||||||
|
label="Type"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.item.typeFk"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/Inks"
|
||||||
|
label="Ink"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.item.inkFk"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/Origins"
|
||||||
|
label="Origin"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.item.originFk"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/Producers"
|
||||||
|
label="Producer"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.item.producerFk"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
</vn-vertical>
|
||||||
|
</vn-card>
|
||||||
|
<vn-button-bar>
|
||||||
|
<vn-submit label="Create"></vn-submit>
|
||||||
|
</vn-button-bar>
|
||||||
|
</div>
|
||||||
|
</form>
|
|
@ -0,0 +1,18 @@
|
||||||
|
import ngModule from '../module';
|
||||||
|
|
||||||
|
class ItemCreate {
|
||||||
|
constructor() {
|
||||||
|
this.item = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
this.$.watcher.submit().then(
|
||||||
|
json => this.$state.go('item.card.basic', {id: json.data.id})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngModule.component('vnItemCreate', {
|
||||||
|
template: require('./item-create.html'),
|
||||||
|
controller: ItemCreate
|
||||||
|
});
|
|
@ -0,0 +1,84 @@
|
||||||
|
|
||||||
|
<mg-ajax
|
||||||
|
path="/item/api/Items/{{patch.params.id}}"
|
||||||
|
options="vnPatch"
|
||||||
|
override="{filter: {include: [{relation: 'itemType'}, {relation: 'origin'}, {relation: 'ink'}, {relation: 'producer'}]}}"
|
||||||
|
>
|
||||||
|
</mg-ajax>
|
||||||
|
<vn-watcher
|
||||||
|
vn-id="watcher"
|
||||||
|
data="$ctrl.item"
|
||||||
|
form="form"
|
||||||
|
save="patch">
|
||||||
|
</vn-watcher>
|
||||||
|
<form name="form" ng-submit="watcher.submit()" ng-cloak>
|
||||||
|
<vn-card>
|
||||||
|
<vn-vertical pad-large>
|
||||||
|
<vn-title>Basic data</vn-title>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-three label="Name" field="$ctrl.item.name" vn-focus></vn-textfield>
|
||||||
|
<vn-textfield vn-one label="Size" field="$ctrl.item.size"></vn-textfield>
|
||||||
|
<vn-textfield vn-one label="Stems" field="$ctrl.item.stems"></vn-textfield>
|
||||||
|
<vn-textfield vn-one label="Category" field="$ctrl.item.category"></vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-one label="Description" field="$ctrl.item.description"></vn-textfield>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/Intrastats"
|
||||||
|
label="Intrastat"
|
||||||
|
show-field="description"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.item.intrastatFk"
|
||||||
|
initial-data="$ctrl.item.intrastat"
|
||||||
|
order = "description DESC"
|
||||||
|
filter-search="{where: {description: {regexp: 'search'}}}"
|
||||||
|
>
|
||||||
|
<tpl-item>{{$parent.$parent.item.description}}</tpl-item>
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/ItemTypes"
|
||||||
|
label="Type"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.item.typeFk"
|
||||||
|
initial-data="$ctrl.item.itemType"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/Inks"
|
||||||
|
label="Ink"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.item.inkFk"
|
||||||
|
initial-data="$ctrl.item.ink"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/Origins"
|
||||||
|
label="Origin"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.item.originFk"
|
||||||
|
initial-data="$ctrl.item.origin"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/Producers"
|
||||||
|
label="Producer"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.item.producer"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
</vn-vertical>
|
||||||
|
</vn-card>
|
||||||
|
<vn-button-bar>
|
||||||
|
<vn-submit label="Save"></vn-submit>
|
||||||
|
</vn-button-bar>
|
||||||
|
</form>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import ngModule from '../module';
|
||||||
|
|
||||||
|
ngModule.component('vnItemData', {
|
||||||
|
template: require('./item-data.html'),
|
||||||
|
bindings: {
|
||||||
|
item: '<'
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,58 @@
|
||||||
|
<div pad-large style="min-width: 30em">
|
||||||
|
<form ng-submit="$ctrl.onSearch()">
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-one label="Id" model="$ctrl.filter.id" vn-focus></vn-textfield>
|
||||||
|
<vn-textfield vn-three label="Description" model="$ctrl.filter.description"></vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
|
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-one label="Category" type="number" model="$ctrl.filter.category"></vn-textfield>
|
||||||
|
<vn-textfield vn-one label="Size" type="number" model="$ctrl.filter.itemSize"></vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
|
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/ItemTypes"
|
||||||
|
label="Type"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.filter.typeFk"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/Inks"
|
||||||
|
label="Ink"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.filter.inkFk"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/Origins"
|
||||||
|
label="Origin"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.filter.originFk"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
url="/item/api/Producers"
|
||||||
|
label="Producer"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
field="$ctrl.filter.producerFk"
|
||||||
|
>
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
|
||||||
|
|
||||||
|
<vn-horizontal margin-large-top>
|
||||||
|
<vn-submit label="Search"></vn-submit>
|
||||||
|
</vn-horizontal>
|
||||||
|
</form>
|
||||||
|
</div>
|
|
@ -0,0 +1,16 @@
|
||||||
|
import ngModule from '../module';
|
||||||
|
|
||||||
|
class ItemFilterPanel {
|
||||||
|
constructor() {
|
||||||
|
this.onSubmit = () => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
onSearch() {
|
||||||
|
this.onSubmit(this.filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngModule.component('vnItemFilterPanel', {
|
||||||
|
template: require('./filter-panel.html'),
|
||||||
|
controller: ItemFilterPanel
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"Ink": "Tinta",
|
||||||
|
"Origin": "Origen",
|
||||||
|
"Producer": "Productor"
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
export * from './module';
|
||||||
|
|
||||||
|
import './list/list';
|
||||||
|
import './filter-panel/filter-panel';
|
||||||
|
import './create/item-create';
|
||||||
|
import './card/item-card';
|
||||||
|
import './data/item-data';
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
<vn-horizontal pad-medium border-solid-bottom>
|
||||||
|
<vn-auto margin-medium-right ng-if="$ctrl.item.image">
|
||||||
|
<img ng-src="http://verdnatura.es/vn-image-data/catalog/200x200/{{$ctrl.item.image}}" />
|
||||||
|
</vn-auto>
|
||||||
|
<vn-one>
|
||||||
|
<div><span translate>Id</span>: <b>{{$ctrl.item.id}}</b></div>
|
||||||
|
<div><span translate>Name</span>: <b>{{$ctrl.item.name}}</b></div>
|
||||||
|
<div><span translate>Description</span>: <b>{{$ctrl.item.description}}</b></div>
|
||||||
|
<div><span translate>Size</span>: <b>{{$ctrl.item.size}}</b></div>
|
||||||
|
<div><span translate>Type</span>: <b>{{$ctrl.item.itemType.name}}</b></div>
|
||||||
|
</vn-one>
|
||||||
|
</vn-horizontal>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import ngModule from '../module';
|
||||||
|
|
||||||
|
ngModule.component('vnItemProduct', {
|
||||||
|
template: require('./item-product.html'),
|
||||||
|
bindings: {
|
||||||
|
item: '<'
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,26 @@
|
||||||
|
<mg-ajax path="/item/api/Items/filter" options="mgIndex"></mg-ajax>
|
||||||
|
<div margin-medium>
|
||||||
|
<div style="max-width: 40em; margin: 0 auto;">
|
||||||
|
<vn-card>
|
||||||
|
<vn-horizontal pad-medium>
|
||||||
|
<vn-searchbar vn-one
|
||||||
|
index="index"
|
||||||
|
on-search="$ctrl.search(index)"
|
||||||
|
advanced="true"
|
||||||
|
popover="vn-item-filter-panel"
|
||||||
|
ignore-keys = "['page', 'size', 'search']"
|
||||||
|
>
|
||||||
|
</vn-searchbar>
|
||||||
|
</vn-horizontal>
|
||||||
|
</vn-card>
|
||||||
|
<vn-card margin-medium-top>
|
||||||
|
<a class="item-product-link" ng-repeat="item in index.model.instances" ui-sref="item.card.data({ id: {{item.id}} })" >
|
||||||
|
<vn-item-product title="View item" item="item"></vn-item-product>
|
||||||
|
</a>
|
||||||
|
</vn-card>
|
||||||
|
<vn-paging index="index" total="index.model.count"></vn-paging>
|
||||||
|
</div>
|
||||||
|
<a ui-sref="item.create" fixed-bottom-right>
|
||||||
|
<vn-float-button icon="add"></vn-float-button>
|
||||||
|
</a>
|
||||||
|
</div>
|
|
@ -0,0 +1,17 @@
|
||||||
|
import ngModule from '../module';
|
||||||
|
import './item-product';
|
||||||
|
import './style.css';
|
||||||
|
|
||||||
|
class ItemList {
|
||||||
|
constructor() {
|
||||||
|
this.model = {};
|
||||||
|
}
|
||||||
|
search(index) {
|
||||||
|
index.accept();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngModule.component('vnItemList', {
|
||||||
|
template: require('./list.html'),
|
||||||
|
controller: ItemList
|
||||||
|
});
|
|
@ -0,0 +1,20 @@
|
||||||
|
vn-item-product {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
a.item-product-link {
|
||||||
|
display: block;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
a.item-product-link:hover {
|
||||||
|
color: white;
|
||||||
|
background-color: #424242;
|
||||||
|
}
|
||||||
|
|
||||||
|
vn-item-product img {
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vn-item-product-name {
|
||||||
|
font-family: vn-font-bold;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"Items": "Artículos",
|
||||||
|
"Item": "Artículo",
|
||||||
|
"Category": "Categoría",
|
||||||
|
"Description": "Descripción",
|
||||||
|
"Size": "Tamaño",
|
||||||
|
"Type": "Tipo"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import {ng} from 'vendor';
|
||||||
|
import 'core';
|
||||||
|
|
||||||
|
const ngModule = ng.module('item', ['vnCore']);
|
||||||
|
export default ngModule;
|
|
@ -5,5 +5,6 @@
|
||||||
"client": [],
|
"client": [],
|
||||||
"production": [],
|
"production": [],
|
||||||
"route": [],
|
"route": [],
|
||||||
"locator": []
|
"locator": [],
|
||||||
|
"item": []
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
"Production" : "Producción",
|
"Production" : "Producción",
|
||||||
"Modules access" : "Acceso a módulos",
|
"Modules access" : "Acceso a módulos",
|
||||||
"Locator": "Localizador",
|
"Locator": "Localizador",
|
||||||
|
"Items": "Artículos",
|
||||||
"name": "Nombre",
|
"name": "Nombre",
|
||||||
"credit": "Crédito",
|
"credit": "Crédito",
|
||||||
"phone": "Teléfono",
|
"phone": "Teléfono",
|
||||||
|
|
|
@ -43,3 +43,14 @@ export const locator = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
core.splitingRegister.register('locator', locator);
|
core.splitingRegister.register('locator', locator);
|
||||||
|
|
||||||
|
export const item = () => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
require.ensure([], () => {
|
||||||
|
require('item');
|
||||||
|
resolve('item');
|
||||||
|
}, 'item');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
core.splitingRegister.register('item', item);
|
||||||
|
|
|
@ -99,3 +99,17 @@ html [pointer], .pointer{
|
||||||
html [noDrop], .noDrop{
|
html [noDrop], .noDrop{
|
||||||
cursor: no-drop;
|
cursor: no-drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vn-main-block {
|
||||||
|
display:block;
|
||||||
|
max-width: 1920px;
|
||||||
|
width:100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
.left-block {
|
||||||
|
max-width: 20em;
|
||||||
|
min-width: 18em;
|
||||||
|
padding-left: 1em;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -87,7 +87,19 @@ services:
|
||||||
expose:
|
expose:
|
||||||
- "3006"
|
- "3006"
|
||||||
ports:
|
ports:
|
||||||
- "3006:3006"
|
- "3006:3006"
|
||||||
|
item:
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=${NODE_ENV}
|
||||||
|
container_name: "${BRANCH_NAME}-item"
|
||||||
|
image: "item:${TAG}"
|
||||||
|
build:
|
||||||
|
context: ./services
|
||||||
|
dockerfile: /item/Dockerfile
|
||||||
|
expose:
|
||||||
|
- "3007"
|
||||||
|
ports:
|
||||||
|
- "3007:3007"
|
||||||
nginx:
|
nginx:
|
||||||
container_name: "${BRANCH_NAME}-nginx"
|
container_name: "${BRANCH_NAME}-nginx"
|
||||||
image: "nginx:${TAG}"
|
image: "nginx:${TAG}"
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
FROM node:6.9.1
|
||||||
|
|
||||||
|
COPY item /app
|
||||||
|
|
||||||
|
COPY loopback /loopback
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
RUN npm -g install pm2
|
||||||
|
|
||||||
|
CMD ["pm2-docker", "./server/server.js"]
|
||||||
|
|
||||||
|
EXPOSE 3007
|
|
@ -0,0 +1,31 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.installMethod('filter', filterParams);
|
||||||
|
|
||||||
|
function filterParams(params) {
|
||||||
|
let filter = {
|
||||||
|
where: {},
|
||||||
|
skip: (params.page - 1) * params.size,
|
||||||
|
limit: params.size,
|
||||||
|
order: params.order || 'relevancy DESC',
|
||||||
|
include: {
|
||||||
|
relation: "itemType",
|
||||||
|
scope: {
|
||||||
|
fields: ["id", "name"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
delete params.page;
|
||||||
|
delete params.size;
|
||||||
|
delete params.order;
|
||||||
|
|
||||||
|
if (params.itemSize) {
|
||||||
|
filter.where.size = params.itemSize;
|
||||||
|
delete params.itemSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(filter.where, params);
|
||||||
|
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "Ink",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "ink",
|
||||||
|
"database": "vn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"showOrder": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"name": "Intrastat",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "intrastat",
|
||||||
|
"database": "vn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"taxGroup": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "TaxGroup",
|
||||||
|
"foreignKey": "taxGroupFk"
|
||||||
|
},
|
||||||
|
"taxCode": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "TaxCode",
|
||||||
|
"foreignKey": "taxCodeFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "ItemType",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "itemType",
|
||||||
|
"database": "vn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"life": {
|
||||||
|
"type": "Number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = function(Self) {
|
||||||
|
require('../methods/item/filter.js')(Self);
|
||||||
|
};
|
|
@ -0,0 +1,74 @@
|
||||||
|
{
|
||||||
|
"name": "Item",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "item",
|
||||||
|
"database": "vn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"category": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"stems": {
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"isOnOffer": {
|
||||||
|
"type": "Boolean"
|
||||||
|
},
|
||||||
|
"isBargain": {
|
||||||
|
"type": "Boolean"
|
||||||
|
},
|
||||||
|
"comment": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"relevancy": {
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"itemType": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "ItemType",
|
||||||
|
"foreignKey": "typeFk"
|
||||||
|
},
|
||||||
|
"ink": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Ink",
|
||||||
|
"foreignKey": "inkFk"
|
||||||
|
},
|
||||||
|
"origin": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Origin",
|
||||||
|
"foreignKey": "originFk"
|
||||||
|
},
|
||||||
|
"producer": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Producer",
|
||||||
|
"foreignKey": "producerFk"
|
||||||
|
},
|
||||||
|
"intrastat": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Intrastat",
|
||||||
|
"foreignKey": "intrastatFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "Origin",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "origin",
|
||||||
|
"database": "vn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"code": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"name": "Producer",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "producer",
|
||||||
|
"database": "vn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"name": "TaxCode",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "taxCode",
|
||||||
|
"database": "vn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"dated": {
|
||||||
|
"type": "date"
|
||||||
|
},
|
||||||
|
"code": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"rate": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"equalizationTax": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"isActive": {
|
||||||
|
"type": "Boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"taxType": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "TaxType",
|
||||||
|
"foreignKey": "taxTypeFk"
|
||||||
|
},
|
||||||
|
"link": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Link",
|
||||||
|
"foreignKey": "linkFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "TaxGroup",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "taxGroup",
|
||||||
|
"database": "vn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"code": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"name": "TaxType",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "taxType",
|
||||||
|
"database": "vn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"nickname": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"serial": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"TIPOOPE": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"country": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Country",
|
||||||
|
"foreignKey": "countryFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"name": "vn-item",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "server/server.js",
|
||||||
|
"scripts": {
|
||||||
|
"lint": "eslint .",
|
||||||
|
"start": "node .",
|
||||||
|
"posttest": "npm run lint && nsp check"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.verdnatura.es/salix"
|
||||||
|
},
|
||||||
|
"license": "GPL-3.0",
|
||||||
|
"description": "vn-item",
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": "^3.1.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"port": 3007
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"dataSource": "salix"
|
||||||
|
},
|
||||||
|
"AccessToken": {
|
||||||
|
"dataSource": "salix",
|
||||||
|
"relations": {
|
||||||
|
"user": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "user",
|
||||||
|
"foreignKey": "userId"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ACL": {
|
||||||
|
"dataSource": "salix"
|
||||||
|
},
|
||||||
|
"RoleMapping": {
|
||||||
|
"dataSource": "salix"
|
||||||
|
},
|
||||||
|
"Role": {
|
||||||
|
"dataSource": "salix"
|
||||||
|
},
|
||||||
|
"Account": {
|
||||||
|
"dataSource": "salix"
|
||||||
|
},
|
||||||
|
"Item": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"ItemType": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"Ink": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"Origin": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"Producer": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"Intrastat": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"TaxGroup": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"TaxCode": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"TaxType": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"Country": {
|
||||||
|
"dataSource": "salix"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
var vnLoopback = require('../../loopback/server/server.js');
|
||||||
|
|
||||||
|
var app = module.exports = vnLoopback.loopback();
|
||||||
|
vnLoopback.boot(app, __dirname, module);
|
|
@ -1,15 +1,20 @@
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var fs = require('fs');
|
let defaultFile = 'datasources.json';
|
||||||
var config = {};
|
|
||||||
|
|
||||||
let devConfigPath = path.join(__dirname, '/config/datasources.development.json');
|
function getFile(fileName) {
|
||||||
let configPath = path.join(__dirname, '/config/datasources.json');
|
return require(path.join(__dirname, `/config/${fileName}`));
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
config = Object.assign(require(configPath), require(devConfigPath));
|
let envFile = 'datasources.development.json';
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === 'test')
|
||||||
|
envFile = 'datasources.test.json';
|
||||||
|
|
||||||
|
config = getFile(envFile);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.code == 'MODULE_NOT_FOUND')
|
if (e.code == 'MODULE_NOT_FOUND')
|
||||||
config = require(configPath);
|
config = getFile(defaultFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
config.proxy = require('../../nginx/config.json');
|
config.proxy = require('../../nginx/config.json');
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
"debug": false,
|
"debug": false,
|
||||||
"defaultLanguage": "es",
|
"defaultLanguage": "es",
|
||||||
"senderMail": "noreply@localhost",
|
"senderMail": "noreply@localhost",
|
||||||
"senderName": ""
|
"senderName": "VerdNatura"
|
||||||
},
|
},
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 3306,
|
"port": 3306,
|
||||||
"user": "reports",
|
"user": "root",
|
||||||
"password": "",
|
"password": "",
|
||||||
"database": ""
|
"database": "vn"
|
||||||
},
|
},
|
||||||
"smtp": {
|
"smtp": {
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
|
|
|
@ -12,15 +12,17 @@ module.exports = {
|
||||||
* Load mail config.
|
* Load mail config.
|
||||||
*/
|
*/
|
||||||
init: function() {
|
init: function() {
|
||||||
|
|
||||||
this.transporter = nodemailer.createTransport(config.smtp);
|
this.transporter = nodemailer.createTransport(config.smtp);
|
||||||
|
|
||||||
this.transporter.verify(function(error, success) {
|
this.transporter.verify(function(error, success) {
|
||||||
if (error) {
|
if (error) {
|
||||||
throw new Error(error);
|
console.error(error);
|
||||||
} else if (config.app.debug) {
|
} else if (config.app.debug) {
|
||||||
console.log('SMTP connection stablished');
|
console.log('SMTP connection stablished');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,10 +4,15 @@ var config = require('../config.js');
|
||||||
var mail = require('../mail.js');
|
var mail = require('../mail.js');
|
||||||
var template = require('../template.js');
|
var template = require('../template.js');
|
||||||
var httpRequest = require('request');
|
var httpRequest = require('request');
|
||||||
|
var auth = require('../auth.js');
|
||||||
|
|
||||||
|
// Auth middleware
|
||||||
|
var requestToken = function(request, response, next) {
|
||||||
|
auth.init(request, response, next);
|
||||||
|
};
|
||||||
|
|
||||||
// Printer setup
|
// Printer setup
|
||||||
router.post('/printer-setup/:clientId', function(request, response) {
|
router.get('/printer-setup/:clientId', requestToken, function(request, response) {
|
||||||
mail.sendWithTemplate('printer-setup', {clientId: request.params.clientId}, error => {
|
mail.sendWithTemplate('printer-setup', {clientId: request.params.clientId}, error => {
|
||||||
if (error)
|
if (error)
|
||||||
return response.status(400).json({message: error.message});
|
return response.status(400).json({message: error.message});
|
||||||
|
@ -17,7 +22,7 @@ router.post('/printer-setup/:clientId', function(request, response) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Printer setup preview
|
// Printer setup preview
|
||||||
router.get('/printer-setup/:clientId', function(request, response) {
|
router.get('/printer-setup/:clientId/preview', requestToken, function(request, response) {
|
||||||
template.get('printer-setup', {clientId: request.params.clientId, isPreview: true}, (error, result) => {
|
template.get('printer-setup', {clientId: request.params.clientId, isPreview: true}, (error, result) => {
|
||||||
if (error)
|
if (error)
|
||||||
return response.status(400).json({message: error.message});
|
return response.status(400).json({message: error.message});
|
||||||
|
@ -27,7 +32,7 @@ router.get('/printer-setup/:clientId', function(request, response) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Client welcome
|
// Client welcome
|
||||||
router.post('/client-welcome/:clientId', function(request, response) {
|
router.get('/client-welcome/:clientId', requestToken, function(request, response) {
|
||||||
mail.sendWithTemplate('client-welcome', {clientId: request.params.clientId}, error => {
|
mail.sendWithTemplate('client-welcome', {clientId: request.params.clientId}, error => {
|
||||||
if (error)
|
if (error)
|
||||||
return response.status(400).json({message: error.message});
|
return response.status(400).json({message: error.message});
|
||||||
|
@ -37,7 +42,7 @@ router.post('/client-welcome/:clientId', function(request, response) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Client welcome preview
|
// Client welcome preview
|
||||||
router.get('/client-welcome/:clientId', function(request, response) {
|
router.get('/client-welcome/:clientId/preview', requestToken, function(request, response) {
|
||||||
template.get('client-welcome', {clientId: request.params.clientId, isPreview: true}, (error, result) => {
|
template.get('client-welcome', {clientId: request.params.clientId, isPreview: true}, (error, result) => {
|
||||||
if (error)
|
if (error)
|
||||||
return response.status(400).json({message: error.message});
|
return response.status(400).json({message: error.message});
|
||||||
|
@ -47,8 +52,13 @@ router.get('/client-welcome/:clientId', function(request, response) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Client SEPA CORE
|
// Client SEPA CORE
|
||||||
router.post('/sepa-core/:clientId', function(request, response) {
|
router.get('/sepa-core/:companyId/:clientId', requestToken, function(request, response) {
|
||||||
let path = `${request.proxyHost}/print/manuscript/sepa-core/${request.params.clientId}`;
|
let params = {
|
||||||
|
clientId: request.params.clientId,
|
||||||
|
companyId: request.params.companyId
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = `${request.proxyHost}/print/manuscript/sepa-core/${params.companyId}/${params.clientId}`;
|
||||||
let options = {
|
let options = {
|
||||||
url: path,
|
url: path,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
@ -59,25 +69,75 @@ router.post('/sepa-core/:clientId', function(request, response) {
|
||||||
|
|
||||||
let httpStream = httpRequest(options, function(error, httpResponse, body) {
|
let httpStream = httpRequest(options, function(error, httpResponse, body) {
|
||||||
if (error || httpResponse.statusCode != 200)
|
if (error || httpResponse.statusCode != 200)
|
||||||
return response.status(400).json({message: error.message});
|
return response.status(400).json({message: error});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (httpStream)
|
if (httpStream)
|
||||||
mail.sendWithTemplate('sepa-core', {
|
params.attachments = [{filename: 'sepa-core.pdf', content: httpStream}];
|
||||||
clientId: request.params.clientId,
|
|
||||||
attachments: [{filename: 'sepa-core.pdf', content: httpStream}]
|
mail.sendWithTemplate('sepa-core', params, error => {
|
||||||
}, error => {
|
if (error)
|
||||||
if (error)
|
return response.status(400).json({message: error.message});
|
||||||
return response.status(400).json({message: error.message});
|
|
||||||
|
return response.json();
|
||||||
return response.json();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Client SEPA CORE preview
|
// Client SEPA CORE preview
|
||||||
router.get('/sepa-core/:clientId', function(request, response) {
|
router.get('/sepa-core/:companyId/:clientId/preview', requestToken, function(request, response) {
|
||||||
template.get('sepa-core', {
|
let params = {
|
||||||
|
clientId: request.params.clientId,
|
||||||
|
companyId: request.params.companyId,
|
||||||
|
token: request.user.token,
|
||||||
|
isPreview: true
|
||||||
|
};
|
||||||
|
|
||||||
|
template.get('sepa-core', params, (error, result) => {
|
||||||
|
if (error)
|
||||||
|
return response.status(400).json({message: error.message});
|
||||||
|
|
||||||
|
response.send(result.body);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// First debtor letter
|
||||||
|
router.get('/letter-debtor-st/:companyId/:clientId', requestToken, function(request, response) {
|
||||||
|
let params = {
|
||||||
|
clientId: request.params.clientId,
|
||||||
|
companyId: request.params.companyId,
|
||||||
|
token: request.user.token
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = `${request.proxyHost}/print/manuscript/letter-debtor/${params.companyId}/${params.clientId}`;
|
||||||
|
let options = {
|
||||||
|
url: path,
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': request.headers.authorization
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let httpStream = httpRequest(options, function(error, httpResponse, body) {
|
||||||
|
if (error || httpResponse.statusCode != 200)
|
||||||
|
return response.status(400).json({message: error});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (httpStream)
|
||||||
|
params.attachments = [{filename: 'extracto.pdf', content: httpStream}];
|
||||||
|
|
||||||
|
mail.sendWithTemplate('letter-debtor-st', params, error => {
|
||||||
|
if (error)
|
||||||
|
return response.status(400).json({message: error.message});
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// First debtor letter preview
|
||||||
|
router.get('/letter-debtor-st/:companyId/:clientId/preview', requestToken, function(request, response) {
|
||||||
|
template.get('letter-debtor-st', {
|
||||||
clientId: request.params.clientId,
|
clientId: request.params.clientId,
|
||||||
|
companyId: request.params.companyId,
|
||||||
token: request.user.token,
|
token: request.user.token,
|
||||||
isPreview: true
|
isPreview: true
|
||||||
}, (error, result) => {
|
}, (error, result) => {
|
||||||
|
@ -88,6 +148,85 @@ router.get('/sepa-core/:clientId', function(request, response) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Second debtor letter
|
||||||
|
router.get('/letter-debtor-nd/:companyId/:clientId', requestToken, function(request, response) {
|
||||||
|
let params = {
|
||||||
|
clientId: request.params.clientId,
|
||||||
|
companyId: request.params.companyId,
|
||||||
|
token: request.user.token
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = `${request.proxyHost}/print/manuscript/letter-debtor/${params.companyId}/${params.clientId}`;
|
||||||
|
let options = {
|
||||||
|
url: path,
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': request.headers.authorization
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let httpStream = httpRequest(options, function(error, httpResponse, body) {
|
||||||
|
if (error || httpResponse.statusCode != 200)
|
||||||
|
return response.status(400).json({message: error});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (httpStream)
|
||||||
|
params.attachments = [{filename: 'extracto.pdf', content: httpStream}];
|
||||||
|
|
||||||
|
mail.sendWithTemplate('letter-debtor-nd', params, error => {
|
||||||
|
if (error)
|
||||||
|
return response.status(400).json({message: error.message});
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Second debtor letter preview
|
||||||
|
router.get('/letter-debtor-nd/:companyId/:clientId/preview', requestToken, function(request, response) {
|
||||||
|
template.get('letter-debtor-nd', {
|
||||||
|
clientId: request.params.clientId,
|
||||||
|
companyId: request.params.companyId,
|
||||||
|
token: request.user.token,
|
||||||
|
isPreview: true
|
||||||
|
}, (error, result) => {
|
||||||
|
if (error)
|
||||||
|
return response.status(400).json({message: error.message});
|
||||||
|
|
||||||
|
response.send(result.body);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Payment method changes
|
||||||
|
router.get('/payment-update/:clientId', requestToken, function(request, response) {
|
||||||
|
mail.sendWithTemplate('payment-update', {clientId: request.params.clientId}, error => {
|
||||||
|
if (error)
|
||||||
|
return response.status(400).json({message: error.message});
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Send notification to alias creditInsurance on client deactivate
|
||||||
|
router.get('/client-deactivate/:clientId', requestToken, function(request, response) {
|
||||||
|
var params = {
|
||||||
|
alias: 'creditInsurance',
|
||||||
|
code: 'clientDeactivate',
|
||||||
|
bodyParams: {
|
||||||
|
clientId: request.params.clientId
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mail.sendWithTemplate('notification-alias', params, error => {
|
||||||
|
if (error)
|
||||||
|
response.status(400).json({message: error.message});
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
|
|
||||||
|
|
||||||
// Single user notification
|
// Single user notification
|
||||||
/* router.post('/:recipient/noticeUserSend', function(request, response) {
|
/* router.post('/:recipient/noticeUserSend', function(request, response) {
|
||||||
var params = {
|
var params = {
|
||||||
|
@ -146,34 +285,4 @@ router.get('/sepa-core/:clientId', function(request, response) {
|
||||||
mail.sendWithTemplate('notification-notice', params, result => {
|
mail.sendWithTemplate('notification-notice', params, result => {
|
||||||
return response.json(result);
|
return response.json(result);
|
||||||
});
|
});
|
||||||
}); */
|
}); */
|
||||||
|
|
||||||
// Payment method changes
|
|
||||||
router.post('/payment-update/:clientId', function(request, response) {
|
|
||||||
mail.sendWithTemplate('payment-update', {clientId: request.params.clientId}, error => {
|
|
||||||
if (error)
|
|
||||||
return response.status(400).json({message: error.message});
|
|
||||||
|
|
||||||
return response.json();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Send notification to alias creditInsurance on client deactivate
|
|
||||||
router.post('/client-deactivate/:clientId', function(request, response) {
|
|
||||||
var params = {
|
|
||||||
alias: 'creditInsurance',
|
|
||||||
code: 'clientDeactivate',
|
|
||||||
bodyParams: {
|
|
||||||
clientId: request.params.clientId
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mail.sendWithTemplate('notification-alias', params, error => {
|
|
||||||
if (error)
|
|
||||||
response.status(400).json({message: error.message});
|
|
||||||
|
|
||||||
return response.json();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
|
|
@ -1,5 +1,7 @@
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = new express.Router();
|
var router = new express.Router();
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
// Mailer default page
|
// Mailer default page
|
||||||
router.get('/', function(request, response) {
|
router.get('/', function(request, response) {
|
||||||
|
@ -9,4 +11,20 @@ router.get('/', function(request, response) {
|
||||||
// Notifications
|
// Notifications
|
||||||
router.use('/notification', require('./route/notification.js'));
|
router.use('/notification', require('./route/notification.js'));
|
||||||
|
|
||||||
|
// Serve static images
|
||||||
|
router.use('/static/:template/:image', function(request, response) {
|
||||||
|
let imagePath = path.join(__dirname, '/template/', request.params.template, '/image/', request.params.image);
|
||||||
|
|
||||||
|
fs.stat(imagePath, function(error) {
|
||||||
|
if (error)
|
||||||
|
return response.json({message: 'Image not found'});
|
||||||
|
|
||||||
|
let readStream = fs.createReadStream(imagePath);
|
||||||
|
|
||||||
|
readStream.on('open', function() {
|
||||||
|
readStream.pipe(response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
|
@ -15,7 +15,7 @@ module.exports = {
|
||||||
get: function(template, params, cb) {
|
get: function(template, params, cb) {
|
||||||
var templatePath = path.join(__dirname, 'template', `${template}`, `index.html`);
|
var templatePath = path.join(__dirname, 'template', `${template}`, `index.html`);
|
||||||
var classPath = path.join(__dirname, 'template', `${template}`, `${template}.js`);
|
var classPath = path.join(__dirname, 'template', `${template}`, `${template}.js`);
|
||||||
var stylePath = path.join(__dirname, 'template', `${template}`, 'static', 'css', 'style.css');
|
var stylePath = path.join(__dirname, 'template', `${template}`, 'style.css');
|
||||||
|
|
||||||
fs.stat(templatePath, (error, stat) => {
|
fs.stat(templatePath, (error, stat) => {
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -65,6 +65,8 @@ module.exports = {
|
||||||
return cb(error);
|
return cb(error);
|
||||||
|
|
||||||
instance._ = result.locale;
|
instance._ = result.locale;
|
||||||
|
instance.isPreview = params.isPreview;
|
||||||
|
|
||||||
getDataCb(null, result);
|
getDataCb(null, result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -173,14 +175,17 @@ module.exports = {
|
||||||
|
|
||||||
// Template default attachments
|
// Template default attachments
|
||||||
for (var i = 0; i < tplAttachments.length; i++) {
|
for (var i = 0; i < tplAttachments.length; i++) {
|
||||||
let name = tplAttachments[i].replace('src="cid:', '').replace('"', '');
|
let src = tplAttachments[i].replace('src="cid:', '').replace('"', '').split('/');
|
||||||
|
let attachmentTpl = src[0];
|
||||||
|
let attachment = src[1];
|
||||||
|
|
||||||
if (isPreview) {
|
if (isPreview) {
|
||||||
let attachmentPath = `/mailer/static/images/${name}`;
|
let attachmentPath = `/mailer/static/${attachmentTpl}/${attachment}`;
|
||||||
body = body.replace(tplAttachments[i], `src="${attachmentPath}"`);
|
body = body.replace(tplAttachments[i], `src="${attachmentPath}"`);
|
||||||
} else {
|
} else {
|
||||||
let attachmentPath = path.join(__dirname, '../static', 'images', name);
|
let attachmentPath = path.join(__dirname, 'template', `${attachmentTpl}`, 'image', attachment);
|
||||||
attachments.push({filename: name, path: attachmentPath, cid: name});
|
let attachmentName = attachmentTpl + '/' + attachment;
|
||||||
|
attachments.push({filename: attachmentName, path: attachmentPath, cid: attachmentName});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,11 @@ module.exports = class ClientWelcome {
|
||||||
c.email recipient
|
c.email recipient
|
||||||
FROM client c
|
FROM client c
|
||||||
JOIN account.user u ON u.id = c.id
|
JOIN account.user u ON u.id = c.id
|
||||||
LEFT JOIN worker w ON w.id = c.workerFk
|
LEFT JOIN worker w ON w.id = c.salesPersonFk
|
||||||
LEFT JOIN account.user wu ON wu.id = w.userFk
|
LEFT JOIN account.user wu ON wu.id = w.userFk
|
||||||
JOIN country ct ON ct.id = c.countryFk
|
JOIN country ct ON ct.id = c.countryFk
|
||||||
WHERE c.id = ?`;
|
WHERE c.id = ?`;
|
||||||
|
|
||||||
database.pool.query(query, [params.clientId], (error, result) => {
|
database.pool.query(query, [params.clientId], (error, result) => {
|
||||||
if (error || result.length == 0)
|
if (error || result.length == 0)
|
||||||
return cb(new Error('No template data found'));
|
return cb(new Error('No template data found'));
|
||||||
|
|
|
@ -22,8 +22,9 @@
|
||||||
<p>{{_.dear}}</p>
|
<p>{{_.dear}}</p>
|
||||||
<p>{{{_.bodyDescription}}}</p>
|
<p>{{{_.bodyDescription}}}</p>
|
||||||
<p>
|
<p>
|
||||||
|
<div>{{_.clientNumber}} <strong>{{clientId}}</strong></div>
|
||||||
<div>{{_.user}} <strong>{{userName}}</strong></div>
|
<div>{{_.user}} <strong>{{userName}}</strong></div>
|
||||||
<div>{{_.password}} <strong>********</strong> {{_.passwordResetText}}</div>
|
<div>{{_.password}} <strong>********</strong> {{{_.passwordResetText}}}</div>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h1>{{_.sectionHowToBuyTitle}}</h1>
|
<h1>{{_.sectionHowToBuyTitle}}</h1>
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
"title": "¡LE DAMOS LA BIENVENIDA!",
|
"title": "¡LE DAMOS LA BIENVENIDA!",
|
||||||
"dear": "Estimado cliente,",
|
"dear": "Estimado cliente,",
|
||||||
"bodyDescription": "Sus datos para poder comprar en la web de verdnatura (<a href=\"https://www.verdnatura.es\" title=\"Visitar Verdnatura\" target=\"_blank\">https://www.verdnatura.es</a>) o en nuestras aplicaciones para <a href=\"https://goo.gl/3hC2mG\" title=\"App Store\" target=\"_blank\">iOS</a> y <a href=\"https://goo.gl/8obvLc\" title=\"Google Play\" target=\"_blank\">Android</a> (<a href=\"https://www.youtube.com/watch?v=gGfEtFm8qkw\" target=\"_blank\"><strong>Ver tutorial de uso</strong></a>), son:",
|
"bodyDescription": "Sus datos para poder comprar en la web de verdnatura (<a href=\"https://www.verdnatura.es\" title=\"Visitar Verdnatura\" target=\"_blank\">https://www.verdnatura.es</a>) o en nuestras aplicaciones para <a href=\"https://goo.gl/3hC2mG\" title=\"App Store\" target=\"_blank\">iOS</a> y <a href=\"https://goo.gl/8obvLc\" title=\"Google Play\" target=\"_blank\">Android</a> (<a href=\"https://www.youtube.com/watch?v=gGfEtFm8qkw\" target=\"_blank\"><strong>Ver tutorial de uso</strong></a>), son:",
|
||||||
|
"clientNumber": "Identificador de cliente:",
|
||||||
"user": "Usuario:",
|
"user": "Usuario:",
|
||||||
"password": "Contraseña:",
|
"password": "Contraseña:",
|
||||||
"passwordResetText": "(Va a recibir un correo para establecer la contraseña)",
|
"passwordResetText": "(<a href=\"https://verdnatura.es\">Haga clic en \"¿Has olvidado tu contraseña?\"</a>)",
|
||||||
"sectionHowToBuyTitle": "Cómo hacer un pedido",
|
"sectionHowToBuyTitle": "Cómo hacer un pedido",
|
||||||
"sectionHowToBuyDescription": "Para realizar un pedido en nuestra web, debe configurarlo indicando:",
|
"sectionHowToBuyDescription": "Para realizar un pedido en nuestra web, debe configurarlo indicando:",
|
||||||
"sectionHowToBuyRequeriment1": "Si quiere recibir el pedido (por agencia o por nuestro propio reparto) o si lo prefiere recoger en alguno de nuestros almacenes.",
|
"sectionHowToBuyRequeriment1": "Si quiere recibir el pedido (por agencia o por nuestro propio reparto) o si lo prefiere recoger en alguno de nuestros almacenes.",
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg fill="#000000" height="48" viewBox="0 0 24 24" width="48" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
|
||||||
|
<path d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 205 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<svg fill="#000000" height="48" viewBox="0 0 24 24" width="48" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<path d="M11.5 9C10.12 9 9 10.12 9 11.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5S12.88 9 11.5 9zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-3.21 14.21l-2.91-2.91c-.69.44-1.51.7-2.39.7C9.01 16 7 13.99 7 11.5S9.01 7 11.5 7 16 9.01 16 11.5c0 .88-.26 1.69-.7 2.39l2.91 2.9-1.42 1.42z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 461 B |
|
@ -5,7 +5,8 @@ var format = require(path.join(__dirname, '../../util/format.js'));
|
||||||
module.exports = class Footer {
|
module.exports = class Footer {
|
||||||
getData(params, cb) {
|
getData(params, cb) {
|
||||||
let query = `SELECT
|
let query = `SELECT
|
||||||
socialName
|
socialName,
|
||||||
|
LOWER(ct.code) countryCode
|
||||||
FROM client c
|
FROM client c
|
||||||
JOIN country ct ON ct.id = c.countryFk
|
JOIN country ct ON ct.id = c.countryFk
|
||||||
WHERE c.id = ?`;
|
WHERE c.id = ?`;
|
||||||
|
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
@ -2,10 +2,10 @@
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a href="https://www.verdnatura.es" target="_blank"><div class="btn">
|
<a href="https://www.verdnatura.es" target="_blank"><div class="btn">
|
||||||
<span class="text">{{_.actionButton}}</span>
|
<span class="text">{{_.actionButton}}</span>
|
||||||
<span class="icon"><img src="cid:action.png"/></span>
|
<span class="icon"><img src="cid:footer/action.png"/></span>
|
||||||
</div></a><a href="https://goo.gl/forms/j8WSL151ZW6QtlT72" target="_blank"><div class="btn">
|
</div></a><a href="https://goo.gl/forms/j8WSL151ZW6QtlT72" target="_blank"><div class="btn">
|
||||||
<span class="text">{{_.infoButton}}</span>
|
<span class="text">{{_.infoButton}}</span>
|
||||||
<span class="icon"><img src="cid:info.png"/></span>
|
<span class="icon"><img src="cid:footer/info.png"/></span>
|
||||||
</div></a>
|
</div></a>
|
||||||
</div>
|
</div>
|
||||||
<!-- Action button block -->
|
<!-- Action button block -->
|
||||||
|
@ -13,22 +13,22 @@
|
||||||
<!-- Networks block -->
|
<!-- Networks block -->
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<a href="https://www.facebook.com/Verdnatura" target="_blank">
|
<a href="https://www.facebook.com/Verdnatura" target="_blank">
|
||||||
<img src="cid:facebook.png" alt="Facebook"/>
|
<img src="cid:footer/facebook.png" alt="Facebook"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.twitter.com/Verdnatura" target="_blank">
|
<a href="https://www.twitter.com/Verdnatura" target="_blank">
|
||||||
<img src="cid:twitter.png" alt="Twitter"/>
|
<img src="cid:footer/twitter.png" alt="Twitter"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.youtube.com/Verdnatura" target="_blank">
|
<a href="https://www.youtube.com/Verdnatura" target="_blank">
|
||||||
<img src="cid:youtube.png" alt="Youtube"/>
|
<img src="cid:footer/youtube.png" alt="Youtube"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.pinterest.com/Verdnatura" target="_blank">
|
<a href="https://www.pinterest.com/Verdnatura" target="_blank">
|
||||||
<img src="cid:pinterest.png" alt="Pinterest"/>
|
<img src="cid:footer/pinterest.png" alt="Pinterest"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.instagram.com/Verdnatura" target="_blank">
|
<a href="https://www.instagram.com/Verdnatura" target="_blank">
|
||||||
<img src="cid:instagram.png" alt="Instagram"/>
|
<img src="cid:footer/instagram.png" alt="Instagram"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.linkedin.com/company/verdnatura" target="_blank">
|
<a href="https://www.linkedin.com/company/verdnatura" target="_blank">
|
||||||
<img src="cid:linkedin.png" alt="Linkedin"/>
|
<img src="cid:footer/linkedin.png" alt="Linkedin"/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<!-- Networks block end -->
|
<!-- Networks block end -->
|
||||||
|
|
|
@ -5,7 +5,8 @@ var format = require(path.join(__dirname, '../../util/format.js'));
|
||||||
module.exports = class Header {
|
module.exports = class Header {
|
||||||
getData(params, cb) {
|
getData(params, cb) {
|
||||||
let query = `SELECT
|
let query = `SELECT
|
||||||
c.name AS clientName
|
c.name AS clientName,
|
||||||
|
LOWER(ct.code) countryCode
|
||||||
FROM client c
|
FROM client c
|
||||||
JOIN country ct ON ct.id = c.countryFk
|
JOIN country ct ON ct.id = c.countryFk
|
||||||
WHERE c.id = ?`;
|
WHERE c.id = ?`;
|
||||||
|
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
@ -1,3 +1,3 @@
|
||||||
<div>
|
<div>
|
||||||
<a href="https://www.verdnatura.es"/><img src="cid:header.png" alt="VerdNatura"/></a>
|
<a href="https://www.verdnatura.es"/><img src="cid:header/logo.png" alt="VerdNatura"/></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
Before Width: | Height: | Size: 8.4 KiB |
|
@ -0,0 +1 @@
|
||||||
|
[]
|
|
@ -0,0 +1,87 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="es">
|
||||||
|
<head>
|
||||||
|
<title>{{_.subject}}</title>
|
||||||
|
<meta charset="utf8"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="container">
|
||||||
|
<!-- Header block -->
|
||||||
|
{{$.header}}
|
||||||
|
<!-- Header block end -->
|
||||||
|
|
||||||
|
<!-- Title block -->
|
||||||
|
<div class="title">
|
||||||
|
<h1>{{_.title}}</h1>
|
||||||
|
</div>
|
||||||
|
<!-- Title block end -->
|
||||||
|
|
||||||
|
<!-- Mail body block -->
|
||||||
|
<div class="body">
|
||||||
|
<p>{{_.dear}}</p>
|
||||||
|
|
||||||
|
<p>{{_.bodyDescription}}</p>
|
||||||
|
<p>{{_.termLimits}}</p>
|
||||||
|
<p>
|
||||||
|
{{_.payMethod}}
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>{{_.payMethodOption1}}</li>
|
||||||
|
<li>{{_.payMethodOption2}}</li>
|
||||||
|
</ol>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{_.legalActions}}
|
||||||
|
<ol type="a">
|
||||||
|
<li>{{_.legalActionsOption1}}</li>
|
||||||
|
<li>{{_.legalActionsOption2}}</li>
|
||||||
|
<li>{{_.legalActionsOption3}}</li>
|
||||||
|
</ol>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>{{_.contact}}</p>
|
||||||
|
|
||||||
|
<p>{{_.waitingForNews}}</p>
|
||||||
|
<p>{{_.conclusion}}</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="text">{{bankName}}</div>
|
||||||
|
<div class="control">{{iban}}</div>
|
||||||
|
<div class="description">
|
||||||
|
<div class="line"><span>{{_.accountTransferData}}</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{#isPreview}}
|
||||||
|
<a href="/print/manuscript/letter-debtor/{{companyId}}/{{clientId}}/preview?token={{token}}" target="_blank" title="Ver adjunto">
|
||||||
|
<div class="attachment">
|
||||||
|
<div class="attachment-icon">
|
||||||
|
<img src="cid:default/preview.svg" alt="Ver adjunto"/>
|
||||||
|
</div>
|
||||||
|
<span>Ver adjunto</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/print/manuscript/letter-debtor/{{companyId}}/{{clientId}}?token={{token}}" target="_blank" title="Descargar adjunto">
|
||||||
|
<div class="attachment">
|
||||||
|
<div class="attachment-icon">
|
||||||
|
<img src="cid:default/download.svg" alt="Descargar adjunto"/>
|
||||||
|
</div>
|
||||||
|
<span>Descargar PDF</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{/isPreview}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mail body block end -->
|
||||||
|
|
||||||
|
<!-- Footer block -->
|
||||||
|
{{$.footer}}
|
||||||
|
<!-- Footer block end -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,39 @@
|
||||||
|
var path = require('path');
|
||||||
|
var database = require(path.join(__dirname, '../../database.js'));
|
||||||
|
var format = require(path.join(__dirname, '../../util/format.js'));
|
||||||
|
|
||||||
|
module.exports = class LetterDebtorNd {
|
||||||
|
getData(params, cb) {
|
||||||
|
let query = `SELECT
|
||||||
|
sa.iban,
|
||||||
|
be.name AS bankName,
|
||||||
|
LOWER(ct.code) countryCode,
|
||||||
|
c.email recipient
|
||||||
|
FROM client c
|
||||||
|
JOIN company AS cny
|
||||||
|
JOIN supplierAccount AS sa ON sa.id = cny.supplierAccountFk
|
||||||
|
JOIN bankEntity be ON be.id = sa.bankEntityFk
|
||||||
|
JOIN country ct ON ct.id = c.countryFk
|
||||||
|
WHERE c.id = ? AND cny.id = ?`;
|
||||||
|
|
||||||
|
this.clientId = params.clientId;
|
||||||
|
this.companyId = params.companyId;
|
||||||
|
this.token = params.token;
|
||||||
|
|
||||||
|
database.pool.query(query, [params.clientId, params.companyId], (error, result) => {
|
||||||
|
if (error || result.length == 0)
|
||||||
|
return cb(new Error('No template data found'));
|
||||||
|
|
||||||
|
Object.assign(this, result[0]);
|
||||||
|
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get previewAttachments() {
|
||||||
|
if (this.isPreview)
|
||||||
|
return `<a href="/print/manuscript/letter-debtor/${this.companyId}/${this.clientId}/preview?token=${this.token}" target="_blank" title="Ver extracto.pdf">` +
|
||||||
|
'<div class="attachment"><div class="attachment-icon"><img src="cid:attachment.png" alt="Descargar adjunto"/></div>' +
|
||||||
|
'<span>extracto.pdf</span></div></a>';
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"subject": "Reiteración de aviso por saldo deudor",
|
||||||
|
"title": "AVISO REITERADO",
|
||||||
|
"dear": "Estimado cliente,",
|
||||||
|
"bodyDescription": "Nos dirigimos a Vd. nuevamente para informarle que sigue pendiente su deuda con nuestra empresa, tal y como puede comprobar en el extracto adjunto.",
|
||||||
|
"termLimits": "Dado que los plazos de pago acordados están ampliamente superados, no procede mayor dilación en la liquidación del importe adeudado.",
|
||||||
|
"payMethod": "Para ello dispone de las siguientes formas de pago:",
|
||||||
|
"payMethodOption1": "Pago online desde nuestra web",
|
||||||
|
"payMethodOption2": "Ingreso o transferencia al número de cuenta que detallamos al pie de esta carta, indicando el número de cliente.",
|
||||||
|
"legalActions": "En caso de no ser atendido este apremio de pago, nos veremos obligados a iniciar las acciones legales que procedan, entre las que están:",
|
||||||
|
"legalActionsOption1": "Inclusión en ficheros negativos sobre solvencia patrimonial y crédito.",
|
||||||
|
"legalActionsOption2": "Reclamación judicial",
|
||||||
|
"legalActionsOption3": "Cesión de deuda a una empresa de gestión de cobro",
|
||||||
|
"contact": "Para consultas, puede ponerse en contacto con nosotros en el 96 324 21 00.",
|
||||||
|
"waitingForNews": "En espera de sus noticias",
|
||||||
|
"conclusion": "Gracias por su atención.",
|
||||||
|
"accountTransferData": "Datos para transferencia bancaria"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
[]
|
|
@ -0,0 +1,69 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="es">
|
||||||
|
<head>
|
||||||
|
<title>{{_.subject}}</title>
|
||||||
|
<meta charset="utf8"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="container">
|
||||||
|
<!-- Header block -->
|
||||||
|
{{$.header}}
|
||||||
|
<!-- Header block end -->
|
||||||
|
|
||||||
|
<!-- Title block -->
|
||||||
|
<div class="title">
|
||||||
|
<h1>{{_.title}}</h1>
|
||||||
|
</div>
|
||||||
|
<!-- Title block end -->
|
||||||
|
|
||||||
|
<!-- Mail body block -->
|
||||||
|
<div class="body">
|
||||||
|
<p>{{_.dear}}</p>
|
||||||
|
|
||||||
|
<p>{{_.bodyDescription}}</p>
|
||||||
|
<p>{{_.viewExtract}}</p>
|
||||||
|
<p>{{_.validData}}</p>
|
||||||
|
<p>{{_.payMethod}}</p>
|
||||||
|
<p>{{_.conclusion}}</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="text">{{bankName}}</div>
|
||||||
|
<div class="control">{{iban}}</div>
|
||||||
|
<div class="description">
|
||||||
|
<div class="line"><span>{{_.accountTransferData}}</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{#isPreview}}
|
||||||
|
<a href="/print/manuscript/letter-debtor/{{companyId}}/{{clientId}}/preview?token={{token}}" target="_blank" title="Ver adjunto">
|
||||||
|
<div class="attachment">
|
||||||
|
<div class="attachment-icon">
|
||||||
|
<img src="cid:default/preview.svg" alt="Ver adjunto"/>
|
||||||
|
</div>
|
||||||
|
<span>Ver adjunto</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/print/manuscript/letter-debtor/{{companyId}}/{{clientId}}?token={{token}}" target="_blank" title="Descargar adjunto">
|
||||||
|
<div class="attachment">
|
||||||
|
<div class="attachment-icon">
|
||||||
|
<img src="cid:default/download.svg" alt="Descargar adjunto"/>
|
||||||
|
</div>
|
||||||
|
<span>Descargar PDF</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{/isPreview}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mail body block end -->
|
||||||
|
|
||||||
|
<!-- Footer block -->
|
||||||
|
{{$.footer}}
|
||||||
|
<!-- Footer block end -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,39 @@
|
||||||
|
var path = require('path');
|
||||||
|
var database = require(path.join(__dirname, '../../database.js'));
|
||||||
|
var format = require(path.join(__dirname, '../../util/format.js'));
|
||||||
|
|
||||||
|
module.exports = class LetterDebtorSt {
|
||||||
|
getData(params, cb) {
|
||||||
|
let query = `SELECT
|
||||||
|
sa.iban,
|
||||||
|
be.name AS bankName,
|
||||||
|
LOWER(ct.code) countryCode,
|
||||||
|
c.email recipient
|
||||||
|
FROM client c
|
||||||
|
JOIN company AS cny
|
||||||
|
JOIN supplierAccount AS sa ON sa.id = cny.supplierAccountFk
|
||||||
|
JOIN bankEntity be ON be.id = sa.bankEntityFk
|
||||||
|
JOIN country ct ON ct.id = c.countryFk
|
||||||
|
WHERE c.id = ? AND cny.id = ?`;
|
||||||
|
|
||||||
|
this.clientId = params.clientId;
|
||||||
|
this.companyId = params.companyId;
|
||||||
|
this.token = params.token;
|
||||||
|
|
||||||
|
database.pool.query(query, [params.clientId, params.companyId], (error, result) => {
|
||||||
|
if (error || result.length == 0)
|
||||||
|
return cb(new Error('No template data found'));
|
||||||
|
|
||||||
|
Object.assign(this, result[0]);
|
||||||
|
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get previewAttachments() {
|
||||||
|
if (this.isPreview)
|
||||||
|
return `<a href="/print/manuscript/letter-debtor/${this.companyId}/${this.clientId}/preview?token=${this.token}" target="_blank" title="Ver extracto.pdf">` +
|
||||||
|
'<div class="attachment"><div class="attachment-icon"><img src="cid:attachment.png" alt="Descargar adjunto"/></div>' +
|
||||||
|
'<span>extracto.pdf</span></div></a>';
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"subject": "Aviso inicial por saldo deudor",
|
||||||
|
"title": "AVISO INICIAL",
|
||||||
|
"dear": "Estimado cliente,",
|
||||||
|
"bodyDescription": "Por el presente escrito le comunicamos que, según nuestros datos contables, su cuenta tiene un saldo pendiente de liquidar.",
|
||||||
|
"viewExtract": "Le solicitamos compruebe que el extracto adjunto corresponde con los datos de que Vd. dispone. Nuestro departamento de administración le aclarará gustosamente cualquier duda que pueda tener, e igualmente le facilitará cualquier documento que solicite.",
|
||||||
|
"validData": "Si al comprobar los datos aportados resultaran correctos, le rogamos proceda a regularizar su situación.",
|
||||||
|
"payMethod": "Si no desea desplazarse personalmente hasta nuestras oficinas, puede realizar el pago mediante transferencia bancaria a la cuenta que figura al pie del comunicado, indicando su número de cliente, o bien puede realizar el pago online desde nuestra página web.",
|
||||||
|
"conclusion": "De antemano le agradecemos su amable colaboración.",
|
||||||
|
"accountTransferData": "Datos para transferencia bancaria"
|
||||||
|
}
|
|
@ -4,8 +4,7 @@ var format = require(path.join(__dirname, '../../util/format.js'));
|
||||||
|
|
||||||
module.exports = class PaymentUpdate {
|
module.exports = class PaymentUpdate {
|
||||||
getData(params, cb) {
|
getData(params, cb) {
|
||||||
let query = `SELECT
|
let query = `SELECT
|
||||||
c.id clientId,
|
|
||||||
pm.id payMethodFk,
|
pm.id payMethodFk,
|
||||||
pm.name payMethodName,
|
pm.name payMethodName,
|
||||||
c.dueDay,
|
c.dueDay,
|
||||||
|
@ -13,9 +12,12 @@ module.exports = class PaymentUpdate {
|
||||||
LOWER(ct.code) countryCode,
|
LOWER(ct.code) countryCode,
|
||||||
c.email recipient
|
c.email recipient
|
||||||
FROM client c
|
FROM client c
|
||||||
JOIN payMethod pm ON pm.id = c.paymentMethodFk
|
JOIN payMethod pm ON pm.id = c.payMethodFk
|
||||||
JOIN country ct ON ct.id = c.countryFk
|
JOIN country ct ON ct.id = c.countryFk
|
||||||
WHERE c.id = ?`;
|
WHERE c.id = ?`;
|
||||||
|
|
||||||
|
this.clientId = params.clientId;
|
||||||
|
|
||||||
database.pool.query(query, [params.clientId], (error, result) => {
|
database.pool.query(query, [params.clientId], (error, result) => {
|
||||||
if (error || result.length == 0)
|
if (error || result.length == 0)
|
||||||
return cb(new Error('No template data found'));
|
return cb(new Error('No template data found'));
|
||||||
|
|
|
@ -4,19 +4,21 @@ var format = require(path.join(__dirname, '../../util/format.js'));
|
||||||
|
|
||||||
module.exports = class PrinterSetup {
|
module.exports = class PrinterSetup {
|
||||||
getData(params, cb) {
|
getData(params, cb) {
|
||||||
let query = `SELECT
|
let query = `SELECT
|
||||||
c.id clientId,
|
|
||||||
CONCAT(w.name, ' ', w.firstName) name,
|
CONCAT(w.name, ' ', w.firstName) name,
|
||||||
w.phone AS phone,
|
w.phone AS phone,
|
||||||
CONCAT(u.name, '@verdnatura.es') AS email,
|
CONCAT(u.name, '@verdnatura.es') AS email,
|
||||||
LOWER(ct.code) countryCode,
|
LOWER(ct.code) countryCode,
|
||||||
c.email recipient
|
c.email recipient
|
||||||
FROM client c
|
FROM client c
|
||||||
LEFT JOIN worker w ON w.id = c.workerFk
|
LEFT JOIN worker w ON w.id = c.salesPersonFk
|
||||||
LEFT JOIN account.user u ON u.id = w.userFk
|
LEFT JOIN account.user u ON u.id = w.userFk
|
||||||
JOIN country ct ON ct.id = c.countryFk
|
JOIN country ct ON ct.id = c.countryFk
|
||||||
WHERE c.id = ?`;
|
WHERE c.id = ?`;
|
||||||
|
|
||||||
|
this.clientId = params.clientId;
|
||||||
|
this.isPreview = params.isPreview;
|
||||||
|
|
||||||
database.pool.query(query, [params.clientId], (error, result) => {
|
database.pool.query(query, [params.clientId], (error, result) => {
|
||||||
if (error || result.length == 0)
|
if (error || result.length == 0)
|
||||||
return cb(new Error('No template data found'));
|
return cb(new Error('No template data found'));
|
||||||
|
|
|
@ -22,7 +22,26 @@
|
||||||
<p>{{_.dear}}</p>
|
<p>{{_.dear}}</p>
|
||||||
<p>{{_.bodyDescription}}</p>
|
<p>{{_.bodyDescription}}</p>
|
||||||
<p>{{_.conclusion}}</p>
|
<p>{{_.conclusion}}</p>
|
||||||
{{{previewAttachments}}}
|
|
||||||
|
{{#isPreview}}
|
||||||
|
<a href="/print/manuscript/sepa-core/{{companyId}}/{{clientId}}/preview?token={{token}}" target="_blank" title="Ver adjunto">
|
||||||
|
<div class="attachment">
|
||||||
|
<div class="attachment-icon">
|
||||||
|
<img src="cid:default/preview.svg" alt="Ver adjunto"/>
|
||||||
|
</div>
|
||||||
|
<span>Ver adjunto</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/print/manuscript/sepa-core/{{companyId}}/{{clientId}}?token={{token}}" target="_blank" title="Descargar adjunto">
|
||||||
|
<div class="attachment">
|
||||||
|
<div class="attachment-icon">
|
||||||
|
<img src="cid:default/download.svg" alt="Descargar adjunto"/>
|
||||||
|
</div>
|
||||||
|
<span>Descargar PDF</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{/isPreview}}
|
||||||
</div>
|
</div>
|
||||||
<!-- Mail body block end -->
|
<!-- Mail body block end -->
|
||||||
|
|
||||||
|
|
|
@ -5,19 +5,19 @@ var format = require(path.join(__dirname, '../../util/format.js'));
|
||||||
module.exports = class SepaCore {
|
module.exports = class SepaCore {
|
||||||
getData(params, cb) {
|
getData(params, cb) {
|
||||||
let query = `SELECT
|
let query = `SELECT
|
||||||
c.id clientId,
|
|
||||||
CONCAT(w.name, ' ', w.firstName) name,
|
CONCAT(w.name, ' ', w.firstName) name,
|
||||||
w.phone AS phone,
|
w.phone AS phone,
|
||||||
CONCAT(u.name, '@verdnatura.es') AS email,
|
CONCAT(u.name, '@verdnatura.es') AS email,
|
||||||
LOWER(ct.code) countryCode,
|
LOWER(ct.code) countryCode,
|
||||||
c.email recipient
|
c.email recipient
|
||||||
FROM client c
|
FROM client c
|
||||||
LEFT JOIN worker w ON w.id = c.workerFk
|
LEFT JOIN worker w ON w.id = c.salesPersonFk
|
||||||
LEFT JOIN account.user u ON u.id = w.userFk
|
LEFT JOIN account.user u ON u.id = w.userFk
|
||||||
JOIN country ct ON ct.id = c.countryFk
|
JOIN country ct ON ct.id = c.countryFk
|
||||||
WHERE c.id = ?`;
|
WHERE c.id = ?`;
|
||||||
|
|
||||||
this.isPreview = params.isPreview;
|
this.clientId = params.clientId;
|
||||||
|
this.companyId = params.companyId;
|
||||||
this.token = params.token;
|
this.token = params.token;
|
||||||
|
|
||||||
database.pool.query(query, [params.clientId], (error, result) => {
|
database.pool.query(query, [params.clientId], (error, result) => {
|
||||||
|
@ -29,11 +29,4 @@ module.exports = class SepaCore {
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get previewAttachments() {
|
|
||||||
if (this.isPreview)
|
|
||||||
return `<a href="/print/manuscript/sepa-core/${this.clientId}/?token=${this.token}" target="_blank" title="Ver sepa-core.pdf">` +
|
|
||||||
'<div class="attachment"><div class="attachment-icon"><img src="cid:attachment.png" alt="Descargar adjunto"/></div>' +
|
|
||||||
'<span>sepa-core.pdf</span></div></a>';
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,13 +13,8 @@ app.use(bodyParser.urlencoded({extended: true}));
|
||||||
|
|
||||||
app.use('/static', express.static(path.join(__dirname, '../static')));
|
app.use('/static', express.static(path.join(__dirname, '../static')));
|
||||||
|
|
||||||
// Auth middleware
|
|
||||||
var requestToken = function(request, response, next) {
|
|
||||||
auth.init(request, response, next);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Load routes
|
// Load routes
|
||||||
app.use('/', requestToken, require('../application/router.js'));
|
app.use('/', require('../application/router.js'));
|
||||||
|
|
||||||
app.start = function() {
|
app.start = function() {
|
||||||
var listener = app.listen(config.app.port, function() {
|
var listener = app.listen(config.app.port, function() {
|
||||||
|
|
|
@ -1,137 +1,221 @@
|
||||||
img {
|
body {
|
||||||
margin: 0
|
padding: 0;
|
||||||
}
|
margin: 0
|
||||||
|
}
|
||||||
p {
|
|
||||||
text-align: justify
|
img {
|
||||||
}
|
margin: 0
|
||||||
|
}
|
||||||
.wrapper {
|
|
||||||
background-color: #EEE
|
p {
|
||||||
}
|
text-align: justify
|
||||||
|
}
|
||||||
.container {
|
|
||||||
font-family: arial, sans-serif;
|
.wrapper {
|
||||||
max-width: 600px;
|
background-color: #EEE
|
||||||
min-width: 320px;
|
}
|
||||||
font-size: 16px;
|
|
||||||
margin: 0 auto;
|
.container {
|
||||||
color: #555
|
font-family: arial, sans-serif;
|
||||||
}
|
max-width: 600px;
|
||||||
|
min-width: 320px;
|
||||||
.title {
|
font-size: 16px;
|
||||||
background-color: #95d831;
|
margin: 0 auto;
|
||||||
text-align: center;
|
color: #555
|
||||||
padding: 35px 0
|
}
|
||||||
}
|
|
||||||
|
.title {
|
||||||
.title h1 {
|
background-color: #95d831;
|
||||||
font-size: 32px;
|
text-align: center;
|
||||||
color: #333;
|
padding: 35px 0
|
||||||
margin: 0
|
}
|
||||||
}
|
|
||||||
|
.title h1 {
|
||||||
.body {
|
font-size: 32px;
|
||||||
background-color:#FFF;
|
color: #333;
|
||||||
padding: 20px
|
margin: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
.body a {
|
.body {
|
||||||
color: #8dba25
|
background-color:#FFF;
|
||||||
}
|
padding: 20px
|
||||||
|
}
|
||||||
.body h1 {
|
|
||||||
color: #999
|
.body a {
|
||||||
}
|
color: #8dba25
|
||||||
|
}
|
||||||
.body h3 {
|
|
||||||
font-size: 16px
|
.body h1 {
|
||||||
}
|
color: #999
|
||||||
|
}
|
||||||
.panel {
|
|
||||||
border: 1px solid #DDD;
|
.body h3 {
|
||||||
margin-bottom: 10px;
|
font-size: 16px
|
||||||
padding:10px
|
}
|
||||||
}
|
|
||||||
|
.panel {
|
||||||
.row {
|
border: 1px solid #DDD;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 10px;
|
||||||
overflow: hidden;
|
position: relative;
|
||||||
content: '';
|
padding:10px
|
||||||
clear: both
|
}
|
||||||
}
|
|
||||||
|
.row {
|
||||||
.row .text {
|
margin-bottom: 15px;
|
||||||
margin-bottom: 5px
|
overflow: hidden
|
||||||
}
|
}
|
||||||
|
|
||||||
.row .control {
|
.row .text {
|
||||||
-webkit-box-sizing: border-box;
|
margin-bottom: 5px
|
||||||
-moz-box-sizing: border-box;
|
}
|
||||||
box-sizing: border-box
|
|
||||||
}
|
.row .control {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
.row .description {
|
-moz-box-sizing: border-box;
|
||||||
font-size: 8px;
|
box-sizing: border-box
|
||||||
color: #999
|
}
|
||||||
}
|
|
||||||
|
.row .text, .row .control {
|
||||||
.row .v-align {
|
overflow: hidden
|
||||||
padding-top: 5px;
|
}
|
||||||
line-height: 21px
|
|
||||||
}
|
.row .description {
|
||||||
|
position: relative;
|
||||||
.row:last-child {
|
padding-top: 2px;
|
||||||
margin-bottom: 0
|
overflow: hidden;
|
||||||
}
|
font-size: 11px;
|
||||||
|
display: block;
|
||||||
.row.inline .text {
|
color: #999
|
||||||
margin-bottom: 0;
|
}
|
||||||
width: 40%;
|
|
||||||
float: left
|
.row .line {
|
||||||
}
|
border-bottom: 1px solid #DDD;
|
||||||
|
border-right: 1px solid #DDD;
|
||||||
.row.inline .control {
|
border-left: 1px solid #DDD;
|
||||||
font-weight: bold;
|
margin-top: 10px;
|
||||||
padding-left: 20px;
|
color: #999;
|
||||||
color: #000;
|
padding: 5px
|
||||||
width: 60%;
|
}
|
||||||
float: left
|
|
||||||
}
|
.row .description span {
|
||||||
|
background-color: #FFF;
|
||||||
.box {
|
margin: -5px 0 0 50px;
|
||||||
border-top: 1px solid #CCC;
|
display: block;
|
||||||
border-right: 1px solid #CCC;
|
padding: 5px;
|
||||||
border-bottom: 1px solid #CCC;
|
float: left
|
||||||
font-weight: bold;
|
}
|
||||||
text-align: center;
|
|
||||||
padding-top: 4px;
|
.row:last-child {
|
||||||
width: 25px;
|
margin-bottom: 0
|
||||||
height: 21px;
|
}
|
||||||
color: #000;
|
|
||||||
float: left
|
.row.inline .text {
|
||||||
}
|
margin-bottom: 0;
|
||||||
|
width: 40%;
|
||||||
.row .control .box:first-child {
|
float: left
|
||||||
border-left: 1px solid #CCC;
|
}
|
||||||
}
|
|
||||||
|
.row.inline .control {
|
||||||
.attachment {
|
font-weight: bold;
|
||||||
overflow: hidden;
|
padding-left: 20px;
|
||||||
margin-top: 10px
|
color: #000;
|
||||||
}
|
width: 60%;
|
||||||
|
float: left
|
||||||
.attachment:after {
|
}
|
||||||
content: ' ';
|
|
||||||
display: block;
|
.row.inline .description {
|
||||||
clear: both
|
position: static;
|
||||||
}
|
overflow: visible
|
||||||
|
}
|
||||||
.attachment-icon {
|
|
||||||
float: left
|
.box {
|
||||||
}
|
border-top: 1px solid #CCC;
|
||||||
|
border-right: 1px solid #CCC;
|
||||||
.attachment span {
|
border-bottom: 1px solid #CCC;
|
||||||
padding: 16px 0 0 10px;
|
font-weight: bold;
|
||||||
float: left
|
text-align: center;
|
||||||
|
padding-top: 4px;
|
||||||
|
width: 25px;
|
||||||
|
height: 21px;
|
||||||
|
color: #000;
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.box.crossed {
|
||||||
|
font-weight: 100;
|
||||||
|
font-size: 16px
|
||||||
|
}
|
||||||
|
|
||||||
|
.row .control .box:first-child {
|
||||||
|
border-left: 1px solid #CCC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font.small {
|
||||||
|
font-size: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.font.verticalAlign {
|
||||||
|
height: 27px;
|
||||||
|
line-height: 27px
|
||||||
|
}
|
||||||
|
|
||||||
|
.font.centered {
|
||||||
|
height: 27px;
|
||||||
|
line-height: 27px;
|
||||||
|
text-align: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.verticalText {
|
||||||
|
-moz-transform: rotate(90deg);
|
||||||
|
-webkit-transform: rotate(90deg);
|
||||||
|
transform: rotate(90deg);
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
font-size: .65em;
|
||||||
|
width: 200px;
|
||||||
|
right: -115px;
|
||||||
|
top: 50%
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment {
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-icon {
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment span {
|
||||||
|
padding: 16px 0 0 10px;
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns {
|
||||||
|
overflow: hidden
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns .size100 {
|
||||||
|
width: 100%;
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns .size75 {
|
||||||
|
width: 75%;
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns .size50 {
|
||||||
|
width: 50%;
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns .size33 {
|
||||||
|
width: 33.33%;
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns .size25 {
|
||||||
|
width: 25%;
|
||||||
|
float: left
|
||||||
}
|
}
|
Before Width: | Height: | Size: 18 KiB |
|
@ -46,6 +46,9 @@ http {
|
||||||
location ~ ^/print(?:/(.*))?$ {
|
location ~ ^/print(?:/(.*))?$ {
|
||||||
proxy_pass http://127.0.0.1:3006/$1$is_args$args;
|
proxy_pass http://127.0.0.1:3006/$1$is_args$args;
|
||||||
}
|
}
|
||||||
|
location ~ ^/item(?:/(.*))?$ {
|
||||||
|
proxy_pass http://127.0.0.1:3007/$1$is_args$args;
|
||||||
|
}
|
||||||
# Este tiene que ser el último
|
# Este tiene que ser el último
|
||||||
location ~ ^(?:/(.*))?$ {
|
location ~ ^(?:/(.*))?$ {
|
||||||
proxy_pass http://127.0.0.1:3001/$1$is_args$args;
|
proxy_pass http://127.0.0.1:3001/$1$is_args$args;
|
||||||
|
|
|
@ -41,6 +41,9 @@ http {
|
||||||
location ~ ^/print(?:/(.*))?$ {
|
location ~ ^/print(?:/(.*))?$ {
|
||||||
proxy_pass http://print:3006/$1$is_args$args;
|
proxy_pass http://print:3006/$1$is_args$args;
|
||||||
}
|
}
|
||||||
|
location ~ ^/item(?:/(.*))?$ {
|
||||||
|
proxy_pass http://item:3007/$1$is_args$args;
|
||||||
|
}
|
||||||
# Este tiene que ser el último
|
# Este tiene que ser el último
|
||||||
location ~ ^(?:/(.*))?$ {
|
location ~ ^(?:/(.*))?$ {
|
||||||
proxy_pass http://salix:3001/$1$is_args$args;
|
proxy_pass http://salix:3001/$1$is_args$args;
|
||||||
|
|
After Width: | Height: | Size: 2.9 KiB |
|
@ -1,15 +1,20 @@
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var fs = require('fs');
|
let defaultFile = 'datasources.json';
|
||||||
var config = {};
|
|
||||||
|
|
||||||
let devConfigPath = path.join(__dirname, '/config/datasources.development.json');
|
function getFile(fileName) {
|
||||||
let configPath = path.join(__dirname, '/config/datasources.json');
|
return require(path.join(__dirname, `/config/${fileName}`));
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
config = Object.assign(require(configPath), require(devConfigPath));
|
let envFile = 'datasources.development.json';
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === 'test')
|
||||||
|
envFile = 'datasources.test.json';
|
||||||
|
|
||||||
|
config = getFile(envFile);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.code == 'MODULE_NOT_FOUND')
|
if (e.code == 'MODULE_NOT_FOUND')
|
||||||
config = require(configPath);
|
config = getFile(defaultFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
config.proxy = require('../../nginx/config.json');
|
config.proxy = require('../../nginx/config.json');
|
||||||
|
|