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

This commit is contained in:
Juan 2018-09-13 15:22:42 +02:00
commit fad2b78cc3
56 changed files with 1759 additions and 278 deletions

View File

@ -16,7 +16,7 @@
"state": "claim.index",
"component": "vn-claim-index",
"description": "List",
"acl": ["salesAssistant"]
"acl": ["salesAssistant", "salesPerson"]
},
{
"url": "/:id",

View File

@ -80,7 +80,7 @@
<vn-dialog
vn-id="addSales">
<tpl-body>
<h3 translate>Claimable sales from ticket</h3><h3> {{$ctrl.claim.ticketFk}}</h3>
<h3><span translate>Claimable sales from ticket</span> {{$ctrl.claim.ticketFk}}</h3>
<vn-table>
<vn-thead>
<vn-tr>

View File

@ -3,6 +3,7 @@ Client Id: Id cliente
Observation: Observación
Responsible: Responsable
Claim Id: Id reclamación
Created: Creado
#sections
Claims: Reclamaciones

View File

@ -19,7 +19,8 @@
<vn-horizontal>
<vn-textfield vn-one label="Postcode" field="$ctrl.address.postalCode"></vn-textfield>
<vn-textfield vn-one label="Town/City" field="$ctrl.address.city"></vn-textfield>
<vn-autocomplete vn-one
<vn-autocomplete
vn-one
field="$ctrl.address.provinceFk"
url="/client/api/Provinces"
show-field="name"
@ -28,7 +29,8 @@
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one
<vn-autocomplete
vn-one
field="$ctrl.address.agencyModeFk"
url="/client/api/AgencyModes/"
show-field="name"

View File

@ -0,0 +1,53 @@
import './icon-menu.js';
describe('Component vnIconMenu', () => {
let $componentController;
let controller;
let $element;
beforeEach(() => {
angular.mock.module('ticket');
});
beforeEach(angular.mock.inject(_$componentController_ => {
$componentController = _$componentController_;
$element = angular.element(`<div class="shown"></div>`);
controller = $componentController('vnIconMenu', {$element: $element, $transclude: null});
}));
describe('getFields()', () => {
it(`should return an array with the fields selectables`, () => {
let fields = controller.getFields();
expect(fields).toEqual(['id', 'name']);
});
});
describe('onClick(event)', () => {
it(`should call preventDefault, onOpen and showDropdown`, () => {
let event = {preventDefault: () => {}};
controller.onOpen = () => {};
spyOn(event, 'preventDefault');
spyOn(controller, 'showDropDown');
spyOn(controller, 'onOpen');
controller.onClick(event);
expect(event.preventDefault).toHaveBeenCalledWith();
expect(controller.showDropDown).toHaveBeenCalledWith();
expect(controller.onOpen).toHaveBeenCalledWith();
});
});
describe('onDropDownSelect(value)', () => {
it(`should set field to a given value and call onChange`, () => {
controller.onChange = () => {};
spyOn(controller, 'onChange');
controller.onDropDownSelect('mariano');
expect(controller.field).toBe('mariano');
expect(controller.onChange).toHaveBeenCalledWith({value: 'mariano'});
});
});
});

View File

@ -40,3 +40,4 @@ import './table';
import './th';
import './input-range';
import './chip';
import './input-number';

View File

@ -0,0 +1,42 @@
<div class="container"
ng-class="{selected: $ctrl.hasFocus}">
<div class="textField">
<div class="leftIcons">
<vn-icon-button
icon="remove"
ng-click="$ctrl.remove()"
tabindex="-1"
title="Remove number">
</vn-icon-button>
</div>
<div class="infix">
<input
class="mdl-textfield__input"
type="number"
name="{{$ctrl.name}}"
ng-model="$ctrl.value"
ng-disabled="$ctrl.disabled"
ng-readonly="$ctrl.readonly"
ng-focus="$ctrl.hasFocus = true"
ng-blur="$ctrl.hasFocus = false"
tabindex="{{$ctrl.input.tabindex}}"/>
<label class="label" translate>{{::$ctrl.label}}</label>
</div>
<div class="underline"></div>
<div class="selected underline"></div>
<div class="suffix">
<vn-icon-button
icon="add"
ng-click="$ctrl.add()"
tabindex="-1"
title="Add number">
</vn-icon-button>
<i class="material-icons"
ng-if="$ctrl.hasInfo"
vn-tooltip="{{$ctrl.info}}">
info_outline
</i>
</div>
<div class="rightIcons"></div>
</div>
</div>

View File

@ -0,0 +1,104 @@
import ngModule from '../../module';
import Textfield from '../textfield/textfield';
import './style.scss';
export default class InputNumber extends Textfield {
constructor($element, $scope, $attrs, vnTemplate, $transclude) {
super($element, $scope, $attrs, vnTemplate, $transclude);
this.input.addEventListener('change', () => {
this.validateValue();
});
}
get value() {
return this._value;
}
set value(value) {
this._value = value;
this.hasValue = this._value !== null;
if (this.hasValue) this.element.classList.add('not-empty');
else this.element.classList.remove('not-empty');
this.element.querySelector('.infix').classList.remove('invalid', 'validated');
}
get max() {
return this.input.max;
}
set max(value) {
if (value)
this.input.max = value;
}
get min() {
return this.input.min;
}
set min(value) {
if (!value) value = 0;
this.input.min = value;
}
get step() {
return parseInt(this.input.step);
}
set step(value) {
this.input.step = value;
}
validateValue() {
if ((this.validate() !== undefined && !this.validate()) ||
(this.max && this.value > this.max) ||
(this.min && this.value < this.min) ||
(this.step && this.value % this.step != 0)) {
this.$element[0].querySelector('.infix').classList.add('invalid', 'validated');
}
if (this.onChange)
this.onChange();
}
add() {
if (this.step && this.value % this.step != 0) {
this.value += (this.step - this.value % this.step);
} else {
this.value += this.step;
}
this.validateValue();
}
remove() {
if (this.step && this.value % this.step != 0) {
this.value -= (this.step + this.value % this.step);
} else {
this.value -= this.step;
}
this.validateValue();
}
}
InputNumber.$inject = ['$element', '$scope', '$attrs', 'vnTemplate', '$transclude'];
ngModule.component('vnInputNumber', {
template: require('./index.html'),
controller: InputNumber,
bindings: {
label: '@?',
disabled: '<?',
min: '<?',
max: '<?',
step: '<?',
rule: '@?',
value: '=model',
validate: '&',
onChange: '&',
onClear: '&'
}
});

View File

@ -0,0 +1,160 @@
import './index.js';
describe('Component vnInputNumber', () => {
let $componentController;
let $scope;
let $attrs;
let $timeout;
let $element;
let controller;
beforeEach(() => {
angular.mock.module('claim');
});
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_, _$timeout_) => {
$componentController = _$componentController_;
$scope = $rootScope.$new();
$attrs = {};
$timeout = _$timeout_;
$element = angular.element('<div><input><div class="infix invalid validated"><div class="rightIcons"></div></div>');
controller = $componentController('vnInputNumber', {$element, $scope, $attrs, $timeout, $transclude: () => {}});
}));
describe('value() setter', () => {
it(`should set _value to a given value, add the class not-empty and remove invalid and validated`, () => {
controller.value = 'pepino';
let classes = controller.element.classList.toString();
expect(classes).toContain('not-empty');
expect(controller._value).toEqual('pepino');
classes = controller.element.querySelector('.infix').classList.toString();
expect(classes).not.toContain('invalid validated');
});
it(`should set _value to a given value and not add the class not-empty if the given value is null`, () => {
controller.value = null;
let classes = controller.element.classList.toString();
expect(classes).not.toContain('not-empty');
expect(controller._value).toEqual(null);
});
});
describe('max() setter', () => {
it(`should set input.max to a given value`, () => {
controller.max = 10;
expect(controller.input.max).toEqual('10');
});
});
describe('min() setter', () => {
it(`should set input.min if theres a given value`, () => {
controller.min = 1;
expect(controller.input.min).toEqual('1');
});
it(`should set input.min to 0 if theres not a given value`, () => {
controller.min = null;
expect(controller.input.min).toEqual('0');
});
});
describe('step() setter/getter', () => {
it(`should set input.step to a given value`, () => {
controller.step = 50;
expect(controller.input.step).toEqual('50');
});
it(`should return a number`, () => {
controller.step = 50;
expect(controller.step).toEqual(50);
expect(typeof controller.step).toEqual('number');
});
});
describe('validateValue()', () => {
it(`should add the classes invalid and validated if the value is less than min`, () => {
controller.validate = () => {};
controller.min = 0;
controller.value = -7;
let classes = controller.element.querySelector('.infix').classList.toString();
expect(classes).not.toContain('invalid validated');
expect(controller.value).toEqual(-7);
controller.validateValue();
classes = controller.element.querySelector('.infix').classList.toString();
expect(classes).toContain('infix invalid validated');
});
it(`should add the classes invalid and validated if the value is greater than max`, () => {
controller.validate = () => {};
controller.max = 10;
controller.value = 15;
let classes = controller.element.querySelector('.infix').classList.toString();
expect(classes).not.toContain('invalid validated');
expect(controller.value).toEqual(15);
controller.validateValue();
classes = controller.element.querySelector('.infix').classList.toString();
expect(classes).toContain('infix invalid validated');
});
it(`should add the classes invalid and validated if the value is not a valid step`, () => {
controller.validate = () => {};
controller.step = 5;
controller.value = 7;
let classes = controller.element.querySelector('.infix').classList.toString();
expect(classes).not.toContain('invalid validated');
expect(controller.value).toEqual(7);
controller.validateValue();
classes = controller.element.querySelector('.infix').classList.toString();
expect(classes).toContain('infix invalid validated');
});
it(`should add the classes invalid and validated if the function validate returns false`, () => {
controller.validate = () => {
return false;
};
controller.step = 5;
controller.value = 7;
let classes = controller.element.querySelector('.infix').classList.toString();
expect(classes).not.toContain('invalid validated');
expect(controller.value).toEqual(7);
controller.validateValue();
classes = controller.element.querySelector('.infix').classList.toString();
expect(classes).toContain('infix invalid validated');
});
});
describe('add()', () => {
it(`should set value to the next possible step and call validateValue`, () => {
spyOn(controller, 'validateValue');
controller.step = 50;
controller.value = -1;
controller.remove();
expect(controller.value).toEqual(-50);
expect(controller.validateValue).toHaveBeenCalledWith();
});
});
});

View File

