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

This commit is contained in:
Carlos Jimenez 2018-08-08 09:07:39 +02:00
commit 68a3a47894
26 changed files with 651 additions and 64 deletions

View File

@ -66,7 +66,7 @@ export default class Controller extends Component {
let shape = this.createShape(data);
setTimeout(() =>
this.hide(shape), data.timeout || 6000);
this.hide(shape), data.timeout || 3000);
setTimeout(() =>
shape.classList.add('shown'), 30);

View File

@ -1,31 +1,32 @@
@import "colors";
vn-snackbar #shapes {
position: fixed;
bottom: 0;
right: 15px;
width: 20em;
max-height: 20.625em;
margin-left: -12.5em;
position: fixed;
z-index: 100;
width: 25em;
left: 50%;
bottom: 0
}
vn-snackbar .shape {
box-sizing: border-box;
background-color: rgba(1, 1, 1, 0.8);
box-shadow: 0 0 .4em rgba(1,1,1,.4);
transition: transform 300ms ease-in-out;
transform: translateY(20em);
box-sizing: border-box;
border-radius: .2em;
margin-bottom: 15px;
color: white;
padding: 1em;
border-radius: .2em;
box-shadow: 0 0 .4em rgba(1,1,1,.4);
margin-bottom: 15px;
transform: translateX(20em);
transition: transform 300ms ease-in-out;
&.text {
text-align: center
}
&.shown {
transform: translateX(0);
transform: translateY(0);
}
&.success {
@ -46,15 +47,15 @@ vn-snackbar .shape {
}
& > button {
cursor: pointer;
float: right;
text-transform: uppercase;
border: none;
background-color: transparent;
font-weight: bold;
color: $main-01;
padding: .5em;
margin: -.5em;
text-transform: uppercase;
margin-left: .5em;
font-weight: bold;
cursor: pointer;
color: $main-01;
float: right;
border: none;
padding: .5em;
margin: -.5em
}
}

View File

@ -57,6 +57,18 @@
"icon": "icon-volume"
}
},
{
"url": "/line",
"state": "order.card.line",
"component": "vn-order-line",
"description": "Lines",
"params": {
"order": "$ctrl.order"
},
"menu": {
"icon": "icon-lines"
}
},
{
"url": "/create",
"state": "order.create",

View File

@ -7,6 +7,8 @@ import './index/';
import './summary';
import './catalogue';
import './catalogue/product';
import './line';
//import './prices-popover';
import './volume';
import './create';
import './create/card';

View File

@ -0,0 +1,82 @@
<vn-watcher
vn-id="watcher"
data="$ctrl.rows">
</vn-watcher>
<vn-vertical>
<vn-card pad-large>
<vn-vertical>
<vn-horizontal>
<vn-title vn-two>Sale</vn-title>
<div class="totalBox">
<vn-label translate>Subtotal</vn-label>
<span>{{$ctrl.order.total - $ctrl.VAT | currency:'€':2}}</span>
<p>
<vn-label translate>VAT</vn-label>
<span>{{$ctrl.VAT | currency:'€':2}}</span>
</p>
<vn-label><strong>Total</strong></vn-label>
<strong>{{$ctrl.order.total | currency:'€':2}}</strong>
</div>
</vn-horizontal>
<vn-table model="model">
<vn-thead>
<vn-tr>
<vn-th style="text-align: center">Item</vn-th>
<vn-th style="text-align: center">ID</vn-th>
<vn-th>Description</vn-th>
<vn-th>Warehouse</vn-th>
<vn-th>Shipped</vn-th>
<vn-th number>Quantity</vn-th>
<vn-th number>Price</vn-th>
<vn-th ng-if="!$ctrl.order.isConfirmed"></vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="row in $ctrl.rows">
<vn-td style="text-align: center">
<img
ng-src="//verdnatura.es/vn-image-data/catalog/50x50/{{::row.item.image}}"
zoom-image="//verdnatura.es/vn-image-data/catalog/1600x900/{{::row.item.image}}"
on-error-src/>
</vn-td>
<vn-td ng-click="$ctrl.showDescriptor($event, row.itemFk)"
pointer number class="link">
{{("000000"+row.itemFk).slice(-6)}}
</vn-td>
<vn-td><vn-fetched-tags concept="row.item.name" tags="row.item.tags"/></vn-td>
<vn-td>{{row.warehouse.name}}</vn-td>
<vn-td>{{row.shipped | dashIfEmpty}}</vn-td>
<vn-td number>{{row.quantity}}</vn-td>
<vn-td number>
{{row.price | currency:'€':2}}
</vn-td>
<vn-td ng-if="!$ctrl.order.isConfirmed">
<vn-icon-button
medium-grey
vn-tooltip="Remove item"
icon="remove_circle_outline"
ng-click="$ctrl.removeRow($index)"
tabindex="-1">
</vn-icon-button>
</vn-td>
</vn-tr>
</vn-tbody>
<vn-empty-rows ng-if="$ctrl.rows.length === 0" translate>
No results
</vn-empty-rows>
</vn-table>
</vn-vertical>
</vn-card>
<vn-button-bar ng-if="!$ctrl.order.isConfirmed">
<vn-button
label="Save"
ng-click="$ctrl.save()">
</vn-button>
</vn-button-bar>
</vn-vertical>
<vn-item-descriptor-popover
vn-id="descriptor">
</vn-item-descriptor-popover>

View File

@ -0,0 +1,95 @@
import ngModule from '../module';
import './style.scss';
class Controller {
constructor($scope, $state, $http, vnApp, $translate) {
this.$scope = $scope;
this.vnApp = vnApp;
this.$translate = $translate;
this.$state = $state;
this.$http = $http;
this.idsToRemove = [];
}
$onInit() {
this.getRows();
this.getVAT();
}
getRows() {
let filter = {
where: {orderFk: this.$state.params.id},
include: [{
relation: 'item',
scope: {
include: {
relation: 'tags',
scope: {
fields: ['tagFk', 'value'],
include: {
relation: 'tag',
scope: {
fields: ['name']
}
}
}
},
fields: ['itemFk', 'name', 'image']
}
},
{relation: 'warehouse'}]
};
filter = encodeURIComponent(JSON.stringify(filter));
let query = `/order/api/OrderRows?filter=${filter}`;
this.$http.get(query).then(res => {
this.rows = res.data;
});
}
getVAT() {
let query = `/order/api/Orders/${this.$state.params.id}/getTaxes`;
this.$http.get(query).then(res => {
this.VAT = res.data.tax;
});
}
removeRow(index) {
let [lineRemoved] = this.rows.splice(index, 1);
this.idsToRemove.push(lineRemoved.id);
}
// Item Descriptor
showDescriptor(event, itemFk) {
this.$scope.descriptor.itemFk = itemFk;
this.$scope.descriptor.parent = event.target;
this.$scope.descriptor.show();
}
onDescriptorLoad() {
this.$scope.popover.relocate();
}
save() {
let params = {
rows: this.idsToRemove,
actualOrderId: this.$state.params.id
};
let query = `/order/api/OrderRows/removes`;
this.$http.post(query, params).then(() => {
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
});
}
}
Controller.$inject = ['$scope', '$state', '$http', 'vnApp', '$translate'];
ngModule.component('vnOrderLine', {
template: require('./index.html'),
controller: Controller,
bindings: {
order: '<'
}
});

View File

@ -0,0 +1,109 @@
import './index.js';
describe('Order', () => {
describe('Component vnOrderLine', () => {
let $componentController;
let $state;
let controller;
let $httpBackend;
beforeEach(() => {
angular.mock.module('order');
});
beforeEach(angular.mock.inject((_$componentController_, _$state_, _$httpBackend_) => {
$componentController = _$componentController_;
$state = _$state_;
$state = {params: {id: 1}};
$httpBackend = _$httpBackend_;
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
controller = $componentController('vnOrderLine', {$state: $state});
controller.rows = [{id: 1}];
controller.$scope.popover = {relocate: () => {}};
controller.$scope.descriptor = {show: () => {}};
controller.vnApp = {showSuccess: () => {}};
}));
describe('getRows()', () => {
it('should make a query to get the rows of a given order', () => {
let filter = {
where: {orderFk: controller.$state.params.id},
include: [{
relation: 'item',
scope: {
include: {
relation: 'tags',
scope: {
fields: ['tagFk', 'value'],
include: {
relation: 'tag',
scope: {
fields: ['name']
}
}
}
},
fields: ['itemFk', 'name', 'image']
}
},
{relation: 'warehouse'}]
};
filter = encodeURIComponent(JSON.stringify(filter));
$httpBackend.expectGET(`/order/api/OrderRows?filter=${filter}`).respond({data: [{id: 1}]});
controller.getRows();
$httpBackend.flush();
});
});
describe('getTaxes()', () => {
it('should make a query to get the taxes of a given order', () => {
$httpBackend.expectGET(`/order/api/Orders/1/getTaxes`).respond({data: {tax: 3}});
controller.getVAT();
$httpBackend.flush();
});
});
describe('removeRow()', () => {
it('should remove a row from rows and add his id to idsRemoved', () => {
controller.removeRow(0);
expect(controller.rows.length).toBe(0);
expect(controller.idsToRemove[0]).toBe(1);
});
});
describe('showDescriptor()', () => {
it('should set $scope.descriptor.itemFk, $scope.descriptor.parent and call $scope.descriptor.show()', () => {
let event = {target: 1};
let itemFk = 1;
spyOn(controller.$scope.descriptor, 'show');
controller.showDescriptor(event, itemFk);
expect(controller.$scope.descriptor.itemFk).toBe(1);
expect(controller.$scope.descriptor.parent).toBe(1);
expect(controller.$scope.descriptor.show).toHaveBeenCalledWith();
});
});
describe('onDescriptorLoad()', () => {
it('should call $scope.popover.relocate()', () => {
spyOn(controller.$scope.popover, 'relocate');
controller.onDescriptorLoad();
expect(controller.$scope.popover.relocate).toHaveBeenCalledWith();
});
});
describe('save()', () => {
it('should make a query to remove the selected rows and call vnApp.showSuccess', () => {
spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expectPOST(`/order/api/OrderRows/removes`).respond();
controller.save();
$httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
});
});
});
});

View File

@ -0,0 +1 @@
Remove item: Eliminar articulo

View File

@ -0,0 +1,8 @@
vn-order-line{
vn-table {
img {
border-radius: 50%;
max-width: 50px;
}
}
}

View File

@ -0,0 +1,64 @@
import './index';
describe('Order', () => {
describe('Component vnOrderVolume', () => {
let $componentController;
let controller;
let $httpBackend;
let $state;
let $scope;
beforeEach(() => {
angular.mock.module('order');
});
beforeEach(angular.mock.inject((_$componentController_, _$state_, _$httpBackend_, $rootScope) => {
$componentController = _$componentController_;
$httpBackend = _$httpBackend_;
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
$scope = $rootScope.$new();
$scope.model = {data: [{itemFk: 1}, {itemFk: 2}], accept: () => {
return {
then: () => {}
};
}};
$scope.descriptor = {show: () => {}};
$scope.popover = {relocate: () => {}};
$state = _$state_;
$state.params.id = 1;
controller = $componentController('vnOrderVolume', {$scope: $scope}, {$httpBackend: $httpBackend}, {$state: $state});
}));
it('should join the sale volumes to its respective sale', () => {
let response = {volumes: [{itemFk: 1, volume: 0.008}, {itemFk: 2, volume: 0.003}]};
$httpBackend.whenGET(`/order/api/Orders/1/getVolumes`).respond(response);
$httpBackend.expectGET(`/order/api/Orders/1/getVolumes`);
controller.onDataChange();
$httpBackend.flush();
expect(controller.$scope.model.data[0].volume).toBe(0.008);
expect(controller.$scope.model.data[1].volume).toBe(0.003);
});
describe('showDescriptor()', () => {
it('should set $scope.descriptor.itemFk, $scope.descriptor.parent and call $scope.descriptor.show()', () => {
let event = {target: 1};
let itemFk = 1;
spyOn(controller.$scope.descriptor, 'show');
controller.showDescriptor(event, itemFk);
expect(controller.$scope.descriptor.itemFk).toBe(1);
expect(controller.$scope.descriptor.parent).toBe(1);
expect(controller.$scope.descriptor.show).toHaveBeenCalledWith();
});
});
describe('onDescriptorLoad()', () => {
it('should call $scope.popover.relocate()', () => {
spyOn(controller.$scope.popover, 'relocate');
controller.onDescriptorLoad();
expect(controller.$scope.popover.relocate).toHaveBeenCalledWith();
});
});
});
});

View File

@ -27,7 +27,7 @@ input[type=reset]::-moz-focus-inner
.totalBox {
border: 1px solid #CCC;
text-align: left;
text-align: right!important;
justify-content: center;
align-items: center;
padding: 18px;

View File

@ -228,7 +228,7 @@
label="Price"
model="$ctrl.editedPrice"
type="text"
accept="$ctrl.updatePrice()">
on-change="$ctrl.updatePrice()">
<t-right-icons>
<span class="filter"></span>
</t-right-icons>

View File

@ -309,6 +309,9 @@ class Controller {
this.$http.post(`/ticket/api/Sales/${id}/updateQuantity`, {quantity: parseInt(quantity)}).then(() => {
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
this.$scope.model.refresh();
}).catch(e => {
this.vnApp.showError(e.data.error.message);
this.$scope.model.refresh();
});
}

View File

@ -326,29 +326,29 @@ INSERT INTO `vn`.`invoiceOut`(`id`, `ref`, `serial`, `amount`, `issued`,`clientF
( 4, 'E4444444' , 'E', 290.30 , DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 103, CURDATE(), 442, CURDATE(), CURDATE(), 8, 1),
( 5, 'E5555555' , 'E', 190.30 , DATE_ADD(CURDATE(), INTERVAL +2 MONTH), 103, CURDATE(), 442, CURDATE(), CURDATE(), 8, 1);
INSERT INTO `vn`.`ticket`(`id`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`)
INSERT INTO `vn`.`ticket`(`id`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`)
VALUES
(1 , 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY) , DATE_ADD(CURDATE(), INTERVAL -15 DAY) , 101, 'Batman', 121, NULL),
(2 , 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -10 DAY) , DATE_ADD(CURDATE(), INTERVAL -10 DAY) , 101, 'Spider-Man', 121, NULL),
(3 , 2, 2, 2, DATE_ADD(CURDATE(), INTERVAL -5 DAY) , DATE_ADD(CURDATE(), INTERVAL -5 DAY) , 102, 'Super-Man', 122, NULL),
(4 , 2, 2, 2, DATE_ADD(CURDATE(), INTERVAL -4 DAY) , DATE_ADD(CURDATE(), INTERVAL -4 DAY) , 102, 'Iron-Man', 122, NULL),
(5 , 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL -3 DAY) , DATE_ADD(CURDATE(), INTERVAL -3 DAY) , 103, 'Magneto', 123, NULL),
(6 , 3, 3, 4, DATE_ADD(CURDATE(), INTERVAL -2 DAY) , DATE_ADD(CURDATE(), INTERVAL -2 DAY) , 103, 'Legion', 123, NULL),
(7 , 4, 4, 4, DATE_ADD(CURDATE(), INTERVAL -1 DAY) , DATE_ADD(CURDATE(), INTERVAL -1 DAY) , 104, 'Ant-Man', 124, NULL),
(8 , 4, 4, 4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 104, 'Professor X', 124, NULL),
(9 , 5, 5, 4, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 105, 'Hulk', 125, NULL),
(10, 6, 5, 5, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(CURDATE(), INTERVAL -3 MONTH), 105, 'Jessica Jones', 125, NULL),
(11, 7, 1, 1, CURDATE() , CURDATE() , 101, 'ticket 1', 121, NULL),
(12, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 101, 'ticket 2', 121, NULL),
(13, 2, 2, 2, DATE_ADD(CURDATE(), INTERVAL +2 MONTH), DATE_ADD(CURDATE(), INTERVAL +2 MONTH), 101, 'ticket 3', 121, NULL),
(14, 2, 2, 2, DATE_ADD(CURDATE(), INTERVAL +3 MONTH), DATE_ADD(CURDATE(), INTERVAL +3 MONTH), 101, 'ticket 4', 121, NULL),
(15, 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL +4 MONTH), DATE_ADD(CURDATE(), INTERVAL +4 MONTH), 101, 'ticket 5', 121, NULL),
(16, 3, 3, 4, CURDATE() , CURDATE() , 101, 'ticket 6', 121, NULL),
(17, 4, 4, 4, CURDATE() , CURDATE() , 106, 'ticket 7', 126, NULL),
(18, 4, 4, 4, CURDATE() , CURDATE() , 107, 'ticket 8', 127, NULL),
(19, 5, 5, 4, CURDATE() , CURDATE() , 108, 'ticket 9', 128, NULL),
(20, 5, 5, 4, CURDATE() , CURDATE() , 109, 'ticket 10', 119, NULL),
(21, 5, 5, 4, CURDATE() , CURDATE() , 110, 'ticket 11', 129, NULL);
(1 , 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY) , DATE_ADD(CURDATE(), INTERVAL -15 DAY) , 101, 'Batman', 121, NULL, 0),
(2 , 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -10 DAY) , DATE_ADD(CURDATE(), INTERVAL -10 DAY) , 101, 'Spider-Man', 121, NULL, 0),
(3 , 2, 2, 2, DATE_ADD(CURDATE(), INTERVAL -5 DAY) , DATE_ADD(CURDATE(), INTERVAL -5 DAY) , 102, 'Super-Man', 122, NULL, 0),
(4 , 2, 2, 2, DATE_ADD(CURDATE(), INTERVAL -4 DAY) , DATE_ADD(CURDATE(), INTERVAL -4 DAY) , 102, 'Iron-Man', 122, NULL, 0),
(5 , 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL -3 DAY) , DATE_ADD(CURDATE(), INTERVAL -3 DAY) , 103, 'Magneto', 123, NULL, 0),
(6 , 3, 3, 4, DATE_ADD(CURDATE(), INTERVAL -2 DAY) , DATE_ADD(CURDATE(), INTERVAL -2 DAY) , 103, 'Legion', 123, NULL, 0),
(7 , 4, 4, 4, DATE_ADD(CURDATE(), INTERVAL -1 DAY) , DATE_ADD(CURDATE(), INTERVAL -1 DAY) , 104, 'Ant-Man', 124, NULL, 0),
(8 , 4, 4, 4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 104, 'Professor X', 124, NULL, 0),
(9 , 5, 5, 4, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 105, 'Hulk', 125, NULL, 0),
(10, 6, 5, 5, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(CURDATE(), INTERVAL -3 MONTH), 105, 'Jessica Jones', 125, NULL, 0),
(11, 7, 1, 1, CURDATE() , CURDATE() , 101, 'ticket 1', 121, NULL, 0),
(12, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 101, 'ticket 2', 121, NULL, 0),
(13, 2, 2, 2, DATE_ADD(CURDATE(), INTERVAL +2 MONTH), DATE_ADD(CURDATE(), INTERVAL +2 MONTH), 101, 'ticket 3', 121, NULL, 0),
(14, 2, 2, 2, DATE_ADD(CURDATE(), INTERVAL +3 MONTH), DATE_ADD(CURDATE(), INTERVAL +3 MONTH), 101, 'ticket 4', 121, NULL, 0),
(15, 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL +4 MONTH), DATE_ADD(CURDATE(), INTERVAL +4 MONTH), 101, 'ticket 5', 121, NULL, 0),
(16, 3, 3, 4, CURDATE() , CURDATE() , 101, 'ticket 6', 121, NULL, 0),
(17, 4, 4, 4, CURDATE() , CURDATE() , 106, 'ticket 7', 126, NULL, 0),
(18, 4, 4, 4, CURDATE() , CURDATE() , 107, 'ticket 8', 127, NULL, 0),
(19, 5, 5, 4, CURDATE() , CURDATE() , 108, 'ticket 9', 128, NULL, 0),
(20, 5, 5, 4, CURDATE() , CURDATE() , 109, 'ticket 10', 119, NULL, 0),
(21, 5, 5, 4, CURDATE() , CURDATE() , 110, 'ticket 11', 129, NULL, 1);
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
VALUES
@ -358,27 +358,27 @@ INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `des
INSERT INTO `vn`.`ticketTracking`(`id`, `ticketFk`, `stateFk`, `workerFk`, `created`)
VALUES
(1, 1, 3, 5, CURDATE()),
(2, 2, 15, 5, CURDATE()),
(3, 3, 16, 5, CURDATE()),
(4, 4, 13, 5, CURDATE()),
(5, 5, 15, 18, CURDATE()),
(6, 6, 16, 18, CURDATE()),
(7, 7, 13, 18, CURDATE()),
(8, 8, 15, 19, CURDATE()),
(9, 9, 16, 19, CURDATE()),
(1 , 1 , 3 , 5 , CURDATE()),
(2 , 2 , 15, 5 , CURDATE()),
(3 , 3 , 16, 5 , CURDATE()),
(4 , 4 , 13, 5 , CURDATE()),
(5 , 5 , 15, 18, CURDATE()),
(6 , 6 , 16, 18, CURDATE()),
(7 , 7 , 13, 18, CURDATE()),
(8 , 8 , 15, 19, CURDATE()),
(9 , 9 , 16, 19, CURDATE()),
(10, 10, 13, 19, CURDATE()),
(11, 11, 3, 19, CURDATE()),
(12, 12, 3, 19, CURDATE()),
(13, 13, 3, 19, CURDATE()),
(14, 14, 3, 19, CURDATE()),
(15, 15, 3, 19, CURDATE()),
(16, 16, 1, 19, CURDATE()),
(17, 17, 1, 19, CURDATE()),
(18, 18, 1, 19, CURDATE()),
(11, 11, 3 , 19, CURDATE()),
(12, 12, 3 , 19, CURDATE()),
(13, 13, 3 , 19, CURDATE()),
(14, 14, 3 , 19, CURDATE()),
(15, 15, 3 , 19, CURDATE()),
(16, 16, 1 , 19, CURDATE()),
(17, 17, 1 , 19, CURDATE()),
(18, 18, 1 , 19, CURDATE()),
(19, 19, 13, 19, CURDATE()),
(20, 20, 15, 19, CURDATE()),
(21, 21, 16, 19, CURDATE());
(21, 21, 3 , 19, CURDATE());
INSERT INTO `vn`.`vehicle`(`id`, `numberPlate`, `tradeMark`, `model`, `companyFk`, `warehouseFk`, `description`, `m3`, `isActive`)
VALUES

View File

@ -38,5 +38,6 @@
"You don't have enough privileges to change the state of this ticket": "No tienes permisos para cambiar el estado de este ticket",
"The new quantity should be smaller than the old one": "La nueva cantidad debe de ser menor que la anterior",
"The value should not be greater than 100%": "El valor no debe de ser mayor de 100%",
"The value should be a number": "El valor debe ser un numero"
"The value should be a number": "El valor debe ser un numero",
"This order is not editable": "Esta orden no se puede modificar"
}

View File

@ -0,0 +1,27 @@
const app = require(`${servicesDir}/ticket/server/server`);
describe('ticket isEditable()', () => {
it('should return false if the ticket given is not editable', async() => {
let result = await app.models.Ticket.isEditable(2);
expect(result).toEqual(false);
});
it('should return false if the ticket given does not exists', async() => {
let result = await app.models.Ticket.isEditable(99999);
expect(result).toEqual(false);
});
it('should return false if the ticket given isDeleted', async() => {
let result = await app.models.Ticket.isEditable(21);
expect(result).toEqual(false);
});
it('should return true if the ticket given is editable', async() => {
let result = await app.models.Ticket.isEditable(1);
expect(result).toEqual(true);
});
});

View File

@ -0,0 +1,3 @@
{
"This order is not editable": "Esta orden no se puede editar"
}

View File

@ -0,0 +1,36 @@
const UserError = require('vn-loopback/common/helpers').UserError;
module.exports = Self => {
Self.remoteMethod('removes', {
description: 'Delete an Order Row',
accessType: '',
accepts: [{
arg: 'params',
type: 'object',
required: true,
description: '[Row IDs], actualOrderId',
http: {source: 'body'}
}],
returns: {
type: 'string',
root: true
},
http: {
path: `/removes`,
verb: 'post'
}
});
Self.removes = async params => {
if (!params.rows || !params.rows.length)
throw new Error('There is nothing delete');
await Self.app.models.Order.isEditable(params.actualOrderId);
let promises = [];
for (let i = 0; i < params.rows.length; i++) {
promises.push(Self.app.models.OrderRow.destroyById(params.rows[i]));
}
return await Promise.all(promises);
};
};

View File

@ -0,0 +1,25 @@
const app = require(`../../../../server/server`);
describe('order removes()', () => {
it('should throw an error if rows property is empty', async() => {
let error;
try {
await app.models.OrderRow.removes({rows: []});
} catch (e) {
error = e;
}
expect(error).toEqual(new Error('There is nothing delete'));
});
it('should throw an error if the row selected is not editable', async() => {
let error;
try {
await app.models.OrderRow.removes({rows: [2]});
} catch (e) {
error = e;
}
expect(error).toEqual(new Error('This order is not editable'));
});
});

View File

@ -0,0 +1,30 @@
module.exports = Self => {
Self.remoteMethod('getTaxes', {
description: 'Gets the taxes of a given order',
accessType: 'READ',
accepts: [{
arg: 'id',
type: 'number',
required: true,
description: 'order id',
http: {source: 'path'}
}],
returns: {
type: 'object',
root: true
},
http: {
path: `/:id/getTaxes`,
verb: 'GET'
}
});
Self.getTaxes = async orderFk => {
let query = `CALL hedera.orderGetTax(?);
SELECT * FROM tmp.orderTax;`;
let res = await Self.rawSql(query, [orderFk]);
let [taxes] = res[1];
return taxes;
};
};

View File

@ -0,0 +1,30 @@
const UserError = require('vn-loopback/common/helpers').UserError;
module.exports = Self => {
Self.remoteMethod('isEditable', {
description: 'Check if an order is editable',
accessType: 'READ',
accepts: [{
arg: 'orderId',
type: 'number',
required: true,
description: 'orderId',
http: {source: 'path'}
}],
returns: {
type: 'boolean',
root: true
},
http: {
path: `/:orderId/isEditable`,
verb: 'get'
}
});
Self.isEditable = async orderId => {
let exists = await Self.app.models.Order.findOne({where: {id: orderId}, fields: ['isConfirmed']});
if (!exists || exists.isConfirmed === 1)
throw new UserError('This order is not editable');
};
};

View File

@ -0,0 +1,21 @@
const app = require(`../../../../server/server`);
describe('order getTaxes()', () => {
it('should call the getTaxes method and return undefined if its called with a string', async() => {
let result = await app.models.Order.getTaxes('pepinillos');
expect(result).toEqual(undefined);
});
it('should call the getTaxes method and return undefined if its called with unknown id', async() => {
let result = await app.models.Order.getTaxes(99999999999999999999999);
expect(result).toEqual(undefined);
});
it('should call the getTaxes method and return the taxes if its called with a known id', async() => {
let result = await app.models.Order.getTaxes(1);
expect(result.tax).toEqual(0.95);
});
});

View File

@ -0,0 +1,26 @@
const app = require(`../../../../server/server`);
const UserError = require('vn-loopback/common/helpers').UserError;
describe('order isEditable()', () => {
it('should throw an error if the order given is not editable', async() => {
let error;
try {
await app.models.Order.isEditable(2);
} catch (e) {
error = e;
}
expect(error).toEqual(new UserError('This order is not editable'));
});
it('should throw an error if the order given does not exists', async() => {
let error;
try {
await app.models.Order.isEditable(99999);
} catch (e) {
error = e;
}
expect(error).toEqual(new UserError('This order is not editable'));
});
});

View File

@ -0,0 +1,4 @@
module.exports = Self => {
//require('../methods/order-row/new')(Self);
require('../methods/order-row/removes')(Self);
};

View File

@ -50,6 +50,11 @@
"type": "belongsTo",
"model": "Order",
"foreignKey": "orderFk"
},
"warehouse": {
"type": "belongsTo",
"model": "Warehouse",
"foreignKey": "warehouseFk"
}
}
}

View File

@ -2,6 +2,8 @@ module.exports = Self => {
require('../methods/order/new')(Self);
require('../methods/order/getTotalVolume')(Self);
require('../methods/order/getVolumes')(Self);
require('../methods/order/getTaxes')(Self);
require('../methods/order/isEditable')(Self);
require('../methods/order/getTotal')(Self);
require('../methods/order/itemFilter')(Self);
};