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