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

This commit is contained in:
Gerard 2018-04-19 09:31:28 +02:00
commit b4af50cc48
39 changed files with 731 additions and 211 deletions

View File

@ -29,4 +29,5 @@ import './combo/combo';
import './card/card';
import './switch/switch';
import './float-button/float-button';
import './step-control/step-control';
import './label-value/label-value';

View File

@ -0,0 +1,33 @@
<section class="step-control">
<section class="steps">
<section class="step" ng-repeat="step in $ctrl.steps track by $index">
<section class="circle"
vn-tooltip="{{::step.name}}"
tooltip-position="down"
ng-click="$ctrl.currentState = step.state"
ng-class="{active: step.state == $ctrl.currentState}">
</section>
</section>
</section>
<section class="buttons">
<section class="step">
<vn-button
ng-if="$ctrl.canMovePrevious()"
label="Previous"
ng-click="$ctrl.onPreviousClick()">
</vn-button>
</section>
<section class="step">
<vn-button
ng-if="$ctrl.canMoveNext()"
label="Next"
ng-click="$ctrl.onNextClick()">
</vn-button>
<vn-submit
ng-if="$ctrl.canFinalize()"
label="Finalize"
ng-click="$ctrl.onStepEnd()">
</vn-submit>
</section>
</section>
</section>

View File

@ -0,0 +1,71 @@
import ngModule from '../../module';
import './style.scss';
export default class StepControl {
constructor($state) {
this.$state = $state;
}
set currentState(state) {
let isAllowed = true;
if (this.onStepChange)
isAllowed = this.onStepChange({state});
if (isAllowed)
this.$state.go(state);
}
get totalSteps() {
return this.steps.length;
}
get currentState() {
return this.$state.current.name;
}
get currentStepIndex() {
for (let i = 0; i < this.steps.length; i++) {
if (this.steps[i].state == this.$state.current.name)
return i;
}
}
onPreviousClick() {
let state = this.steps[this.currentStepIndex - 1].state;
this.currentState = state;
}
onNextClick() {
let state = this.steps[this.currentStepIndex + 1].state;
this.currentState = state;
}
canMovePrevious() {
return this.steps[0].state != this.currentState;
}
canFinalize() {
let lastStep = this.steps[this.totalSteps - 1];
return lastStep.state == this.currentState;
}
canMoveNext() {
let lastStep = this.steps[this.totalSteps - 1];
return lastStep.state != this.currentState;
}
}
StepControl.$inject = ['$state'];
ngModule.component('vnStepControl', {
template: require('./step-control.html'),
controller: StepControl,
bindings: {
steps: '<',
onStepChange: '&?',
onStepEnd: '&?'
}
});

View File

@ -0,0 +1,49 @@
import './step-control.js';
describe('Component vnStepControl', () => {
let $componentController;
let controller;
let $state;
beforeEach(() => {
angular.mock.module('ticket');
});
beforeEach(angular.mock.inject((_$componentController_, _$state_) => {
$componentController = _$componentController_;
$state = _$state_;
controller = $componentController('vnStepControl', {$state: $state});
}));
describe('currentState()', () => {
it(`should call the onStepChange method then return false and never call the go method`, () => {
controller.onStepChange = jasmine.createSpy(controller, 'onStepChange').and.returnValue(false);
spyOn(controller.$state, 'go');
controller.currentState = "something";
expect(controller.onStepChange).toHaveBeenCalledWith({state: 'something'});
expect(controller.$state.go).not.toHaveBeenCalledWith("something");
});
it(`should call the onStepChange method then return true and finally call the go method`, () => {
controller.onStepChange = jasmine.createSpy(controller, 'onStepChange').and.returnValue(true);
spyOn(controller.$state, 'go');
controller.currentState = "something";
expect(controller.onStepChange).toHaveBeenCalledWith({state: 'something'});
expect(controller.$state.go).toHaveBeenCalledWith("something");
});
});
describe('currentStepIndex()', () => {
it('should get the current state index from an Array of states', () => {
controller.$state.current.name = 'iam_a_current_state';
controller.steps = [{state: 'iam_not_current_state'}, {state: 'iam_a_current_state'}];
let result = controller.currentStepIndex;
expect(result).toEqual(1);
});
});
});

View File