@ -0,0 +1,21 @@
@import 'colors';
@import '../textfield/style.scss';
vn-input-number {
@extend vn-textfield;
input {
text-align: center!important;
}
vn-icon[icon=add],
vn-icon[icon=remove]{
&:not(:hover){
color: $secondary-font-color;
}
i {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
}
}

View File

@ -56,7 +56,7 @@ vn-table {
display: table-footer-group
}
vn-tr {
vn-tr, a.vn-tr {
display: table-row
}
@ -67,10 +67,8 @@ vn-table {
padding: 10px
}
vn-thead,
vn-tbody,
vn-tfoot {
vn-tr {
vn-thead, vn-tbody, vn-tfoot {
vn-tr, a.vn-tr {
display: table-row;
vn-th {
@ -101,7 +99,7 @@ vn-table {
vn-thead, vn-tbody, vn-empty-rows {
border-bottom: 3px solid $lines;
}
vn-tbody > vn-tr {
vn-tbody > vn-tr, vn-tbody > a.vn-tr {
border-bottom: 1px solid $lines;
transition: background-color 200ms ease-in-out;

View File

@ -1,6 +1,24 @@
@import 'colors';
vn-textarea {
& > .mdl-textfield {
width: initial;
display: block;
}
label {
position: absolute;
bottom: 0;
pointer-events: none;
color: $secondary-font-color;
transition-duration: .2s;
transition-timing-function: cubic-bezier(.4,0,.2,1);
}
& textarea.ng-not-empty+label.placeholder{
top: 5px;
color: $main-01;
padding: 0;
font-size: 12px;
visibility: visible!important;
content: normal!important;
}
}

View File

@ -5,5 +5,5 @@
ng-disabled="$ctrl.disabled"
ng-model="$ctrl.model">
</textarea>
<label class="mdl-textfield__label" translate>{{$ctrl.label}}</label>
<label class="mdl-textfield__label placeholder" translate>{{$ctrl.label}}</label>
</div>

View File

@ -81,6 +81,7 @@ export default class Textfield extends Input {
clear() {
this.saveOldValue();
this.value = null;
if (this.onClear) this.onClear();
this.input.focus();
}
}
@ -102,6 +103,7 @@ ngModule.component('vnTextfield', {
rule: '@?',
type: '@?',
vnTabIndex: '@?',
onChange: '&'
onChange: '&',
onClear: '&'
}
});

View File

@ -3,7 +3,7 @@
.icon-volume:before { content: '\e801'; } /* '' */
.icon-barcode:before { content: '\e802'; } /* '' */
.icon-bucket:before { content: '\e803'; } /* '' */
.icon-accessory:before { content: '\e804'; } /* '' */
.icon-accesory:before { content: '\e804'; } /* '' */
.icon-dfiscales:before { content: '\e805'; } /* '' */
.icon-doc:before { content: '\e806'; } /* '' */
.icon-eye:before { content: '\e807'; } /* '' */
@ -13,6 +13,8 @@
.icon-disabled:before { content: '\e80b'; } /* '' */
.icon-invoices:before { content: '\e80c'; } /* '' */
.icon-frozen-1:before { content: '\e80d'; } /* '' */
.icon-actions:before { content: '\e80e'; } /* '' */
.icon-details:before { content: '\e80f'; } /* '' */
.icon-noweb:before { content: '\e812'; } /* '' */
.icon-payment:before { content: '\e813'; } /* '' */
.icon-recovery:before { content: '\e815'; } /* '' */
@ -33,8 +35,9 @@
.icon-solunion:before { content: '\e827'; } /* '' */
.icon-reserva:before { content: '\e828'; } /* '' */
.icon-entry:before { content: '\e829'; } /* '' */
.icon-traceability:before { content: '\e82a'; } /* '' */
.icon-transaction:before { content: '\e82b'; } /* '' */
.icon-greenery:before { content: '\e82c'; } /* '' */
.icon-verde:before { content: '\e82c'; } /* '' */
.icon-regentry:before { content: '\e82d'; } /* '' */
.icon-plant:before { content: '\e82e'; } /* '' */
.icon-artificial:before { content: '\e82f'; } /* '' */

View File

@ -34,11 +34,11 @@
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-class="{'warning': $ctrl.isToday(sale.date)}"
<vn-tr ng-class="::{'warning': $ctrl.isToday(sale.date)}"
ng-repeat="sale in sales" vn-repeat-last on-last="$ctrl.scrollToActive()">
<vn-td>{{::sale.date | date:'dd/MM/yyyy HH:mm' }}</vn-td>
<vn-td number>
<span ng-class="{'link pointer': sale.isTicket}"
<span ng-class="::{'link pointer': sale.isTicket}"
ng-click="$ctrl.showDescriptor($event, sale)">
{{::sale.origin | dashIfEmpty}}
</span>
@ -46,9 +46,9 @@
<vn-td>{{::sale.stateName | dashIfEmpty}}</vn-td>
<vn-td>{{::sale.reference | dashIfEmpty}}</vn-td>
<vn-td>
<span ng-class="{'link pointer': sale.isTicket}"
<span ng-class="::{'link pointer': sale.isTicket}"
ng-click="$ctrl.showClientDescriptor($event, sale)">
{{sale.name | dashIfEmpty}}
{{::sale.name | dashIfEmpty}}
</span>
</vn-td>
<vn-td number>{{::sale.in | dashIfEmpty}}</vn-td>

View File

@ -74,7 +74,7 @@ class Controller {
};
this.$http.post(`order/api/Orders/new`, params).then(res => {
this.vnApp.showSuccess(this.translate.instant('Data saved!'));
this.$state.go("order.card.catalogue", {id: res.data});
this.$state.go("order.card.catalog", {id: res.data});
}).catch(e => {
this.vnApp.showError(this.translate.instant(e.data.error.message));
});

View File

@ -88,7 +88,7 @@ describe('Order', () => {
$httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
expect(controller.$state.go).toHaveBeenCalledWith("order.card.catalogue", {id: 1});
expect(controller.$state.go).toHaveBeenCalledWith("order.card.catalog", {id: 1});
});
});
});

View File

@ -17,6 +17,12 @@ input[type=reset]::-moz-focus-inner
{
border: none;
}
.unselectable {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
.link{
text-decoration: underline;
cursor: pointer;

View File

@ -37,8 +37,9 @@
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="ticket in tickets"
class="{{::$ctrl.compareDate(ticket.shipped)}} clickable"
<a
ng-repeat="ticket in tickets"
class="{{::$ctrl.compareDate(ticket.shipped)}} clickable vn-tr"
ui-sref="ticket.card.summary({id: {{::ticket.id}}})">
<vn-td>
<vn-icon ng-show="ticket.problem" class="bright"
@ -71,7 +72,7 @@
icon="desktop_windows">
</vn-icon-button>
</vn-td>
</vn-tr>
</a>
</vn-tbody>
</vn-table>
</vn-card>

View File

@ -48,7 +48,7 @@
<vn-table model="model">
<vn-thead>
<vn-tr>
<vn-th number ng-show="$ctrl.isEditable">
<vn-th number>
<vn-multi-check
data="$ctrl.sales">
</vn-multi-check>
@ -65,7 +65,7 @@
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="sale in sales">
<vn-td number ng-show="$ctrl.isEditable">
<vn-td number >
<vn-check
field="sale.checked">
</vn-check>

View File

@ -16,7 +16,8 @@ class Controller {
{callback: this.showDeleteTicketDialog, name: "Delete ticket", always: true},
{callback: this.markAsReserved, name: 'Mark as reserved'},
{callback: this.unmarkAsReserved, name: 'Unmark as reserved'},
{callback: this.showEditDialog, name: 'Update discount'}
{callback: this.showEditDialog, name: 'Update discount'},
{callback: this.createClaim, name: 'Add claim'}
];
}
@ -78,7 +79,6 @@ class Controller {
for (let i = 0; i < data.length; i++)
if (data[i].checked)
lines.push({id: data[i].id, instance: i});
return lines;
}
@ -177,7 +177,6 @@ class Controller {
});
}
// In Progress
linesToNewTicket() {
let ticket = {
oldTicketFk: this.ticket.id,
@ -197,6 +196,22 @@ class Controller {
});
}
createClaim() {
let claim = {
ticketFk: this.ticket.id,
clientFk: this.ticket.clientFk,
ticketCreated: this.ticket.shipped,
workerFk: this.ticket.client.salesPersonFk
};
let sales = this.getCheckedLines();
for (let i = 0; i < sales.length; i++)
sales[i].quantity = this.sales[sales[i].instance].quantity;
this.$http.post(`claim/api/Claims/createFromSales`, {claim: claim, sales: sales}).then(res => {
let url = this.$state.href("claim.card.basicData", {id: res.data.id}, {absolute: true});
window.open(url, '_blank');
});
}
goToTicket(ticketID) {
this.$state.go("ticket.card.sale", {id: ticketID});
}

View File

@ -33,14 +33,28 @@ describe('Ticket', () => {
quantity: 20,
price: 5.5,
discount: 0,
checked: true
checked: false
}
]};
$scope.addTurn = {show: () => {}};
controller = $componentController('vnTicketSale', {$scope: $scope}, {$state: $state});
controller.ticket = {id: 1};
controller.ticket = {id: 1, clientFk: 1, shipped: 1, client: {salesPersonFk: 1}};
spyOn(window, 'open');
}));
describe('createClaim()', () => {
it('should perfrom a query and call windows open', () => {
controller.sales = controller.$scope.model.data;
let res = {id: 1};
$httpBackend.expectPOST(`claim/api/Claims/createFromSales`).respond(res);
controller.createClaim();
$httpBackend.flush();
let urlMock = null;
expect(window.open).toHaveBeenCalledWith(urlMock, '_blank');
});
});
describe('getSales()', () => {
it('should make a query and call getTaxes()', () => {
let data = [
@ -56,7 +70,7 @@ describe('Ticket', () => {
quantity: 20,
price: 5.5,
discount: 0,
checked: true
checked: false
}
];
@ -113,9 +127,10 @@ describe('Ticket', () => {
describe('getCheckedLines()', () => {
it('should make an array of the instances with the property checked true()', () => {
controller.sales = [{id: 1, checked: true}, {id: 2, checked: false}, {id: 3, checked: true}];
let expectedResult = [{id: 1, instance: 0}];
controller.sales = controller.$scope.model.data;
expect(controller.getCheckedLines()).toEqual([{id: 1, instance: 0}, {id: 3, instance: 2}]);
expect(controller.getCheckedLines()).toEqual(expectedResult);
});
});

View File

@ -23,5 +23,6 @@ Thursday: Jueves
Friday: Viernes
Saturday: Sábado
Sunday: Domingo
Add claim: Crear reclamación
Transfer lines: Transferir líneas
Change ticket state to 'Ok': Cambiar estado del ticket a 'Ok'

View File

@ -167,7 +167,7 @@ export default {
itemCreateView: {
name: `${components.vnTextfield}[name="name"]`,
typeSelect: `vn-autocomplete[field="$ctrl.item.typeFk"] input`,
typeSelectOptionOne: `vn-autocomplete[field="$ctrl.item.typeFk"] vn-drop-down ul > li:nth-child(2)`,
typeSelectOptionThree: `vn-autocomplete[field="$ctrl.item.typeFk"] vn-drop-down ul > li:nth-child(3)`,
intrastatSelect: `vn-autocomplete[field="$ctrl.item.intrastatFk"] input`,
intrastatSelectOptionOne: `vn-autocomplete[field="$ctrl.item.intrastatFk"] vn-drop-down ul > li:nth-child(2)`,
originSelect: `vn-autocomplete[field="$ctrl.item.originFk"] input`,
@ -180,7 +180,7 @@ export default {
goToItemIndexButton: 'vn-item-descriptor [ui-sref="item.index"]',
basicDataButton: `vn-menu-item a[ui-sref="item.card.data"]`,
typeSelect: `vn-autocomplete[field="$ctrl.item.typeFk"] input`,
typeSelectOptionTwo: `vn-autocomplete[field="$ctrl.item.typeFk"] vn-drop-down ul > li:nth-child(2)`,
typeSelectOptionThree: `vn-autocomplete[field="$ctrl.item.typeFk"] vn-drop-down ul > li:nth-child(3)`,
intrastatSelect: `vn-autocomplete[field="$ctrl.item.intrastatFk"] input`,
intrastatSelectOptionOne: `vn-autocomplete[field="$ctrl.item.intrastatFk"] vn-drop-down ul > li:nth-child(1)`,
nameInput: `vn-horizontal:nth-child(2) > ${components.vnTextfield}`,
@ -274,7 +274,9 @@ export default {
},
ticketsIndex: {
createTicketButton: `vn-ticket-index ${components.vnFloatButton}`,
searchResult: `vn-ticket-index vn-card > div > vn-table > div > vn-tbody > vn-tr`,
searchResult: `vn-ticket-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr`,
searchResultDate: `vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)`,
searchResultAddress: `vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(6)`,
searchTicketInput: `vn-ticket-index ${components.vnTextfield}`,
searchButton: `vn-ticket-index vn-searchbar vn-icon-button[icon="search"]`
},
@ -295,10 +297,10 @@ export default {
ticketPackages: {
packagesButton: `vn-menu-item a[ui-sref="ticket.card.package.index"]`,
firstPackageSelect: `vn-autocomplete[label="Package"] > div > div > input`,
firstPackageSelectOptionThree: `vn-autocomplete[label="Package"] vn-drop-down ul > li:nth-child(3)`,
firstQuantityInput: `vn-textfield[label="Quantity"] > div > input`,
firstPackageSelectOptionTwo: `vn-autocomplete[label="Package"] vn-drop-down ul > li:nth-child(2)`,
firstQuantityInput: `vn-textfield[label="Quantity"] input`,
firstRemovePackageButton: `vn-icon[vn-tooltip="Remove package"]`,
addPackageButton: `vn-icon[vn-tooltip="Add package"]`,
addPackageButton: `vn-icon-button[vn-tooltip="Add package"]`,
clearPackageSelectButton: `vn-autocomplete[label="Package"] > div > div > div > vn-icon > i`,
savePackagesButton: `${components.vnSubmit}`
},
@ -319,10 +321,17 @@ export default {
firstSaleDiscount: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(8)',
firstSaleDiscountInput: 'vn-ticket-sale:nth-child(1) vn-ticket-sale-edit-discount > div > vn-textfield > div > div > div.infix > input.ng-not-empty',
firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(9)',
totalImport: 'vn-ticket-sale vn-tfoot > vn-tr > vn-td:nth-child(9) > section > p:nth-child(3) > strong',
secondSaleText: `vn-table div > vn-tbody > vn-tr:nth-child(2)`,
selectAllSalesCheckbox: `vn-ticket-sale vn-thead vn-check label`,
firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(2)',
firstSaleColour: `vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(5) section:nth-child(5)`,
firstSaleLength: `vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(5) section:nth-child(3)`,
firstSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(1) vn-check[field="sale.checked"] label`,
secondSaleColour: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(5) section:nth-child(5)`,
secondSalePrice: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(7)`,
secondSaleDiscount: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(8)`,
secondSaleImport: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(9)`,
secondSaleText: `vn-table div > vn-tbody > vn-tr:nth-child(2)`,
totalImport: 'vn-ticket-sale vn-tfoot > vn-tr > vn-td:nth-child(9) > section > p:nth-child(3) > strong',
selectAllSalesCheckbox: `vn-ticket-sale vn-thead vn-check label`,
secondSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(2) vn-check[field="sale.checked"] label`,
thirdSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(3) vn-check[field="sale.checked"] label`,
deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]',
@ -331,7 +340,8 @@ export default {
moveToTicketInputClearButton: 'vn-popover.shown i[title="Clear"]',
moveToTicketButton: 'vn-ticket-sale vn-popover.transfer vn-icon[icon="arrow_forward_ios"]',
moveToNewTicketButton: 'vn-ticket-sale vn-popover.transfer vn-button[label="New ticket"]',
acceptDeleteButton: `vn-ticket-sale > vn-confirm[vn-id="delete-lines"] button[response=ACCEPT]`,
acceptDeleteLineButton: `vn-ticket-sale > vn-confirm[vn-id="delete-lines"] button[response=ACCEPT]`,
acceptDeleteTicketButton: `vn-ticket-sale > vn-confirm[vn-id="deleteConfirmation"] button[response=ACCEPT]`,
stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-icon-menu[label="State"] button',
stateMenuOptions: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(1)',
moreMenuButton: 'vn-ticket-sale vn-tool-bar > vn-icon-menu[label="More"] button',
@ -340,7 +350,7 @@ export default {
moreMenuUnmarkResevedOption: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(4)',
moreMenuUpdateDiscount: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(5)',
moreMenuUpdateDiscountInput: 'vn-ticket-sale vn-dialog.shown vn-ticket-sale-edit-discount input',
firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(2)'
moreMenuCreateClaim: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(6)'
},
ticketTracking: {
trackingButton: `vn-left-menu a[ui-sref="ticket.card.tracking.index"]`,

View File

@ -1,106 +1,104 @@
import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/helpers.js';
describe('Claim', () => {
describe('Edit basic data path', () => {
const nightmare = createNightmare();
describe('Claim edit basic data path', () => {
const nightmare = createNightmare();
beforeAll(() => {
return nightmare
.waitForLogin('developer');
beforeAll(() => {
return nightmare
.waitForLogin('salesAssistant');
});
it('should click on the Claims button of the top bar menu', () => {
return nightmare
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.claimsButton)
.wait(selectors.claimsIndex.searchClaimInput)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/claim/index');
});
});
it('should click on the Claims button of the top bar menu', () => {
return nightmare
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.claimsButton)
.wait(selectors.claimsIndex.searchClaimInput)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/claim/index');
});
it('should search for the claim with id 1', () => {
return nightmare
.wait(selectors.claimsIndex.searchResult)
.type(selectors.claimsIndex.searchClaimInput, '1')
.click(selectors.claimsIndex.searchButton)
.waitForNumberOfElements(selectors.claimsIndex.searchResult, 1)
.countElement(selectors.claimsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
});
it('should search for the claim with id 1', () => {
return nightmare
.wait(selectors.claimsIndex.searchResult)
.type(selectors.claimsIndex.searchClaimInput, '1')
.click(selectors.claimsIndex.searchButton)
.waitForNumberOfElements(selectors.claimsIndex.searchResult, 1)
.countElement(selectors.claimsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
it(`should click on the search result to access to the claim Basic Data`, () => {
return nightmare
.waitToClick(selectors.claimsIndex.searchResult)
.waitToClick(selectors.claimBasicData.basicDataButton)
.waitForURL('basic-data')
.url()
.then(url => {
expect(url).toContain('basic-data');
});
});
it(`should click on the search result to access to the ticket Basic Data`, () => {
return nightmare
.waitToClick(selectors.claimsIndex.searchResult)
.waitToClick(selectors.claimBasicData.basicDataButton)
.waitForURL('basic-data')
.url()
.then(url => {
expect(url).toContain('basic-data');
});
it(`should edit claim state, is paid with mana and observation fields`, () => {
return nightmare
.waitToClick(selectors.claimBasicData.claimStateSelect)
.waitToClick(selectors.claimBasicData.claimStateSelectThirdOption)
.waitToClick(selectors.claimBasicData.isPaidWithManaCheckbox)
.clearInput(selectors.claimBasicData.observationInput)
.type(selectors.claimBasicData.observationInput, 'edited observation')
.click(selectors.claimBasicData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual(jasmine.arrayContaining(['Data saved!']));
});
});
it(`should edit claim state, is paid with mana and observation fields`, () => {
return nightmare
.waitToClick(selectors.claimBasicData.claimStateSelect)
.waitToClick(selectors.claimBasicData.claimStateSelectThirdOption)
.waitToClick(selectors.claimBasicData.isPaidWithManaCheckbox)
.clearInput(selectors.claimBasicData.observationInput)
.type(selectors.claimBasicData.observationInput, 'edited observation')
.click(selectors.claimBasicData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual(jasmine.arrayContaining(['Data saved!']));
});
it('should confirm the claim state was edited', () => {
return nightmare
.click(selectors.claimDetails.detailsButton)
.wait(selectors.claimDetails.addItemButton)
.click(selectors.claimBasicData.basicDataButton)
.wait(selectors.claimBasicData.claimStateSelect)
.getInputValue(selectors.claimBasicData.claimStateSelect)
.then(result => {
expect(result).toEqual('Gestionado');
});
});
it('should confirm the claim state was edited', () => {
return nightmare
.click(selectors.claimDetails.detailsButton)
.wait(selectors.claimDetails.addItemButton)
.click(selectors.claimBasicData.basicDataButton)
.wait(selectors.claimBasicData.claimStateSelect)
.getInputValue(selectors.claimBasicData.claimStateSelect)
.then(result => {
expect(result).toEqual('Gestionado');
});
it('should confirm the Is paid with mana checkbox is checked', () => {
return nightmare
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.claimBasicData.isPaidWithManaCheckbox)
.then(value => {
expect(value).toBeTruthy();
});
});
it('should confirm the Is paid with mana checkbox is checked', () => {
return nightmare
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.claimBasicData.isPaidWithManaCheckbox)
.then(value => {
expect(value).toBeTruthy();
});
it('should confirm the claim observation was edited', () => {
return nightmare
.getInputValue(selectors.claimBasicData.observationInput)
.then(result => {
expect(result).toEqual('edited observation');
});
});
it('should confirm the claim observation was edited', () => {
return nightmare
.getInputValue(selectors.claimBasicData.observationInput)
.then(result => {
expect(result).toEqual('edited observation');
});
});
it(`should edit the claim to leave it untainted`, () => {
return nightmare
.waitToClick(selectors.claimBasicData.claimStateSelect)
.waitToClick(selectors.claimBasicData.claimStateSelectFourthOption)
.waitToClick(selectors.claimBasicData.isPaidWithManaCheckbox)
.clearInput(selectors.claimBasicData.observationInput)
.type(selectors.claimBasicData.observationInput, 'Observation one')
.click(selectors.claimBasicData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual(jasmine.arrayContaining(['Data saved!']));
});
it(`should edit the claim to leave it untainted`, () => {
return nightmare
.waitToClick(selectors.claimBasicData.claimStateSelect)
.waitToClick(selectors.claimBasicData.claimStateSelectFourthOption)
.waitToClick(selectors.claimBasicData.isPaidWithManaCheckbox)
.clearInput(selectors.claimBasicData.observationInput)
.type(selectors.claimBasicData.observationInput, 'Observation one')
.click(selectors.claimBasicData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual(jasmine.arrayContaining(['Data saved!']));
});
});
});

View File

@ -49,7 +49,7 @@ describe('Item', () => {
.clearInput(selectors.itemBasicData.nameInput)
.type(selectors.itemBasicData.nameInput, 'Rose of Purity')
.waitToClick(selectors.itemBasicData.typeSelect)
.waitToClick(selectors.itemBasicData.typeSelectOptionTwo)
.waitToClick(selectors.itemBasicData.typeSelectOptionThree)
.waitToClick(selectors.itemBasicData.intrastatSelect)
.waitToClick(selectors.itemBasicData.intrastatSelectOptionOne)
.clearInput(selectors.itemBasicData.relevancyInput)

View File

@ -20,7 +20,7 @@ describe('Item', () => {
});
});
it('should search for the item Gem of Time', () => {
it('should search for the item Mjolnir', () => {
return nightmare
.wait(selectors.itemsIndex.searchResult)
.type(selectors.itemsIndex.searchItemInput, 'Mjolnir')

View File

@ -65,7 +65,7 @@ describe('Item', () => {
return nightmare
.type(selectors.itemCreateView.name, 'Infinity Gauntlet')
.waitToClick(selectors.itemCreateView.typeSelect)
.waitToClick(selectors.itemCreateView.typeSelectOptionOne)
.waitToClick(selectors.itemCreateView.typeSelectOptionThree)
.waitToClick(selectors.itemCreateView.intrastatSelect)
.waitToClick(selectors.itemCreateView.intrastatSelectOptionOne)
.waitToClick(selectors.itemCreateView.originSelect)

View File

@ -1,74 +1,128 @@
import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/helpers';
describe('Ticket', () => {
describe('List sale path', () => {
const nightmare = createNightmare();
describe('Ticket List sale path', () => {
const nightmare = createNightmare();
beforeAll(() => {
return nightmare
.waitForLogin('developer');
beforeAll(() => {
return nightmare
.waitForLogin('developer');
});
it('should click on the Tickets button of the top bar menu', () => {
return nightmare
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.ticketsButton)
.wait(selectors.ticketsIndex.createTicketButton)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/ticket/index');
});
});
it('should click on the Tickets button of the top bar menu', () => {
return nightmare
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.ticketsButton)
.wait(selectors.ticketsIndex.createTicketButton)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/ticket/index');
});
it('should search for the ticket 1', () => {
return nightmare
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:1')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.countElement(selectors.ticketsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
});
it('should search for the ticket 1', () => {
return nightmare
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:1')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.countElement(selectors.ticketsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
it(`should click on the search result to access to the ticket's sale`, () => {
return nightmare
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketSales.saleButton)
.waitForURL('sale')
.url()
.then(url => {
expect(url).toContain('sale');
});
});
it(`should click on the search result to access to the ticket's sale`, () => {
return nightmare
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketSales.saleButton)
.waitForURL('sale')
.url()
.then(url => {
expect(url).toContain('sale');
});
it('should confirm the first ticket sale contains the colour', () => {
return nightmare
.wait(selectors.ticketSales.firstSaleText)
.getInnerText(selectors.ticketSales.firstSaleColour)
.then(value => {
expect(value).toContain('Yellow');
});
});
it('should confirm the first ticket sale is the expected one', () => {
return nightmare
.wait(selectors.ticketSales.firstSaleText)
.getInnerText(selectors.ticketSales.firstSaleText)
.then(value => {
expect(value).toContain('Yellow');
expect(value).toContain('5');
expect(value).toContain('€9.60');
expect(value).toContain('0 %');
expect(value).toContain('€48.00');
});
it('should confirm the first ticket sale contains the lenght', () => {
return nightmare
.wait(selectors.ticketSales.firstSaleText)
.getInnerText(selectors.ticketSales.firstSaleText)
.then(value => {
expect(value).toContain('5');
});
});
it('should confirm the second ticket sale is the expected one', () => {
return nightmare
.wait(selectors.ticketSales.secondSaleText)
.getInnerText(selectors.ticketSales.secondSaleText)
.then(value => {
expect(value).toContain('Red');
expect(value).toContain('€4.21');
expect(value).toContain('0 %');
expect(value).toContain('€42.10');
});
it('should confirm the first ticket sale contains the price', () => {
return nightmare
.wait(selectors.ticketSales.firstSaleText)
.getInnerText(selectors.ticketSales.firstSalePrice)
.then(value => {
expect(value).toContain('€11.42');
});
});
it('should confirm the first ticket sale contains the discount', () => {
return nightmare
.wait(selectors.ticketSales.firstSaleText)
.getInnerText(selectors.ticketSales.firstSaleDiscount)
.then(value => {
expect(value).toContain('0 %');
});
});
it('should confirm the first ticket sale contains the total import', () => {
return nightmare
.wait(selectors.ticketSales.firstSaleText)
.getInnerText(selectors.ticketSales.firstSaleImport)
.then(value => {
expect(value).toContain('57.10');
});
});
it('should confirm the second ticket sale contains the colour', () => {
return nightmare
.wait(selectors.ticketSales.secondSaleText)
.getInnerText(selectors.ticketSales.secondSaleColour)
.then(value => {
expect(value).toContain('Red');
});
});
it('should confirm the second ticket sale contains the price', () => {
return nightmare
.wait(selectors.ticketSales.secondSaleText)
.getInnerText(selectors.ticketSales.secondSalePrice)
.then(value => {
expect(value).toContain('€1.30');
});
});
it('should confirm the second ticket sale contains the discount', () => {
return nightmare
.wait(selectors.ticketSales.secondSaleText)
.getInnerText(selectors.ticketSales.secondSaleDiscount)
.then(value => {
expect(value).toContain('0 %');
});
});
it('should confirm the second ticket sale contains the total import', () => {
return nightmare
.wait(selectors.ticketSales.secondSaleText)
.getInnerText(selectors.ticketSales.secondSaleImport)
.then(value => {
expect(value).toContain('13.00');
});
});
});

View File

@ -1,8 +1,7 @@
import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/helpers';
// #640 Ticket Create packages path is excluded
xdescribe('Ticket Create packages path', () => {
describe('Ticket Create packages path', () => {
const nightmare = createNightmare();
beforeAll(() => {
@ -36,7 +35,7 @@ xdescribe('Ticket Create packages path', () => {
it(`should click on the search result to access to the ticket packages`, () => {
return nightmare
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'Batman')
.waitForTextInElement(selectors.ticketsIndex.searchResultAddress, 'address 21')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketPackages.packagesButton)
.waitForURL('package/index')
@ -51,11 +50,11 @@ xdescribe('Ticket Create packages path', () => {
.waitToClick(selectors.ticketPackages.firstRemovePackageButton)
.waitToClick(selectors.ticketPackages.addPackageButton)
.waitToClick(selectors.ticketPackages.firstPackageSelect)
.waitToClick(selectors.ticketPackages.firstPackageSelectOptionThree)
.waitToClick(selectors.ticketPackages.firstPackageSelectOptionTwo)
.click(selectors.ticketPackages.savePackagesButton)
.waitForSnackbar()
.waitForLastSnackbar()
.then(result => {
expect(result).toEqual(jasmine.arrayContaining(['Some fields are invalid']));
expect(result).toEqual('Some fields are invalid');
});
});
@ -63,44 +62,44 @@ xdescribe('Ticket Create packages path', () => {
return nightmare
.type(selectors.ticketPackages.firstQuantityInput, 'ninety 9')
.click(selectors.ticketPackages.savePackagesButton)
.waitForSnackbar()
.waitForLastSnackbar()
.then(result => {
expect(result).toEqual(jasmine.arrayContaining(['Some fields are invalid']));
expect(result).toEqual('Some fields are invalid');
});
});
it(`should attempt create a new package but receive an error if quantity is 0`, () => {
return nightmare
.clearInput(selectors.ticketPackages.firstQuantityInput)
.type(selectors.ticketPackages.firstQuantityInput, '0')
.type(selectors.ticketPackages.firstQuantityInput, 0)
.click(selectors.ticketPackages.savePackagesButton)
.waitForSnackbar()
.waitForLastSnackbar()
.then(result => {
expect(result).toEqual(jasmine.arrayContaining(['Some fields are invalid']));
expect(result).toEqual('Some fields are invalid');
});
});
it(`should attempt create a new package but receive an error if package is blank`, () => {
return nightmare
.clearInput(selectors.ticketPackages.firstQuantityInput)
.type(selectors.ticketPackages.firstQuantityInput, '99')
.type(selectors.ticketPackages.firstQuantityInput, 99)
.click(selectors.ticketPackages.clearPackageSelectButton)
.click(selectors.ticketPackages.savePackagesButton)
.waitForSnackbar()
.waitForLastSnackbar()
.then(result => {
expect(result).toEqual(jasmine.arrayContaining(['Package cannot be blank']));
expect(result).toEqual('The package cannot be blank');
});
});
it(`should create a new package with correct data`, () => {
return nightmare
.waitToClick(selectors.ticketPackages.firstPackageSelect)
.waitToClick(selectors.ticketPackages.firstPackageSelectOptionThree)
.waitForTextInInput(selectors.ticketPackages.firstPackageSelect, 'Iron Patriot')
.waitToClick(selectors.ticketPackages.firstPackageSelectOptionTwo)
.waitForTextInInput(selectors.ticketPackages.firstPackageSelect, 'Legendary Box')
.click(selectors.ticketPackages.savePackagesButton)
.waitForSnackbar()
.waitForLastSnackbar()
.then(result => {
expect(result).toEqual(jasmine.arrayContaining(['Data saved!']));
expect(result).toEqual('Data saved!');
});
});
@ -109,10 +108,10 @@ xdescribe('Ticket Create packages path', () => {
.click(selectors.ticketSales.saleButton)
.wait(selectors.ticketSales.firstPackageSelect)
.click(selectors.ticketPackages.packagesButton)
.waitForTextInInput(selectors.ticketPackages.firstPackageSelect, 'Iron Patriot')
.waitForTextInInput(selectors.ticketPackages.firstPackageSelect, 'Legendary Box')
.getInputValue(selectors.ticketPackages.firstPackageSelect)
.then(result => {
expect(result).toEqual('Iron Patriot');
expect(result).toEqual('Legendary Box');
});
});

View File

@ -120,7 +120,7 @@ describe('Ticket', () => {
return nightmare
.getInnerText(selectors.ticketBasicData.stepTwoTotalPriceDif)
.then(result => {
expect(result).toContain('-€206.60');
expect(result).toContain('-€20.65');
});
});

View File

@ -0,0 +1,772 @@
import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/helpers';
describe('Ticket Edit sale path', () => {
const nightmare = createNightmare();
beforeAll(() => {
return nightmare
.waitForLogin('salesPerson');
});
it('should click on the Tickets button of the top bar menu', () => {
return nightmare
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.ticketsButton)
.wait(selectors.ticketsIndex.createTicketButton)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/ticket/index');
});
});
it('should search for a specific ticket', () => {
return nightmare
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:16')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.countElement(selectors.ticketsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
});
it(`should click on the search result to access to the ticket Sale`, () => {
return nightmare
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketSales.saleButton)
.waitForURL('/sale')
.url()
.then(url => {
expect(url).toContain('/sale');
});
});
describe('Before tests begings', () => {
it(`should check the quantity in the 1st line which we will be using in the further tests`, () => {
return nightmare
.wait(selectors.ticketSales.firstSaleText)
.getInputValue(selectors.ticketSales.firstSaleQuantity)
.then(value => {
expect(value).toEqual('5');
});
});
it(`should check the Price in the 1st line which we will be using in the further tests`, () => {
return nightmare
.wait(selectors.ticketSales.firstSaleText)
.getInnerText(selectors.ticketSales.firstSalePrice)
.then(value => {
expect(value).toEqual('€11.42');
});
});
it(`should check the Discount in the 1st line which we will be using in the further tests`, () => {
return nightmare
.wait(selectors.ticketSales.firstSaleText)
.getInnerText(selectors.ticketSales.firstSaleDiscount)
.then(value => {
expect(value).toEqual('0 %');
});
});
it(`should check the Import in the 1st line which we will be using in the further tests`, () => {
return nightmare
.wait(selectors.ticketSales.firstSaleText)
.getInnerText(selectors.ticketSales.firstSaleImport)
.then(value => {
expect(value).toEqual('€57.10');
});
});
it(`should count the ticket lines to verify there are 4 for further testing`, () => {
return nightmare
.countElement(selectors.ticketSales.saleLine)
.then(result => {
expect(result).toEqual(4);
});
});
});
it(`should check the zoomed image isnt present`, () => {
return nightmare
.countElement(selectors.ticketSales.firstSaleZoomedImage)
.then(result => {
expect(result).toEqual(0);
});
});
it(`should click on the thumbnail image of the 1st sale and see the zoomed image`, () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleThumbnailImage)
.countElement(selectors.ticketSales.firstSaleZoomedImage)
.then(result => {
expect(result).toEqual(1);
});
});
it(`should click on the zoomed image to close it`, () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleZoomedImage)
.countElement(selectors.ticketSales.firstSaleZoomedImage)
.then(result => {
expect(result).toEqual(0);
});
});
it(`should confirm the item descriptor insnt visible yet`, () => {
return nightmare
.isVisible(selectors.ticketSales.saleDescriptorPopover)
.then(result => {
expect(result).toBeFalsy();
});
});
it(`should click on the first sale ID making the item descriptor visible`, () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleID)
.isVisible(selectors.ticketSales.saleDescriptorPopover)
.then(result => {
expect(result).toBeTruthy();
});
});
it(`should click on the descriptor image of the 1st sale and see the zoomed image`, () => {
return nightmare
.waitToClick('vn-item-descriptor img')
.countElement(selectors.ticketSales.firstSaleZoomedImage)
.then(result => {
expect(result).toEqual(1);
});
});
it(`should click on the zoomed image to close it`, () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleZoomedImage)
.countElement(selectors.ticketSales.firstSaleZoomedImage)
.then(result => {
expect(result).toEqual(0);
});
});
it(`should click on the summary icon of the item-descriptor to access to the item summary`, () => {
return nightmare
.waitToClick(selectors.ticketSales.saleDescriptorPopoverSummaryButton)
.waitForURL('/summary')
.url()
.then(url => {
expect(url).toContain('/summary');
});
});
it('should return to ticket sales section', () => {
return nightmare
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.ticketsButton)
.wait(selectors.ticketsIndex.createTicketButton)
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:16')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketSales.saleButton)
.waitForURL('/sale')
.url()
.then(url => {
expect(url).toContain('/sale');
});
});
it('should try to add a higher quantity value and then receive an error', () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleQuantityClearInput)
.type(selectors.ticketSales.firstSaleQuantity, '9\u000d')
.waitForLastSnackbar()
.then(result => {
expect(result).toEqual('The new quantity should be smaller than the old one');
});
});
it('should remove 1 from quantity', () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleQuantityClearInput)
.type(selectors.ticketSales.firstSaleQuantity, '4\u000d')
.waitForLastSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should update the price', () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSalePrice)
.wait(selectors.ticketSales.firstSalePriceInput)
.type(selectors.ticketSales.firstSalePriceInput, 5)
.type('body', '\u000d') // simulates enter
.waitForLastSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the price have been updated', () => {
return nightmare
.getInnerText(selectors.ticketSales.firstSalePrice)
.then(result => {
expect(result).toContain('€5.00');
});
});
it('should confirm the total price for that item have been updated', () => {
return nightmare
.getInnerText(selectors.ticketSales.firstSaleImport)
.then(result => {
expect(result).toContain('€20.00');
});
});
it('should update the discount', () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleDiscount)
.wait('vn-textfield[label="Discount"] > div[class="container selected"]') // a function selects the text after it's loaded
.type(selectors.ticketSales.firstSaleDiscountInput, 50)
.type('body', '\u000d') // simulates enter
.waitForLastSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the discount have been updated', () => {
return nightmare
.waitForTextInElement(selectors.ticketSales.firstSaleDiscount, '50 %')
.getInnerText(selectors.ticketSales.firstSaleDiscount)
.then(result => {
expect(result).toContain('50 %');
});
});
it('should confirm the total import for that item have been updated', () => {
return nightmare
.waitForTextInElement(selectors.ticketSales.firstSaleImport, '€10.00')
.getInnerText(selectors.ticketSales.firstSaleImport)
.then(result => {
expect(result).toContain('€10.00');
});
});
it('should select the third sale and create a claim of it', () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleCheckbox)
.waitToClick(selectors.ticketSales.moreMenuButton)
.waitToClick(selectors.ticketSales.moreMenuCreateClaim)
.waitForLogin('Developer')
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.claimsButton)
.wait(selectors.claimsIndex.searchResult)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/claim/index');
});
});
it('should click on the Claims button of the top bar menu', () => {
return nightmare
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.claimsButton)
.wait(selectors.claimsIndex.searchClaimInput)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/claim/index');
});
});
it('should search for the claim with id 4', () => {
return nightmare
.wait(selectors.claimsIndex.searchResult)
.type(selectors.claimsIndex.searchClaimInput, 4)
.click(selectors.claimsIndex.searchButton)
.waitForNumberOfElements(selectors.claimsIndex.searchResult, 1)
.countElement(selectors.claimsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
});
it('should click the Tickets button of the top bar menu', () => {
return nightmare
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.ticketsButton)
.wait(selectors.ticketsIndex.createTicketButton)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/ticket/index');
});
});
it('should search the ticket', () => {
return nightmare
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:16')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.countElement(selectors.ticketsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
});
it(`should click on the result to access to the ticket Sale`, () => {
return nightmare
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketSales.saleButton)
.waitForURL('/sale')
.url()
.then(url => {
expect(url).toContain('/sale');
});
});
it('should select the third sale and delete it', () => {
return nightmare
.waitToClick(selectors.ticketSales.thirdSaleCheckbox)
.waitToClick(selectors.ticketSales.deleteSaleButton)
.waitToClick(selectors.ticketSales.acceptDeleteLineButton)
.waitForLastSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it(`should confirm the third sale was deleted`, () => {
return nightmare
.countElement(selectors.ticketSales.saleLine)
.then(result => {
expect(result).toEqual(3);
});
});
it('should select the third sale and attempt to send it to a frozen client ticket', () => {
return nightmare
.waitToClick(selectors.ticketSales.thirdSaleCheckbox)
.waitToClick(selectors.ticketSales.transferSaleButton)
.wait(selectors.ticketSales.moveToTicketInput)
.type(selectors.ticketSales.moveToTicketInput, 2)
.waitToClick(selectors.ticketSales.moveToTicketButton)
.waitForLastSnackbar()
.then(result => {
expect(result).toEqual(`The sales of that ticket can't be modified`);
});
});
it('should transfer the sale to a valid ticket', () => {
return nightmare
.waitToClick(selectors.ticketSales.moveToTicketInputClearButton)
.type(selectors.ticketSales.moveToTicketInput, 12)
.waitToClick(selectors.ticketSales.moveToTicketButton)
.waitForURL('ticket/12/sale')
.url()
.then(result => {
expect(result).toContain(`ticket/12/sale`);
});
});
it('should confirm the transfered line is the correct one', () => {
return nightmare
.wait(selectors.ticketSales.firstSaleText)
.getInnerText(selectors.ticketSales.firstSaleText)
.then(result => {
expect(result).toContain(`Mark I`);
});
});
it('should go back to the original ticket sales section', () => {
return nightmare
.waitToClick(selectors.itemsIndex.goBackToModuleIndexButton)
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:16')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketSales.saleButton)
.waitForURL('/sale')
.url()
.then(url => {
expect(url).toContain('/sale');
});
});
it(`should confirm the original ticket has only two lines now`, () => {
return nightmare
.wait(selectors.ticketSales.saleLine)
.countElement(selectors.ticketSales.saleLine)
.then(result => {
expect(result).toEqual(2);
});
});
it('should go back to the receiver ticket sales section', () => {
return nightmare
.waitToClick(selectors.itemsIndex.goBackToModuleIndexButton)
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:12')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketSales.saleButton)
.waitForURL('/sale')
.url()
.then(url => {
expect(url).toContain('/sale');
});
});
it('should transfer the sale back to the original ticket', () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleCheckbox)
.waitToClick(selectors.ticketSales.transferSaleButton)
.wait(selectors.ticketSales.moveToTicketInput)
.type(selectors.ticketSales.moveToTicketInput, 16)
.waitToClick(selectors.ticketSales.moveToTicketButton)
.waitForURL('ticket/16/sale')
.url()
.then(result => {
expect(result).toContain(`ticket/16/sale`);
});
});
it('should confirm the original ticket received the line', () => {
return nightmare
.wait(selectors.ticketSales.saleLine)
.countElement(selectors.ticketSales.saleLine)
.then(result => {
expect(result).toEqual(3);
});
});
it('should select the second and third sale and tranfer them to a new ticket then get to the ticket index', () => {
return nightmare
.waitToClick(selectors.ticketSales.secondSaleCheckbox)
.waitToClick(selectors.ticketSales.thirdSaleCheckbox)
.waitToClick(selectors.ticketSales.transferSaleButton)
.waitToClick(selectors.ticketSales.moveToNewTicketButton)
.waitForLogin('salesPerson')
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.ticketsButton)
.wait(selectors.ticketsIndex.createTicketButton)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/ticket/index');
});
});
it('should search for a specific created ticket', () => {
return nightmare
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:22')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.countElement(selectors.ticketsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
});
it(`should click on the search result to access to the ticket Sale`, () => {
return nightmare
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketSales.saleButton)
.waitForURL('/sale')
.url()
.then(url => {
expect(url).toContain('/sale');
});
});
it('should confirm the new ticket received both lines', () => {
return nightmare
.countElement(selectors.ticketSales.saleLine)
.then(result => {
expect(result).toEqual(2);
});
});
it('should check the first sale reserved icon isnt visible', () => {
return nightmare
.isVisible(selectors.ticketSales.firstSaleReservedIcon)
.then(result => {
expect(result).toBeFalsy();
});
});
it('should mark the first sale as reserved', () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleCheckbox)
.waitToClick(selectors.ticketSales.moreMenuButton)
.waitToClick(selectors.ticketSales.moreMenuReseveOption)
.waitForClassNotPresent(selectors.ticketSales.firstSaleReservedIcon, 'ng-hide')
.isVisible(selectors.ticketSales.firstSaleReservedIcon)
.then(result => {
expect(result).toBeTruthy();
});
});
it('should unmark the first sale as reserved', () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleCheckbox)
.waitToClick(selectors.ticketSales.moreMenuButton)
.waitToClick(selectors.ticketSales.moreMenuUnmarkResevedOption)
.waitForClassPresent(selectors.ticketSales.firstSaleReservedIcon, 'ng-hide')
.isVisible(selectors.ticketSales.firstSaleReservedIcon)
.then(result => {
expect(result).toBeFalsy();
});
});
it('should update all sales discount', () => {
return nightmare
.waitToClick(selectors.ticketSales.selectAllSalesCheckbox)
.waitToClick(selectors.ticketSales.moreMenuButton)
.waitToClick(selectors.ticketSales.moreMenuUpdateDiscount)
.wait(selectors.ticketSales.moreMenuUpdateDiscountInput)
.type(selectors.ticketSales.moreMenuUpdateDiscountInput, 100)
.type('body', '\u000d') // simulates enter
.waitForTextInElement(selectors.ticketSales.totalImport, '€0.00')
.getInnerText(selectors.ticketSales.totalImport)
.then(result => {
expect(result).toEqual('€0.00');
});
});
it('should log in as Production role and go to the ticket index', () => {
return nightmare
.waitToClick(selectors.globalItems.logOutButton)
.waitForLogin('production')
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.ticketsButton)
.wait(selectors.ticketsIndex.createTicketButton)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/ticket/index');
});
});
it('should now search for a specific ticket', () => {
return nightmare
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:16')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.countElement(selectors.ticketsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
});
it(`should now click on the search result to access to the ticket Tracking`, () => {
return nightmare
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketTracking.trackingButton)
.waitForURL('/tracking/index')
.url()
.then(url => {
expect(url).toContain('/tracking/index');
});
});
it(`should click on the edit ticket tracking state button`, () => {
return nightmare
.waitToClick(selectors.ticketTracking.createStateButton)
.waitForURL('/tracking/edit')
.url()
.then(url => {
expect(url).toContain('/tracking/edit');
});
});
it(`should set the state of the ticket to preparation`, () => {
return nightmare
.waitToClick(selectors.ticketTracking.stateSelect)
.wait(selectors.ticketTracking.stateSelectInput)
.type(selectors.ticketTracking.stateSelectInput, 'Preparación')
.waitToClick(selectors.ticketTracking.stateSelectFirstResult)
.waitForTextInInput(selectors.ticketTracking.stateSelectInput, 'Preparación')
.click(selectors.ticketTracking.saveButton)
.waitForURL('/tracking/index')
.url()
.then(url => {
expect(url).toContain('/tracking/index');
});
});
it(`should click on the ticket Sale menu button`, () => {
return nightmare
.waitToClick(selectors.ticketSales.saleButton)
.waitForURL('/sale')
.url()
.then(url => {
expect(url).toContain('/sale');
});
});
describe('when state is preparation and loged as Production', () => {
it(`should not be able to edit the sale price`, () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSalePrice)
.exists(selectors.ticketSales.firstSalePriceInput)
.then(result => {
expect(result).toBeFalsy();
});
});
it(`should not be able to edit the sale discount`, () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleDiscount)
.exists(selectors.ticketSales.firstSaleDiscountInput)
.then(result => {
expect(result).toBeFalsy();
});
});
it(`should not be able to edit the sale state`, () => {
return nightmare
.waitToClick(selectors.ticketSales.stateMenuButton)
.exists(selectors.ticketSales.stateMenuOptions)
.then(result => {
expect(result).toBeFalsy();
});
});
it('should log in as salesPerson role and go to the ticket index', () => {
return nightmare
.waitToClick(selectors.globalItems.logOutButton)
.waitForLogin('salesPerson')
.waitToClick(selectors.globalItems.applicationsMenuButton)
.wait(selectors.globalItems.applicationsMenuVisible)
.waitToClick(selectors.globalItems.ticketsButton)
.wait(selectors.ticketsIndex.createTicketButton)
.parsedUrl()
.then(url => {
expect(url.hash).toEqual('#!/ticket/index');
});
});
it('should again search for a specific ticket', () => {
return nightmare
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:16')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.countElement(selectors.ticketsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
});
it(`should again click on the search result to access to the ticket Sales`, () => {
return nightmare
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketSales.saleButton)
.waitForURL('/sale')
.url()
.then(url => {
expect(url).toContain('/sale');
});
});
});
describe('when state is preparation and loged as salesPerson', () => {
it(`shouldnt be able to edit the sale price`, () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSalePrice)
.exists(selectors.ticketSales.firstSalePriceInput)
.then(result => {
expect(result).toBeFalsy();
});
});
it(`shouldnt be able to edit the sale discount`, () => {
return nightmare
.waitToClick(selectors.ticketSales.firstSaleDiscount)
.exists(selectors.ticketSales.firstSaleDiscountInput)
.then(result => {
expect(result).toBeFalsy();
});
});
it(`shouldnt be able to edit the sale state`, () => {
return nightmare
.waitToClick(selectors.ticketSales.stateMenuButton)
.exists(selectors.ticketSales.stateMenuOptions)
.then(result => {
expect(result).toBeFalsy();
});
});
it('should go to another ticket sales section', () => {
return nightmare
.waitToClick(selectors.itemsIndex.goBackToModuleIndexButton)
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:17')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 26')
.waitToClick(selectors.ticketsIndex.searchResult)
.waitToClick(selectors.ticketSales.saleButton)
.waitForURL('/sale')
.url()
.then(url => {
expect(url).toContain('/sale');
});
});
it(`should be able to delete the ticket`, () => {
return nightmare
.waitToClick(selectors.ticketSales.moreMenuButton)
.waitToClick(selectors.ticketSales.moreMenuDeleteOption)
.waitToClick(selectors.ticketSales.acceptDeleteTicketButton)
.waitForURL('/ticket/index')
.url()
.then(url => {
expect(url).toContain('/ticket/index');
});
});
it(`should search for the deleted ticket`, () => {
return nightmare
.wait(selectors.ticketsIndex.searchResult)
.type(selectors.ticketsIndex.searchTicketInput, 'id:17')
.click(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.countElement(selectors.ticketsIndex.searchResult)
.then(result => {
expect(result).toEqual(1);
});
});
it(`should search for the deleted ticket`, () => {
return nightmare
.wait(selectors.ticketsIndex.searchResultDate)
.getInnerText(selectors.ticketsIndex.searchResultDate)
.then(result => {
expect(result).toContain(2000);
});
});
});
});

View File

@ -0,0 +1,50 @@
module.exports = Self => {
Self.remoteMethod('createFromSales', {
description: 'Create a claim',
accessType: '',
accepts: [{
arg: 'claim',
type: 'object',
required: true,
description: ' newTicketFk, clientFk, ticketCreated',
http: {source: 'body'}
}, {
arg: 'sales',
type: 'object',
required: true,
description: '[sales IDs]',
http: {source: 'body'}
}],
returns: {
type: 'object',
root: true
},
http: {
path: `/createFromSales`,
verb: 'post'
}
});
Self.createFromSales = async params => {
let model = Self.app.models;
let transaction = await Self.beginTransaction({});
try {
let newClaim = await Self.create(params.claim, {transaction});
let promises = [];
for (let i = 0; i < params.sales.length; i++) {
promises.push(model.ClaimBeginning.create(
{saleFk: params.sales[i].id,
claimFk: newClaim.id,
quantity: params.sales[i].quantity},
{transaction}));
}
await Promise.all(promises);
await transaction.commit();
return newClaim;
} catch (e) {
transaction.rollback();
throw e;
}
};
};

View File

@ -0,0 +1,53 @@
const app = require(`${servicesDir}/claim/server/server`);
describe('Claim Create', () => {
let newDate = new Date();
let createdClaimFk;
afterAll(async() => {
await app.models.Claim.destroyById(createdClaimFk);
});
let newClaim = {
ticketFk: 2,
clientFk: 101,
ticketCreated: newDate,
workerFk: 18
};
let newSale = [{
id: 3,
instance: 0,
quantity: 10
}];
let params = {claim: newClaim, sales: newSale};
it('should create a new claim', async() => {
let claim = await app.models.Claim.createFromSales(params);
expect(claim.ticketFk).toEqual(newClaim.ticketFk);
expect(claim.clientFk).toEqual(newClaim.clientFk);
expect(claim.ticketCreated).toEqual(newClaim.ticketCreated);
expect(claim.workerFk).toEqual(newClaim.workerFk);
let claimBeginning = await app.models.ClaimBeginning.findOne({where: {claimFk: claim.id}});
expect(claimBeginning.saleFk).toEqual(newSale[0].id);
expect(claimBeginning.quantity).toEqual(newSale[0].quantity);
createdClaimFk = claim.id;
});
it('should not be able to create a claim if exists that sale', async() => {
let error;
await app.models.Claim.createFromSales(params)
.catch(e => {
error = e;
});
expect(error.toString()).toContain(`A claim with that sale already exists`);
});
});

