Tarea #438 order.line

This commit is contained in:
gerard 2018-08-07 16:04:42 +02:00
parent da9a783843
commit 65ffade0a3
9 changed files with 348 additions and 2 deletions

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

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

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,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

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