#1260 ticket.service textfield por autocomplete
This commit is contained in:
parent
417dc511f5
commit
43bf6b45cf
|
@ -2,18 +2,18 @@
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="/ticket/api/TicketServices"
|
url="/ticket/api/TicketServices"
|
||||||
link="{ticketFk: $ctrl.$stateParams.id}"
|
link="{ticketFk: $ctrl.$stateParams.id}"
|
||||||
data="services"
|
data="$ctrl.services"
|
||||||
auto-load="true">
|
auto-load="true">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-watcher
|
<vn-watcher
|
||||||
vn-id="watcher"
|
vn-id="watcher"
|
||||||
data="services"
|
data="$ctrl.services"
|
||||||
form="form">
|
form="form">
|
||||||
</vn-watcher>
|
</vn-watcher>
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" compact>
|
<form name="form" ng-submit="$ctrl.onSubmit()" compact>
|
||||||
<vn-card pad-large>
|
<vn-card pad-large>
|
||||||
<vn-one>
|
<vn-one>
|
||||||
<vn-horizontal ng-repeat="service in services track by $index">
|
<vn-horizontal ng-repeat="service in $ctrl.services track by $index">
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
vn-focus
|
vn-focus
|
||||||
url="/api/TicketServiceTypes"
|
url="/api/TicketServiceTypes"
|
||||||
|
@ -22,6 +22,12 @@
|
||||||
value-field="name"
|
value-field="name"
|
||||||
field="service.description">
|
field="service.description">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
|
<vn-icon-button vn-auto margin-medium-v
|
||||||
|
icon="add_circle"
|
||||||
|
vn-tooltip="New service type"
|
||||||
|
ng-click="$ctrl.newServiceTypeDialog($index)"
|
||||||
|
vn-acl="administrative">
|
||||||
|
</vn-icon-button>
|
||||||
<vn-input-number vn-one min="0" step="1"
|
<vn-input-number vn-one min="0" step="1"
|
||||||
label="Quantity"
|
label="Quantity"
|
||||||
model="service.quantity"
|
model="service.quantity"
|
||||||
|
@ -60,4 +66,24 @@
|
||||||
<vn-button-bar>
|
<vn-button-bar>
|
||||||
<vn-submit label="Save"></vn-submit>
|
<vn-submit label="Save"></vn-submit>
|
||||||
</vn-button-bar>
|
</vn-button-bar>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<!-- Create service type dialog -->
|
||||||
|
<vn-dialog class="edit"
|
||||||
|
vn-id="createServiceTypeDialog"
|
||||||
|
on-open="$ctrl.onNewServiceTypeOpen()"
|
||||||
|
on-response="$ctrl.onNewServiceTypeResponse(response)">
|
||||||
|
<tpl-body>
|
||||||
|
<h5 pad-small-v translate>New service type</h5>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-one
|
||||||
|
label="Description"
|
||||||
|
model="$ctrl.newServiceType.name">
|
||||||
|
</vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
|
</tpl-body>
|
||||||
|
<tpl-buttons>
|
||||||
|
<input type="button" response="CANCEL" translate-attr="{value: 'Cancel'}"/>
|
||||||
|
<button response="ACCEPT" translate>Create</button>
|
||||||
|
</tpl-buttons>
|
||||||
|
</vn-dialog>
|
|
@ -1,19 +1,72 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
constructor($scope, $stateParams) {
|
constructor($http, $scope, $stateParams, vnApp, $translate, $element) {
|
||||||
|
this.$http = $http;
|
||||||
this.$scope = $scope;
|
this.$scope = $scope;
|
||||||
this.$stateParams = $stateParams;
|
this.$stateParams = $stateParams;
|
||||||
|
this.vnApp = vnApp;
|
||||||
|
this.$translate = $translate;
|
||||||
|
this.$element = $element;
|
||||||
|
this.services = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$onInit() {
|
||||||
|
this.getDefaultTaxClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultTaxClass() {
|
||||||
|
let config = {params: {
|
||||||
|
filter: {
|
||||||
|
where: {
|
||||||
|
code: 'G'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
let query = '/api/TaxClasses/findOne';
|
||||||
|
this.$http.get(query, config).then(res => {
|
||||||
|
if (res.data)
|
||||||
|
this.defaultTaxClass = res.data;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
add() {
|
add() {
|
||||||
this.$scope.model.insert({
|
this.$scope.model.insert({
|
||||||
taxClassFk: 2,
|
taxClassFk: this.defaultTaxClass.id,
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
ticketFk: this.$stateParams.id
|
ticketFk: this.$stateParams.id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onNewServiceTypeOpen() {
|
||||||
|
this.newServiceType.name = '';
|
||||||
|
|
||||||
|
this.nameInput = this.$element[0].querySelector('.edit input');
|
||||||
|
this.nameInput.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
newServiceTypeDialog(elementIndex) {
|
||||||
|
this.$scope.createServiceTypeDialog.show();
|
||||||
|
this.currentServiceIndex = elementIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
onNewServiceTypeResponse(response) {
|
||||||
|
if (response == 'ACCEPT') {
|
||||||
|
try {
|
||||||
|
if (!this.newServiceType.name)
|
||||||
|
throw new Error(`Name can't be empty`);
|
||||||
|
|
||||||
|
this.$http.post(`/api/TicketServiceTypes`, this.newServiceType).then(response => {
|
||||||
|
this.services[this.currentServiceIndex].description = response.data.name;
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
this.vnApp.showError(this.$translate.instant(err.message));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.$scope.watcher.check();
|
this.$scope.watcher.check();
|
||||||
this.$scope.model.save().then(() => {
|
this.$scope.model.save().then(() => {
|
||||||
|
@ -23,7 +76,7 @@ class Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.$inject = ['$scope', '$stateParams'];
|
Controller.$inject = ['$http', '$scope', '$stateParams', 'vnApp', '$translate', '$element'];
|
||||||
|
|
||||||
ngModule.component('vnTicketService', {
|
ngModule.component('vnTicketService', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
import './index.js';
|
||||||
|
|
||||||
|
describe('Ticket component vnTicketService', () => {
|
||||||
|
let controller;
|
||||||
|
let $httpBackend;
|
||||||
|
let $httpParamSerializer;
|
||||||
|
let $scope;
|
||||||
|
let $element;
|
||||||
|
|
||||||
|
beforeEach(ngModule('ticket'));
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject(($componentController, _$httpBackend_, _$httpParamSerializer_, $rootScope) => {
|
||||||
|
$element = angular.element(`<div></div>`);
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$httpParamSerializer = _$httpParamSerializer_;
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
controller = $componentController('vnTicketService', {$scope, $element});
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('getDefaultTaxClass', () => {
|
||||||
|
it('should set the default tax class in the controller', () => {
|
||||||
|
const config = {
|
||||||
|
filter: {
|
||||||
|
where: {
|
||||||
|
code: 'G'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let serializedParams = $httpParamSerializer(config);
|
||||||
|
|
||||||
|
$httpBackend.when('GET', `/api/TaxClasses/findOne?${serializedParams}`).respond({id: 4000, name: 'Whatever', code: 'GG'});
|
||||||
|
$httpBackend.expect('GET', `/api/TaxClasses/findOne?${serializedParams}`);
|
||||||
|
controller.getDefaultTaxClass();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.defaultTaxClass.code).toEqual('GG');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onNewServiceTypeResponse', () => {
|
||||||
|
it(`should throw an error`, () => {
|
||||||
|
controller.newServiceType = {name: undefined};
|
||||||
|
let error = controller.onNewServiceTypeResponse('ACCEPT');
|
||||||
|
|
||||||
|
expect(error.message).toEqual(`Name can't be empty`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set the description of the selected service upon service type creation', () => {
|
||||||
|
controller.services = [
|
||||||
|
{id: 1, description: 'not too great service'}
|
||||||
|
];
|
||||||
|
|
||||||
|
controller.newServiceType = {name: 'totally new stuff'};
|
||||||
|
controller.currentServiceIndex = 0;
|
||||||
|
|
||||||
|
$httpBackend.when('POST', '/api/TicketServiceTypes').respond({id: 4001, name: 'great service!'});
|
||||||
|
$httpBackend.expect('POST', '/api/TicketServiceTypes');
|
||||||
|
controller.onNewServiceTypeResponse('ACCEPT');
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.services[0].description).toEqual('great service!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,4 +1,5 @@
|
||||||
Service: Servicios
|
Service: Servicios
|
||||||
Tax class: Tipo IVA
|
Tax class: Tipo IVA
|
||||||
Add service: Añadir servicio
|
Add service: Añadir servicio
|
||||||
Remove service: Quitar servicio
|
Remove service: Quitar servicio
|
||||||
|
New service type: Nuevo tipo de servicio
|
Loading…
Reference in New Issue