View File

@ -1,3 +1,4 @@
module.exports = Self => {
require('../methods/claim/getSummary')(Self);
require('../methods/claim/createFromSales')(Self);
};

View File

@ -21,16 +21,16 @@
"required": true
},
"isChargedToMana": {
"type": "boolean",
"required": true
"type": "boolean"
},
"created": {
"type": "date",
"required": true
"type": "date"
},
"responsibility": {
"type": "Number",
"required": true
"type": "Number"
},
"ticketFk": {
"type": "Number"
}
},
"relations": {

View File

@ -0,0 +1,70 @@
USE `vn`;
DROP procedure IF EXISTS `ticketGetTax`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketGetTax`()
READS SQL DATA
BEGIN
/**
* Calcula la base imponible, el IVA y el recargo de equivalencia para
* un conjunto de tickets.
*
* @table tmp.ticket(ticketFk) Identificadores de los tickets a calcular
* @return tmp.ticketTax Impuesto desglosado para cada ticket
* @return tmp.ticketAmount
*/
DROP TEMPORARY TABLE IF EXISTS tmp.addressCompany;
CREATE TEMPORARY TABLE tmp.addressCompany
(INDEX (addressFk, companyFk))
ENGINE = MEMORY
SELECT DISTINCT t.addressFk, t.companyFk
FROM tmp.ticket tmpTicket
JOIN ticket t ON t.id = tmpTicket.ticketFk;
CALL addressTaxArea ();
DROP TEMPORARY TABLE IF EXISTS tmp.ticketTax;
CREATE TEMPORARY TABLE tmp.ticketTax
(INDEX (ticketFk))
ENGINE = MEMORY
SELECT tmpTicket.ticketFk,
bp.pgcFk,
ROUND(SUM(s.quantity * s.price * (100 - s.discount)/100
),2) AS taxableBase,
ROUND(SUM(s.quantity * s.price * (100 - s.discount)/100
) * pgc.rate / 100,2) AS tax,
tc.code
FROM tmp.ticket tmpTicket
JOIN sale s ON s.ticketFk = tmpTicket.ticketFk
JOIN item i ON i.id = s.itemFk
JOIN ticket t ON t.id = tmpTicket.ticketFk
JOIN supplier su ON su.id = t.companyFk
JOIN tmp.addressTaxArea ata
ON ata.addressFk = t.addressFk AND ata.companyFk = t.companyFk
JOIN itemTaxCountry itc
ON itc.itemFk = i.id AND itc.countryFk = su.countryFk
JOIN bookingPlanner bp
ON bp.countryFk = su.countryFk
AND bp.taxAreaFk = ata.areaFk
AND bp.taxClassFk = itc.taxClassFk
JOIN pgc ON pgc.code = bp.pgcFk
JOIN taxClass tc ON tc.id = bp.taxClassFk
GROUP BY tmpTicket.ticketFk, pgc.code
HAVING taxableBase != 0;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketAmount;
CREATE TEMPORARY TABLE tmp.ticketAmount
(INDEX (ticketFk))
ENGINE = MEMORY
SELECT ticketFk, taxableBase, SUM(tax) tax
FROM tmp.ticketTax
GROUP BY ticketFk, code;
DROP TEMPORARY TABLE IF EXISTS tmp.addressCompany;
DROP TEMPORARY TABLE IF EXISTS tmp.addressTaxArea;
END$$
DELIMITER ;

View File

@ -0,0 +1,7 @@
UPDATE `salix`.`ACL` SET `model`='ClaimEnd' WHERE `id`='96';
UPDATE `salix`.`ACL` SET `model`='ClaimEnd' WHERE `id`='97';
UPDATE `salix`.`ACL` SET `model`='ClaimBeginning', `accessType`='*' WHERE `id`='98';
UPDATE `salix`.`ACL` SET `model`='ClaimDevelopment' WHERE `id`='99';
UPDATE `salix`.`ACL` SET `model`='ClaimDevelopment' WHERE `id`='100';
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (101, 'Claim', '*', '*', 'ALLOW', 'ROLE', 'employee');
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (102, 'Claim', 'createFromSales', '*', 'ALLOW', 'ROLE', 'employee');

View File

@ -441,10 +441,11 @@ INSERT INTO `vn`.`itemCategory`(`id`, `name`, `display`, `color`, `icon`)
INSERT INTO `vn`.`itemType`(`id`, `code`, `name`, `categoryFk`, `life`,`workerFk`, `isPackaging`)
VALUES
(1, 'CRI', 'Crisantemo' , 2, 31, 5, 0),
(2, 'ITG', 'Anthurium' , 1, 31, 5, 0),
(3, 'WPN', 'Paniculata' , 2, 31, 5, 0),
(4, 'PRT', 'Delivery ports', 3, 31, 5, 1);
(1, 'CRI', 'Crisantemo', 2, 31, 5, 0),
(2, 'ITG', 'Anthurium', 1, 31, 5, 0),
(3, 'WPN', 'Paniculata', 2, 31, 5, 0),
(4, 'PRT', 'Delivery ports', 3, NULL, 5, 1),
(5, 'CON', 'Container', 3, NULL, 5, 1);
INSERT INTO `vn`.`ink`(`id`, `name`, `picture`, `showOrder`)
VALUES
@ -487,12 +488,14 @@ INSERT INTO `vn`.`intrastat`(`id`, `description`, `taxClassFk`, `taxCodeFk`)
INSERT INTO `vn`.`item`(`id`, `name`,`typeFk`,`size`,`inkFk`,`category`,`stems`,`originFk`,`description`,`producerFk`,`intrastatFk`,`isOnOffer`,`expenceFk`,`isBargain`,`comment`,`relevancy`,`image`,`taxClassFk`,`longName`,`subName`,`tag5`,`value5`,`tag6`,`value6`,`tag7`,`value7`,`tag8`,`value8`)
VALUES
(1 , 'Gem of Time', 2, 70, 'AMA', 'EXT', 1 , 1, 'One of the infinity gems' , 1 , 06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, 'Gem of Time' , NULL, 'Medida', '70', 'Color', 'Amarillo' , 'Categoria', 'EXT', 'Tallos', '1'),
(2 , 'Gem of Mind', 2, 70, 'AZL', 'EXT', 1 , 2, 'One of the infinity gems' , 1 , 06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, 'Gem of Mind' , NULL, 'Medida', '70', 'Color', 'Azul' , 'Categoria', 'EXT', 'Tallos', '1'),
(3 , 'Iron Patriot', 1, 60, 'AMR', 'EXT', 1 , 3, 'Rhodeys armor' , 1 , 05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, 'Iron Patriot', NULL, 'Medida', '60', 'Color', 'Rosa/Amarillo', 'Categoria', 'EXT', 'Tallos', '1'),
(4 , 'Mark I', 1, 60, 'AMR', 'EXT', 1 , 1, 'Iron Mans first armor' , 1 , 05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, 'Mark I' , NULL, 'Medida', '60', 'Color', 'Rosa/Amarillo', 'Categoria', 'EXT', 'Tallos', '1'),
(5 , 'Mjolnir', 3, 30, 'AZL', 'EXT', 1 , 2, 'Thors hammer!' , 2 , 06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, 'Mjolnir' , NULL, 'Medida', '30', 'Color', 'Azul' , 'Categoria', 'EXT', 'Tallos', '1'),
(71, 'ShippingCost', 4, NULL, NULL, NULL, NULL, 1, NULL , NULL, 06021010, 1, 4751000000, 0, NULL, 0, NULL, 2, 'ShippingCost', NULL, NULL , NULL, NULL , NULL , NULL, NULL , NULL , NULL);
(1 , 'Gem of Time', 2, 70, 'AMA', 'EXT', 1 , 1, 'One of the infinity gems', 1, 06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, 'Gem of Time', NULL, 'Medida', '70', 'Color', 'Amarillo' , 'Categoria', 'EXT', 'Tallos', '1'),
(2 , 'Gem of Mind', 2, 70, 'AZL', 'EXT', 1 , 2, 'One of the infinity gems', 1, 06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, 'Gem of Mind', NULL, 'Medida', '70', 'Color', 'Azul' , 'Categoria', 'EXT', 'Tallos', '1'),
(3 , 'Iron Patriot', 1, 60, 'AMR', 'EXT', 1 , 3, 'Rhodeys armor', 1, 05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, 'Iron Patriot', NULL, 'Medida', '60', 'Color', 'Rosa/Amarillo', 'Categoria', 'EXT', 'Tallos', '1'),
(4 , 'Mark I', 1, 60, 'AMR', 'EXT', 1 , 1, 'Iron Mans first armor', 1, 05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, 'Mark I', NULL, 'Medida', '60', 'Color', 'Rosa/Amarillo', 'Categoria', 'EXT', 'Tallos', '1'),
(5 , 'Mjolnir', 3, 30, 'GRE', 'EXT', 1 , 2, 'Thors hammer!', 2, 06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, 'Mjolnir', NULL, 'Medida', '30', 'Color', 'Azul' , 'Categoria', 'EXT', 'Tallos', '1'),
(6 , 'Broken Box', 5, 30, 'GRE', 'EXT', 1 , 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, 'Legendary Box', NULL, 'Medida', '30', 'Color', 'Gris' , NULL, NULL, NULL, NULL),
(7 , 'Legendary Box', 5, 90, 'AZL', 'EXT', 1 , 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, 'Broken Box', NULL, 'Medida', '90', 'Color', 'Gris' , NULL, NULL, NULL, NULL),
(71, 'ShippingCost', 4, NULL, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, NULL, 2, 'ShippingCost', NULL, NULL , NULL, NULL , NULL , NULL, NULL, NULL, NULL);
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`)
VALUES
@ -505,30 +508,29 @@ INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `create
INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPackageReturnable`, `created`, `itemFk`, `price`)
VALUES
(1, 0.00, 10, 10, 0, 0, CURDATE(), 1, 1.50),
(2, 100.00, 20, 20, 0, 0, CURDATE(), 2, 1.00),
('a', 50.00, 30, 30, 0, 1, CURDATE(), 3, 0.00);
(1, 0.00, 10, 10, 0, 0, CURDATE(), 6, 1.50),
(2, 100.00, 20, 20, 0, 0, CURDATE(), 7, 1.00);
INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`, `created`, `pvp`)
VALUES
( 1, 1, 1, 2, CURDATE(), NULL),
( 2, 2, 2, 1, CURDATE(), NULL),
( 3, 3, 'a', 4, CURDATE(), NULL);
( 1, 1, 2, 2, CURDATE(), NULL),
( 2, 2, 2, 1, CURDATE(), NULL),
( 3, 3, 2, 4, CURDATE(), NULL);
INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `price`, `discount`, `reserved`, `isPicked`, `created`)
VALUES
( 1, 1, 1 , 'Gem of Time', 5 , 9.60, 0, 0, 0, CURDATE()),
( 2, 2, 1 , 'Gem of Mind', 10 , 4.21, 0, 0, 0, CURDATE()),
( 3, 1, 1 , 'Gem of Time', 2 , 9.60, 0, 0, 0, CURDATE()),
( 4, 4, 1 , 'Mark I' , 20 , 7.06, 0, 0, 0, CURDATE()),
( 5, 1, 2 , 'Gem of Time', 10 , 9.60, 0, 0, 0, CURDATE()),
( 6, 1, 3 , 'Gem of Time', 15 , 9.60, 0, 0, 0, CURDATE()),
( 7, 2, 11, 'Gem of Mind', 15 , 4.21, 0, 0, 0, CURDATE()),
( 8, 4, 11, 'Mark I' , 10 , 7.06, 0, 0, 0, CURDATE()),
( 9, 1, 16, 'Gem of Time', 5 , 9.60, 0, 0, 0, CURDATE()),
( 10, 2, 16, 'Gem of Mind', 10 , 4.21, 0, 0, 0, CURDATE()),
( 11, 1, 16, 'Gem of Time', 2 , 9.60, 0, 0, 0, CURDATE()),
( 12, 4, 16, 'Mark I' , 20 , 7.06, 0, 0, 0, CURDATE());
( 1, 1, 1 , 'Gem of Time', 5 , 11.42, 0, 0, 0, CURDATE()),
( 2, 2, 1 , 'Gem of Mind', 10 , 1.30, 0, 0, 0, CURDATE()),
( 3, 1, 1 , 'Gem of Time', 2 , 11.42, 0, 0, 0, CURDATE()),
( 4, 4, 1 , 'Mark I' , 20 , 3.26, 0, 0, 0, CURDATE()),
( 5, 1, 2 , 'Gem of Time', 10 , 11.42, 0, 0, 0, CURDATE()),
( 6, 1, 3 , 'Gem of Time', 15 , 11.42, 0, 0, 0, CURDATE()),
( 7, 2, 11, 'Gem of Mind', 15 , 1.30, 0, 0, 0, CURDATE()),
( 8, 4, 11, 'Mark I' , 10 , 3.26, 0, 0, 0, CURDATE()),
( 9, 1, 16, 'Gem of Time', 5 , 11.42, 0, 0, 0, CURDATE()),
( 10, 2, 16, 'Gem of Mind', 10 , 1.30, 0, 0, 0, CURDATE()),
( 11, 1, 16, 'Gem of Time', 2 , 11.42, 0, 0, 0, CURDATE()),
( 12, 4, 16, 'Mark I' , 20 , 3.26, 0, 0, 0, CURDATE());
INSERT INTO `vn`.`saleChecked`(`saleFk`, `isChecked`)
VALUES
@ -785,12 +787,12 @@ INSERT INTO `bi`.`claims_ratio`(`id_Cliente`, `Consumo`, `Reclamaciones`, `Ratio
INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`,`minPrice`,`producer`,`printedStickers`,`isChecked`,`isIgnored`, `created`)
VALUES
(1, 1, 1, 2.5, 5000 , 1, 1, 0.350, 0.050, 0.000, 1, 1, 0, NULL, 1.50, 1.25, 1.30, 2.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
(2, 2, 1, 20 , 100 , 1, 1, 0.700, 0.020, 0.000, 1, 1, 0, NULL, 2.50, 1.00, 2.50, 2.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(3, 3, 1, 20 , 100 , 1, 1, 0.700, 0.020, 0.000, 1, 1, 0, NULL, 2.50, 1.00, 2.50, 2.00, NULL, 0, 1, 0, CURDATE()),
(4, 2, 2, 5 , 450 , 1, 1, 0.500, 0.100, 0.000, 1, 1, 0, NULL, 2, 1.00, 1.30, 2.00, NULL, 0, 1, 0, CURDATE()),
(5, 3, 3, 10 , 500 , 1, 1, 1.000, 0.050, 0.000, 1, 1, 0, NULL, 2.50, 1.00, 2.50, 2.00, NULL, 0, 1, 0, CURDATE()),
(6, 4, 4, 20 , 100 , 1, 1, 0.700, 0.020, 0.000, 1, 1, 0, NULL, 2.50, 1.00, 2.50, 2.00, NULL, 0, 1, 0, CURDATE());
(1, 1, 1, 2.5, 5000 , 1, 1, 0.350, 0.050, 0.000, 10, 10, 1, NULL, 0.00, 1.30, 1.25, 1.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
(2, 2, 1, 20 , 100 , 1, 1, 0.700, 0.020, 0.000, 5, 5, 1, NULL, 0.00, 2.50, 2.00, 0.50, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(3, 3, 1, 20 , 100 , 1, 1, 0.700, 0.020, 0.000, 1, 1, 0, NULL, 0.00, 2.50, 2.00, 0.50, NULL, 0, 1, 0, CURDATE()),
(4, 2, 2, 5 , 450 , 1, 1, 0.500, 0.100, 0.000, 10, 10, 0, NULL, 0.00, 1.30, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(5, 3, 3, 10 , 500 , 1, 1, 1.000, 0.050, 0.000, 10, 10, 0, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(6, 4, 4, 20 , 100 , 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE());
INSERT INTO `vn2008`.`tblContadores`(`id`,`FechaInventario`)
VALUES

View File

@ -46,5 +46,6 @@
"Barcode must be unique": "El código de barras debe ser único",
"The warehouse can't be repeated": "El almacén no puede repetirse",
"The tag can't be repeated": "El tag no puede repetirse",
"The observation type can't be repeated": "El tipo de observación no puede repetirse"
"The observation type can't be repeated": "El tipo de observación no puede repetirse",
"A claim with that sale already exists": "Ya existe una reclamación para esta línea"
}

View File

@ -4,7 +4,7 @@ describe('client getDebt()', () => {
it('should return the client debt', async() => {
let result = await app.models.Client.getDebt(101);
expect(result.debt).toEqual(1342.66);
expect(result.debt).toEqual(1048.76);
});
});

View File

@ -17,7 +17,7 @@ describe('client summary()', () => {
it('should return a summary object containing debt', async() => {
let result = await app.models.Client.summary(101);
expect(result.debt.debt).toEqual(1342.66);
expect(result.debt.debt).toEqual(1048.76);
});
it('should return a summary object containing averageInvoiced', async() => {

View File

@ -2,7 +2,7 @@ let UserError = require('../../helpers').UserError;
module.exports = Self => {
Self.remoteMethod('moveToTicket', {
description: 'Change the state of a ticket',
description: 'Moves a line to a given ticket',
accessType: '',
accepts: [{
arg: 'params',

View File

@ -10,8 +10,8 @@ describe('sale priceDifference()', () => {
};
let result = await app.models.Sale.priceDifference(1, data);
expect(result.totalUnitPrice).toEqual(30.469999999999995);
expect(result.totalNewPrice).toEqual(26.12);
expect(result.totalDifference).toEqual(63.8);
expect(result.totalUnitPrice).toEqual(27.4);
expect(result.totalNewPrice).toEqual(22.33);
expect(result.totalDifference).toEqual(22.54);
});
});

View File

@ -1,5 +1,5 @@
module.exports = Self => {
Self.remoteMethod('deleted', {
Self.remoteMethodCtx('deleted', {
description: 'Sets the isDeleted value of a ticket to 1',
accessType: '',
accepts: [{
@ -19,7 +19,15 @@ module.exports = Self => {
}
});
Self.deleted = async params => {
return await Self.app.models.Ticket.update({id: params.id}, {isDeleted: '1'});
Self.deleted = async(ctx, params) => {
await Self.app.models.Ticket.update({id: params.id}, {isDeleted: '1'});
if (ctx.req.accessToken) {
let token = ctx.req.accessToken;
let currentUserId = token && token.userId;
let worker = await Self.app.models.Worker.findOne({where: {userFk: currentUserId}});
params.workerFk = worker.id;
}
return await Self.app.models.TicketTracking.create({ticketFk: params.id, stateFk: 17, workerFk: params.workerFk});
};
};

View File

@ -27,6 +27,6 @@ module.exports = Self => {
totalTax += tax.tax;
});
return totalTax;
return Math.round(totalTax * 100) / 100;
};
};

View File

@ -1,15 +1,25 @@
const app = require(`${servicesDir}/ticket/server/server`);
describe('ticket deleted()', () => {
it('should call the getShipped method', async() => {
let oldTicket = await app.models.Ticket.findOne({where: {id: 1}});
let ticket;
expect(oldTicket.isDeleted).toEqual(false);
await app.models.Ticket.deleted({id: 1});
let ticket = await app.models.Ticket.findOne({where: {id: 1}, fields: ['isDeleted']});
afterAll(async() => {
await app.models.Ticket.upsert(ticket);
await app.models.TicketTracking.create({ticketFk: ticket.id, stateFk: 3});
});
expect(ticket.isDeleted).toEqual(true);
oldTicket.isDeleted = 0;
await app.models.Ticket.upsert(oldTicket);
it('should change the state of a ticket to deleted, and set the property isDeleted true', async() => {
ticket = await app.models.Ticket.findOne({where: {id: 1}});
expect(ticket.isDeleted).toEqual(false);
ctx = {req: {accessToken: {userId: 9}}};
params = {id: 1};
await app.models.Ticket.deleted(ctx, params);
let deletedTicket = await app.models.Ticket.findOne({where: {id: 1}, fields: ['isDeleted']});
let changedState = await app.models.TicketState.findOne({where: {id: 1}});
expect(deletedTicket.isDeleted).toEqual(true);
expect(changedState.stateFk).toEqual(17);
});
});

View File

@ -4,6 +4,6 @@ describe('ticket getTaxes()', () => {
it('should return the tax of a given ticket', async() => {
let result = await app.models.Ticket.getTaxes(1);
expect(result[0].tax).toEqual(10.93);
expect(result[0].tax).toEqual(9.29);
});
});

View File

@ -4,7 +4,7 @@ describe('ticket getTotal()', () => {
it('should return the total of a ticket', async() => {
let result = await app.models.Ticket.getTotal(1);
expect(result).toEqual(291.08);
expect(result).toEqual(181.12);
});
it(`should return zero if the ticket doesn't have lines`, async() => {

