Merge branch 'dev' of https://git.verdnatura.es/salix into dev
This commit is contained in:
commit
2a7c73988c
12
README.md
12
README.md
|
@ -8,14 +8,26 @@ Salix is also the scientific name of a beautifull tree! :)
|
|||
|
||||
Required applications.
|
||||
|
||||
* Visual Studio Code
|
||||
* Node.js = 8.9.4
|
||||
* NGINX
|
||||
* Docker
|
||||
|
||||
In Visual Studio Code we use the ESLint extension. Open Visual Studio Code, press Ctrl+P and paste the following command
|
||||
```
|
||||
ext install dbaeumer.vscode-eslint
|
||||
```
|
||||
|
||||
You will need to install globally the following items.
|
||||
```
|
||||
$ npm install -g karma-cli gulp webpack nodemon
|
||||
```
|
||||
## Linux Only Prerequisites
|
||||
|
||||
Your user must be on the docker group to use it so you will need to run this command:
|
||||
```
|
||||
$ sudo usermod -G docker yourusername
|
||||
```
|
||||
|
||||
## Getting Started // Installing
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
value-field="id"
|
||||
select-fields="name"
|
||||
label="Salesperson"
|
||||
vn-acl="salesAssistant"
|
||||
where="{or: [{firstName: {regexp: 'search'}}, {name: {regexp: 'search'}}]}">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
|
|
|
@ -3,4 +3,3 @@ Enable web access: Habilitar acceso web
|
|||
New password: Nueva contraseña
|
||||
Repeat password: Repetir contraseña
|
||||
Change password: Cambiar contraseña
|
||||
Client must be checked to activate: No se puede activar un cliente si no esta verificado (036)
|
|
@ -13,8 +13,7 @@
|
|||
vn-one
|
||||
label="Enable web access"
|
||||
field="$ctrl.account.active"
|
||||
vn-acl="employee"
|
||||
acl-conditional-to-employee="{{$ctrl.canEnableCheckBox}}">
|
||||
vn-acl="employee">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
|
@ -23,7 +22,6 @@
|
|||
vn-one
|
||||
margin-medium-top
|
||||
label="User"
|
||||
info="Client must be checked to activate"
|
||||
field="$ctrl.account.name">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
|
|
|
@ -16,16 +16,20 @@
|
|||
<vn-autocomplete vn-one
|
||||
url="/item/api/ItemTypes"
|
||||
label="Type"
|
||||
show-field="name"
|
||||
select-fields=["code","name"]
|
||||
value-field="id"
|
||||
field="$ctrl.item.typeFk">
|
||||
field="$ctrl.item.typeFk"
|
||||
where="{or: [{code: {regexp: 'search'}}, {name: {regexp: 'search'}}]}">
|
||||
<tpl-item>{{code}} : {{name}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
url="/item/api/Intrastats"
|
||||
label="Intrastat"
|
||||
value-field="id"
|
||||
show-field="description"
|
||||
field="$ctrl.item.intrastatFk">
|
||||
value-field="id"
|
||||
field="$ctrl.item.intrastatFk"
|
||||
where="{or: [{id: {regexp: 'search'}}, {description: {regexp: 'search'}}]}">
|
||||
<tpl-item>{{id}} : {{description}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"module": "ticket",
|
||||
"name": "Tickets",
|
||||
"icon": "icon-ticket",
|
||||
"validations": false,
|
||||
"validations": true,
|
||||
"routes": [
|
||||
{
|
||||
"url": "/ticket",
|
||||
|
@ -77,16 +77,36 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"url" : "/review",
|
||||
"state": "ticket.card.review",
|
||||
"component": "vn-ticket-review",
|
||||
"url" : "/tracking",
|
||||
"state": "ticket.card.tracking",
|
||||
"component": "vn-ticket-tracking",
|
||||
"params": {
|
||||
"ticket": "$ctrl.ticket"
|
||||
},
|
||||
"menu": {
|
||||
"description": "Review",
|
||||
"description": "Tracking",
|
||||
"icon": "remove_red_eye"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "/create",
|
||||
"state": "ticket.card.tracking.create",
|
||||
"component": "vn-ticket-tracking-create",
|
||||
"params": {
|
||||
"client": "$ctrl.client"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url" : "/sale",
|
||||
"state": "ticket.card.sale",
|
||||
"component": "vn-ticket-sale",
|
||||
"params": {
|
||||
"ticket": "$ctrl.ticket"
|
||||
},
|
||||
"menu": {
|
||||
"description": "Sale",
|
||||
"icon": "icon-lines"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import FilterList from 'core/src/lib/filter-list';
|
||||
|
||||
export default class FilterTicketList extends FilterList {
|
||||
constructor($scope, $timeout, $state) {
|
||||
super($scope, $timeout, $state);
|
||||
this.modelName = 'ticketFk';
|
||||
}
|
||||
}
|
||||
FilterTicketList.$inject = ['$scope', '$timeout', '$state'];
|
|
@ -1,6 +1,13 @@
|
|||
Tickets: Tickets
|
||||
Amount: Importe
|
||||
Basic data: Datos básicos
|
||||
Description: Descripción
|
||||
Discount: Descuento
|
||||
Item: Articulo
|
||||
Notes: Notas
|
||||
Observation type: Tipo de observación
|
||||
Description: Descripción
|
||||
The observation type must be unique: El tipo de observación debe ser único
|
||||
Price: Precio
|
||||
Quantity: Cantidad
|
||||
Sale: Lineas del pedido
|
||||
Some fields are invalid: Algunos campos no son válidos
|
||||
The observation type must be unique: El tipo de observación debe ser único
|
||||
Tickets: Tickets
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
<mg-ajax
|
||||
path="/ticket/api/Tickets/{{index.params.id}}/packages"
|
||||
options="mgIndex">
|
||||
options="mgIndex" actions="$ctrl.getPackages()">
|
||||
</mg-ajax>
|
||||
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.packages"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
|
||||
<form name="form" ng-submit="$ctrl.submit()">
|
||||
<vn-card pad-large>
|
||||
<vn-title>Packages</vn-title>
|
||||
<vn-one>
|
||||
<vn-horizontal ng-repeat="package in index.model track by package.id">
|
||||
<vn-horizontal ng-repeat="package in index.model track by $index">
|
||||
<vn-autocomplete vn-one
|
||||
margin-large-right
|
||||
url="/ticket/api/Packagings/listPackaging"
|
||||
|
@ -20,7 +27,8 @@
|
|||
vn-one
|
||||
margin-large-right
|
||||
label="Quantity"
|
||||
model="package.quantity">
|
||||
model="package.quantity"
|
||||
rule="TicketPackaging.quantity">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
|
@ -54,3 +62,7 @@
|
|||
</vn-icon>
|
||||
</vn-one>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Save"></vn-submit>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -2,9 +2,63 @@ import ngModule from '../../module';
|
|||
|
||||
class Controller {
|
||||
|
||||
construct($http, $scope) {
|
||||
constructor($http, $scope, $translate, vnApp) {
|
||||
this.$http = $http;
|
||||
this.$ = $scope;
|
||||
this.$translate = $translate;
|
||||
this.vnApp = vnApp;
|
||||
this.removedPackages = [];
|
||||
this.updatedPackages = [];
|
||||
}
|
||||
|
||||
submit() {
|
||||
let query = `/ticket/api/TicketPackagings/crudTicketPackaging`;
|
||||
let packagesObj = {
|
||||
delete: this.removedPackages,
|
||||
create: [],
|
||||
update: []
|
||||
};
|
||||
|
||||
this.packages.forEach(item => {
|
||||
if (typeof item.id === 'undefined')
|
||||
packagesObj.create.push(item);
|
||||
|
||||
if (typeof item.id !== 'undefined' && angular.equals(item, this.oldPackages[item.id]))
|
||||
packagesObj.update.push(item);
|
||||
});
|
||||
|
||||
this.$http.post(query, packagesObj).then(res => {
|
||||
this.$.index.accept();
|
||||
});
|
||||
}
|
||||
|
||||
removePackage(index) {
|
||||
if (this.packages[index] && this.packages[index].id)
|
||||
this.removedPackages.push(this.packages[index].id);
|
||||
|
||||
this.packages.splice(index, 1);
|
||||
}
|
||||
|
||||
addPackage() {
|
||||
let data = {
|
||||
packagingFk: null,
|
||||
quantity: null,
|
||||
created: Date.now(),
|
||||
ticketFk: this.ticket.id
|
||||
};
|
||||
this.packages.push(data);
|
||||
}
|
||||
|
||||
getPackages() {
|
||||
this.packages = this.$.index.model;
|
||||
this.setOldPackages();
|
||||
}
|
||||
|
||||
setOldPackages() {
|
||||
this.oldPackages = [];
|
||||
this.packages.forEach(item => {
|
||||
this.oldPackages[item.id] = item;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import './package-list.js';
|
||||
|
||||
describe('Ticket', () => {
|
||||
describe('Component vnTicketPackageList', () => {
|
||||
let $componentController;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
let $scope;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('ticket');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_, $rootScope) => {
|
||||
$componentController = _$componentController_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$scope = {
|
||||
index: {
|
||||
accept: function() {}
|
||||
}
|
||||
};
|
||||
controller = $componentController('vnTicketPackageList', {$scope: $scope});
|
||||
}));
|
||||
|
||||
describe('removePackage()', () => {
|
||||
it('should push a package to removedPackages in the controller', () => {
|
||||
controller.packages = [{id: 1}, {id: 2}];
|
||||
controller.removePackage(0);
|
||||
|
||||
expect(controller.removedPackages).toEqual([1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('submit()', () => {
|
||||
it('should perform a post', () => {
|
||||
spyOn(angular, 'equals').and.returnValue(true);
|
||||
let query = '/ticket/api/TicketPackagings/crudTicketPackaging';
|
||||
controller.removedPackages = [];
|
||||
controller.oldPackages = [
|
||||
{id: 1, quantity: 5, ticketFk: 1}
|
||||
];
|
||||
controller.packages = [
|
||||
{quantity: 5, ticketFk: 1},
|
||||
{id: 1, quantity: 25, ticketFk: 1}
|
||||
];
|
||||
let packagesObj = {
|
||||
delete: controller.removedPackages,
|
||||
create: [],
|
||||
update: []
|
||||
};
|
||||
|
||||
$httpBackend.whenPOST(query, packagesObj).respond('omg YEAH');
|
||||
$httpBackend.expectPOST(query, packagesObj);
|
||||
controller.submit();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,4 +0,0 @@
|
|||
date : Fecha
|
||||
Employee : Empleado
|
||||
State: Estado
|
||||
Review: Revision
|
|
@ -1,23 +0,0 @@
|
|||
<mg-ajax path="" options="vnIndexNonAuto"></mg-ajax>
|
||||
<vn-vertical pad-medium>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-title>Review</vn-title>
|
||||
<vn-grid-header on-order="$ctrl.onOrder(field, order)">
|
||||
<vn-column-header vn-one pad-medium-h field="date" text="date"></vn-column-header>
|
||||
<vn-column-header vn-two pad-medium-h field="employee" text="Employee" default-order="ASC"></vn-column-header>
|
||||
<vn-column-header vn-two pad-medium-h field="state" text="State" order-locked></vn-column-header>
|
||||
</vn-grid-header>
|
||||
<vn-one class="list list-content">
|
||||
|
||||
</vn-horizontal>
|
||||
</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"></vn-horizontal>
|
||||
<vn-paging vn-one margin-large-top index="index" total="index.model.count"></vn-paging>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
</vn-vertical>
|
||||
<a ui-sref="clientCard.ticket.create" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
|
@ -1,18 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class ticketReview {
|
||||
construct($http, $scope) {
|
||||
this.$http = $http;
|
||||
this.$ = $scope;
|
||||
}
|
||||
}
|
||||
|
||||
ticketReview.$inject = ['$http', '$scope'];
|
||||
|
||||
ngModule.component('vnTicketReview', {
|
||||
template: require('./review.html'),
|
||||
controller: ticketReview,
|
||||
bindings: {
|
||||
ticket: '<'
|
||||
}
|
||||
});
|
|
@ -7,4 +7,5 @@ import './summary/ticket-summary';
|
|||
import './data/ticket-data';
|
||||
import './notes/ticket-observations';
|
||||
import './package/list/package-list';
|
||||
import './review/review';
|
||||
import './sale/sale';
|
||||
import './tracking/tracking';
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
Date : Fecha
|
||||
Employee : Empleado
|
||||
State: Estado
|
||||
Tracking: Revisión
|
||||
Created : Añadido
|
|
@ -0,0 +1,31 @@
|
|||
<mg-ajax path="/ticket/api/TicketTrackings/filter" options="vnIndexNonAuto"></mg-ajax>
|
||||
<vn-vertical pad-medium>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-title>Tracking</vn-title>
|
||||
<vn-grid-header on-order="$ctrl.onOrder(field, order)">
|
||||
<vn-column-header vn-one pad-medium-h field="state.name" text="State"></vn-column-header>
|
||||
<vn-column-header vn-two pad-medium-h field="employee" text="Employee"></vn-column-header>
|
||||
<vn-column-header vn-two pad-medium-h field="created" text="Created" default-order="ASC"></vn-column-header>
|
||||
|
||||
</vn-grid-header>
|
||||
<vn-one class="list list-content">
|
||||
<vn-horizontal
|
||||
vn-one class="list list-element text-center"
|
||||
pad-small-bottom
|
||||
ng-repeat="ticket in index.model.instances track by ticket.id">
|
||||
<vn-one pad-medium-h>{{::ticket.state.name}}</vn-one>
|
||||
<vn-two pad-medium-h>{{::ticket.worker.firstName}} {{::ticket.worker.name}}</vn-two>
|
||||
<vn-two pad-medium-h>{{::ticket.created | date:'dd/MM/yyyy HH:mm' }}</vn-two>
|
||||
|
||||
</vn-horizontal>
|
||||
</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"></vn-horizontal>
|
||||
<vn-paging vn-one margin-large-top index="index" total="index.model.count"></vn-paging>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
</vn-vertical>
|
||||
<a ui-sref="ticket.card.tracking.create" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
|
@ -0,0 +1,7 @@
|
|||
import ngModule from '../module';
|
||||
import FilterTicketList from '../filter-ticket-list';
|
||||
|
||||
ngModule.component('vnTicketTracking', {
|
||||
template: require('./tracking.html'),
|
||||
controller: FilterTicketList
|
||||
});
|
File diff suppressed because it is too large
Load Diff
|
@ -19,6 +19,7 @@
|
|||
"fs-extra": "^5.0.0",
|
||||
"material-design-lite": "^1.3.0",
|
||||
"mg-crud": "^1.1.2",
|
||||
"npm": "^5.7.1",
|
||||
"oclazyload": "^0.6.3",
|
||||
"require-yaml": "0.0.1",
|
||||
"validator": "^6.2.1"
|
||||
|
|
|
@ -510,3 +510,18 @@ INSERT INTO `vn`.`recovery`(`id`, `clientFk`, `started`, `finished`, `amount`, `
|
|||
( 2, 102, CURDATE(), date_add(CURDATE(),INTERVAL 3 MONTH), 100, 1),
|
||||
( 3, 102, CURDATE(), date_add(CURDATE(),INTERVAL 1 MONTH), 50, 7),
|
||||
( 4, 103, CURDATE(), NULL, 50, 7);
|
||||
|
||||
INSERT INTO `bi`.`rotacion`(`Id_Article`, `warehouse_id`, `total`, `rotacion`, `cm3`, `almacenaje`, `manipulacion`, `auxiliar`, `mermas`)
|
||||
VALUES
|
||||
( 1, 1, 0, 0.0000, 1500, 0.0015, 0.0250, 0.0085, 0.0000),
|
||||
( 1, 2, 0, 0.0000, 100, 0.0060, 0.0200, 0.0080, 0.0000),
|
||||
( 2, 1, 10, 3.5000, 0, 0.0000, 0.0000, 0.0080, 0.0000),
|
||||
( 3, 1, 50, 5.5000, 100, 0.0000, 0.0000, 0.0080, 0.0000);
|
||||
|
||||
INSERT INTO `vn`.`annualAverageInvoiced`(`clientFk`, `invoiced`)
|
||||
VALUES
|
||||
( 101, 0),
|
||||
( 102, 100),
|
||||
( 103, 1000),
|
||||
( 104, 500),
|
||||
( 105, 5000);
|
|
@ -12,3 +12,4 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri
|
|||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Expedition', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Expedition', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Expedition', '*', 'WRITE', 'ALLOW', 'ROLE', 'production');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('AnnualAverageInvoiced', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
USE `vn`;
|
||||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`annualAverageInvoiced` AS
|
||||
SELECT
|
||||
`e`.`Id_Cliente` AS `clientFk`, `e`.`Consumo` AS `invoiced`
|
||||
FROM
|
||||
`bi`.`facturacion_media_anual` `e`;
|
|
@ -5,5 +5,6 @@
|
|||
"The default consignee can not be unchecked": "The default consignee can not be unchecked",
|
||||
"Unable to default a disabled consignee": "Unable to default a disabled consignee",
|
||||
"El método de pago seleccionado requiere que se especifique el IBAN": "El método de pago seleccionado requiere que se especifique el IBAN",
|
||||
"Ya existe un usuario con ese nombre": "Ya existe un usuario con ese nombre"
|
||||
"Ya existe un usuario con ese nombre": "Ya existe un usuario con ese nombre",
|
||||
"Quantity cannot be zero": "Quantity cannot be zero"
|
||||
}
|
|
@ -8,7 +8,6 @@
|
|||
"can't be blank": "can't be blank",
|
||||
"DNI Incorrecto": "DNI Incorrecto",
|
||||
"Ya existe un usuario con ese nombre": "Ya existe un usuario con ese nombre",
|
||||
"ValidationError: The `Item` instance is not valid. Details: `originFk` Cannot be blank (value: undefined).": "ValidationError: The `Item` instance is not valid. Details: `originFk` Cannot be blank (value: undefined).",
|
||||
"Error: ER_NO_REFERENCED_ROW_2: Cannot add or update a child row: a foreign key constraint fails (`vn2008`.`Articles`, CONSTRAINT `Articles_ibfk_5` FOREIGN KEY (`tipo_id`) REFERENCES `Tipos` (`tipo_id`) ON UPDATE CASCADE)": "Error: ER_NO_REFERENCED_ROW_2: Cannot add or update a child row: a foreign key constraint fails (`vn2008`.`Articles`, CONSTRAINT `Articles_ibfk_5` FOREIGN KEY (`tipo_id`) REFERENCES `Tipos` (`tipo_id`) ON UPDATE CASCADE)",
|
||||
"Error: ER_NO_REFERENCED_ROW_2: Cannot add or update a child row: a foreign key constraint fails (`vn2008`.`Articles`, CONSTRAINT `expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `Gastos` (`Id_Gasto`) ON UPDATE CASCADE)": "Error: ER_NO_REFERENCED_ROW_2: Cannot add or update a child row: a foreign key constraint fails (`vn2008`.`Articles`, CONSTRAINT `expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `Gastos` (`Id_Gasto`) ON UPDATE CASCADE)"
|
||||
"is invalid": "is invalid",
|
||||
"Quantity cannot be zero": "La cantidad no puede ser cero"
|
||||
}
|
|
@ -12,6 +12,9 @@
|
|||
"id": true,
|
||||
"description": "Identifier"
|
||||
},
|
||||
"code": {
|
||||
"type": "String"
|
||||
},
|
||||
"name": {
|
||||
"type": "String"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = Self => {
|
||||
Self.installCrudModel('crudTicketPackaging');
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
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: "itemTag",
|
||||
scope: {
|
||||
fields: ["id", "value", "priority", "tagFk"],
|
||||
include: {
|
||||
relation: "tag",
|
||||
scope: {
|
||||
fields: ["name"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
}
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
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 || 'created DESC',
|
||||
include: [
|
||||
{
|
||||
relation: "worker",
|
||||
scope: {
|
||||
fields: ["firstName", "name"]
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: "state",
|
||||
scope: {
|
||||
fields: ["name"]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "AnnualAverageInvoiced",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "annualAverageInvoiced"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"invoiced": {
|
||||
"type": "Number"
|
||||
},
|
||||
"clientFk": {
|
||||
"id": true
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"client": {
|
||||
"type": "belongsTo",
|
||||
"model": "client",
|
||||
"foreignKey": "clientFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = function(Self) {
|
||||
require('../methods/sale/filter.js')(Self);
|
||||
};
|
|
@ -41,6 +41,11 @@
|
|||
"foreignKey": "itemFk",
|
||||
"required": true
|
||||
},
|
||||
"itemTag": {
|
||||
"type": "hasMany",
|
||||
"model": "ItemTag",
|
||||
"foreignKey": "itemFk"
|
||||
},
|
||||
"ticket": {
|
||||
"type": "belongsTo",
|
||||
"model": "Ticket",
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
module.exports = function(Self) {
|
||||
require('../methods/packaging/crudTicketPackaging')(Self);
|
||||
|
||||
Self.validateBinded('quantity', validateQuantity, {
|
||||
message: 'Quantity cannot be zero',
|
||||
allowNull: false,
|
||||
allowBlank: false
|
||||
});
|
||||
|
||||
function validateQuantity(quantity) {
|
||||
return quantity != 0;
|
||||
}
|
||||
|
||||
Self.validatesPresenceOf('packagingFk', {message: 'Package cannot be blank'});
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = function(Self) {
|
||||
require('../methods/ticketTracking/filter')(Self);
|
||||
};
|
|
@ -28,6 +28,9 @@
|
|||
},
|
||||
"Expedition": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"AnnualAverageInvoiced": {
|
||||
"dataSource": "vn"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue