Merge branch 'dev' into 2865-e2e_run_optimization
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Carlos Jimenez Ruiz 2021-04-19 08:05:03 +00:00
commit 14303cca4e
7 changed files with 279 additions and 167 deletions

View File

@ -13,7 +13,8 @@
on-error-src/>
</div>
<div class="description">
<h3>
<h3 class="link"
ng-click="itemDescriptor.show($event, item.id)">
{{::item.name}}
</h3>
<h4 class="ellipsize">
@ -65,3 +66,6 @@
vn-id="pricesPopover"
order="$ctrl.order">
</vn-order-prices-popover>
<vn-item-descriptor-popover
vn-id="itemDescriptor">
</vn-item-descriptor-popover>

View File

@ -1,37 +1,11 @@
<default>
<vn-descriptor-content
module="item"
description="$ctrl.item.name"
descriptor="$ctrl"
class="vn-order-prices-popover">
<slot-body>
<div class="attributes">
<vn-label-value
label="Buyer"
value="{{$ctrl.item.firstName}} {{$ctrl.item.lastName}}">
</vn-label-value>
<vn-label-value
ng-repeat="tag in $ctrl.tags"
label="{{::tag.tag.name}}"
value="{{::tag.value}}">
</vn-label-value>
</div>
<div class="quicklinks">
<vn-quick-link
tooltip="Diary"
state="['item.card.diary', {id: $ctrl.id}]"
icon="icon-transaction">
</vn-quick-link>
</div>
</slot-body>
<slot-after>
<form name="form" class="prices">
<vn-table>
<vn-tbody>
<vn-tr ng-repeat="price in $ctrl.prices">
<vn-td shrink class="warehouse">
<vn-td class="warehouse" expand>
<span
class="ellipsize text"
class="text"
title="{{::price.warehouse}}">
{{::price.warehouse}}
</span>
@ -44,16 +18,24 @@
<span> x {{::price.price | currency: 'EUR': 2}}</span>
</div>
<div class="price-kg" ng-show="::price.priceKg">
{{price.priceKg | currency: 'EUR'}}/Kg
{{::price.priceKg | currency: 'EUR'}}/Kg
</div>
</vn-td>
<vn-td shrink>
<vn-input-number
<!-- Focus first element -->
<vn-input-number ng-if="$index === 0"
min="0"
name="quantity"
ng-model="price.quantity"
step="price.grouping"
class="dense"
vn-focus>
</vn-input-number>
<vn-input-number ng-if="$index > 0"
min="0"
name="quantity"
ng-model="price.quantity"
step="price.grouping"
on-change="$ctrl.validate()"
class="dense">
</vn-input-number>
</vn-td>
@ -61,15 +43,10 @@
</vn-tbody>
</vn-table>
<div class="footer vn-pa-md">
<div class="error">
<span translate>Wrong quantity</span>
</div>
<vn-submit
label="Save"
label="Add"
ng-click="$ctrl.submit()">
</vn-submit>
</div>
</form>
</slot-after>
</vn-descriptor-content>
</default>

View File

