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

This commit is contained in:
Javi Gallego 2018-02-08 09:44:32 +01:00
commit 378c04b123
36 changed files with 1145 additions and 538 deletions

View File

@ -19,4 +19,4 @@ rules:
no-eq-null: 0 no-eq-null: 0
no-console: 0 no-console: 0
no-warning-comments: 0 no-warning-comments: 0
no-empty: 0 no-empty: [error, allowEmptyCatch: true]

View File

@ -77,7 +77,7 @@
margin-medium-left margin-medium-left
orange orange
icon="add_circle" icon="add_circle"
ng-if = "observation.showAddIcon" ng-if = "observation.showAddIcon && observationsTypes.model.length > $ctrl.observations.length"
ng-click="$ctrl.addObservation()" ng-click="$ctrl.addObservation()"
></vn-icon> ></vn-icon>
</vn-one> </vn-one>

View File

@ -13,7 +13,7 @@ export default class Controller {
id: parseInt($state.params.addressId) id: parseInt($state.params.addressId)
}; };
this.observations = []; this.observations = [];
this.observationsDictionary = {}; this.observationsOld = {};
this.observationsRemoved = []; this.observationsRemoved = [];
} }
@ -60,11 +60,16 @@ export default class Controller {
return this.$http.post(`/client/api/AddressObservations/crudAddressObservations`, objectObservations); return this.$http.post(`/client/api/AddressObservations/crudAddressObservations`, objectObservations);
} }
_observationsEquals(ob1, ob2) {
return ob1.id === ob2.id && ob1.observationTypeFk === ob2.observationTypeFk && ob1.description === ob2.description;
}
submit() { submit() {
this._unsetDirtyForm(); this._unsetDirtyForm();
let submitWatcher = this.$scope.watcher.dataChanged(); let submitWatcher = this.$scope.watcher.dataChanged();
let submitObservations; let submitObservations;
let repeatedTypes = false; let repeatedTypes = false;
let types = [];
let observationsObj = { let observationsObj = {
delete: this.observationsRemoved, delete: this.observationsRemoved,
create: [], create: [],
@ -73,31 +78,28 @@ export default class Controller {
for (let i = 0; i < this.observations.length; i++) { for (let i = 0; i < this.observations.length; i++) {
let observation = this.observations[i]; let observation = this.observations[i];
// only one observation is allowed for each of its types let isNewObservation = observation.id === undefined;
if (this.observationsDictionary[observation.observationTypeFk] !== undefined && // IF the dictionary contains the type
( if (observation.observationTypeFk && types.indexOf(observation.observationTypeFk) !== -1) {
// AND (is a new Observation OR is old but with distinct Id) --> repeated
!observation.id || (observation.id && this.observationsDictionary[observation.observationTypeFk].id !== observation.id)
)
) {
repeatedTypes = true; repeatedTypes = true;
break; break;
} }
if (!observation.id && observation.observationTypeFk && observation.description) { if (observation.observationTypeFk)
types.push(observation.observationTypeFk);
if (isNewObservation && observation.observationTypeFk && observation.description) {
observationsObj.create.push(observation); observationsObj.create.push(observation);
} else if (observation.id && this.observationsDictionary[observation.observationTypeFk].description !== observation.description) { } else if (!isNewObservation && !this._observationsEquals(this.observationsOld[observation.id], observation)) {
observationsObj.update.push(observation); observationsObj.update.push(observation);
} }
this.observationsDictionary[observation.observationTypeFk] = observation;
} }
submitObservations = observationsObj.update.length > 0 || observationsObj.create.length > 0 || observationsObj.delete.length > 0; submitObservations = observationsObj.update.length > 0 || observationsObj.create.length > 0 || observationsObj.delete.length > 0;
if (repeatedTypes) { if (repeatedTypes) {
this.vnApp.showMessage( this.vnApp.showMessage(
this.$translate.instant('you can not repeat the types of observations') this.$translate.instant('The observation type must be unique')
); );
} else if (submitWatcher && !submitObservations) { } else if (submitWatcher && !submitObservations) {
this.$scope.watcher.submit().then(() => { this.$scope.watcher.submit().then(() => {
@ -126,7 +128,7 @@ export default class Controller {
this.$http.get(`/client/api/AddressObservations?filter=${JSON.stringify(filter)}`).then(res => { this.$http.get(`/client/api/AddressObservations?filter=${JSON.stringify(filter)}`).then(res => {
this.observations = res.data; this.observations = res.data;
res.data.forEach(item => { res.data.forEach(item => {
this.observationsDictionary[item.observationTypeFk] = Object.assign({}, item); this.observationsOld[item.id] = Object.assign({}, item);
}); });
}); });
} }

View File

@ -20,7 +20,75 @@ describe('Client', () => {
})); }));
it('should define and set address property', () => { it('should define and set address property', () => {
expect(controller.address.id).toBe(1); expect(controller.address.id).toEqual(1);
});
describe('_setIconAdd()', () => {
it('should set the propertie sowAddIcon from all observations to false less last one that be true', () => {
controller.observations = [
{id: 1, description: 'Spiderman rocks', showAddIcon: true},
{id: 2, description: 'Batman sucks', showAddIcon: true},
{id: 3, description: 'Ironman rules', showAddIcon: false}
];
controller._setIconAdd();
expect(controller.observations[0].showAddIcon).toBeFalsy();
expect(controller.observations[1].showAddIcon).toBeFalsy();
expect(controller.observations[2].showAddIcon).toBeTruthy();
});
});
describe('addObservation()', () => {
it('should add one empty observation into controller observations collection and call _setIconAdd()', () => {
controller.observations = [];
spyOn(controller, '_setIconAdd').and.callThrough();
controller.addObservation();
expect(controller._setIconAdd).toHaveBeenCalledWith();
expect(controller.observations.length).toEqual(1);
expect(controller.observations[0].id).toBe(undefined);
expect(controller.observations[0].showAddIcon).toBeTruthy();
});
});
describe('removeObservation(index)', () => {
it('should remove an observation that occupies the position in the index given and call _setIconAdd()', () => {
let index = 2;
controller.observations = [
{id: 1, description: 'Spiderman rocks', showAddIcon: false},
{id: 2, description: 'Batman sucks', showAddIcon: false},
{id: 3, description: 'Ironman rules', showAddIcon: true}
];
spyOn(controller, '_setIconAdd').and.callThrough();
controller.removeObservation(index);
expect(controller._setIconAdd).toHaveBeenCalledWith();
expect(controller.observations.length).toEqual(2);
expect(controller.observations[0].showAddIcon).toBeFalsy();
expect(controller.observations[1].showAddIcon).toBeTruthy();
expect(controller.observations[index]).toBe(undefined);
});
});
describe('_observationsEquals', () => {
it('should return true if two observations are equals independent of control attributes', () => {
let ob1 = {id: 1, observationTypeFk: 1, description: 'Spiderman rocks', showAddIcon: true};
let ob2 = {id: 1, observationTypeFk: 1, description: 'Spiderman rocks', showAddIcon: false};
let equals = controller._observationsEquals(ob2, ob1);
expect(equals).toBeTruthy();
});
it('should return false if two observations are not equals independent of control attributes', () => {
let ob1 = {id: 1, observationTypeFk: 1, description: 'Spiderman rocks', showAddIcon: true};
let ob2 = {id: 1, observationTypeFk: 1, description: 'Spiderman sucks', showAddIcon: true};
let equals = controller._observationsEquals(ob2, ob1);
expect(equals).toBeFalsy();
});
}); });
describe('$onInit()', () => { describe('$onInit()', () => {

View File

@ -1,2 +1,5 @@
Enabled: Activo Enabled: Activo
Is equalizated: Recargo de equivalencia Is equalizated: Recargo de equivalencia
Observation type: Tipo de observación
Description: Descripción
The observation type must be unique: El tipo de observación ha de ser único

View File

@ -11,7 +11,15 @@
<vn-horizontal style="align-items: center;"> <vn-horizontal style="align-items: center;">
<vn-none pad-medium-h style="color:#FFA410;"> <vn-none pad-medium-h style="color:#FFA410;">
<i class="material-icons" ng-if="address.isDefaultAddress">star</i> <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-none>
<vn-one border-solid-right> <vn-one border-solid-right>
<div><b>{{::address.nickname}}</b></div> <div><b>{{::address.nickname}}</b></div>

View File

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

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,5 +1,4 @@
<mg-ajax path="/item/api/items/1/getLog"></mg-ajax> <mg-ajax path="/item/api/ItemLogs/getLog" options="vnIndex"></mg-ajax>
<!-- <mg-ajax path="/item/api/history/{{edit.params.id}}/sumAmount" options="mgEdit"></mg-ajax> -->
<vn-card pad-medium> <vn-card pad-medium>
<vn-vertical pad-medium> <vn-vertical pad-medium>
<vn-title vn-one margin-large-bottom>Item history</vn-title> <vn-title vn-one margin-large-bottom>Item history</vn-title>
@ -15,19 +14,17 @@
class="list list-element text-center" class="list list-element text-center"
pad-small-bottom pad-small-bottom
ng-repeat="itemLog in index.model.instances track by itemLog.id"> ng-repeat="itemLog in index.model.instances track by itemLog.id">
<vn-one pad-medium-h>{{::itemLog.originFk}}</vn-one> <vn-one pad-medium-h>{{::itemLog.origin.name}}</vn-one>
<vn-two pad-medium-h>{{::itemLog.userFk}}</vn-two> <vn-two pad-medium-h>{{::itemLog.user.name}}</vn-two>
<vn-one pad-medium-h>{{::itemLog.action}}</vn-one> <vn-one pad-medium-h>{{::itemLog.action}}</vn-one>
<vn-one pad-medium-h>{{::itemLog.creationDate | date:'dd/MM/yyyy HH:mm'}}</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-one pad-medium-h>{{::itemLog.description}}</vn-one>
</vn-horizontal> </vn-horizontal>
</vn-one> </vn-one>
<vn-one class="text-center pad-small-v" ng-if="index.model.count === 0" translate>No results</vn-one>
<vn-horizontal vn-one class="list list-footer text-center"> <vn-horizontal vn-one class="list list-footer text-center">
<vn-one pad-medium-h></vn-one> <vn-one pad-medium-h></vn-one>
<vn-two pad-medium-h></vn-two> <vn-two pad-medium-h></vn-two>
<vn-one pad-medium-h></vn-one> <vn-one pad-medium-h></vn-one>
</vn-horizontal> </vn-horizontal>
<vn-paging margin-large-top vn-one index="index" total="index.model.count"></vn-paging>
</vn-vertical> </vn-vertical>
</vn-card> </vn-card>

View File

@ -1,20 +1,20 @@
require('require-yaml'); require('require-yaml');
const gulp = require('gulp'); const gulp = require('gulp');
const gutil = require('gulp-util'); const gutil = require('gulp-util');
const wrap = require('gulp-wrap');
const concat = require('gulp-concat');
const merge = require('merge-stream');
const print = require('gulp-print'); const print = require('gulp-print');
const runSequence = require('run-sequence'); const runSequence = require('run-sequence');
const fs = require('fs-extra'); const fs = require('fs-extra');
const webpack = require('webpack'); const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server'); const WebpackDevServer = require('webpack-dev-server');
const exec = require('child_process').exec; const exec = require('child_process').exec;
const path = require('path');
// Configuration // Configuration
const isWindows = /^win/.test(process.platform); const isWindows = /^win/.test(process.platform);
if (gutil.env.NODE_ENV)
process.env.NODE_ENV = gutil.env.NODE_ENV;
const env = process.env.NODE_ENV ? process.env.NODE_ENV : 'development'; const env = process.env.NODE_ENV ? process.env.NODE_ENV : 'development';
const langs = ['es', 'en']; const langs = ['es', 'en'];
@ -81,9 +81,17 @@ gulp.task('e2e-run', () => {
gulp.task('clean', () => { gulp.task('clean', () => {
const del = require('del'); const del = require('del');
return del([`${buildDir}/*`, `!${buildDir}/templates`, `!${buildDir}/images`], {force: true}); const files = [
`${buildDir}/*`,
`!${buildDir}/templates`,
`!${buildDir}/images`,
`docker-compose.yml`
];
return del(files, {force: true});
}); });
gulp.task('i', ['install']);
gulp.task('install', () => { gulp.task('install', () => {
const install = require('gulp-install'); const install = require('gulp-install');
let jsonFile = []; let jsonFile = [];
@ -101,9 +109,6 @@ gulp.task('install', () => {
})); }));
}); });
// Gulp install alias
gulp.task('i', ['install']);
// Deployment // Deployment
gulp.task('build', ['clean'], () => { gulp.task('build', ['clean'], () => {
@ -111,27 +116,26 @@ gulp.task('build', ['clean'], () => {
}); });
gulp.task('docker-compose', async () => { gulp.task('docker-compose', async () => {
let compose = await fs.readFile('./docker-compose.tpl.yml', 'utf8');
const yaml = require('js-yaml'); const yaml = require('js-yaml');
let compose = await fs.readFile('./docker-compose.tpl.yml', 'utf8');
let composeYml = yaml.safeLoad(compose); let composeYml = yaml.safeLoad(compose);
let services = await getServices(); let services = await getServices();
for (let service of services) { for (let service of services) {
let dockerFile = `${__dirname}/Dockerfile`; let dockerFile = `${__dirname}/services/${service.name}/Dockerfile`;
if (await fs.exists(`./services/${service.name}/Dockerfile`)) // if (await fs.exists(`./services/${service.name}/Dockerfile`))
dockerFile = 'Dockerfile'; // dockerFile = 'Dockerfile';
composeYml.services[service.name] = { composeYml.services[service.name] = {
environment: ['NODE_ENV=${NODE_ENV}'], environment: ['NODE_ENV=${NODE_ENV}'],
container_name: `\${BRANCH_NAME}-${service.name}`, container_name: `\${BRANCH_NAME}-${service.name}`,
image: `${service.name}:\${TAG}`, image: `${service.name}:\${TAG}`,
build: { build: {
context: `./services/${service.name}`, context: `./services`,
dockerfile: dockerFile dockerfile: dockerFile
}, },
ports: [`${defaultPort}:${service.port}`] ports: [`${service.port}:${defaultPort}`]
}; };
composeYml.services.nginx.links.push( composeYml.services.nginx.links.push(
`${service.name}:\${BRANCH_NAME}-${service.name}` `${service.name}:\${BRANCH_NAME}-${service.name}`
@ -191,9 +195,8 @@ gulp.task('nginx-stop', ['nginx-conf'], async () => {
gulp.task('nginx-conf', async () => { gulp.task('nginx-conf', async () => {
const mustache = require('mustache'); const mustache = require('mustache');
if (!fs.existsSync(nginxTemp)) { if (!await fs.exists(nginxTemp))
fs.mkdirSync(nginxTemp); await fs.mkdir(nginxTemp);
}
let params = { let params = {
services: await getServices(), services: await getServices(),
@ -220,11 +223,8 @@ gulp.task('nginx-clean', () => {
return del([`${nginxTemp}/*`], {force: true}); return del([`${nginxTemp}/*`], {force: true});
}); });
let services;
async function getServices() { async function getServices() {
if (services) return services; let services;
let startPort = defaultPort + 1; let startPort = defaultPort + 1;
services = []; services = [];
@ -290,11 +290,13 @@ gulp.task('webpack-dev-server', function() {
// Locale // Locale
let localeFiles = `${srcDir}/**/locale/*.json`; let localeFiles = `${srcDir}/**/locale/*.yml`;
gulp.task('locales', function() { gulp.task('locales', function() {
const extend = require('gulp-extend'); const extend = require('gulp-extend');
const yaml = require('gulp-yaml'); const yaml = require('gulp-yaml');
const merge = require('merge-stream');
let streams = []; let streams = [];
for (let mod in modules) for (let mod in modules)
@ -314,6 +316,9 @@ gulp.task('locales', function() {
let routeFiles = `${srcDir}/**/routes.json`; let routeFiles = `${srcDir}/**/routes.json`;
gulp.task('routes', function() { gulp.task('routes', function() {
const concat = require('gulp-concat');
const wrap = require('gulp-wrap');
return gulp.src(routeFiles) return gulp.src(routeFiles)
.pipe(concat('routes.js', {newLine: ','})) .pipe(concat('routes.js', {newLine: ','}))
.pipe(wrap('var routes = [<%=contents%>\n];')) .pipe(wrap('var routes = [<%=contents%>\n];'))

View File

@ -88,7 +88,7 @@ module.exports = function(config) {
customLaunchers: { customLaunchers: {
FirefoxHeadless: { FirefoxHeadless: {
base: 'Firefox', base: 'Firefox',
flags: ['--headless'] flags: ['-headless']
} }
} }
}; };

16
package-lock.json generated
View File

@ -113,7 +113,7 @@
"angular": { "angular": {
"version": "1.6.8", "version": "1.6.8",
"resolved": "https://registry.npmjs.org/angular/-/angular-1.6.8.tgz", "resolved": "https://registry.npmjs.org/angular/-/angular-1.6.8.tgz",
"integrity": "sha1-W+N4pYvpGlSJ54tZxFGM2f0nP/s=" "integrity": "sha512-9WErZIOw1Cu1V5Yxdvxz/6YpND8ntdP71fdPpufPFJvZodZXqCjQBYrHqEoMZreO5i84O3D/Jw/vepoFt68Azw=="
}, },
"angular-cookies": { "angular-cookies": {
"version": "1.6.4", "version": "1.6.4",
@ -1119,7 +1119,7 @@
"bluebird": { "bluebird": {
"version": "3.5.1", "version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
"integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk=", "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
"dev": true "dev": true
}, },
"bn.js": { "bn.js": {
@ -9909,7 +9909,7 @@
"jasmine-spec-reporter": { "jasmine-spec-reporter": {
"version": "4.2.1", "version": "4.2.1",
"resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz", "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz",
"integrity": "sha1-HWMq7ANBZwrTJPkrqEtLMrNeniI=", "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==",
"dev": true, "dev": true,
"requires": { "requires": {
"colors": "1.1.2" "colors": "1.1.2"
@ -10051,7 +10051,7 @@
"karma": { "karma": {
"version": "1.7.1", "version": "1.7.1",
"resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz", "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz",
"integrity": "sha1-hcwI6eCiLXzpzKN8ShvoJPaisa4=", "integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==",
"dev": true, "dev": true,
"requires": { "requires": {
"bluebird": "3.5.1", "bluebird": "3.5.1",
@ -10103,7 +10103,7 @@
"karma-chrome-launcher": { "karma-chrome-launcher": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz",
"integrity": "sha1-zxudBxNswY/iOTJ9JGVMPbw2is8=", "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==",
"dev": true, "dev": true,
"requires": { "requires": {
"fs-access": "1.0.1", "fs-access": "1.0.1",
@ -10113,7 +10113,7 @@
"karma-firefox-launcher": { "karma-firefox-launcher": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.1.0.tgz", "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.1.0.tgz",
"integrity": "sha1-LEcDBFLwRTHrfRPU/HZpYwu5Mzk=", "integrity": "sha512-LbZ5/XlIXLeQ3cqnCbYLn+rOVhuMIK9aZwlP6eOLGzWdo1UVp7t6CN3DP4SafiRLjexKwHeKHDm0c38Mtd3VxA==",
"dev": true "dev": true
}, },
"karma-jasmine": { "karma-jasmine": {
@ -10134,7 +10134,7 @@
"karma-webpack": { "karma-webpack": {
"version": "2.0.9", "version": "2.0.9",
"resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.9.tgz", "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.9.tgz",
"integrity": "sha1-YciAkffdkQY1E0wDKyZqRlr/tX8=", "integrity": "sha512-F1j3IG/XhiMzcunAXbWXH95uizjzr3WdTzmVWlta8xqxcCtAu9FByCb4sccIMxaVFAefpgnUW9KlCo0oLvIX6A==",
"dev": true, "dev": true,
"requires": { "requires": {
"async": "0.9.2", "async": "0.9.2",
@ -14654,7 +14654,7 @@
"useragent": { "useragent": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz",
"integrity": "sha1-IX+UOtVAyyEoZYqyP8lg9qiMmXI=", "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==",
"dev": true, "dev": true,
"requires": { "requires": {
"lru-cache": "4.1.1", "lru-cache": "4.1.1",

11
services/auth/Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM node:8.9.4
COPY auth /app
COPY loopback /loopback
WORKDIR /app
RUN npm install
RUN npm -g install pm2
CMD ["pm2-docker", "./server/server.js"]

View File

@ -0,0 +1,12 @@
FROM node:8.9.4
COPY client /app
COPY loopback /loopback
WORKDIR /app
RUN npm install
RUN npm -g install pm2
CMD ["pm2-docker", "./server/server.js"]

View File

@ -0,0 +1,38 @@
DROP PROCEDURE IF EXISTS mysql.truncateAll;
DELIMITER $$
CREATE PROCEDURE mysql.truncateAll()
BEGIN
DECLARE vSchema VARCHAR(255);
DECLARE vTable VARCHAR(255);
DECLARE vDone BOOL;
DECLARE cTables CURSOR FOR
SELECT `TABLE_SCHEMA`, `TABLE_NAME`
FROM `information_schema`.`TABLES`
WHERE `TABLE_TYPE` = 'BASE TABLE'
AND `TABLE_ROWS` > 0
AND `TABLE_SCHEMA` NOT IN ('information_schema', 'mysql', 'performance_schema');
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
SET FOREIGN_KEY_CHECKS = FALSE;
OPEN cTables;
l: LOOP
SET vDone = FALSE;
FETCH cTables INTO vSchema, vTable;
IF vDone THEN
LEAVE l;
END IF;
SET @stmt = CONCAT('TRUNCATE TABLE `', vSchema, '`.`', vTable, '`');
PREPARE stmt FROM @stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cTables;
SET FOREIGN_KEY_CHECKS = TRUE;
END$$
DELIMITER ;

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +0,0 @@
CREATE TABLE vn.itemLog
SELECT * FROM vn.entryLog LIMIT 0;
ALTER TABLE `vn`.`itemLog`
ADD INDEX `itemLogItemFk_idx` (`originFk` ASC),
ADD INDEX `itemLogUserFk_idx` (`userFk` ASC);
ALTER TABLE `vn`.`itemLog`
ADD CONSTRAINT `itemLogItemFk`
FOREIGN KEY (`originFk`)
REFERENCES `vn2008`.`Articles` (`Id_Article`)
ON DELETE NO ACTION
ON UPDATE CASCADE,
ADD CONSTRAINT `itemLogUserFk`
FOREIGN KEY (`userFk`)
REFERENCES `account`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE CASCADE;

6
services/db/02-changes.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
for file in changes/*/*.sql; do
echo "Importing $file"
mysql -u root < $file
done

View File

@ -272,14 +272,14 @@ INSERT INTO `account`.`user`(`id`,`name`,`password`,`role`,`active`,`email`)
(10, 'JessicaJones', 'ac754a330530832ba1bf7687f577da91', 9, 1, 'JessicaJones@verdnatura.es'), (10, 'JessicaJones', 'ac754a330530832ba1bf7687f577da91', 9, 1, 'JessicaJones@verdnatura.es'),
(11, 'Cyborg', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'cyborg@verdnatura.es'); (11, 'Cyborg', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'cyborg@verdnatura.es');
INSERT INTO `salix`.`Country`(`id`, `name`, `inCee`, `code`, `currencyFk`, `realCountryFk`) INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`)
VALUES VALUES
(1, 'España', 0, 'ES', 1, 1), (1, 'España', 0, 'ES', 1),
(2, 'Italia', 1, 'IT', 1, 2), (2, 'Italia', 1, 'IT', 1),
(3, 'Alemania', 1, 'DE', 1, 3), (3, 'Alemania', 1, 'DE', 1),
(4, 'Rumania', 1, 'RO', 1, 4), (4, 'Rumania', 1, 'RO', 1),
(5, 'Holanda', 1, 'NL', 1, 5), (5, 'Holanda', 1, 'NL', 1),
(30,'Francia', 1, 'FR', 1, 6); (30,'Francia', 1, 'FR', 1);
INSERT INTO `vn`.`warehouse`(`id`, `name`, `isComparative`, `isInventory`, `isManaged`) INSERT INTO `vn`.`warehouse`(`id`, `name`, `isComparative`, `isInventory`, `isManaged`)
VALUES VALUES
@ -305,7 +305,7 @@ INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`)
VALUES VALUES
(8, 'Pay on receipt', '0000000000', 4, 0, 1); (8, 'Pay on receipt', '0000000000', 4, 0, 1);
INSERT INTO `salix`.`Agency`(`id`, `name`, `warehouseFk`, `isVolumetric`, `bankFk`, `warehouseAliasFk`) INSERT INTO `vn`.`agency`(`id`, `name`, `warehouseFk`, `isVolumetric`, `bankFk`, `warehouseAliasFk`)
VALUES VALUES
(1, 'inhouse pickup', 1, 0, 8, 1), (1, 'inhouse pickup', 1, 0, 8, 1),
(2, 'Super-Man delivery', 1, 0, 8, 1), (2, 'Super-Man delivery', 1, 0, 8, 1),
@ -329,7 +329,7 @@ INSERT INTO `vn`.`payMethod`(`id`, `name`, `graceDays`, `outstandingDebt`, `iban
(4, 'PayMethod with IBAN', 0, 001, 1), (4, 'PayMethod with IBAN', 0, 001, 1),
(5, 'PayMethod five', 10, 001, 0); (5, 'PayMethod five', 10, 001, 0);
INSERT INTO `salix`.`Zone`(`id`, `name`, `printingOrder`) INSERT INTO `vn2008`.`zones`(`zone_id`, `name`, `printingOrder`)
VALUES VALUES
(1, 'zone one', 1), (1, 'zone one', 1),
(2, 'zone two', 2), (2, 'zone two', 2),
@ -388,20 +388,20 @@ INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city
(9, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceBanner@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1), (9, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceBanner@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1),
(10, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'JessicaJones@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1); (10, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'JessicaJones@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1);
INSERT INTO `salix`.`Address`(`id`, `consignee`, `street`, `city`, `postcode`, `provinceFk`, `phone`, `mobile`, `isEnabled`, `isDefaultAddress`, `clientFk`, `defaultAgencyFk`, `longitude`, `latitude`, `isEqualizated`) INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `isDefaultAddress`, `clientFk`, `agencyFk`, `longitude`, `latitude`, `isEqualizated`)
VALUES VALUES
(1, 'Bruce Wayne', 'The Bat cave', 'Silla', 46460, 1, NULL, NULL, 1, 1, 1, 2, NULL, NULL, 0), (101, 'Bruce Wayne', 'The Bat cave', 'Silla', 46460, 1, NULL, NULL, 1, 1, 1, 2, NULL, NULL, 0),
(2, 'Petter Parker', 'NY roofs', 'Silla', 46460, 1, NULL, NULL, 1, 1, 2, 2, NULL, NULL, 0), (102, 'Petter Parker', 'NY roofs', 'Silla', 46460, 1, NULL, NULL, 1, 1, 2, 2, NULL, NULL, 0),
(3, 'Clark Kenn', 'The phone box', 'Silla', 46460, 1, NULL, NULL, 1, 1, 3, 2, NULL, NULL, 0), (103, 'Clark Kenn', 'The phone box', 'Silla', 46460, 1, NULL, NULL, 1, 1, 3, 2, NULL, NULL, 0),
(4, 'Tony Stark', 'Stark tower', 'Silla', 46460, 1, NULL, NULL, 1, 1, 4, 2, NULL, NULL, 0), (104, 'Tony Stark', 'Stark tower', 'Silla', 46460, 1, NULL, NULL, 1, 1, 4, 2, NULL, NULL, 0),
(5, 'Max Eisenhardt', 'The plastic cell', 'Silla', 46460, 1, NULL, NULL, 1, 1, 5, 2, NULL, NULL, 0), (105, 'Max Eisenhardt', 'The plastic cell', 'Silla', 46460, 1, NULL, NULL, 1, 1, 5, 2, NULL, NULL, 0),
(6, 'David Charles Haller', 'Many places', 'Silla', 46460, 1, NULL, NULL, 1, 1, 6, 2, NULL, NULL, 0), (106, 'David Charles Haller', 'Many places', 'Silla', 46460, 1, NULL, NULL, 1, 1, 6, 2, NULL, NULL, 0),
(7, 'Hank Pym', 'Your pocket', 'Silla', 46460, 1, NULL, NULL, 1, 1, 7, 2, NULL, NULL, 0), (107, 'Hank Pym', 'Your pocket', 'Silla', 46460, 1, NULL, NULL, 1, 1, 7, 2, NULL, NULL, 0),
(8, 'Charles Xavier', 'Cerebro', 'Silla', 46460, 1, NULL, NULL, 1, 1, 8, 2, NULL, NULL, 0), (108, 'Charles Xavier', 'Cerebro', 'Silla', 46460, 1, NULL, NULL, 1, 1, 8, 2, NULL, NULL, 0),
(9, 'Bruce Banner', 'Somewhere in Thailand', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0), (109, 'Bruce Banner', 'Somewhere in Thailand', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(10,'Jessica Jones', 'Luke Cages Bar', 'Silla', 46460, 1, NULL, NULL, 1, 1, 10, 2, NULL, NULL, 0); (110, 'Jessica Jones', 'Luke Cages Bar', 'Silla', 46460, 1, NULL, NULL, 1, 1, 10, 2, NULL, NULL, 0);
INSERT INTO `salix`.`ClientCredit`(`id`, `clientFk`, `employeeFk`, `amount`, `created`) INSERT INTO `vn`.`clientCredit`(`id`, `clientFk`, `workerFk`, `amount`, `created`)
VALUES VALUES
(1, 1, 1, 1200, CURDATE()), (1, 1, 1, 1200, CURDATE()),
(2, 2, 2, 800, CURDATE()), (2, 2, 2, 800, CURDATE()),
@ -409,13 +409,13 @@ INSERT INTO `salix`.`ClientCredit`(`id`, `clientFk`, `employeeFk`, `amount`, `cr
(4, 4, 4, 90, CURDATE()), (4, 4, 4, 90, CURDATE()),
(5, 5, 5, 90, CURDATE()); (5, 5, 5, 90, CURDATE());
INSERT INTO `salix`.`ClientCreditLimit`(`id`, `maxAmount`, `roleFk`) INSERT INTO `vn`.`clientCreditLimit`(`id`, `maxAmount`, `roleFk`)
VALUES VALUES
(1, 1000, 5), (1, 1000, 5),
(2, 600, 5), (2, 600, 5),
(3, 0, 5); (3, 0, 5);
INSERT INTO `salix`.`ClientObservation`(`id`, `clientFk`, `employeeFk`, `text`, `created`) INSERT INTO `vn`.`clientObservation`(`id`, `clientFk`, `workerFk`, `text`, `created`)
VALUES VALUES
(1, 1, 1, 'Madness, as you know, is like gravity, all it takes is a little push', CURDATE()), (1, 1, 1, 'Madness, as you know, is like gravity, all it takes is a little push', CURDATE()),
(2, 2, 1, 'With great power, comes great responsibility', CURDATE()), (2, 2, 1, 'With great power, comes great responsibility', CURDATE()),
@ -448,7 +448,7 @@ INSERT INTO `vn`.`creditClassification`(`id`, `client`, `dateStart`, `dateEnd`)
(4, 4, CURDATE(), CURDATE()), (4, 4, CURDATE(), CURDATE()),
(5, 5, CURDATE(), CURDATE()); (5, 5, CURDATE(), CURDATE());
INSERT INTO `salix`.`Route`(`id`, `date`) INSERT INTO `vn`.`route`(`id`, `created`)
VALUES VALUES
(1, CURDATE()), (1, CURDATE()),
(2, CURDATE()), (2, CURDATE()),
@ -458,7 +458,7 @@ INSERT INTO `salix`.`Route`(`id`, `date`)
(6, CURDATE()), (6, CURDATE()),
(7, CURDATE()); (7, CURDATE());
INSERT INTO `salix`.`State`(`id`, `name`, `order`, `alertLevel`, `code`) INSERT INTO `vn`.`state`(`id`, `name`, `order`, `alertLevel`, `code`)
VALUES VALUES
(1, 'To check', 2, 0, 'FIXING'), (1, 'To check', 2, 0, 'FIXING'),
(2, 'Owes', 1, 0, 'FREE'), (2, 'Owes', 1, 0, 'FREE'),
@ -475,16 +475,16 @@ INSERT INTO `vn2008`.`empresa`(`id`, `abbreviation`, `registro`, `gerente_id`, `
INSERT INTO `vn`.`ticket`(`id`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `clientFk`,`nickname`, `addressFk`) INSERT INTO `vn`.`ticket`(`id`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `clientFk`,`nickname`, `addressFk`)
VALUES VALUES
(1, 1, 1, NULL, CURDATE(), 1, 'Batman', 1), (1, 1, 1, NULL, CURDATE(), 1, 'Batman', 101),
(2, 1, 1, NULL, CURDATE(), 1, 'Spider-Man', 2), (2, 1, 1, NULL, CURDATE(), 1, 'Spider-Man', 102),
(3, 2, 2, NULL, CURDATE(), 2, 'Super-Man', 3), (3, 2, 2, NULL, CURDATE(), 2, 'Super-Man', 103),
(4, 2, 2, NULL, CURDATE(), 2, 'Iron-Man', 4), (4, 2, 2, NULL, CURDATE(), 2, 'Iron-Man', 104),
(5, 3, 3, NULL, CURDATE(), 3, 'Magneto', 5), (5, 3, 3, NULL, CURDATE(), 3, 'Magneto', 105),
(6, 3, 3, NULL, CURDATE(), 3, 'Legion', 6), (6, 3, 3, NULL, CURDATE(), 3, 'Legion', 106),
(7, 4, 4, NULL, CURDATE(), 4, 'Ant-Man', 7), (7, 4, 4, NULL, CURDATE(), 4, 'Ant-Man', 107),
(8, 4, 4, NULL, CURDATE(), 4, 'Professor X', 8), (8, 4, 4, NULL, CURDATE(), 4, 'Professor X', 108),
(9, 5, 5, NULL, CURDATE(), 5, 'Hulk', 9), (9, 5, 5, NULL, CURDATE(), 5, 'Hulk', 109),
(10, 6, 5, NULL, CURDATE(), 5, 'Jessica Jones', 10); (10, 6, 5, NULL, CURDATE(), 5, 'Jessica Jones', 110);
INSERT INTO `vn`.`ticketTracking`(`id`, `ticketFk`, `stateFk`, `workerFk`, `created`) INSERT INTO `vn`.`ticketTracking`(`id`, `ticketFk`, `stateFk`, `workerFk`, `created`)
VALUES VALUES

View File

@ -3,9 +3,11 @@ FROM mysql:5.6.37
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
ENV TZ GMT-1 ENV TZ GMT-1
COPY *.sql /docker-entrypoint-initdb.d/ WORKDIR /docker-entrypoint-initdb.d
COPY *.sql ./
RUN chmod -R 755 /docker-entrypoint-initdb.d COPY 02-changes.sh .
COPY changes changes
RUN chmod -R 755 .
CMD ["mysqld"] CMD ["mysqld"]

View File

@ -0,0 +1,20 @@
CREATE OR REPLACE
ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`agencyMode` AS
SELECT
`a`.`Id_Agencia` AS `id`,
`a`.`Agencia` AS `name`,
`a`.`description` AS `description`,
`a`.`Vista` AS `deliveryMethodFk`,
`a`.`m3` AS `m3`,
`a`.`cod71` AS `cod71`,
`a`.`web` AS `web`,
`a`.`agency_id` AS `agencyFk`,
`a`.`agency_service_id` AS `agencyServiceFk`,
`a`.`inflacion` AS `inflation`,
`a`.`is_volumetric` AS `isVolumetric`,
`a`.`send_mail` AS `reportMail`
FROM
`vn2008`.`Agencias` `a`

View File

@ -0,0 +1,15 @@
CREATE OR REPLACE
ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`agencyHour` AS
SELECT
`h`.`agency_hour_id` AS `id`,
`h`.`agency_id` AS `agencyFk`,
`h`.`week_day` AS `weekDay`,
`h`.`warehouse_id` AS `warehouseFk`,
`h`.`province_id` AS `provinceFk`,
`h`.`subtract_day` AS `substractDay`,
`h`.`max_hour` AS `maxHour`
FROM
`vn2008`.`agency_hour` `h`

View File

@ -0,0 +1,24 @@
CREATE OR REPLACE
ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`address` AS
SELECT
`t`.`id_consigna` AS `id`,
`t`.`Id_cliente` AS `clientFk`,
`t`.`domicilio` AS `street`,
`t`.`poblacion` AS `city`,
`t`.`codPostal` AS `postalCode`,
`t`.`province_id` AS `provinceFk`,
`t`.`telefono` AS `phone`,
`t`.`movil` AS `mobile`,
`t`.`consignatario` AS `nickname`,
`t`.`predeterminada` AS `isDefaultAddress`,
`t`.`longitude` AS `longitude`,
`t`.`latitude` AS `latitude`,
`t`.`warehouse_id` AS `warehouseFk`,
`t`.`Id_Agencia` AS `agencyFk`,
`t`.`isEqualizated` AS `isEqualizated`,
`t`.`active` AS `isActive`
FROM
`vn2008`.`Consignatarios` `t`

12
services/item/Dockerfile Normal file
View File

@ -0,0 +1,12 @@
FROM node:8.9.4
COPY item /app
COPY loopback /loopback
WORKDIR /app
RUN npm install
RUN npm -g install pm2
CMD ["pm2-docker", "./server/server.js"]

View File

@ -1,27 +1,19 @@
module.exports = Self => { module.exports = Self => {
Self.remoteMethod('itemLog', { Self.installMethod('getLog', filterParams);
description: 'Returns the item changes log',
accessType: 'READ',
accepts: [{
arg: 'id',
type: 'number',
required: true,
description: 'The item id',
http: {source: 'path'}
}],
returns: {
arg: 'data',
type: ['Object'],
root: true
},
http: {
path: `/:id/itemLog`,
verb: 'get'
}
});
Self.itemLog = itemFk => { function filterParams(params) {
let query = `SELECT * FROM vn.itemLog WHERE itemFk = ?`; return {
return Self.rawSql(query, [itemFk]); where: {
itemFk: params.itemFk
},
skip: (params.page - 1) * params.size,
limit: params.size,
include: [{
relation: "origin"
},
{
relation: "user"
}]
}; };
}
}; };

View File

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

View File

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

View File

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

View File

@ -34,5 +34,8 @@
}, },
"Tag": { "Tag": {
"dataSource": "vn" "dataSource": "vn"
},
"ItemLog": {
"dataSource": "vn"
} }
} }

View File

@ -0,0 +1,11 @@
FROM node:8.9.4
COPY mailer /app
COPY loopback /loopback
WORKDIR /app
RUN npm install
RUN npm -g install pm2
CMD ["pm2-docker", "./server/server.js"]

11
services/print/Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM node:8.9.4
COPY print /app
COPY loopback /loopback
WORKDIR /app
RUN npm install
RUN npm -g install pm2
CMD ["pm2-docker", "./server/server.js"]

View File

@ -0,0 +1,11 @@
FROM node:8.9.4
COPY production /app
COPY loopback /loopback
WORKDIR /app
RUN npm install
RUN npm -g install pm2
CMD ["pm2-docker", "./server/server.js"]

11
services/route/Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM node:8.9.4
COPY route /app
COPY loopback /loopback
WORKDIR /app
RUN npm install
RUN npm -g install pm2
CMD ["pm2-docker", "./server/server.js"]

11
services/salix/Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM node:8.9.4
COPY salix /app
COPY loopback /loopback
WORKDIR /app
RUN npm install
RUN npm -g install pm2
CMD ["pm2-docker", "./server/server.js"]

View File

@ -36,4 +36,3 @@ jasmine.addReporter(new SpecReporter({
})); }));
jasmine.execute(); jasmine.execute();