Item request refactor #1818
This commit is contained in:
parent
58a763acf5
commit
2ed4cf3e4a
|
@ -61,7 +61,7 @@ export default {
|
|||
fiscalDataButton: 'vn-left-menu a[ui-sref="client.card.fiscalData"]',
|
||||
socialNameInput: `vn-textfield input[name="socialName"]`,
|
||||
fiscalIdInput: `vn-textfield input[name="fi"]`,
|
||||
equalizationTaxCheckbox: 'vn-check[label="Is equalizated"]',
|
||||
equalizationTaxCheckbox: 'vn-check[ng-model="$ctrl.client.isEqualizated"]',
|
||||
acceptPropagationButton: 'vn-client-fiscal-data > vn-confirm button[response=ACCEPT]',
|
||||
addressInput: `vn-textfield input[name="street"]`,
|
||||
postcodeInput: `vn-textfield input[name="postcode"]`,
|
||||
|
@ -482,7 +482,7 @@ export default {
|
|||
addRequestButton: 'vn-ticket-request-index > a > vn-float-button > button',
|
||||
request: 'vn-ticket-request-index vn-table vn-tr',
|
||||
descriptionInput: 'vn-ticket-request-create > form > div > vn-card > div > vn-horizontal:nth-child(1) > vn-textfield input',
|
||||
atenderAutocomplete: 'vn-ticket-request-create vn-autocomplete[ng-model="$ctrl.ticketRequest.atenderFk"]',
|
||||
atenderAutocomplete: 'vn-ticket-request-create vn-autocomplete[ng-model="$ctrl.ticketRequest.attenderFk"]',
|
||||
quantityInput: 'vn-ticket-request-create vn-input-number input[name=quantity]',
|
||||
priceInput: 'vn-ticket-request-create vn-input-number input[name=price]',
|
||||
firstRemoveRequestButton: 'vn-ticket-request-index vn-icon[icon="delete"]:nth-child(1)',
|
||||
|
@ -534,7 +534,7 @@ export default {
|
|||
itemDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
|
||||
itemDescriptorPopoverItemDiaryButton: '.vn-popover.shown vn-item-descriptor a[href="#!/item/2/diary"]',
|
||||
firstDevelopmentWorker: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(5) vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > span',
|
||||
firstDevelopmentWorkerGoToClientButton: '.vn-popover.shown vn-worker-descriptor div.quicklinks > a[href="#!/client/21/summary"]',
|
||||
firstDevelopmentWorkerGoToClientButton: '.vn-popover.shown vn-worker-descriptor vn-quick-links > a[href="#!/client/21/summary"]',
|
||||
firstActionTicketId: 'vn-claim-summary > vn-card > div > vn-horizontal > vn-auto:nth-child(6) vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
|
||||
firstActionTicketDescriptor: '.vn-popover.shown vn-ticket-descriptor'
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@ import ngModule from '../module';
|
|||
const regex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i;
|
||||
export const isMobile = regex.test(navigator.userAgent);
|
||||
|
||||
export function focus(input) {
|
||||
export function focus($scope, input) {
|
||||
if (isMobile) return;
|
||||
|
||||
const element = input;
|
||||
|
@ -23,9 +23,9 @@ export function focus(input) {
|
|||
}
|
||||
|
||||
input.focus();
|
||||
|
||||
if (input.select)
|
||||
$scope.$applyAsync(() => {
|
||||
input.select();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,7 +37,7 @@ export function directive() {
|
|||
return {
|
||||
restrict: 'A',
|
||||
link: function($scope, $element) {
|
||||
$scope.$watch('', () => focus($element[0]));
|
||||
$scope.$watch('', () => focus($scope, $element[0]));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ describe('Directive focus', () => {
|
|||
it('should call select function on the element', () => {
|
||||
let html = `<input vn-focus></input>`;
|
||||
compile(html);
|
||||
$scope.$apply();
|
||||
|
||||
expect($element[0].select).toHaveBeenCalledWith();
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<a ng-if="$ctrl.links.btnOne"
|
||||
vn-tooltip="{{::$ctrl.links.btnOne.tooltip}}"
|
||||
class="vn-button colored"
|
||||
ui-sref="{{::$ctrl.links.btnOne.state}}" target="_blank">
|
||||
ui-sref="{{::$ctrl.links.btnOne.state}}">
|
||||
<vn-icon
|
||||
icon="{{::$ctrl.links.btnOne.icon}}">
|
||||
</vn-icon>
|
||||
|
@ -9,7 +9,7 @@
|
|||
<a ng-if="$ctrl.links.btnTwo"
|
||||
vn-tooltip="{{::$ctrl.links.btnTwo.tooltip}}"
|
||||
class="vn-button colored"
|
||||
ui-sref="{{::$ctrl.links.btnTwo.state}}" target="_blank">
|
||||
ui-sref="{{::$ctrl.links.btnTwo.state}}">
|
||||
<vn-icon
|
||||
icon="{{::$ctrl.links.btnTwo.icon}}">
|
||||
</vn-icon>
|
||||
|
@ -17,7 +17,7 @@
|
|||
<a ng-if="$ctrl.links.btnThree"
|
||||
vn-tooltip="{{::$ctrl.links.btnThree.tooltip}}"
|
||||
class="vn-button colored"
|
||||
ui-sref="{{::$ctrl.links.btnThree.state}}" target="_blank">
|
||||
ui-sref="{{::$ctrl.links.btnThree.state}}">
|
||||
<vn-icon
|
||||
icon="{{::$ctrl.links.btnThree.icon}}">
|
||||
</vn-icon>
|
||||
|
|
|
@ -82,17 +82,6 @@ describe('claim', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('setClaimDestination(id, claimDestinationFk)', () => {
|
||||
it('should make a patch and call refresh and showSuccess', () => {
|
||||
spyOn(controller.vnApp, 'showSuccess');
|
||||
$httpBackend.expectPATCH(`claim/api/ClaimEnds/`).respond({});
|
||||
controller.setClaimDestination(1, 1);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('calculateTotals()', () => {
|
||||
it('should calculate the total price of the items claimed', () => {
|
||||
controller.salesClaimed = [
|
||||
|
|
|
@ -8,12 +8,11 @@
|
|||
<div class="content-block">
|
||||
<vn-card class="vn-pa-md vn-w-sm">
|
||||
<vn-horizontal style="align-items: center;">
|
||||
<vn-searchbar
|
||||
<vn-searchbar vn-focus
|
||||
panel="vn-item-search-panel"
|
||||
on-search="$ctrl.onSearch($params)"
|
||||
info="Search items by id, name or barcode"
|
||||
suggested-filter="{isActive: true}"
|
||||
vn-focus>
|
||||
suggested-filter="{isActive: true}">
|
||||
</vn-searchbar>
|
||||
<vn-icon-menu
|
||||
vn-id="more-button"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.atenderFk"
|
||||
ng-model="filter.attenderFk"
|
||||
url="/client/api/Clients/activeWorkersWithRole"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
|
|
|
@ -1,121 +1,116 @@
|
|||
<vn-crud-model
|
||||
<vn-crud-model auto-load="true"
|
||||
vn-id="model"
|
||||
url="/ticket/api/TicketRequests/filter"
|
||||
limit="20"
|
||||
data="requests"
|
||||
order="isOk ASC"
|
||||
auto-load="false">
|
||||
order="shipped ASC, isOk ASC">
|
||||
</vn-crud-model>
|
||||
<form name="form">
|
||||
<div class="vn-ma-md">
|
||||
<vn-card class="vn-pa-md vn-list">
|
||||
<vn-horizontal>
|
||||
<vn-searchbar
|
||||
auto-load="false"
|
||||
panel="vn-request-search-panel"
|
||||
on-search="$ctrl.onSearch($params)"
|
||||
info="Search request by id or alias"
|
||||
vn-one
|
||||
vn-focus>
|
||||
</vn-searchbar>
|
||||
</vn-horizontal>
|
||||
<vn-searchbar vn-one vn-focus
|
||||
auto-load="false"
|
||||
panel="vn-request-search-panel"
|
||||
on-search="$ctrl.onSearch($params)"
|
||||
info="Search request by id or alias"
|
||||
suggested-filter="$ctrl.filter.where">
|
||||
</vn-searchbar>
|
||||
</vn-card>
|
||||
<vn-card class="vn-my-md">
|
||||
<vn-table model="model" auto-load="false">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th field="ticketFk" number>Ticket ID</vn-th>
|
||||
<vn-th field="shipped">Shipped</vn-th>
|
||||
<vn-th field="warehouse">Warehouse</vn-th>
|
||||
<vn-th field="salesPersonNickname">SalesPerson</vn-th>
|
||||
<vn-th field="description">Description</vn-th>
|
||||
<vn-th field="quantity" number editable>Quantity</vn-th>
|
||||
<vn-th field="price" number>Price</vn-th>
|
||||
<vn-th field="atenderNickname">Atender</vn-th>
|
||||
<vn-th field="itemFk">Item</vn-th>
|
||||
<vn-th field="description">Concept</vn-th>
|
||||
<vn-th field="saleQuantity" number>Sale quantity</vn-th>
|
||||
<vn-th field="isOk">State</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="request in requests">
|
||||
<vn-td number>
|
||||
<span class="link"
|
||||
ng-click="$ctrl.showTicketDescriptor($event, request.ticketFk)">
|
||||
{{request.ticketFk}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<span title="{{::request.shipped | date: 'dd/MM/yyyy'}}"
|
||||
class="chip {{$ctrl.compareDate(request.shipped)}}">
|
||||
{{::request.shipped | date: 'dd/MM/yyyy'}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>{{::request.warehouse}}</vn-td>
|
||||
<vn-td>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, request.salesPersonFk)">
|
||||
{{::request.salesPersonNickname}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td title="{{::request.description}}">{{::request.description}}</vn-td>
|
||||
<vn-td number>{{::request.quantity}}</vn-td>
|
||||
<vn-td number>{{::request.price | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, request.atenderFk)">
|
||||
{{::request.atenderNickname}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td-editable disabled="request.isOk === 0" number>
|
||||
<text>{{request.itemFk}}</text>
|
||||
<field>
|
||||
<vn-input-number
|
||||
ng-model="request.itemFk"
|
||||
on-change="$ctrl.confirmRequest(request)">
|
||||
</vn-input-number>
|
||||
</field>
|
||||
</vn-td-editable>
|
||||
<vn-td>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showItemDescriptor($event, request.itemFk)"
|
||||
title="{{::request.itemDescription}}">
|
||||
{{::request.itemDescription}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td-editable disabled="request.isOk === 0" number>
|
||||
<text number>{{request.saleQuantity}}</text>
|
||||
<field>
|
||||
<vn-input-number
|
||||
ng-model="request.saleQuantity"
|
||||
on-change="$ctrl.changeQuantity(request)">
|
||||
</vn-input-number>
|
||||
</field>
|
||||
</vn-td-editable>
|
||||
<vn-td>{{::$ctrl.getState(request.isOk)}}</vn-td>
|
||||
<vn-td>
|
||||
<vn-icon
|
||||
ng-if="request.response.length"
|
||||
vn-tooltip="{{request.response}}"
|
||||
icon="insert_drive_file">
|
||||
</vn-icon>
|
||||
<vn-icon-button
|
||||
ng-if="request.isOk != 0"
|
||||
number
|
||||
icon="thumb_down"
|
||||
ng-click="$ctrl.showDenyReason($event, request.id)"
|
||||
vn-tooltip="Discard">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-card>
|
||||
<vn-pagination model="model"></vn-pagination>
|
||||
<vn-data-viewer model="model" class="vn-my-md">
|
||||
<vn-card>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th field="ticketFk" number>Ticket ID</vn-th>
|
||||
<vn-th field="shipped">Shipped</vn-th>
|
||||
<vn-th field="warehouse">Warehouse</vn-th>
|
||||
<vn-th field="salesPersonNickname">SalesPerson</vn-th>
|
||||
<vn-th field="description">Description</vn-th>
|
||||
<vn-th field="quantity" number editable>Requested</vn-th>
|
||||
<vn-th field="price" number>Price</vn-th>
|
||||
<vn-th field="atenderNickname">Atender</vn-th>
|
||||
<vn-th field="itemFk">Item</vn-th>
|
||||
<vn-th field="saleQuantity">Achieved</vn-th>
|
||||
<vn-th field="description">Concept</vn-th>
|
||||
<vn-th field="isOk">State</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="request in requests">
|
||||
<vn-td number>
|
||||
<span class="link"
|
||||
ng-click="$ctrl.showTicketDescriptor($event, request.ticketFk)">
|
||||
{{request.ticketFk}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<span title="{{::request.shipped | date: 'dd/MM/yyyy'}}"
|
||||
class="chip {{$ctrl.compareDate(request.shipped)}}">
|
||||
{{::request.shipped | date: 'dd/MM/yyyy'}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>{{::request.warehouse}}</vn-td>
|
||||
<vn-td>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, request.salesPersonFk)">
|
||||
{{::request.salesPersonNickname}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td title="{{::request.description}}">{{::request.description}}</vn-td>
|
||||
<vn-td number>{{::request.quantity}}</vn-td>
|
||||
<vn-td number>{{::request.price | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, request.attenderFk)">
|
||||
{{::request.atenderNickname}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td-editable disabled="request.isOk != null" number>
|
||||
<text>{{request.itemFk}}</text>
|
||||
<field>
|
||||
<vn-input-number class="dense" vn-focus
|
||||
ng-model="request.itemFk">
|
||||
</vn-input-number>
|
||||
</field>
|
||||
</vn-td-editable>
|
||||
<vn-td-editable disabled="!request.itemFk || request.isOk != null" number>
|
||||
<text number>{{request.saleQuantity}}</text>
|
||||
<field>
|
||||
<vn-input-number class="dense" vn-focus
|
||||
ng-model="request.saleQuantity"
|
||||
on-change="$ctrl.changeQuantity(request)">
|
||||
</vn-input-number>
|
||||
</field>
|
||||
</vn-td-editable>
|
||||
<vn-td>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showItemDescriptor($event, request.itemFk)"
|
||||
title="{{request.itemDescription}}">
|
||||
{{request.itemDescription}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>{{$ctrl.getState(request.isOk)}}</vn-td>
|
||||
<vn-td>
|
||||
<vn-icon
|
||||
ng-if="request.response.length"
|
||||
ranslate-attr="{title: request.response}"
|
||||
icon="insert_drive_file">
|
||||
</vn-icon>
|
||||
<vn-icon-button
|
||||
ng-if="request.isOk != 0"
|
||||
icon="thumb_down"
|
||||
ng-click="$ctrl.showDenyReason($event, request)"
|
||||
translate-attr="{title: 'Discard'}">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
</div>
|
||||
</form>
|
||||
<vn-worker-descriptor-popover
|
||||
|
@ -129,21 +124,17 @@
|
|||
</vn-item-descriptor-popover>
|
||||
<vn-dialog
|
||||
vn-id="denyReason"
|
||||
class="modal-form">
|
||||
on-response="$ctrl.denyRequest(response)">
|
||||
<tpl-body>
|
||||
<vn-horizontal class="header">
|
||||
<h5><span translate>Indicate the reasons to deny this request</span></h5>
|
||||
</vn-horizontal>
|
||||
<h5 class="vn-pa-md" translate>Specify the reasons to deny this request</h5>
|
||||
<vn-horizontal class="vn-pa-md">
|
||||
<vn-textarea
|
||||
ng-model="$ctrl.denyObservation">
|
||||
</vn-textarea>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-pa-md">
|
||||
<vn-button
|
||||
label="Save"
|
||||
ng-click="$ctrl.denyRequest()">
|
||||
</vn-button>
|
||||
</vn-horizontal>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input type="button" response="CANCEL" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="ACCEPT" translate>Save</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
|
@ -9,8 +9,23 @@ export default class Controller {
|
|||
this.$ = $;
|
||||
this.vnApp = vnApp;
|
||||
this._ = $translate;
|
||||
if (!$stateParams.q)
|
||||
this.filter = {isOk: false, mine: true};
|
||||
if (!$stateParams.q) {
|
||||
const today = new Date();
|
||||
today.setHours(23, 59, 59, 59);
|
||||
|
||||
const lastWeek = new Date();
|
||||
lastWeek.setHours(0, 0, 0, 0);
|
||||
lastWeek.setDate(lastWeek.getDate() - 7);
|
||||
|
||||
this.filter = {
|
||||
where: {
|
||||
isOk: false,
|
||||
mine: true,
|
||||
from: lastWeek,
|
||||
to: today
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
$postLink() {
|
||||
|
@ -21,7 +36,7 @@ export default class Controller {
|
|||
getState(isOk) {
|
||||
if (isOk === null)
|
||||
return 'Nueva';
|
||||
else if (isOk === -1 || isOk === 1)
|
||||
else if (isOk === -1 || isOk)
|
||||
return 'Aceptada';
|
||||
else
|
||||
return 'Denegada';
|
||||
|
@ -34,14 +49,12 @@ export default class Controller {
|
|||
quantity: request.saleQuantity
|
||||
};
|
||||
|
||||
let endpoint = `/api/TicketRequests/${request.id}/confirm`;
|
||||
let query = `/api/TicketRequests/${request.id}/confirm`;
|
||||
this.$http.post(query, params).then(res => {
|
||||
request.itemDescription = res.data.concept;
|
||||
request.isOk = true;
|
||||
|
||||
this.$http.post(endpoint, params).then(() => {
|
||||
this.vnApp.showSuccess(this._.instant('Data saved!'));
|
||||
this.$.model.refresh();
|
||||
}).catch( e => {
|
||||
this.$.model.refresh();
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -56,10 +69,7 @@ export default class Controller {
|
|||
|
||||
this.$http.patch(endpoint, params).then(() => {
|
||||
this.vnApp.showSuccess(this._.instant('Data saved!'));
|
||||
}).catch( e => {
|
||||
this.$.model.refresh();
|
||||
throw e;
|
||||
});
|
||||
}).then(() => this.confirmRequest(request));
|
||||
} else
|
||||
this.confirmRequest(request);
|
||||
}
|
||||
|
@ -86,7 +96,7 @@ export default class Controller {
|
|||
}
|
||||
|
||||
showDenyReason(event, requestId) {
|
||||
this.denyRequestId = requestId;
|
||||
this.selectedRequest = requestId;
|
||||
this.$.denyReason.parent = event.target;
|
||||
this.$.denyReason.show();
|
||||
document.querySelector('vn-item-request vn-textarea textArea').focus();
|
||||
|
@ -96,17 +106,21 @@ export default class Controller {
|
|||
delete this.denyRequestId;
|
||||
}
|
||||
|
||||
denyRequest() {
|
||||
denyRequest(response) {
|
||||
if (response !== 'ACCEPT') return;
|
||||
|
||||
let params = {
|
||||
observation: this.denyObservation
|
||||
};
|
||||
|
||||
let endpoint = `/api/TicketRequests/${this.denyRequestId}/deny`;
|
||||
let query = `/api/TicketRequests/${this.selectedRequest.id}/deny`;
|
||||
this.$http.post(query, params).then(res => {
|
||||
const request = res.data;
|
||||
this.selectedRequest.isOk = request.isOk;
|
||||
this.selectedRequest.attenderFk = request.attenderFk;
|
||||
this.selectedRequest.response = request.response;
|
||||
|
||||
this.$http.post(endpoint, params).then(() => {
|
||||
this.vnApp.showSuccess(this._.instant('Data saved!'));
|
||||
this.$.model.refresh();
|
||||
this.$.denyReason.hide();
|
||||
this.denyObservation = null;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -53,15 +53,15 @@ describe('Item', () => {
|
|||
let model = controller.$.model;
|
||||
spyOn(model, 'refresh');
|
||||
|
||||
const expectedResult = {concept: 'Melee Weapon'};
|
||||
let request = {itemFk: 1, saleQuantity: 1, id: 1};
|
||||
|
||||
$httpBackend.when('POST', `/api/TicketRequests/${request.id}/confirm`).respond();
|
||||
$httpBackend.expect('POST', `/api/TicketRequests/${request.id}/confirm`).respond();
|
||||
$httpBackend.when('POST', `/api/TicketRequests/${request.id}/confirm`).respond(expectedResult);
|
||||
$httpBackend.expect('POST', `/api/TicketRequests/${request.id}/confirm`).respond(expectedResult);
|
||||
controller.confirmRequest(request);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||
expect($scope.model.refresh).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -110,20 +110,17 @@ describe('Item', () => {
|
|||
describe('denyRequest()', () => {
|
||||
it(`should perform a query and call vnApp.showSuccess(), refresh(), hide() and set denyObservation to null in the controller`, () => {
|
||||
spyOn(controller.vnApp, 'showSuccess');
|
||||
let model = controller.$.model;
|
||||
spyOn(model, 'refresh');
|
||||
spyOn(controller.$.denyReason, 'hide');
|
||||
|
||||
controller.denyRequestId = 1;
|
||||
const request = {id: 1};
|
||||
const expectedResult = {isOk: false, attenderFk: 106, response: 'Denied!'};
|
||||
controller.selectedRequest = request;
|
||||
|
||||
$httpBackend.when('POST', `/api/TicketRequests/${controller.denyRequestId}/deny`).respond();
|
||||
$httpBackend.expect('POST', `/api/TicketRequests/${controller.denyRequestId}/deny`).respond();
|
||||
controller.denyRequest();
|
||||
$httpBackend.when('POST', `/api/TicketRequests/${request.id}/deny`).respond(expectedResult);
|
||||
$httpBackend.expect('POST', `/api/TicketRequests/${request.id}/deny`).respond(expectedResult);
|
||||
controller.denyRequest('ACCEPT');
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||
expect($scope.model.refresh).toHaveBeenCalledWith();
|
||||
expect($scope.denyReason.hide).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
Discard: Descartar
|
||||
Indicate the reasons to deny this request: Indique las razones para descartar esta peticion
|
||||
Specify the reasons to deny this request: Especifica las razones para descartar la petición
|
||||
Buy requests: Peticiones de compra
|
||||
Search request by id or alias: Buscar peticiones por identificador o alias
|
||||
Sale quantity: C. conseguida
|
||||
Requested: Solicitado
|
||||
Achieved: Conseguido
|
|
@ -38,27 +38,27 @@ module.exports = Self => {
|
|||
try {
|
||||
let options = {transaction: tx};
|
||||
|
||||
let item = await models.Item.findById(ctx.args.itemFk);
|
||||
let item = await models.Item.findById(ctx.args.itemFk, null, options);
|
||||
if (!item)
|
||||
throw new UserError(`That item doesn't exists`);
|
||||
|
||||
let request = await models.TicketRequest.findById(ctx.args.id, {
|
||||
include: {relation: 'ticket'}
|
||||
});
|
||||
}, options);
|
||||
|
||||
let [[stock]] = await Self.rawSql(`CALL vn.getItemVisibleAvailable(?,?,?,?)`, [
|
||||
ctx.args.itemFk,
|
||||
request.ticket().shipped,
|
||||
request.ticket().warehouseFk,
|
||||
false
|
||||
]);
|
||||
], options);
|
||||
|
||||
if (stock.available < 0)
|
||||
throw new UserError(`This item is not available`);
|
||||
|
||||
|
||||
if (request.saleFk) {
|
||||
sale = await models.Sale.findById(request.saleFk);
|
||||
sale = await models.Sale.findById(request.saleFk, null, options);
|
||||
sale.updateAttributes({
|
||||
itemFk: ctx.args.itemFk,
|
||||
quantity: ctx.args.quantity,
|
||||
|
@ -71,7 +71,11 @@ module.exports = Self => {
|
|||
quantity: ctx.args.quantity,
|
||||
concept: item.name
|
||||
}, options);
|
||||
request.updateAttributes({saleFk: sale.id, itemFk: sale.itemFk, isOk: true}, options);
|
||||
request.updateAttributes({
|
||||
saleFk: sale.id,
|
||||
itemFk: sale.itemFk,
|
||||
isOk: true
|
||||
}, options);
|
||||
}
|
||||
|
||||
query = `CALL vn.ticketCalculateSale(?)`;
|
||||
|
@ -86,6 +90,8 @@ module.exports = Self => {
|
|||
}, options);
|
||||
|
||||
await tx.commit();
|
||||
|
||||
return sale;
|
||||
} catch (error) {
|
||||
await tx.rollback();
|
||||
throw error;
|
||||
|
|
|
@ -29,7 +29,7 @@ module.exports = Self => {
|
|||
|
||||
let params = {
|
||||
isOk: false,
|
||||
atenderFk: worker.id,
|
||||
attenderFk: worker.id,
|
||||
response: ctx.args.observation,
|
||||
};
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ module.exports = Self => {
|
|||
type: 'Number',
|
||||
description: `Search by warehouse`
|
||||
}, {
|
||||
arg: 'atenderFk',
|
||||
arg: 'attenderFk',
|
||||
type: 'Number',
|
||||
description: `Search requests atended by the given worker`
|
||||
}, {
|
||||
|
@ -65,7 +65,7 @@ module.exports = Self => {
|
|||
let worker = await Self.app.models.Worker.findOne({where: {userFk: userId}});
|
||||
|
||||
if (ctx.args.mine)
|
||||
ctx.args.atenderFk = worker.id;
|
||||
ctx.args.attenderFk = worker.id;
|
||||
|
||||
let where = buildFilter(ctx.args, (param, value) => {
|
||||
switch (param) {
|
||||
|
@ -75,7 +75,7 @@ module.exports = Self => {
|
|||
: {'t.nickname': {like: `%${value}%`}};
|
||||
case 'ticketFk':
|
||||
return {'t.id': value};
|
||||
case 'atenderFk':
|
||||
case 'attenderFk':
|
||||
return {'tr.atenderFk': value};
|
||||
case 'isOk':
|
||||
return {'tr.isOk': value};
|
||||
|
@ -106,13 +106,13 @@ module.exports = Self => {
|
|||
tr.ticketFk,
|
||||
tr.quantity,
|
||||
tr.price,
|
||||
tr.atenderFk,
|
||||
tr.atenderFk attenderFk,
|
||||
tr.description,
|
||||
tr.response,
|
||||
tr.saleFk,
|
||||
tr.isOk,
|
||||
s.quantity AS saleQuantity,
|
||||
s.itemFK,
|
||||
s.itemFk,
|
||||
i.name AS itemDescription,
|
||||
t.shipped,
|
||||
t.nickname,
|
||||
|
|
|
@ -1,27 +1,14 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('ticket-request confirm()', () => {
|
||||
let request;
|
||||
let sale;
|
||||
let originalRequest;
|
||||
let originalSale;
|
||||
let createdSaleId;
|
||||
|
||||
afterAll(async done => {
|
||||
const paramsForRequest = {
|
||||
saleFk: request.saleFk,
|
||||
isOk: request.isOk,
|
||||
itemFk: request.itemFk,
|
||||
ticketFk: request.ticketFk
|
||||
};
|
||||
|
||||
const paramsForSale = {
|
||||
itemFk: sale.itemFk,
|
||||
quantity: sale.quantity,
|
||||
concept: sale.concept,
|
||||
};
|
||||
|
||||
await request.updateAttributes(paramsForRequest);
|
||||
await sale.updateAttributes(paramsForSale);
|
||||
app.models.Sale.destroyById(createdSaleId);
|
||||
await originalRequest.updateAttributes(originalRequest);
|
||||
await originalSale.updateAttributes(originalSale);
|
||||
await app.models.Sale.destroyById(createdSaleId);
|
||||
done();
|
||||
});
|
||||
|
||||
|
@ -65,10 +52,11 @@ describe('ticket-request confirm()', () => {
|
|||
const itemId = 1;
|
||||
const quantity = 10;
|
||||
|
||||
request = await app.models.TicketRequest.findById(requestId);
|
||||
sale = await app.models.Sale.findById(saleId);
|
||||
originalRequest = await app.models.TicketRequest.findById(requestId);
|
||||
originalSale = await app.models.Sale.findById(saleId);
|
||||
|
||||
request.updateAttributes({saleFk: saleId});
|
||||
const request = await app.models.TicketRequest.findById(requestId);
|
||||
await request.updateAttributes({saleFk: saleId});
|
||||
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {
|
||||
itemFk: itemId,
|
||||
|
@ -89,7 +77,8 @@ describe('ticket-request confirm()', () => {
|
|||
const itemId = 1;
|
||||
const quantity = 10;
|
||||
|
||||
request.updateAttributes({saleFk: null});
|
||||
const request = await app.models.TicketRequest.findById(requestId);
|
||||
await request.updateAttributes({saleFk: null});
|
||||
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {
|
||||
itemFk: itemId,
|
||||
|
|
|
@ -5,7 +5,7 @@ describe('ticket-request deny()', () => {
|
|||
afterAll(async done => {
|
||||
let params = {
|
||||
isOk: null,
|
||||
atenderFk: request.atenderFk,
|
||||
attenderFk: request.attenderFk,
|
||||
response: null,
|
||||
};
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ describe('ticket-request filter()', () => {
|
|||
});
|
||||
|
||||
it('should return the ticket request matching the atender ID', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {atenderFk: 35}};
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {attenderFk: 35}};
|
||||
|
||||
let result = await app.models.TicketRequest.filter(ctx);
|
||||
let requestId = result[0].id;
|
||||
|
|
|
@ -33,9 +33,12 @@
|
|||
"isOk": {
|
||||
"type": "Boolean"
|
||||
},
|
||||
"atenderFk": {
|
||||
"attenderFk": {
|
||||
"type": "Number",
|
||||
"required": true
|
||||
"required": true,
|
||||
"mysql": {
|
||||
"columnName": "atenderFk"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"type": "String"
|
||||
|
@ -55,7 +58,7 @@
|
|||
"atender": {
|
||||
"type": "belongsTo",
|
||||
"model": "Worker",
|
||||
"foreignKey": "atenderFk"
|
||||
"foreignKey": "attenderFk"
|
||||
},
|
||||
"requester": {
|
||||
"type": "belongsTo",
|
||||
|
|
|
@ -176,7 +176,7 @@ class Controller {
|
|||
links.btnTwo = {
|
||||
icon: 'icon-stowaway',
|
||||
state: `ticket.card.summary({id: ${value.stowaway.shipFk}})`,
|
||||
tooltip: 'Ship'
|
||||
tooltip: 'Ship stowaways'
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-model="$ctrl.ticketRequest.atenderFk"
|
||||
ng-model="$ctrl.ticketRequest.attenderFk"
|
||||
url="/client/api/Clients/activeWorkersWithRole"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/ticket/api/TicketRequests"
|
||||
fields="['id', 'description', 'created', 'requesterFk', 'atenderFk', 'quantity', 'price', 'saleFk', 'isOk']"
|
||||
fields="['id', 'description', 'created', 'requesterFk', 'attenderFk', 'quantity', 'price', 'saleFk', 'isOk']"
|
||||
order="created ASC"
|
||||
link="{ticketFk: $ctrl.$stateParams.id}"
|
||||
filter="::$ctrl.filter"
|
||||
|
@ -43,7 +43,7 @@
|
|||
<vn-td expand>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, request.atenderFk)">
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, request.attenderFk)">
|
||||
{{::request.atender.user.nickname | dashIfEmpty}}
|
||||
</span>
|
||||
</vn-td>
|
||||
|
|
Loading…
Reference in New Issue