@ -0,0 +1,58 @@
vn-step-control {
display: flex;
justify-content: center;
.step-control {
border-top: 2px solid rgb(255,152,0);
margin-bottom: 15px;
& > .steps {
display: flex;
flex-direction: row
}
& > .steps > .step {
justify-content: center;
min-width: 125px;
display: flex;
flex: auto
}
& > .steps > .step .circle {
border: 2px solid rgb(255,152,0);
background-color: #FFF;
align-content: center;
margin-top: -9.5px;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
cursor: pointer;
height: 15px;
width: 15px
}
& > .steps > .step .circle.active {
background-color: rgb(255,152,0);
}
& > .buttons {
display: flex;
flex: auto;
flex-direction: row;
justify-content: space-between;
margin-top: 10px
}
& > .buttons > .step {
display: flex
}
& > .buttons > .step > .mdl-button {
line-height: 32px;
font-size: 12px;
padding: 0 12px;
height: 32px
}
}
}

View File

@ -7,4 +7,7 @@ Add: Add
Search: Search
Show More: Show More
No more results: No more results
Hide: Hide
Hide: Hide
Next: Next
Finalize: Finalize
Previous: Back

View File

@ -7,4 +7,7 @@ Add: Añadir
Search: Buscar
Show More: Ver más
No more results: No hay más resultados
Hide: Ocultar
Hide: Ocultar
Next: Siguiente
Finalize: Finalizar
Previous: Anterior

View File

@ -3,6 +3,14 @@
id="user">
<h6>{{currentUserName}}</h6>
</div>
<a href="/salix/version-notes.html"
target="version-notes">
<vn-icon
id="version-notes"
icon="info"
translate-attr="{title: 'What is new'}">
</vn-icon>
</a>
<vn-icon
id="apps"
icon="apps"

View File