View File

@ -4,7 +4,7 @@ describe('ticket getTotalVolume()', () => {
it('should return the total volume of a ticket', async() => {
let ticketFk = 1;
let expectedResult = 0.276;
let expectedResult = 0.078;
let result = await app.models.Ticket.getTotalVolume(ticketFk);

View File

@ -4,7 +4,7 @@ describe('ticket getVAT()', () => {
it('should call the getVAT method and return the response', async() => {
await app.models.Ticket.getVAT(1)
.then(response => {
expect(response).toEqual(40.58);
expect(response).toEqual(22.98);
});
});

View File

@ -17,18 +17,19 @@ describe('ticket summary()', () => {
it('should return a summary object containing subTotal for 1 ticket', async() => {
let result = await app.models.Ticket.summary(1);
expect(result.subTotal).toEqual(250.5);
expect(result.subTotal).toEqual(158.14);
});
it('should return a summary object containing VAT for 1 ticket', async() => {
let result = await app.models.Ticket.summary(1);
expect(result.VAT).toEqual(40.58);
expect(Math.round(result.VAT * 100) / 100).toEqual(22.98);
});
it('should return a summary object containing total for 1 ticket', async() => {
let result = await app.models.Ticket.summary(1);
let expectedTotal = result.subTotal + result.VAT;
let total = result.subTotal + result.VAT;
let expectedTotal = Math.round(total * 100) / 100;
expect(result.total).toEqual(expectedTotal);
});

View File

@ -86,6 +86,8 @@ module.exports = Self => {
tcp.itemFk,
tcp.grouping,
tcp.price,
tcp.rate,
tcp.warehouseFk,
w.name AS warehouse
FROM tmp.ticketComponentPrice tcp
JOIN vn.warehouse w ON w.id = tcp.warehouseFk`

View File

@ -6,7 +6,7 @@ describe('ticket listPackaging()', () => {
let response = await app.models.Packaging.listPackaging(filter);
expect(response[0].name).toBeDefined();
expect(response[0].name).toEqual('Gem of Time');
expect(response[0].name).toEqual('Broken Box');
});
});