@ -11,34 +11,18 @@ class Controller extends Popover {
set prices(value) {
this._prices = value;
if (value && value[0].grouping)
this.calculateTotal();
this.getTotalQuantity();
}
get prices() {
return this._prices;
}
getTags() {
const filter = {
where: {
itemFk: this.id,
priority: {gte: 4}
},
order: 'priority ASC',
include: {relation: 'tag'}
};
this.$http.get(`ItemTags`, {filter})
.then(res => {
this.tags = res.data;
this.$.$applyAsync(() => this.relocate());
});
}
show(parent, item) {
this.item = JSON.parse(JSON.stringify(item));
this.id = item.id;
this.prices = this.item.prices;
this.getTags();
super.show(parent);
}
@ -47,60 +31,62 @@ class Controller extends Popover {
this.item = {};
this.tags = {};
this._prices = {};
this.total = 0;
this.totalQuantity = 0;
super.onClose();
}
calculateMax() {
this.max = this.item.available - this.total;
getTotalQuantity() {
let total = 0;
for (let price of this.prices) {
if (!price.quantity) price.quantity = 0;
total += price.quantity;
}
calculateTotal() {
this.total = 0;
this.prices.forEach(price => {
if (!price.quantity) price.quantity = 0;
this.total += price.quantity;
});
this.calculateMax();
this.totalQuantity = total;
this.maxQuantity = this.item.available - total;
}
addQuantity(price) {
if (this.total + price.grouping <= this.max)
this.getTotalQuantity();
const quantity = this.totalQuantity + price.grouping;
if (quantity <= this.maxQuantity)
price.quantity += price.grouping;
}
getFilledLines() {
const filledLines = [];
let match;
this.prices.forEach(price => {
getGroupings() {
const filledRows = [];
for (let price of this.prices) {
if (price.quantity && price.quantity > 0) {
match = filledLines.find(element => {
return element.warehouseFk == price.warehouseFk;
const priceMatch = filledRows.find(row => {
return row.warehouseFk == price.warehouseFk;
});
if (!match) {
filledLines.push(Object.assign({}, price));
return;
if (!priceMatch)
filledRows.push(Object.assign({}, price));
else priceMatch.quantity += price.quantity;
}
match.quantity += price.quantity;
}
});
return filledLines;
return filledRows;
}
submit() {
this.calculateTotal();
const filledLines = this.getFilledLines();
const filledRows = this.getGroupings();
if (filledLines.length <= 0) {
this.vnApp.showError(this.$t('First you must add some quantity'));
return;
}
try {
const hasValidGropings = filledRows.some(row =>
row.quantity % row.grouping == 0
);
if (filledRows.length <= 0)
throw new Error('First you must add some quantity');
if (!hasValidGropings)
throw new Error(`The amounts doesn't match with the grouping`);
const params = {
orderFk: this.order.id,
items: filledLines
items: filledRows
};
this.$http.post(`OrderRows/addToOrder`, params)
.then(() => {
@ -108,6 +94,11 @@ class Controller extends Popover {
this.hide();
if (this.card) this.card.reload();
});
} catch (e) {
this.vnApp.showError(this.$t(e.message));
return false;
}
return true;
}
}

View File

@ -0,0 +1,171 @@
import './index.js';
describe('Order', () => {
describe('Component vnOrderPricesPopover', () => {
let controller;
let $httpBackend;
let orderId = 16;
beforeEach(ngModule('order'));
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
$httpBackend = _$httpBackend_;
const $scope = $rootScope.$new();
const $element = angular.element('<vn-order-prices-popover></vn-order-prices-popover>');
const $transclude = {
$$boundTransclude: {
$$slots: []
}
};
controller = $componentController('vnOrderPricesPopover', {$element, $scope, $transclude});
controller._prices = [
{warehouseFk: 1, grouping: 10, quantity: 0},
{warehouseFk: 1, grouping: 100, quantity: 100}
];
controller.item = {available: 1000};
controller.order = {id: orderId};
}));
describe('prices() setter', () => {
it('should call to the getTotalQuantity() method', () => {
controller.getTotalQuantity = jest.fn();
controller.prices = [
{grouping: 10, quantity: 0},
{grouping: 100, quantity: 0},
{grouping: 1000, quantity: 0},
];
expect(controller.getTotalQuantity).toHaveBeenCalledWith();
});
});
describe('getTotalQuantity()', () => {
it('should set the totalQuantity and maxQuantity properties', () => {
controller.getTotalQuantity();
expect(controller.totalQuantity).toEqual(100);
expect(controller.maxQuantity).toEqual(900);
});
});
describe('addQuantity()', () => {
it('should call to the getTotalQuantity() method and NOT set the quantity property', () => {
jest.spyOn(controller, 'getTotalQuantity');
controller.prices = [
{grouping: 10, quantity: 0},
{grouping: 100, quantity: 0},
{grouping: 1000, quantity: 1000},
];
const oneThousandGrouping = controller.prices[2];
expect(oneThousandGrouping.quantity).toEqual(1000);
controller.addQuantity(oneThousandGrouping);
expect(controller.getTotalQuantity).toHaveBeenCalledWith();
expect(oneThousandGrouping.quantity).toEqual(1000);
});
it('should call to the getTotalQuantity() method and then set the quantity property', () => {
jest.spyOn(controller, 'getTotalQuantity');
const oneHandredGrouping = controller.prices[1];
controller.addQuantity(oneHandredGrouping);
expect(controller.getTotalQuantity).toHaveBeenCalledWith();
expect(oneHandredGrouping.quantity).toEqual(200);
});
});
describe('getGroupings()', () => {
it('should return a row with the total filled quantity', () => {
jest.spyOn(controller, 'getTotalQuantity');
controller.prices = [
{warehouseFk: 1, grouping: 10, quantity: 10},
{warehouseFk: 1, grouping: 100, quantity: 100},
{warehouseFk: 1, grouping: 1000, quantity: 1000},
];
const rows = controller.getGroupings();
const firstRow = rows[0];
expect(rows.length).toEqual(1);
expect(firstRow.quantity).toEqual(1110);
});
it('should return two filled rows with a quantity', () => {
jest.spyOn(controller, 'getTotalQuantity');
controller.prices = [
{warehouseFk: 1, grouping: 10, quantity: 10},
{warehouseFk: 2, grouping: 10, quantity: 10},
{warehouseFk: 1, grouping: 100, quantity: 0},
{warehouseFk: 1, grouping: 1000, quantity: 1000},
];
const rows = controller.getGroupings();
const firstRow = rows[0];
const secondRow = rows[1];
expect(rows.length).toEqual(2);
expect(firstRow.quantity).toEqual(1010);
expect(secondRow.quantity).toEqual(10);
});
});
describe('submit()', () => {
it('should throw an error if none of the rows contains a quantity', () => {
jest.spyOn(controller, 'getTotalQuantity');
jest.spyOn(controller.vnApp, 'showError');
controller.prices = [
{warehouseFk: 1, grouping: 10, quantity: 0},
{warehouseFk: 1, grouping: 100, quantity: 0}
];
controller.submit();
expect(controller.vnApp.showError).toHaveBeenCalledWith(`First you must add some quantity`);
});
it(`should throw an error if the quantity doesn't match the grouping value`, () => {
jest.spyOn(controller, 'getTotalQuantity');
jest.spyOn(controller.vnApp, 'showError');
controller.prices = [
{warehouseFk: 1, grouping: 10, quantity: 0},
{warehouseFk: 1, grouping: 100, quantity: 101}
];
controller.submit();
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The amounts doesn't match with the grouping`);
});
it('should should make an http query and then show a success message', () => {
jest.spyOn(controller, 'getTotalQuantity');
jest.spyOn(controller.vnApp, 'showSuccess');
controller.prices = [
{warehouseFk: 1, grouping: 10, quantity: 0},
{warehouseFk: 1, grouping: 100, quantity: 100}
];
const params = {
orderFk: orderId,
items: [{warehouseFk: 1, grouping: 100, quantity: 100}]
};
$httpBackend.expectPOST('OrderRows/addToOrder', params).respond(200);
controller.submit();
$httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith(`Data saved!`);
});
});
});
});

View File

@ -1,4 +1,3 @@
Last entries: Últimas entradas
Qty.: Cant.
Wrong quantity: Cantidad errónea
First you must add some quantity: Primero debes agregar alguna cantidad
The amounts doesn't match with the grouping: Las cantidades no coinciden con el grouping

View File

@ -1,47 +1,18 @@
@import "variables";
.vn-order-prices-popover .content {
max-width: 350px;
.header > a:first-child {
visibility: hidden;
}
img[ng-src] {
height: 100%;
width: 100%;
}
vn-vertical.data {
padding-right: 16px;
border-right: 1px solid $color-main;
}
.prices {
vn-table {
.warehouse {
width: 48px;
max-width: 48px;
}
.price-kg {
color: $color-font-secondary;
font-size: .75rem
}
.vn-input-number {
width: 56px;
width: 80px;
}
}
.footer {
text-align: center;
.error {
display: none;
}
&.invalid {
.error {
display: block;
padding-top: 10px;
color: $color-alert;
text-align: center;
}
}
}
}
}

View File

@ -7,7 +7,6 @@
<vn-item
ng-click="addTurn.show()"
vn-acl="buyer"
ng-show="$ctrl.isEditable"
vn-acl-action="remove"
name="addTurn"
translate>