Merge branch 'dev' of https://git.verdnatura.es/salix into dev

This commit is contained in:
SAMBA\bernat 2018-02-09 14:45:29 +01:00
commit b2edcaf472
31 changed files with 3032 additions and 1149 deletions

View File

@ -121,7 +121,8 @@
"menu": {
"description": "Credit",
"icon": "credit_card"
}
},
"acl": ["manager", "salesAssistant", "teamBoss", "teamManager"]
}, {
"url": "/create",
"state": "clientCard.credit.create",

View File

@ -3,9 +3,10 @@
url="/client/api/Addresses"
id-field="id"
data="$ctrl.address"
save="post"
form="form">
</vn-watcher>
<form name="form" ng-submit="watcher.submitGo('clientCard.addresses')" pad-medium>
<form name="form" ng-submit="watcher.submitGo('clientCard.addresses.list')" pad-medium>
<vn-card >
<vn-vertical pad-large>
<vn-title>Address</vn-title>

View File

@ -11,7 +11,15 @@
<vn-horizontal style="align-items: center;">
<vn-none pad-medium-h style="color:#FFA410;">
<i class="material-icons" ng-if="address.isDefaultAddress">star</i>
<i class="material-icons pointer" ng-if="!address.isDefaultAddress" vn-tooltip="Set as default" tooltip-position="left" ng-click="$ctrl.setDefault(address.id)">star_border</i>
<i class="material-icons"
vn-tooltip="Active first to set as default"
tooltip-position="left"
ng-if="!address.isActive">star_border</i>
<i class="material-icons pointer"
ng-if="address.isActive && !address.isDefaultAddress"
vn-tooltip="Set as default"
tooltip-position="left"
ng-click="$ctrl.setDefault(address)">star_border</i>
</vn-none>
<vn-one border-solid-right>
<div><b>{{::address.nickname}}</b></div>

View File

@ -5,11 +5,13 @@ class ClientAddresses {
this.$http = $http;
this.$scope = $scope;
}
setDefault(id) {
let params = {isDefaultAddress: true};
this.$http.patch(`/client/api/Addresses/${id}`, params).then(
() => this.$scope.index.accept()
);
setDefault(address) {
if (address.isActive) {
let params = {isDefaultAddress: true};
this.$http.patch(`/client/api/Addresses/${address.id}`, params).then(
() => this.$scope.index.accept()
);
}
}
}
ClientAddresses.$inject = ['$http', '$scope'];

View File

@ -1 +1,2 @@
Set as default: Establecer como predeterminado
Set as default: Establecer como predeterminado
Active first to set as default: Active primero para marcar como predeterminado

View File

@ -1,9 +1,7 @@
import ngModule from '../module';
import FilterClientList from '../filterClientList';
class ClientCreditList extends FilterClientList {}
ngModule.component('vnClientCreditList', {
template: require('./credit-list.html'),
controller: ClientCreditList
controller: FilterClientList
});

View File

@ -1,40 +1,8 @@
// Generic object to list models, related to the client, with mgCrud
export default class FilterClientList {
import FilterList from '../../core/src/lib/filterList';
export default class FilterClientList extends FilterList {
constructor($scope, $timeout, $state) {
this.$ = $scope;
this.$timeout = $timeout;
this.$state = $state;
this.waitingMgCrud = 0;
this.clientFk = $state.params.id;
}
onOrder(field, order) {
this.filter(`${field} ${order}`);
}
filter(order) {
if (this.$.index && this.clientFk) {
this.waitingMgCrud = 0;
this.$.index.filter = {
page: 1,
size: 10,
clientFk: this.clientFk
};
if (order) {
this.$.index.filter.order = order;
}
this.$.index.accept();
} else if (!this.clientFk) {
throw new Error('Error: ClientFk not found');
} else if (this.waitingMgCrud > 3) {
throw new Error('Error: Magic Crud is not loaded');
} else {
this.waitingMgCrud++;
this.$timeout(() => {
this.filter(order);
}, 250);
}
super($scope, $timeout, $state);
this.modelName = 'clientFk';
}
}
FilterClientList.$inject = ['$scope', '$timeout', '$state'];

View File

@ -1,9 +1,7 @@
import ngModule from '../module';
import FilterClientList from '../filterClientList';
class ClientGreugeList extends FilterClientList {}
ngModule.component('vnClientGreugeList', {
template: require('./greuge-list.html'),
controller: ClientGreugeList
controller: FilterClientList
});

View File

@ -3,6 +3,7 @@
url="/client/api/ClientObservations"
id-field="id"
data="$ctrl.note"
save="post"
form="form">
</vn-watcher>
<form name="form" ng-submit="watcher.submitGo('clientCard.notes.list')" pad-medium>

View File

@ -0,0 +1,40 @@
// Generic object to list models
export default class FilterList {
constructor($scope, $timeout, $state) {
this.$ = $scope;
this.$timeout = $timeout;
this.$state = $state;
this.waitingMgCrud = 0;
this.modelId = $state.params.id;
}
onOrder(field, order) {
this.filter(`${field} ${order}`);
}
filter(order) {
if (this.$.index && this.modelId && this.modelName) {
this.waitingMgCrud = 0;
this.$.index.filter = {
page: 1,
size: 10
};
this.$.index.filter[this.modelName] = this.modelId;
if (order) {
this.$.index.filter.order = order;
}
this.$.index.accept();
} else if (!this.modelId || !this.modelName) {
throw new Error('Error: model not found');
} else if (this.waitingMgCrud > 3) {
throw new Error('Error: Magic Crud is not loaded');
} else {
this.waitingMgCrud++;
this.$timeout(() => {
this.filter(order);
}, 250);
}
}
}

View File

@ -6,6 +6,7 @@ import './app';
import './interceptor';
import './aclService';
import './storageServices';
import './filterList';
export * from './util';
export {default as splitingRegister} from './splitingRegister';

View File

@ -47,7 +47,7 @@ export default class Watcher extends Component {
fetchData() {
let id = this.data[this.idField];
// return new Promise((resolve, reject) => {
// return new Promise((resolve, reject) => {
this.$http.get(`${this.url}/${id}`).then(
json => {
this.data = copyObject(json.data);
@ -55,26 +55,33 @@ export default class Watcher extends Component {
}
// json => reject(json)
);
// });
// });
}
/**
* Submits the data and goes back in the history.
*
* @return {Promise} The request promise
*/
submitBack() {
return this.submit().then(
() => this.window.history.back()
);
}
/**
* Submits the data and goes another state.
*
* @param {String} state The state name
* @param {Object} params The request params
* @return {Promise} The request promise
*/
submitGo(state, params) {
return this.submit().then(
() => this.$state.go(state, params || {})
);
}
/**
* Submits the data to the server.
*
@ -94,7 +101,9 @@ export default class Watcher extends Component {
(resolve, reject) => this.noChanges(reject)
);
}
let changedData = (this.$attrs.save && this.$attrs.save.toLowerCase() === 'post') ? this.copyInNewObject(this.data) : getModifiedData(this.data, this.orgData);
let changedData = (this.$attrs.save && this.$attrs.save.toLowerCase() === 'post')
? this.copyInNewObject(this.data)
: getModifiedData(this.data, this.orgData);
if (this.save && this.save.accept) {
this.save.model = changedData; // this.copyInNewObject(changedData);

View File

@ -0,0 +1,8 @@
import FilterList from '../../core/src/lib/filterList';
export default class FilterItemList extends FilterList {
constructor($scope, $timeout, $state) {
super($scope, $timeout, $state);
this.modelName = 'itemFk';
}
}
FilterItemList.$inject = ['$scope', '$timeout', '$state'];

View File

@ -1,24 +1,22 @@
<mg-ajax path="/item/api/ItemLogs/getLog" options="vnIndex"></mg-ajax>
<vn-card pad-medium>
<vn-vertical pad-medium>
<mg-ajax path="/item/api/ItemLogs/getLog" options="vnIndexNonAuto"></mg-ajax>
<vn-card>
<vn-vertical pad-large>
<vn-title vn-one margin-large-bottom>Item history</vn-title>
<vn-grid-header on-order="$ctrl.onOrder(field, order)">
<vn-column-header vn-one pad-medium-h field="originFk" text="Origin"></vn-column-header>
<vn-column-header vn-two pad-medium-h field="userFk" text="Changed by"></vn-column-header>
<vn-column-header vn-two pad-medium-h field="description" text="Description"></vn-column-header>
<vn-column-header vn-one pad-medium-h field="action" text="Action"></vn-column-header>
<vn-column-header vn-one pad-medium-h field="creationDate" text="Date"></vn-column-header>
<vn-column-header vn-one pad-medium-h field="description" text="Description"></vn-column-header>
<vn-column-header vn-one pad-medium-h field="userFk" text="Changed by"></vn-column-header>
<vn-column-header vn-one pad-medium-h field="creationDate" text="Date" default-order="ASC"></vn-column-header>
</vn-grid-header>
<vn-one class="list list-content">
<vn-horizontal
class="list list-element text-center"
pad-small-bottom
ng-repeat="itemLog in index.model.instances track by itemLog.id">
<vn-one pad-medium-h>{{::itemLog.origin.name}}</vn-one>
<vn-two pad-medium-h>{{::itemLog.user.name}}</vn-two>
<vn-two pad-medium-h>{{::itemLog.description}}</vn-two>
<vn-one pad-medium-h>{{::itemLog.action}}</vn-one>
<vn-one pad-medium-h>{{::itemLog.user.name}}</vn-one>
<vn-one pad-medium-h>{{::itemLog.creationDate | date:'dd/MM/yyyy HH:mm'}}</vn-one>
<vn-one pad-medium-h>{{::itemLog.description}}</vn-one>
</vn-horizontal>
</vn-one>
<vn-horizontal vn-one class="list list-footer text-center">

View File

@ -1,5 +1,7 @@
import ngModule from '../module';
import FilterItemList from '../filterItemList';
ngModule.component('vnItemHistory', {
template: require('./item-history.html')
template: require('./item-history.html'),
controller: FilterItemList
});

View File

@ -1,5 +1,6 @@
export * from './module';
import './filterItemList';
import './list/list';
import './filter-panel/filter-panel';
import './create/item-create';

View File

@ -1,19 +1,18 @@
require('require-yaml');
const gulp = require('gulp');
const gutil = require('gulp-util');
const print = require('gulp-print');
const runSequence = require('run-sequence');
const fs = require('fs-extra');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const exec = require('child_process').exec;
const PluginError = require('plugin-error');
const argv = require('minimist')(process.argv.slice(2));
const log = require('fancy-log');
// Configuration
const isWindows = /^win/.test(process.platform);
if (gutil.env.NODE_ENV)
process.env.NODE_ENV = gutil.env.NODE_ENV;
if (argv.NODE_ENV)
process.env.NODE_ENV = argv.NODE_ENV;
const env = process.env.NODE_ENV ? process.env.NODE_ENV : 'development';
@ -23,9 +22,6 @@ const servicesDir = './services';
const nginxDir = `${servicesDir}/nginx`;
const buildDir = `${nginxDir}/static`;
const modules = require('./client/modules.yml');
const webpackConfig = require('./webpack.config.js');
let proxyConf = require(`${nginxDir}/config.yml`);
let proxyEnvFile = `${nginxDir}/config.${env}.yml`;
@ -42,65 +38,45 @@ gulp.task('default', () => {
return gulp.start('services', 'client');
});
gulp.task('client', ['clean'], () => {
gulp.task('client', ['build-clean'], () => {
return gulp.start('watch', 'routes', 'locales', 'webpack-dev-server');
});
gulp.task('services', callback => {
let command = isWindows
? 'docker inspect dblocal | findstr Status'
: 'docker inspect dblocal | grep Status';
exec(command, (err, stdout, stderr) => {
if (err) return callback(err);
let isNotRunning = !stdout.includes('running');
if (isNotRunning)
runSequence('docker-wait', 'services-run', callback);
else
runSequence('services-run', callback);
});
gulp.task('services', async () => {
await runSequenceP('docker-start', 'services-only', 'nginx');
});
gulp.task('services-run', async () => {
gulp.task('services-only', async () => {
const services = await getServices();
for (let service of services)
require(service.index).start(service.port);
return gulp.start('nginx');
});
gulp.task('e2e', ['docker-wait'], () => {
return gulp.start('e2e-run');
gulp.task('e2e', ['docker-rebuild'], async () => {
await runSequenceP('e2e-only');
});
gulp.task('e2e-run', () => {
gulp.task('e2e-only', () => {
const jasmine = require('gulp-jasmine');
gulp.src('./e2e_tests.js')
return gulp.src('./e2e_tests.js')
.pipe(jasmine({reporter: 'none'}));
});
gulp.task('clean', () => {
const del = require('del');
const files = [
`${buildDir}/*`,
`!${buildDir}/templates`,
`!${buildDir}/images`,
`docker-compose.yml`
];
return del(files, {force: true});
});
gulp.task('clean', ['build-clean', 'nginx-clean']);
gulp.task('i', ['install']);
gulp.task('install', () => {
const install = require('gulp-install');
let jsonFile = [];
const print = require('gulp-print');
let packageFiles = [];
let services = fs.readdirSync(servicesDir);
services.push('..');
services.forEach(service => {
jsonFile.push(`${servicesDir}/${service}/package.json`);
packageFiles.push(`${servicesDir}/${service}/package.json`);
});
return gulp.src(jsonFile)
return gulp.src(packageFiles)
.pipe(print(filepath => {
return `Installing packages in ${filepath}`;
}))
@ -117,6 +93,7 @@ gulp.task('build', ['clean'], () => {
gulp.task('docker-compose', async () => {
const yaml = require('js-yaml');
let compose = await fs.readFile('./docker-compose.tpl.yml', 'utf8');
let composeYml = yaml.safeLoad(compose);
let services = await getServices();
@ -146,49 +123,41 @@ gulp.task('docker-compose', async () => {
await fs.writeFile('./docker-compose.yml', ymlString);
});
gulp.task('build-clean', () => {
const del = require('del');
const files = [
`${buildDir}/*`,
`!${buildDir}/templates`,
`!${buildDir}/images`,
`docker-compose.yml`
];
return del(files, {force: true});
});
// Nginx & services
let nginxConf = 'temp/nginx.conf';
let nginxTemp = `${nginxDir}/temp`;
async function nginxGetBin() {
if (isWindows)
return 'nginx';
try {
let nginxBin = '/usr/sbin/nginx';
await fs.stat(nginxBin);
return nginxBin;
} catch (e) {
return 'nginx';
}
}
gulp.task('nginx', async () => {
await runSequenceP('nginx-stop', 'nginx-start');
});
gulp.task('nginx', ['nginx-stop'], async () => {
gulp.task('nginx-start', ['nginx-conf'], async () => {
let nginxBin = await nginxGetBin();
if (isWindows)
nginxBin = `start /B ${nginxBin}`;
return new Promise((resolve, reject) => {
exec(`${nginxBin} -c "${nginxConf}" -p "${nginxDir}"`, err => {
if (err) return reject(err);
resolve();
});
});
log(`Application will be at http://${proxyConf.host}:${proxyConf.port}/`);
await execP(`${nginxBin} -c "${nginxConf}" -p "${nginxDir}"`);
});
gulp.task('nginx-stop', ['nginx-conf'], async () => {
gulp.task('nginx-stop', async () => {
try {
let nginxBin = await nginxGetBin();
await fs.stat(`${nginxTemp}/nginx.pid`);
let command = `${nginxBin} -c "${nginxConf}" -p "${nginxDir}" -s stop`;
return new Promise((resolve, reject) => {
exec(command, err => {
if (err && err.code != 1) return reject(err);
resolve();
});
});
await execP(`${nginxBin} -c "${nginxConf}" -p "${nginxDir}" -s stop`);
} catch (e) {}
});
@ -218,11 +187,23 @@ gulp.task('nginx-conf', async () => {
await fs.writeFile(`${nginxTemp}/nginx.conf`, nginxConf);
});
gulp.task('nginx-clean', () => {
gulp.task('nginx-clean', ['nginx-stop'], () => {
const del = require('del');
return del([`${nginxTemp}/*`], {force: true});
});
async function nginxGetBin() {
if (isWindows)
return 'nginx';
try {
let nginxBin = '/usr/sbin/nginx';
await fs.stat(nginxBin);
return nginxBin;
} catch (e) {
return 'nginx';
}
}
async function getServices() {
let services;
let startPort = defaultPort + 1;
@ -248,18 +229,25 @@ async function getServices() {
// Webpack
gulp.task('webpack', function(cb) {
gulp.task('webpack', function(callback) {
const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');
let configCopy = Object.create(webpackConfig);
let compiler = webpack(configCopy);
compiler.run(function(err, stats) {
if (err) throw new gutil.PluginError('webpack', err);
gutil.log('[webpack]', stats.toString({colors: true}));
cb();
if (err) throw new PluginError('webpack', err);
log('[webpack]', stats.toString({colors: true}));
callback();
});
});
gulp.task('webpack-dev-server', function() {
const WebpackDevServer = require('webpack-dev-server');
const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');
let configCopy = Object.create(webpackConfig);
for (let entry in configCopy.entry) {
@ -284,7 +272,7 @@ gulp.task('webpack-dev-server', function() {
chunkModules: false
}
}).listen(devServerPort, '127.0.0.1', function(err) {
if (err) throw new gutil.PluginError('webpack-dev-server', err);
if (err) throw new PluginError('webpack-dev-server', err);
});
});
@ -296,6 +284,7 @@ gulp.task('locales', function() {
const extend = require('gulp-extend');
const yaml = require('gulp-yaml');
const merge = require('merge-stream');
const modules = require('./client/modules.yml');
let streams = [];
@ -334,51 +323,93 @@ gulp.task('watch', function() {
// Docker
gulp.task('docker', callback => {
runSequence('docker-delete', 'docker-delete-image', 'docker-build', 'docker-run', callback);
gulp.task('docker-rebuild', async () => {
try {
await execP('docker rm -f dblocal');
} catch (e) {}
try {
await execP('docker rmi dblocal:latest');
} catch (e) {}
await runSequenceP('docker-run');
});
gulp.task('docker-wait', ['docker'], callback => {
gulp.task('docker-start', async () => {
let result;
try {
result = await execP('docker container inspect -f "{{json .State}}" dblocal');
} catch (err) {
return await runSequenceP('docker-run');
}
switch (JSON.parse(result.stdout).Status) {
case 'running':
return;
case 'exited':
return await execP('docker start dblocal');
default:
throw new Error(`Unknown docker status: ${status}`);
}
});
gulp.task('docker-run', async () => {
try {
await execP('docker image inspect -f "{{json .Id}}" dblocal');
} catch (err) {
await execP('docker build -t dblocal:latest ./services/db');
}
await execP('docker run -d --name dblocal -p 3306:3306 dblocal');
await runSequenceP('docker-wait');
});
gulp.task('docker-wait', callback => {
let maxInterval = 30 * 60000;
let interval = 1000;
let timer = 0;
console.log('Waiting for MySQL init process...');
log('Waiting for MySQL init process...');
let waitForLocaldb = setInterval(() => {
if (timer < maxInterval) {
timer += interval;
exec('docker logs --tail 4 dblocal', (err, stdout, stderr) => {
if (stdout.includes('MySQL init process done. Ready for start up.')) {
exec('docker logs --tail 1 dblocal', (err, stdout, stderr) => {
if (stderr.includes('starting as process 1') || err) {
clearInterval(waitForLocaldb);
callback(err);
}
});
} else {
console.log(`MySQL connection not established whithin ${maxInterval / 1000} secs!`);
clearInterval(waitForLocaldb);
callback(new Error(`MySQL not initialized whithin ${maxInterval / 1000} secs`));
}
}, interval);
});
gulp.task('docker-run', callback => {
exec('docker run -d --name dblocal -p 3306:3306 dblocal', (err, stdout, stderr) => {
callback(err);
});
});
// Helpers
gulp.task('docker-build', callback => {
exec('docker build -t dblocal:latest ./services/db', (err, stdout, stderr) => {
callback(err);
function execP(command) {
return new Promise((resolve, reject) => {
exec(command, (err, stdout, stderr) => {
if (err)
reject(err);
else
resolve({
stdout: stdout,
stderr: stderr
});
});
});
});
}
gulp.task('docker-delete-image', callback => {
exec('docker rmi dblocal:latest', (err, stdout, stderr) => {
callback(err);
function runSequenceP() {
return new Promise((resolve, reject) => {
let args = Array.prototype.slice.call(arguments);
args.push(err => {
if (err)
reject(err);
else
resolve();
});
runSequence(...args);
});
});
gulp.task('docker-delete', callback => {
exec('docker stop dblocal && docker wait dblocal && docker rm -f dblocal', (err, stdout, stderr) => {
callback(err);
});
});
}

3557
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -25,10 +25,10 @@
},
"devDependencies": {
"angular-mocks": "^1.6.6",
"babel": "^6.5.2",
"babel-core": "^6.22.1",
"babel-loader": "^6.4.1",
"babel-preset-es2015": "^6.22.0",
"babel": "^6.23.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"cors": "^2.8.1",
"css-loader": "^0.25.0",
"del": "^2.2.2",
@ -40,40 +40,40 @@
"eslint-config-xo": "^0.17.0",
"eslint-plugin-angular": "^1.4.1",
"eslint-plugin-jasmine": "^2.8.4",
"file-loader": "^0.9.0",
"fancy-log": "^1.3.2",
"file-loader": "^1.1.6",
"gulp": "^3.9.1",
"gulp-concat": "^2.6.0",
"gulp-extend": "^0.2.0",
"gulp-install": "^1.1.0",
"gulp-jasmine": "^3.0.0",
"gulp-print": "^2.0.1",
"gulp-util": "^3.0.7",
"gulp-wrap": "^0.13.0",
"gulp-yaml": "^1.0.1",
"html-loader": "^0.4.4",
"jasmine": "^2.9.0",
"jasmine-spec-reporter": "^4.2.1",
"js-yaml": "^3.10.0",
"json-loader": "^0.5.7",
"karma": "^1.7.1",
"karma-chrome-launcher": "^2.2.0",
"karma-firefox-launcher": "^1.1.0",
"karma-jasmine": "^1.1.1",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^2.0.9",
"md5": "^2.2.1",
"merge-stream": "^1.0.1",
"minimist": "^1.2.0",
"mustache": "^2.3.0",
"mysql": "^2.15.0",
"nightmare": "^2.10.0",
"node-sass": "^4.7.2",
"nodemon": "^1.12.1",
"plugin-error": "^1.0.1",
"raw-loader": "*",
"run-sequence": "^2.2.0",
"sass-loader": "^4.1.1",
"style-loader": "^0.13.1",
"webpack": "^2.2.0",
"webpack-dev-server": "^2.2.0",
"sass-loader": "^6.0.6",
"style-loader": "^0.20.1",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.11.1",
"yaml-loader": "^0.5.0"
},
"scripts": {

View File

@ -7,7 +7,9 @@
"start": "node .",
"posttest": "npm run lint && nsp check"
},
"dependencies": {},
"dependencies": {
"md5": "^2.2.1"
},
"repository": {
"type": "git",
"url": "https://git.verdnatura.es/salix"

View File

@ -15,5 +15,13 @@
"name": {
"type": "String"
}
}
},
"acls": [
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
}
]
}

View File

@ -390,24 +390,52 @@ INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city
INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `isDefaultAddress`, `clientFk`, `agencyFk`, `longitude`, `latitude`, `isEqualizated`)
VALUES
(101, 'Bruce Wayne', 'The Bat cave', 'Silla', 46460, 1, NULL, NULL, 1, 1, 1, 2, NULL, NULL, 0),
(102, 'Petter Parker', 'NY roofs', 'Silla', 46460, 1, NULL, NULL, 1, 1, 2, 2, NULL, NULL, 0),
(103, 'Clark Kenn', 'The phone box', 'Silla', 46460, 1, NULL, NULL, 1, 1, 3, 2, NULL, NULL, 0),
(104, 'Tony Stark', 'Stark tower', 'Silla', 46460, 1, NULL, NULL, 1, 1, 4, 2, NULL, NULL, 0),
(105, 'Max Eisenhardt', 'The plastic cell', 'Silla', 46460, 1, NULL, NULL, 1, 1, 5, 2, NULL, NULL, 0),
(106, 'David Charles Haller', 'Many places', 'Silla', 46460, 1, NULL, NULL, 1, 1, 6, 2, NULL, NULL, 0),
(107, 'Hank Pym', 'Your pocket', 'Silla', 46460, 1, NULL, NULL, 1, 1, 7, 2, NULL, NULL, 0),
(108, 'Charles Xavier', 'Cerebro', 'Silla', 46460, 1, NULL, NULL, 1, 1, 8, 2, NULL, NULL, 0),
(109, 'Bruce Banner', 'Somewhere in Thailand', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(110, 'Jessica Jones', 'Luke Cages Bar', 'Silla', 46460, 1, NULL, NULL, 1, 1, 10, 2, NULL, NULL, 0);
(101, 'Bruce Banner', 'Somewhere in Thailand', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(102, 'Bruce Banner', 'Somewhere in New York', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(103, 'Bruce Banner', 'Somewhere in Japan', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(104, 'Bruce Banner', 'Somewhere in Spain', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(105, 'Bruce Banner', 'Somewhere in Potugal', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(106, 'Bruce Banner', 'Somewhere in UK', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(107, 'Bruce Banner', 'Somewhere in Valencia', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(108, 'Bruce Banner', 'Somewhere in Silla', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(109, 'Bruce Banner', 'Somewhere in London', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(110, 'Bruce Banner', 'Somewhere in Algemesi', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(111, 'Bruce Banner', 'Somewhere in Carlet', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(112, 'Bruce Banner', 'Somewhere in Campanar', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(113, 'Bruce Banner', 'Somewhere in Malilla', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(114, 'Bruce Banner', 'Somewhere in France', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(115, 'Bruce Banner', 'Somewhere in Birmingham', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(116, 'Bruce Banner', 'Somewhere in Scotland', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(117, 'Bruce Banner', 'Somewhere in nowhere', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(118, 'Bruce Banner', 'Somewhere over the rainbow', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(119, 'Bruce Banner', 'Somewhere in Alberic', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(120, 'Bruce Banner', 'Somewhere in Montortal', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(121, 'Petter Parker', 'NY roofs', 'Silla', 46460, 1, NULL, NULL, 1, 1, 2, 2, NULL, NULL, 0),
(122, 'Clark Kenn', 'The phone box', 'Silla', 46460, 1, NULL, NULL, 1, 1, 3, 2, NULL, NULL, 0),
(123, 'Tony Stark', 'Stark tower', 'Silla', 46460, 1, NULL, NULL, 1, 1, 4, 2, NULL, NULL, 0),
(124, 'Max Eisenhardt', 'The plastic cell', 'Silla', 46460, 1, NULL, NULL, 1, 1, 5, 2, NULL, NULL, 0),
(125, 'David Charles Haller', 'Many places', 'Silla', 46460, 1, NULL, NULL, 1, 1, 6, 2, NULL, NULL, 0),
(126, 'Hank Pym', 'Your pocket', 'Silla', 46460, 1, NULL, NULL, 1, 1, 7, 2, NULL, NULL, 0),
(127, 'Charles Xavier', 'Cerebro', 'Silla', 46460, 1, NULL, NULL, 1, 1, 8, 2, NULL, NULL, 0),
(128, 'Jessica Jones', 'Luke Cages Bar', 'Silla', 46460, 1, NULL, NULL, 1, 1, 10, 2, NULL, NULL, 0);
INSERT INTO `vn`.`clientCredit`(`id`, `clientFk`, `workerFk`, `amount`, `created`)
VALUES
(1, 1, 1, 1200, CURDATE()),
(2, 2, 2, 800, CURDATE()),
(3, 3, 3, 200, CURDATE()),
(4, 4, 4, 90, CURDATE()),
(5, 5, 5, 90, CURDATE());
(1, 1, 1, 1000, DATE_ADD(CURDATE(), INTERVAL 1 MONTH)),
(2, 1, 2, 900, DATE_ADD(CURDATE(), INTERVAL 2 MONTH)),
(3, 1, 3, 800, DATE_ADD(CURDATE(), INTERVAL 3 MONTH)),
(4, 1, 4, 700, DATE_ADD(CURDATE(), INTERVAL 4 MONTH)),
(5, 1, 5, 600, DATE_ADD(CURDATE(), INTERVAL 5 MONTH)),
(6, 1, 1, 500, DATE_ADD(CURDATE(), INTERVAL 6 MONTH)),
(7, 1, 2, 400, DATE_ADD(CURDATE(), INTERVAL 7 MONTH)),
(8, 1, 3, 300, DATE_ADD(CURDATE(), INTERVAL 8 MONTH)),
(9, 1, 4, 200, DATE_ADD(CURDATE(), INTERVAL 9 MONTH)),
(10, 1, 5, 100, DATE_ADD(CURDATE(), INTERVAL 10 MONTH)),
(11, 1, 1, 50, DATE_ADD(CURDATE(), INTERVAL 11 MONTH)),
(12, 2, 2, 800, CURDATE()),
(13, 3, 3, 200, CURDATE()),
(14, 4, 4, 90, CURDATE()),
(15, 5, 5, 90, CURDATE());
INSERT INTO `vn`.`clientCreditLimit`(`id`, `maxAmount`, `roleFk`)
VALUES
@ -523,12 +551,18 @@ INSERT INTO `vn`.`greugeType`(`id`, `name`)
INSERT INTO `vn`.`greuge`(`id`, `clientFk`, `description`, `amount`, `shipped`, `created`, `greugeTypeFk`, `ticketFk`)
VALUES
(1, 1, 'some diff charges', 1000, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 1, 1),
(2, 1, 'some recovery charges', 1000, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 2, 1),
(3, 1, 'some manna charges', 1000, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 3, 1),
(4, 1, 'some claim charges', 1000, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 4, 1),
(5, 1, 'some heritage charges', 1000, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 5, 1),
(6, 1, 'some miscellaneous charges', 1000, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 1, 1);
(1, 1, 'some diff charges', -19.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 1, 1),
(2, 1, 'more diff charges', 60, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 2, 1),
(3, 1, 'even more! diff charges', -9.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 3, 1),
(4, 1, 'insane diff charges', 60, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 4, 1),
(5, 1, 'gargantuous diff charges', -9.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 5, 1),
(6, 1, 'diff charges', 88.30, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 6, 1),
(7, 1, 'unaffordable diff charges', -39.12, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 1, 1),
(8, 1, 'some recovery charges', 29.35, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 2, 1),
(9, 1, 'some manna charges', -9.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 3, 1),
(10, 1, 'some claim charges', 13.13, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 4, 1),
(11, 1, 'some heritage charges', -15.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 5, 1),
(12, 1, 'some miscellaneous charges', 58.00, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 6, 1);
INSERT INTO `vn`.`mandateType`(`id`, `name`)
VALUES

View File

@ -4,15 +4,18 @@ module.exports = Self => {
function filterParams(params) {
return {
where: {
itemFk: params.itemFk
originFk: params.itemFk
},
skip: (params.page - 1) * params.size,
limit: params.size,
include: [{
relation: "origin"
relation: "item"
},
{
relation: "user"
relation: "user",
scope: {
fields: ["name"]
}
}]
};
}

View File

@ -1,35 +1,38 @@
{
"name": "ItemLog",
"base": "VnModel",
"options": {
"mysql": {
"table": "itemLog",
"database": "vn"
}
},
"properties": {
"id": {
"type": "Number",
"id": true,
"description": "Identifier"
},
"creationDate": {
"type": "Date"
},
"description": {
"type": "String"
"name": "ItemLog",
"base": "VnModel",
"options": {
"mysql": {
"table": "itemLog",
"database": "vn"
}
},
"properties": {
"id": {
"type": "Number",
"id": true,
"description": "Identifier"
},
"relations": {
"origin": {
"type": "belongsTo",
"model": "Origin",
"foreignKey": "originFk"
},
"user": {
"type": "belongsTo",
"model": "User",
"foreignKey": "userFk"
}
"creationDate": {
"type": "Date"
},
"description": {
"type": "String"
},
"action": {
"type": "String"
}
},
"relations": {
"item": {
"type": "belongsTo",
"model": "Item",
"foreignKey": "originFk"
},
"user": {
"type": "belongsTo",
"model": "Account",
"foreignKey": "userFk"
}
}
}

View File

@ -15,6 +15,7 @@
"loopback-connector-mysql": "^3.0.0",
"loopback-connector-remote": "^3.1.1",
"loopback-context": "^3.3.0",
"md5": "^2.2.1",
"serve-favicon": "^2.0.1",
"strong-error-handler": "^2.1.0"
},

View File

@ -36,14 +36,16 @@ function vnBoot(app, rootDir, rootModule) {
// Initialization
let packageJson = require(rootDir + '/../package.json');
let appName = packageJson.name;
app.start = function(port) {
function onListen() {
app.emit('started');
let baseUrl = app.get('url').replace(/\/$/, '');
console.log(`Web server ${appName} listening at: %s`, baseUrl);
if (require.main === rootModule) {
let packageJson = require(`${rootDir}/../package.json`);
let appName = packageJson.name;
let baseUrl = app.get('url').replace(/\/$/, '');
console.log(`Web server ${appName} listening at: %s`, baseUrl);
}
}
let args = port ? [port, onListen] : [onListen];

View File

@ -22,10 +22,9 @@ app.start = function(port) {
database.init();
database.testEmail();
let packageJson = require('../package.json');
console.log(`Web server ${packageJson.name} listening at: ${servicePath}`);
if (config.app.debug) {
let packageJson = require('../package.json');
console.log(`Web server ${packageJson.name} listening at: ${servicePath}`);
console.log(`${packageJson.name} service debug mode enabled`);
}
});

View File

@ -6,10 +6,8 @@ RUN rm /etc/nginx/conf.d/default.conf
COPY temp/nginx.conf /etc/nginx/nginx.conf
COPY static /usr/share/nginx/html
RUN apt-get update && apt-get -y install vim dnsmasq dnsutils
RUN apt-get update && apt-get -y install vim dnsmasq dnsutils iptools-ping
RUN rm -fr /usr/share/dns
RUN echo listen-address=127.0.0.1 > /etc/dnsmasq.d/dnsmasq.conf
CMD service dnsmasq restart && nginx -g "daemon off;"
EXPOSE 80

View File

@ -21,7 +21,7 @@ http {
{{#services}}
location ~ ^/{{name}}(?:/(.*))?$ {
proxy_pass http://{{name}}:{{port}}/$1$is_args$args;
proxy_pass http://{{name}}:{{defaultPort}}/$1$is_args$args;
}
{{/services}}

View File

@ -16,10 +16,9 @@ app.start = function(port) {
var servicePath = 'http://' + listener.address().address + ':' + listener.address().port;
database.init();
let packageJson = require('../package.json');
console.log(`Web server ${packageJson.name} listening at: ${servicePath}`);
if (config.app.debug) {
let packageJson = require('../package.json');
console.log(`Web server ${packageJson.name} listening at: ${servicePath}`);
console.log(`${packageJson.name} service debug mode enabled`);
}
});

View File

@ -17,7 +17,7 @@ var config = {
chunkFilename: 'chunk.[name].[chunkhash].js'
},
module: {
loaders: [
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
@ -45,10 +45,9 @@ var config = {
},
resolve: {
modules: [
path.join(__dirname, 'client'),
`${__dirname}/client`,
__dirname,
'node_modules',
'/usr/lib/node_modules'
'node_modules'
]
},
plugins: [