@ -6,7 +6,7 @@ vn-main-menu {
height: 2.5em;
vertical-align: middle;
}
& > div > vn-icon {
& > div > vn-icon, & > div > a > vn-icon {
font-size: 2.2em;
cursor: pointer;

View File

@ -1,26 +1,27 @@
Applications: Aplicaciones
Home: Inicio
Notifications: Notificaciones
Logout: Cerrar sesión
Change language: Cambiar idioma
Profile: Perfil
Data saved!: ¡Datos guardados!
Can't contact with server: No se pudo contactar con el servidor
Push on applications menu: Para abrir un módulo pulsa en el menú de aplicaciones
Clients: Clientes
Routes : Rutas
Production : Producción
Modules access : Acceso a módulos
Locator: Localizador
Items: Artículos
name: Nombre
credit: Crédito
phone: Teléfono
creditInsurance: Crédito Asegurado
Return to module index: Volver a la página principal del módulo
Preview: Vista previa
Client has debt: Cliente con riesgo
Web Account inactive: Sin acceso Web
Change language: Cambiar idioma
Client Frozen: Cliente congelado
Client has debt: Cliente con riesgo
Client inactive: Cliente inactivo
Client not checked: Cliente no comprobado
Client not checked: Cliente no comprobado
Clients: Clientes
credit: Crédito
creditInsurance: Crédito Asegurado
Data saved!: ¡Datos guardados!
Home: Inicio
Items: Artículos
Locator: Localizador
Logout: Cerrar sesión
Modules access : Acceso a módulos
Notifications: Notificaciones
name: Nombre
phone: Teléfono
Preview: Vista previa
Production : Producción
Profile: Perfil
Push on applications menu: Para abrir un módulo pulsa en el menú de aplicaciones
Return to module index: Volver a la página principal del módulo
Routes: Rutas
What is new: Novedades de la versión
Web Account inactive: Sin acceso Web

View File

@ -1,4 +1,4 @@
<form name="form" ng-submit="$ctrl.onSubmit()" ng-cloak>
<form name="form">
<vn-card pad-large>
<vn-title>Basic data</vn-title>
<vn-horizontal>
@ -19,7 +19,7 @@
initial-data="$ctrl.ticket.addressFk">
</vn-autocomplete>
<vn-autocomplete vn-one
url="/api/AgencyModes/"
url="/api/AgencyModes"
label="Agency"
show-field="name"
value-field="id"
@ -48,7 +48,4 @@
</vn-autocomplete>
</vn-horizontal>
</vn-card>
<vn-button-bar>
<vn-submit label="Next"></vn-submit>
</vn-button-bar>
</form>

View File

@ -1,22 +1,17 @@
import ngModule from '../../module';
class Controller {
constructor($scope, $timeout, $state) {
constructor($scope) {
this.$scope = $scope;
this.$timeout = $timeout;
this.$state = $state;
}
onSubmit() {
this.$state.go('ticket.card.data.stepTwo');
}
}
Controller.$inject = ['$scope', '$timeout', '$state'];
Controller.$inject = ['$scope'];
ngModule.component('vnTicketDataStepOne', {
template: require('./step-one.html'),
controller: Controller,
bindings: {
ticket: '<'
},
controller: Controller
}
});

View File

@ -0,0 +1,8 @@
<form name="form">
<vn-card pad-large>
<vn-title>Step tree</vn-title>
<vn-horizontal>
Ticket id {{$ctrl.ticket.id}}
</vn-horizontal>
</vn-card>
</form>

View File

@ -0,0 +1,15 @@
import ngModule from '../../module';
class Controller {
constructor($scope) {
this.$scope = $scope;
}
}
ngModule.component('vnTicketDataStepThree', {
template: require('./step-three.html'),
controller: Controller,
bindings: {
ticket: '<'
}
});

View File

@ -0,0 +1,29 @@
<form name="form">
<vn-card pad-large>
<vn-title>Price gap</vn-title>
<vn-horizontal>
<table class="vn-grid">
<thead>
<tr>
<th number translate>Item</th>
<th translate style="text-align:center">Description</th>
<th number translate>Quantity</th>
<th number translate>Price</th>
<th number translate>New price</th>
<th number translate>Price gap</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="sale in $ctrl.ticket.sales track by sale.id">
<td number>{{("000000"+sale.itemFk).slice(-6)}}</td>
<td><vn-fetched-tags sale="sale"/></td>
<td number>{{::sale.quantity}}</td>
<td number>{{::sale.price | currency:'€':2}}</td>
<td number>-</td>
<td number>-</td>
</tr>
</tbody>
</table>
</vn-horizontal>
</vn-card>
</form>

View File

@ -0,0 +1,28 @@
import ngModule from '../../module';
class Controller {
constructor($http, $scope) {
this.$http = $http;
this.$scope = $scope;
}
$onChanges(data) {
if (!this.ticket || !this.ticket.id) return;
let query = `/ticket/api/sales/${this.ticket.id}/priceGap`;
this.$http.get(query).then(res => {
if (res.data)
this.ticket.sales = res.data;
});
}
}
Controller.$inject = ['$http', '$scope'];
ngModule.component('vnTicketDataStepTwo', {
template: require('./step-two.html'),
controller: Controller,
bindings: {
ticket: '<'
}
});

View File

@ -151,6 +151,13 @@ INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city
(109, '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, 0, 1, NULL, 0, 0, 19, 0, 1),
(110, '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, 0, 1, NULL, 0, 0, NULL, 0, 1);
INSERT INTO `vn`.`clientManaCache`(`clientFk`, `mana`, `dated`)
VALUES
( 101, 50, CURDATE()),
( 102, 100, CURDATE()),
( 103, 0, CURDATE()),
( 104, -30, CURDATE());
INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `isDefaultAddress`, `clientFk`, `agencyModeFk`, `longitude`, `latitude`, `isEqualizated`)
VALUES
(101, '01', 'Somewhere in Thailand', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
@ -537,7 +544,7 @@ INSERT INTO `bi`.`rotacion`(`Id_Article`, `warehouse_id`, `total`, `rotacion`, `
INSERT INTO `vn`.`annualAverageInvoiced`(`clientFk`, `invoiced`)
VALUES
( 101, 0),
( 101, 1500),
( 102, 100),
( 103, 1000),
( 104, 500),

View File

@ -0,0 +1,29 @@
USE `vn`;
DROP procedure IF EXISTS `ticketVolume`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketVolume`(IN vTicketId INT)
BEGIN
DECLARE vWarehouseId INTEGER;
DECLARE vShippedDate DATE;
DROP TEMPORARY TABLE IF EXISTS ticketVolume;
SELECT warehouseFk, shipped INTO vWarehouseId,vShippedDate FROM vn.ticket WHERE id = vTicketId;
CREATE TEMPORARY TABLE IF NOT EXISTS ticketVolume ENGINE MEMORY
SELECT itemFk, saleFk, quantity, concept, VolUd as m3_uni, volume as m3, volume * quantity as volumeTimesQuantity, @m3:= @m3 + ifnull(volume,0) as m3_total
FROM
(
SELECT round(r.cm3 / 1000000,3) as VolUd ,s.quantity, round(r.cm3 * s.quantity / 1000000,3) as volume,
s.itemFk, s.id AS saleFk, s.concept, @m3:= 0, @vol:=0, t.agencyModeFk
FROM sale s
JOIN vn.ticket t on t.id = s.ticketFk
JOIN bi.rotacion r ON r.Id_Article = s.itemFk AND r.warehouse_id = t.warehouseFk
WHERE s.ticketFk = vTicketId
) sub;
END$$
DELIMITER ;

View File

@ -0,0 +1,17 @@
USE `vn`;
DROP function IF EXISTS `messageSend`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` FUNCTION `messageSend`(vRecipient VARCHAR(255) CHARSET utf8, vMessage TEXT CHARSET utf8) RETURNS int(11)
BEGIN
DECLARE result INT;
DECLARE vSenderFk INT;
SELECT id INTO vSenderFk
FROM account.user WHERE `name` = account.userGetName();
RETURN (SELECT messageSendWithUser(vSenderFk, vRecipient, vMessage));
END$$
DELIMITER ;

View File

@ -0,0 +1,57 @@
USE `vn`;
DROP function IF EXISTS `messageSendWithUser`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` FUNCTION `messageSendWithUser`(vSenderFK INT, vRecipient VARCHAR(255) CHARSET utf8, vMessage TEXT CHARSET utf8) RETURNS int(11)
BEGIN
DECLARE vCount INT;
DECLARE vUuid VARCHAR(255);
DECLARE vSendDate DATETIME DEFAULT NOW();
DECLARE vSender VARCHAR(255) CHARSET utf8;
SELECT `name` INTO vSender
FROM account.user WHERE id = vSenderFK;
SET vRecipient = LOWER(vRecipient);
DROP TEMPORARY TABLE IF EXISTS tRecipients;
CREATE TEMPORARY TABLE tRecipients
SELECT u.name finalRecipient
FROM account.mailAlias a
JOIN account.mailAliasAccount aa ON aa.mailAlias = a.id
JOIN account.user u ON u.id = aa.account
WHERE a.alias = vRecipient COLLATE utf8_unicode_ci
AND u.name != vSender
AND u.active
UNION
SELECT u.name FROM account.user u
WHERE u.name = vRecipient
AND u.active;
SELECT COUNT(*) INTO vCount FROM tRecipients;
IF vCount = 0 THEN
RETURN vCount;
END IF;
SET vUuid = UUID();
INSERT INTO message
SET uuid = vUuid,
sender = vSender,
recipient = vRecipient,
message = vMessage,
sendDate = vSendDate;
INSERT INTO messageInbox (uuid, sender, recipient, finalRecipient, message, sendDate)
SELECT vUuid, vSender, vRecipient, finalRecipient, vMessage, vSendDate
FROM tRecipients;
DROP TEMPORARY TABLE tRecipients;
RETURN vCount;
END$$
DELIMITER ;

View File

@ -1,17 +1,18 @@
const getAverageInvoiced = require('../getAverageInvoiced');
const {rawSql} = require('../../../test-helpers/rawSql');
const model = {
remoteMethod: () => {}
};
let Loopback = require('../../../test-helpers/loopback');
Loopback.init(model);
rawSql(model);
Loopback.rawSql(model);
getAverageInvoiced(model);
describe('client getAverageInvoiced()', () => {
it('should call the getAverageInvoiced method', done => {
model.getAverageInvoiced(101)
.then(response => {
expect(response.invoiced).toEqual(0);
expect(response.invoiced).toEqual(1500);
done();
});
});

View File

@ -1,17 +1,18 @@
const getMana = require('../getMana');
const {rawSql} = require('../../../test-helpers/rawSql');
const model = {
remoteMethod: () => {}
};
let Loopback = require('../../../test-helpers/loopback');
Loopback.init(model);
rawSql(model);
Loopback.rawSql(model);
getMana(model);
describe('client getMana()', () => {
it('should call the getMana method', done => {
model.getMana(101)
.then(response => {
expect(response.mana).toEqual(0);
expect(response.mana).toEqual(30.02);
done();
});
});

View File

@ -1,4 +1,4 @@
var UserError = require('../../helpers').UserError;
let UserError = require('../../helpers').UserError;
module.exports = Self => {
Self.remoteMethod('clone', {

View File

@ -0,0 +1,22 @@
const clone = require('../clone');
const model = {
remoteMethod: () => {}
};
let Loopback = require('../../../test-helpers/loopback');
Loopback.init(model);
Loopback.rawSql(model);
clone(model);
// disabled test while loopback findOne method isnt extended to model yet.
describe('item clone()', () => {
it('should', () => {
// let itemFk = 1;
// model.clone(itemFk)
// .then(response => {
// expect(response).toEqual('whatever');
// done();
// });
});
});

View File

@ -25,7 +25,7 @@ module.exports = Self => {
}
});
Self.updateTaxes = async (id, taxes) => {
Self.updateTaxes = async(id, taxes) => {
let promises = [];
for (let tax of taxes) {
if (!tax.taxClassFk)

View File

@ -1,10 +1,11 @@
const getTaxes = require('../get-taxes');
const {rawSql} = require('../../../test-helpers/rawSql');
const model = {
remoteMethod: () => {}
};
let Loopback = require('../../../test-helpers/loopback');
Loopback.init(model);
rawSql(model);
Loopback.rawSql(model);
getTaxes(model);
describe('ticket getTaxes()', () => {

View File

@ -1,10 +1,11 @@
const getTotal = require('../get-total');
const {rawSql} = require('../../../test-helpers/rawSql');
const model = {
remoteMethod: () => {}
};
let Loopback = require('../../../test-helpers/loopback');
Loopback.init(model);
rawSql(model);
Loopback.rawSql(model);
getTotal(model);
describe('ticket getTotal()', () => {

View File

@ -1,10 +1,11 @@
const getVolume = require('../get-volume');
const {rawSql} = require('../../../test-helpers/rawSql');
const model = {
remoteMethod: () => {}
};
let Loopback = require('../../../test-helpers/loopback');
Loopback.init(model);
rawSql(model);
Loopback.rawSql(model);
getVolume(model);
describe('ticket getVolume()', () => {
@ -16,4 +17,4 @@ describe('ticket getVolume()', () => {
done();
});
});
});
});

View File

@ -1,4 +1,5 @@
module.exports = function(Self) {
require('../methods/sale/filter')(Self);
require('../methods/sale/priceGap')(Self);
require('../methods/sale/saleComponentFilter.js')(Self);
require('../methods/sale/price-gap')(Self);
};

View File

@ -1,38 +1,38 @@
{
"name": "Sale",
"base": "VnModel",
"options": {
"mysql": {
"table": "sale"
}
"name": "Sale",
"base": "VnModel",
"options": {
"mysql": {
"table": "sale"
}
},
"properties": {
"id": {
"id": true,
"type": "Number",
"description": "Identifier"
},
"properties": {
"id": {
"id": true,
"type": "Number",
"description": "Identifier"
},
"concept": {
"type": "String"
},
"quantity": {
"type": "Number"
},
"price": {
"type": "Number"
},
"discount": {
"type": "Number"
},
"reserved": {
"type": "Number"
},
"isPicked": {
"type": "Number"
},
"created": {
"type": "date"
}
"concept": {
"type": "String"
},
"quantity": {
"type": "Number"
},
"price": {
"type": "Number"
},
"discount": {
"type": "Number"
},
"reserved": {
"type": "Number"
},
"isPicked": {
"type": "Number"
},
"created": {
"type": "date"
}
},
"relations": {
"item": {
@ -51,6 +51,11 @@
"type": "hasOne",
"model": "SaleChecked",
"foreignKey": "saleFk"
}
},
"components": {
"type": "hasMany",
"model": "SaleComponent",
"foreignKey": "saleFk"
}
}
}

View File

@ -0,0 +1,39 @@
module.exports = {
importLoopbackModules: function() {
this.rawSqlModule = require('../methods/vnModel/rawSql.js');
this.findOneModule = require('../methods/vnModel/rawSql.js');
},
/**
* Initializes DataSource once
* @param {Object} Self - Model
*/
init: function(Self) {
if (!this.dataSource)
this.connect();
Self.dataSource = this.dataSource;
this.importLoopbackModules();
},
/**
* Instantiate Loopback DataSource
*/
connect: function() {
let DataSource = require('loopback-datasource-juggler').DataSource;
let dataSourceConfig = {
connector: 'mysql',
host: 'localhost',
user: 'root',
password: 'root',
database: 'salix'
};
this.dataSource = new DataSource(dataSourceConfig);
},
rawSql: function(Self) {
this.rawSqlModule(Self);
}
};

View File

@ -1,14 +0,0 @@
module.exports.rawSql = Self => {
const DataSource = require('loopback-datasource-juggler').DataSource;
const rawSql = require('../methods/vnModel/rawSql.js');
const dataSourceConfig = {
connector: 'mysql',
host: 'localhost',
user: 'root',
password: 'root',
database: 'salix'
};
const dataSource = new DataSource(dataSourceConfig);
Self.dataSource = dataSource;
rawSql(Self);
};

View File

@ -0,0 +1,160 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1252"/>
<title></title>
<meta name="generator" content="LibreOffice 6.0.1.1 (Windows)"/>
<meta name="created" content="00:00:00"/>
<meta name="changed" content="2018-04-18T12:46:42.134000000"/>
<style type="text/css">
body,div,table,thead,tbody,tfoot,tr,th,td,p { font-family:"Liberation Sans"; font-size:x-small }
a.comment-indicator:hover + comment { background:#ffd; position:absolute; display:block; border:1px solid black; padding:0.5em; }
a.comment-indicator { background:red; display:inline-block; border:1px solid black; width:0.5em; height:0.5em; }
comment { display:none; }
</style>
</head>
<body>
<table cellspacing="0" border="0">
<colgroup width="33"></colgroup>
<colgroup width="81"></colgroup>
<colgroup width="386"></colgroup>
<tr>
<td height="17" align="left">#</td>
<td align="left">Estado</td>
<td align="left">Asunto</td>
</tr>
<tr>
<td height="17" align="right" sdval="166" sdnum="3082;">166</td>
<td align="left">In Progress</td>
<td align="left">refactorizar buscador avanzado de articulos</td>
</tr>
<tr>
<td height="17" align="right" sdval="171" sdnum="3082;">171</td>
<td align="left">In Progress</td>
<td align="left">A&ntilde;adir revision</td>
</tr>
<tr>
<td height="17" align="right" sdval="211" sdnum="3082;">211</td>
<td align="left">In Progress</td>
<td align="left">Forzar a ciertos tags</td>
</tr>
<tr>
<td height="17" align="right" sdval="213" sdnum="3082;">213</td>
<td align="left">In Progress</td>
<td align="left">Sumario Tickets</td>
</tr>
<tr>
<td height="17" align="right" sdval="216" sdnum="3082;">216</td>
<td align="left">In Progress</td>
<td align="left">Seccion Configuracion paso 2</td>
</tr>
<tr>
<td height="17" align="right" sdval="124" sdnum="3082;">124</td>
<td align="left">Resolved</td>
<td align="left">address observations validations</td>
</tr>
<tr>
<td height="17" align="right" sdval="199" sdnum="3082;">199</td>
<td align="left">Resolved</td>
<td align="left">A&ntilde;adir manejador de cliente que no existe</td>
</tr>
<tr>
<td height="17" align="right" sdval="138" sdnum="3082;">138</td>
<td align="left">Resolved</td>
<td align="left">Refactorizaci&oacute;n Popover</td>
</tr>
<tr>
<td height="17" align="right" sdval="172" sdnum="3082;">172</td>
<td align="left">Resolved</td>
<td align="left">E2E revision</td>
</tr>
<tr>
<td height="17" align="right" sdval="175" sdnum="3082;">175</td>
<td align="left">Resolved</td>
<td align="left">E2E embalajes</td>
</tr>
<tr>
<td height="17" align="right" sdval="177" sdnum="3082;">177</td>
<td align="left">Resolved</td>
<td align="left">Listar modelo saleChecked</td>
</tr>
<tr>
<td height="17" align="right" sdval="182" sdnum="3082;">182</td>
<td align="left">Resolved</td>
<td align="left">Listar volumen del ticket</td>
</tr>
<tr>
<td height="17" align="right" sdval="196" sdnum="3082;">196</td>
<td align="left">Resolved</td>
<td align="left">E2E listar lineas ticket</td>
</tr>
<tr>
<td height="17" align="right" sdval="198" sdnum="3082;">198</td>
<td align="left">Resolved</td>
<td align="left">refactorizar tag con nuevo + - </td>
</tr>
<tr>
<td height="17" align="right" sdval="201" sdnum="3082;">201</td>
<td align="left">Resolved</td>
<td align="left">Listar Mana del cliente</td>
</tr>
<tr>
<td height="17" align="right" sdval="202" sdnum="3082;">202</td>
<td align="left">Resolved</td>
<td align="left">A&ntilde;adir a Sumario Cliente una seccion financia</td>
</tr>
<tr>
<td height="17" align="right" sdval="209" sdnum="3082;">209</td>
<td align="left">Resolved</td>
<td align="left">Contratos de credito</td>
</tr>
<tr>
<td height="17" align="right" sdval="210" sdnum="3082;">210</td>
<td align="left">Resolved</td>
<td align="left">item tags</td>
</tr>
<tr>
<td height="17" align="right" sdval="212" sdnum="3082;">212</td>
<td align="left">Resolved</td>
<td align="left">Mostrar solo las agencias con el campo isActive(tpv) en TRUE</td>
</tr>
<tr>
<td height="17" align="right" sdval="215" sdnum="3082;">215</td>
<td align="left">Resolved</td>
<td align="left">Seccion Configuracion paso 1</td>
</tr>
<tr>
<td height="17" align="right" sdval="220" sdnum="3082;">220</td>
<td align="left">Resolved</td>
<td align="left">Al crear un consignatario mirar RE</td>
</tr>
<tr>
<td height="17" align="right" sdval="222" sdnum="3082;">222</td>
<td align="left">Resolved</td>
<td align="left">nuevo dni espa&ntilde;a</td>
</tr>
<tr>
<td height="17" align="right" sdval="223" sdnum="3082;">223</td>
<td align="left">Resolved</td>
<td align="left">Manejador de errores global</td>
</tr>
<tr>
<td height="17" align="right" sdval="227" sdnum="3082;">227</td>
<td align="left">Resolved</td>
<td align="left">traducciones pendientes</td>
</tr>
<tr>
<td height="17" align="right" sdval="219" sdnum="3082;">219</td>
<td align="left">Feedback</td>
<td align="left">Pair programming</td>
</tr>
</table>
<!-- ************************************************************************** -->
</body>
</html>

View File

@ -1,39 +0,0 @@
module.exports = Self => {
Self.installMethod('filter', filterParams);
function filterParams(params) {
return {
where: {
ticketFk: params.ticketFk
},
skip: (params.page - 1) * params.size,
limit: params.size,
order: params.order || 'concept ASC',
include: [{
relation: "item",
scope: {
include: {
relation: "itemTag",
scope: {
fields: ["tagFk", "value"],
include: {
relation: "tag",
scope: {
fields: ["name"]
}
},
limit: 6
}
},
fields: ["itemFk", "name"]
}
},
{
relation: "isChecked",
scope: {
fields: ["isChecked"]
}
}]
};
}
};

View File

@ -1,4 +0,0 @@
module.exports = function(Self) {
require('../methods/sale/filter.js')(Self);
require('../methods/sale/saleComponentFilter.js')(Self);
};

View File

@ -1,61 +0,0 @@
{
"name": "Sale",
"base": "VnModel",
"options": {
"mysql": {
"table": "sale"
}
},
"properties": {
"id": {
"id": true,
"type": "Number",
"description": "Identifier"
},
"concept": {
"type": "String"
},
"quantity": {
"type": "Number"
},
"price": {
"type": "Number"
},
"discount": {
"type": "Number"
},
"reserved": {
"type": "Number"
},
"isPicked": {
"type": "Number"
},
"created": {
"type": "date"
}
},
"relations": {
"item": {
"type": "belongsTo",
"model": "Item",
"foreignKey": "itemFk",
"required": true
},
"ticket": {
"type": "belongsTo",
"model": "Ticket",
"foreignKey": "ticketFk",
"required": true
},
"isChecked": {
"type": "hasOne",
"model": "SaleChecked",
"foreignKey": "saleFk"
},
"components": {
"type": "hasMany",
"model": "SaleComponent",
"foreignKey": "saleFk"
}
}
}

View File

@ -5,9 +5,6 @@
"ObservationType": {
"dataSource": "vn"
},
"Sale": {
"dataSource": "vn"
},
"TicketTracking": {
"dataSource": "vn"
},