#1882 Boileplate code removed, declarative quicklinks
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
parent
b536c8291a
commit
6a8e1bf6b5
|
@ -1,27 +1,31 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from '../../lib/component';
|
||||
import './style.scss';
|
||||
|
||||
/**
|
||||
* Floating box displaying debugging information.
|
||||
* Enabled only in development environment.
|
||||
*/
|
||||
export default class Controller {
|
||||
export default class Controller extends Component {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.env = process.env.NODE_ENV || 'development';
|
||||
|
||||
if (this.env == 'development')
|
||||
this.interval = setInterval(() => $.$digest(), 2000);
|
||||
else
|
||||
$element[0].style.display = 'none';
|
||||
|
||||
$element[0].addEventListener('mouseover',
|
||||
() => this.classList.toggle('right'));
|
||||
}
|
||||
|
||||
$onDestroy() {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$element', '$scope'];
|
||||
|
||||
ngModule.component('vnDebugInfo', {
|
||||
ngModule.vnComponent('vnDebugInfo', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@import "variables";
|
||||
|
||||
vn-debug-info {
|
||||
.vn-debug-info {
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
left: 16px;
|
||||
|
@ -13,8 +13,9 @@ vn-debug-info {
|
|||
box-shadow: $shadow;
|
||||
transition: opacity 400ms ease-in-out;
|
||||
|
||||
&:hover {
|
||||
opacity: .5;
|
||||
&.right {
|
||||
left: auto;
|
||||
right: 16px;
|
||||
}
|
||||
& > h6 {
|
||||
font-weight: normal;
|
||||
|
|
|
@ -8,6 +8,7 @@ import './style.scss';
|
|||
* A simple popover.
|
||||
*
|
||||
* @property {HTMLElement} parent The parent element to show drop down relative to
|
||||
* @property {HTMLElement} content Element holding the popover content
|
||||
*
|
||||
* @event open Thrown when popover is displayed
|
||||
* @event close Thrown when popover is hidden
|
||||
|
|
|
@ -15,6 +15,7 @@ describe('Directive focus', () => {
|
|||
$element[0].focus = jasmine.createSpy('focus');
|
||||
$element[0].select = jasmine.createSpy('select');
|
||||
$compile($element)($scope);
|
||||
$scope.$apply();
|
||||
$flushPendingTasks();
|
||||
});
|
||||
};
|
||||
|
@ -37,7 +38,6 @@ 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();
|
||||
});
|
||||
|
|
|
@ -184,6 +184,7 @@ runFn.$inject = [
|
|||
'$translate',
|
||||
'$q',
|
||||
'$http',
|
||||
'$httpParamSerializer',
|
||||
'$state',
|
||||
'$stateParams',
|
||||
'$timeout',
|
||||
|
|
|
@ -29,11 +29,10 @@ html [wrap-reverse] {
|
|||
/* Horizontal & vertical childs */
|
||||
|
||||
html [vn-auto], vn-auto, .vn-auto {
|
||||
flex-basis: auto;
|
||||
flex: initial;
|
||||
}
|
||||
html [vn-none], vn-none, .vn-none {
|
||||
flex: none;
|
||||
flex-basis: .1px;
|
||||
flex: none 0 1px;
|
||||
}
|
||||
html [vn-one], vn-one, .vn-one {
|
||||
flex: 1;
|
||||
|
|
|
@ -6,5 +6,4 @@
|
|||
ng-if="!$ctrl.showLayout">
|
||||
</ui-view>
|
||||
<vn-snackbar vn-id="snackbar"></vn-snackbar>
|
||||
|
||||
<!-- <vn-debug-info></vn-debug-info> -->
|
||||
<vn-debug-info></vn-debug-info>
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
<default>
|
||||
<vn-spinner
|
||||
ng-if="$ctrl.canceler"
|
||||
enable="true">
|
||||
</vn-spinner>
|
||||
<div
|
||||
ng-if="$ctrl.entity"
|
||||
ng-transclude="descriptor"
|
||||
class="descriptor-wrapper">
|
||||
</div>
|
||||
|
|
|
@ -3,70 +3,14 @@ import Popover from 'core/components/popover';
|
|||
import './style.scss';
|
||||
|
||||
export default class DescriptorPopover extends Popover {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this._quicklinks = {};
|
||||
this.entity = null;
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this._id;
|
||||
}
|
||||
|
||||
set id(value) {
|
||||
if (value == this._id) return;
|
||||
this._id = value;
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
get entity() {
|
||||
return this._entity;
|
||||
}
|
||||
|
||||
set entity(value) {
|
||||
this._entity = value;
|
||||
}
|
||||
|
||||
get quicklinks() {
|
||||
return this._quicklinks;
|
||||
}
|
||||
|
||||
set quicklinks(value = {}) {
|
||||
Object.keys(value).forEach(key => {
|
||||
this._quicklinks[key] = value[key];
|
||||
});
|
||||
}
|
||||
|
||||
show(parent, id) {
|
||||
if (id !== undefined)
|
||||
this.id = id;
|
||||
super.show(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the descriptor data. Should be implemented or overriden by child
|
||||
* classes.
|
||||
*/
|
||||
loadData() {
|
||||
throw new Error('DescriptorPopover::loadData() method not implemented');
|
||||
}
|
||||
|
||||
getData(url, options) {
|
||||
if (this.canceler) this.canceler.resolve();
|
||||
this.canceler = this.$q.defer();
|
||||
this.entity = null;
|
||||
|
||||
options = Object.assign(options || {}, {
|
||||
timeout: this.canceler.promise
|
||||
});
|
||||
|
||||
this.relocate();
|
||||
return this.$http.get(url, options)
|
||||
.then(res => {
|
||||
const descriptor = this.content.querySelector('.vn-descriptor');
|
||||
descriptor.$ctrl.load(id)
|
||||
.then(() => {
|
||||
this.$.$applyAsync(() => this.relocate());
|
||||
return res;
|
||||
})
|
||||
.finally(() => this.canceler = null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,4 +10,7 @@
|
|||
.descriptor-wrapper {
|
||||
width: 260px;
|
||||
}
|
||||
}
|
||||
.vn-descriptor > .header > a:first-child {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,26 @@
|
|||
<vn-spinner
|
||||
ng-if="$ctrl.canceler"
|
||||
ng-if="$ctrl.descriptor.canceler"
|
||||
enable="true">
|
||||
</vn-spinner>
|
||||
<div
|
||||
ng-if="$ctrl.entity"
|
||||
ng-transclude="body"
|
||||
class="descriptor-wrapper">
|
||||
<div ng-if="$ctrl.descriptor.entity">
|
||||
<div class="header">
|
||||
<a
|
||||
translate-attr="{title: 'Return to module index'}"
|
||||
ui-sref="{{::$ctrl.module}}.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a
|
||||
translate-attr="{title: 'Preview'}"
|
||||
ui-sref="{{::$ctrl.module}}.card.summary({id: $ctrl.descriptor.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-button
|
||||
icon="more_vert"
|
||||
vn-popover="menu">
|
||||
</vn-icon-button>
|
||||
</div>
|
||||
<vn-menu vn-id="menu">
|
||||
<div ng-transclude="menu"></div>
|
||||
</vn-menu>
|
||||
<div ng-transclude="body"></div>
|
||||
</div>
|
|
@ -1,39 +1,126 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from 'core/lib/component';
|
||||
import './style.scss';
|
||||
import './quick-links';
|
||||
import './quick-link';
|
||||
|
||||
export default class Descriptor extends Component {
|
||||
$postLink() {
|
||||
const content = this.element.querySelector('vn-descriptor-content');
|
||||
|
||||
if (content) {
|
||||
angular.element(content)
|
||||
.controller('vnDescriptorContent')
|
||||
.descriptor = this;
|
||||
}
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this._id;
|
||||
}
|
||||
|
||||
set id(value) {
|
||||
this.load(value);
|
||||
}
|
||||
|
||||
get entity() {
|
||||
return this._entity;
|
||||
}
|
||||
|
||||
set entity(value) {
|
||||
this._entity = value;
|
||||
this._id = value && value.id;
|
||||
}
|
||||
|
||||
get quicklinks() {
|
||||
return this._quicklinks;
|
||||
load(id) {
|
||||
if (id == this._id)
|
||||
return this.$q.resolve();
|
||||
|
||||
this._id = id;
|
||||
|
||||
if (!id) {
|
||||
this.entity = null;
|
||||
return this.$q.resolve();
|
||||
}
|
||||
|
||||
return this.loadData();
|
||||
}
|
||||
|
||||
set quicklinks(value = {}) {
|
||||
this._quicklinks = Object.assign(value, this._quicklinks);
|
||||
/**
|
||||
* Reloads the descriptor data. Should be implemented or overriden by child
|
||||
* classes.
|
||||
*/
|
||||
loadData() {
|
||||
throw new Error('DescriptorPopover::loadData() method not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a cancellable request.
|
||||
*
|
||||
* @param {String} url The http path
|
||||
* @param {Object} options The request options
|
||||
* @return {Promise} Resolved with request response
|
||||
*/
|
||||
getData(url, options) {
|
||||
if (this.canceler) this.canceler.resolve();
|
||||
this.canceler = this.$q.defer();
|
||||
this.entity = null;
|
||||
|
||||
options = Object.assign(options || {}, {
|
||||
timeout: this.canceler.promise
|
||||
});
|
||||
|
||||
return this.$http.get(url, options)
|
||||
.finally(() => this.canceler = null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a report in another window, automatically adds the authorization
|
||||
* token to params.
|
||||
*
|
||||
* @param {String} report The report name
|
||||
* @param {Object} params The report parameters
|
||||
*/
|
||||
showReport(report, params) {
|
||||
params = Object.assign({
|
||||
authorization: this.vnToken.token
|
||||
}, params);
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
window.open(`api/report/${report}?${serializedParams}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an email displaying a notification when it's sent.
|
||||
*
|
||||
* @param {String} report The email report name
|
||||
* @param {Object} params The email parameters
|
||||
* @return {Promise} Promise resolved when it's sent
|
||||
*/
|
||||
sendEmail(report, params) {
|
||||
return this.$http.get(`email/${report}`, {params})
|
||||
.then(() => this.vnApp.showMessage(this.$t('Notification sent!')));
|
||||
}
|
||||
}
|
||||
Descriptor.$inject = ['$element', '$scope'/* , '$transclude'*/];
|
||||
|
||||
ngModule.vnComponent('vnDescriptor', {
|
||||
template: require('./index.html'),
|
||||
controller: Descriptor,
|
||||
bindings: {
|
||||
entity: '<?',
|
||||
quicklinks: '<'
|
||||
id: '<?'
|
||||
},
|
||||
transclude: {
|
||||
body: '?slotBody',
|
||||
btnOne: '?btnOne',
|
||||
btnTwo: '?btnTwo',
|
||||
btnThree: '?btnThree'
|
||||
}
|
||||
});
|
||||
|
||||
ngModule.component('vnDescriptorContent', {
|
||||
template: require('./index.html'),
|
||||
bindings: {
|
||||
module: '@'
|
||||
},
|
||||
transclude: {
|
||||
body: 'slotBody',
|
||||
menu: '?slotMenu'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<a
|
||||
ui-sref="{{$ctrl.state}}"
|
||||
ui-sref="{{::$ctrl.state[0]}}($ctrl.state[1])"
|
||||
vn-tooltip="{{::$ctrl.tooltip}}"
|
||||
class="vn-button colored">
|
||||
<vn-icon
|
||||
|
|
|
@ -6,7 +6,7 @@ ngModule.component('vnQuickLink', {
|
|||
template: require('./quick-link.html'),
|
||||
controller: QuickLink,
|
||||
bindings: {
|
||||
state: '@?',
|
||||
state: '<?',
|
||||
icon: '@?',
|
||||
tooltip: '@?'
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
<a ng-repeat="button in $ctrl.links"
|
||||
vn-tooltip="{{::button.tooltip}}"
|
||||
class="vn-button colored"
|
||||
ui-sref="{{::button.state}}">
|
||||
<vn-icon
|
||||
icon="{{::button.icon}}">
|
||||
</vn-icon>
|
||||
</a>
|
|
@ -1,11 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
|
||||
export default class QuickLinks {}
|
||||
|
||||
ngModule.component('vnQuickLinks', {
|
||||
template: require('./quick-links.html'),
|
||||
controller: QuickLinks,
|
||||
bindings: {
|
||||
links: '<?'
|
||||
}
|
||||
});
|
|
@ -2,89 +2,84 @@
|
|||
@import "./effects";
|
||||
@import "./variables";
|
||||
|
||||
.vn-descriptor,
|
||||
.vn-descriptor slot-body {
|
||||
display: block;
|
||||
box-shadow: 0 1px 3px $color-shadow;
|
||||
.vn-descriptor > vn-descriptor-content {
|
||||
& > div {
|
||||
display: block;
|
||||
box-shadow: 0 1px 3px $color-shadow;
|
||||
|
||||
& > .header {
|
||||
display: flex;
|
||||
background: $color-main;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
color: $color-font-dark;
|
||||
|
||||
& > * {
|
||||
@extend %clickable;
|
||||
min-width: 45px;
|
||||
height: 45px;
|
||||
box-sizing: border-box;
|
||||
& > .header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: inherit;
|
||||
background: $color-main;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
color: $color-font-dark;
|
||||
|
||||
& > vn-icon {
|
||||
padding: 10px;
|
||||
}
|
||||
vn-icon {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
& > .body {
|
||||
padding: $spacing-sm;
|
||||
|
||||
& > * {
|
||||
padding: $spacing-sm;
|
||||
}
|
||||
& > .attributes > h5 {
|
||||
padding-bottom: $spacing-sm;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
& > .icons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
|
||||
& > vn-icon {
|
||||
padding: $spacing-sm;
|
||||
color: $color-marginal;
|
||||
font-size: 1.5rem;
|
||||
|
||||
&.bright {
|
||||
color: $color-main;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.quicklinks,
|
||||
vn-quick-links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
& > a,
|
||||
vn-quick-link > a {
|
||||
& > * {
|
||||
@extend %clickable;
|
||||
min-width: 45px;
|
||||
height: 45px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 $spacing-md;
|
||||
margin: 0 $spacing-sm;
|
||||
color: inherit;
|
||||
|
||||
& > vn-icon {
|
||||
padding: 10px;
|
||||
}
|
||||
vn-icon {
|
||||
font-size: 1.75rem;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
& > div > slot-body {
|
||||
display: block;
|
||||
padding: $spacing-sm;
|
||||
|
||||
& > * {
|
||||
padding: $spacing-sm;
|
||||
}
|
||||
& > .attributes > h5 {
|
||||
padding-bottom: $spacing-sm;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
& > .icons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
|
||||
& > vn-icon {
|
||||
padding: $spacing-sm;
|
||||
color: $color-marginal;
|
||||
font-size: 1.5rem;
|
||||
|
||||
&.bright {
|
||||
color: $color-main;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
& > .quicklinks {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
vn-quick-link > a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 $spacing-md;
|
||||
margin: 0 $spacing-sm;
|
||||
|
||||
& > vn-icon {
|
||||
font-size: 1.75rem;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.vn-popover {
|
||||
.vn-descriptor > .header > a:first-child {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
justify-content: center;
|
||||
|
||||
& > .product {
|
||||
flex: initial;
|
||||
box-sizing: border-box;
|
||||
padding: $spacing-sm;
|
||||
width: 448px;
|
||||
|
|
|
@ -1,61 +1,89 @@
|
|||
<div class="vn-descriptor">
|
||||
<div class="header">
|
||||
<a translate-attr="{title: 'Return to module index'}" ui-sref="claim.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a translate-attr="{title: 'Preview'}" ui-sref="claim.card.summary({id: $ctrl.claim.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-menu
|
||||
vn-id="more-button"
|
||||
icon="more_vert"
|
||||
show-filter="false"
|
||||
value-field="callback"
|
||||
translate-fields="['name']"
|
||||
data="$ctrl.moreOptions"
|
||||
on-change="$ctrl.onMoreChange(value)"
|
||||
on-open="$ctrl.onMoreOpen()">
|
||||
</vn-icon-menu>
|
||||
</div>
|
||||
<div class="body">
|
||||
<vn-descriptor-content module="claim">
|
||||
<slot-menu>
|
||||
<ul class="vn-list">
|
||||
<li>
|
||||
<a class="vn-item"
|
||||
ui-sref="ticket.create({clientFk: $ctrl.client.id})"
|
||||
translate>
|
||||
Show Pickup order
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="confirmPickupOrder.show()"
|
||||
translate>
|
||||
Send Pickup order
|
||||
</div>
|
||||
</li>
|
||||
<li vn-acl="salesAssistant">
|
||||
<div class="vn-item"
|
||||
ng-click="confirmDeleteClaim.show()"
|
||||
translate>
|
||||
Delete claim
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<h5>{{$ctrl.claim.id}}</h5>
|
||||
<vn-label-value label="Client"
|
||||
value="{{::$ctrl.claim.client.name}}">
|
||||
<vn-label-value
|
||||
label="Client"
|
||||
value="{{::$ctrl.claim.client.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="State"
|
||||
<vn-label-value
|
||||
label="State"
|
||||
value="{{$ctrl.claim.claimState.description}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Created"
|
||||
value="{{$ctrl.claim.created | date: 'dd/MM/yyyy HH:mm'}}">
|
||||
<vn-label-value
|
||||
label="Created"
|
||||
value="{{$ctrl.claim.created | date: 'dd/MM/yyyy HH:mm'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Salesperson"
|
||||
<vn-label-value
|
||||
label="Salesperson"
|
||||
value="{{$ctrl.claim.client.salesPerson.user.nickname}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Attended by"
|
||||
<vn-label-value
|
||||
label="Attended by"
|
||||
value="{{$ctrl.claim.worker.user.nickname}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Agency"
|
||||
value="{{$ctrl.claim.ticket.agencyMode.name}}">
|
||||
<vn-label-value
|
||||
label="Agency"
|
||||
value="{{$ctrl.claim.ticket.agencyMode.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Ticket"
|
||||
value="{{$ctrl.claim.ticketFk}}">
|
||||
<vn-label-value
|
||||
label="Ticket"
|
||||
value="{{$ctrl.claim.ticketFk}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
<vn-quick-links
|
||||
links="$ctrl.quicklinks">
|
||||
</vn-quick-links>
|
||||
</div>
|
||||
</div>
|
||||
<div class="quicklinks">
|
||||
<div ng-transclude="btnOne">
|
||||
<vn-quick-link
|
||||
tooltip="Client ticket list"
|
||||
state="['client.card.summary', {id: $ctrl.claim.clientFk}]"
|
||||
icon="person">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnTwo">
|
||||
<vn-quick-link
|
||||
tooltip="Claimed ticket"
|
||||
state="['ticket.card.summary', {id: $ctrl.claim.ticketFk}]"
|
||||
icon="icon-ticket">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnThree"></div>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-confirm
|
||||
vn-id="confirm-pickup-order"
|
||||
on-response="$ctrl.sendPickupOrder($response)"
|
||||
on-accept="$ctrl.sendPickupOrder()"
|
||||
question="Send Pickup order"
|
||||
message="Are you sure you want to send it?">
|
||||
</vn-confirm>
|
||||
<vn-confirm
|
||||
vn-id="confirm-delete-claim"
|
||||
on-response="$ctrl.deleteClaim($response)"
|
||||
on-accept="$ctrl.deleteClaim()"
|
||||
question="Delete claim"
|
||||
message="Are you sure you want to delete this claim?">
|
||||
</vn-confirm>
|
||||
|
|
|
@ -2,102 +2,42 @@ import ngModule from '../module';
|
|||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
constructor($element, $, $httpParamSerializer) {
|
||||
super($element, $);
|
||||
this.$httpParamSerializer = $httpParamSerializer;
|
||||
|
||||
this.moreOptions = [
|
||||
{callback: this.showPickupOrder, name: 'Show Pickup order'},
|
||||
{callback: this.confirmPickupOrder, name: 'Send Pickup order'},
|
||||
{callback: this.confirmDeleteClaim, name: 'Delete claim', acl: 'salesAssistant'}
|
||||
];
|
||||
}
|
||||
|
||||
onMoreOpen() {
|
||||
let options = this.moreOptions.filter(option => {
|
||||
const hasAclProperty = Object.hasOwnProperty.call(option, 'acl');
|
||||
|
||||
return !hasAclProperty || (hasAclProperty && this.aclService.hasAny([option.acl]));
|
||||
});
|
||||
this.$.moreButton.data = options;
|
||||
}
|
||||
|
||||
onMoreChange(callback) {
|
||||
callback.call(this);
|
||||
}
|
||||
|
||||
get claim() {
|
||||
return this._claim;
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set claim(value) {
|
||||
this._claim = value;
|
||||
|
||||
if (!value) return;
|
||||
|
||||
this._quicklinks = {
|
||||
btnOne: {
|
||||
icon: 'person',
|
||||
state: `client.card.summary({id: ${value.clientFk}})`,
|
||||
tooltip: 'Client card'
|
||||
},
|
||||
btnTwo: {
|
||||
icon: 'icon-ticket',
|
||||
state: `ticket.card.summary({id: ${this.claim.ticketFk}})`,
|
||||
tooltip: 'Claimed ticket'
|
||||
}
|
||||
};
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
showPickupOrder() {
|
||||
const params = {
|
||||
this.showReport('claim-pickup-order', {
|
||||
clientId: this.claim.clientFk,
|
||||
claimId: this.claim.id,
|
||||
authorization: this.vnToken.token
|
||||
};
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
let url = `api/report/claim-pickup-order?${serializedParams}`;
|
||||
window.open(url);
|
||||
claimId: this.claim.id
|
||||
});
|
||||
}
|
||||
|
||||
confirmPickupOrder() {
|
||||
this.$.confirmPickupOrder.show();
|
||||
sendPickupOrder() {
|
||||
return this.sendEmail('claim-pickup-order', {
|
||||
recipient: this.claim.client.email,
|
||||
clientId: this.claim.clientFk,
|
||||
claimId: this.claim.id
|
||||
});
|
||||
}
|
||||
|
||||
sendPickupOrder(response) {
|
||||
if (response === 'accept') {
|
||||
const params = {
|
||||
recipient: this.claim.client.email,
|
||||
clientId: this.claim.clientFk,
|
||||
claimId: this.claim.id
|
||||
};
|
||||
this.$http.get(`email/claim-pickup-order`, {params}).then(
|
||||
() => this.vnApp.showMessage(this.$t('Notification sent!'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
confirmDeleteClaim() {
|
||||
this.$.confirmDeleteClaim.show();
|
||||
}
|
||||
|
||||
deleteClaim(response) {
|
||||
if (response === 'accept') {
|
||||
this.$http.delete(`Claims/${this.claim.id}`).then(() => {
|
||||
this.vnApp.showSuccess(this.$translate.instant('Claim deleted!'));
|
||||
deleteClaim() {
|
||||
return this.$http.delete(`Claims/${this.claim.id}`)
|
||||
.then(() => {
|
||||
this.vnApp.showSuccess(this.$t('Claim deleted!'));
|
||||
this.$state.go('claim.index');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$element', '$scope', '$httpParamSerializer'];
|
||||
|
||||
ngModule.vnComponent('vnClaimDescriptor', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
claim: '<',
|
||||
tags: '<'
|
||||
claim: '<'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,96 +1,62 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Item Component vnClaimDescriptor', () => {
|
||||
let $httpParamSerializer;
|
||||
let $httpBackend;
|
||||
let $element;
|
||||
let $scope;
|
||||
let controller;
|
||||
|
||||
const claim = {
|
||||
id: 2,
|
||||
clientFk: 101,
|
||||
client: {email: 'client@email'}
|
||||
};
|
||||
|
||||
beforeEach(ngModule('claim'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpParamSerializer = _$httpParamSerializer_;
|
||||
$scope = $rootScope.$new();
|
||||
|
||||
$element = angular.element('<vn-claim-descriptor></vn-claim-descriptor>');
|
||||
controller = $componentController('vnClaimDescriptor', {$element, $scope});
|
||||
controller.claim = {id: 2, clientFk: 101, client: {email: 'client@email'}};
|
||||
controller = $componentController('vnClaimDescriptor', {$element: null}, {claim});
|
||||
}));
|
||||
|
||||
describe('showPickupOrder()', () => {
|
||||
it('should open a new window showing a pickup order PDF document', () => {
|
||||
controller.showReport = jest.fn();
|
||||
|
||||
const params = {
|
||||
clientId: controller.claim.clientFk,
|
||||
claimId: controller.claim.id
|
||||
clientId: claim.clientFk,
|
||||
claimId: claim.id
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
let expectedPath = `api/report/claim-pickup-order?${serializedParams}`;
|
||||
jest.spyOn(window, 'open').mockReturnThis();
|
||||
controller.showPickupOrder();
|
||||
|
||||
expect(window.open).toHaveBeenCalledWith(expectedPath);
|
||||
expect(controller.showReport).toHaveBeenCalledWith('claim-pickup-order', params);
|
||||
});
|
||||
});
|
||||
|
||||
describe('confirmPickupOrder()', () => {
|
||||
it('should call confirmPickupOrder.show()', () => {
|
||||
controller.$.confirmPickupOrder = {
|
||||
show: jasmine.createSpy('show')
|
||||
};
|
||||
controller.claim = {id: 2};
|
||||
controller.confirmPickupOrder();
|
||||
|
||||
expect(controller.$.confirmPickupOrder.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('sendPickupOrder(response)', () => {
|
||||
describe('sendPickupOrder()', () => {
|
||||
it('should make a query and call vnApp.showMessage() if the response is accept', () => {
|
||||
jest.spyOn(controller.vnApp, 'showMessage');
|
||||
jest.spyOn(controller, 'sendEmail');
|
||||
|
||||
const params = {
|
||||
recipient: 'client@email',
|
||||
clientId: controller.claim.clientFk,
|
||||
claimId: controller.claim.id
|
||||
recipient: claim.client.email,
|
||||
clientId: claim.clientFk,
|
||||
claimId: claim.id
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
controller.sendPickupOrder();
|
||||
|
||||
$httpBackend.when('GET', `email/claim-pickup-order?${serializedParams}`).respond();
|
||||
$httpBackend.expect('GET', `email/claim-pickup-order?${serializedParams}`).respond();
|
||||
controller.sendPickupOrder('accept');
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('Notification sent!');
|
||||
expect(controller.sendEmail).toHaveBeenCalledWith('claim-pickup-order', params);
|
||||
});
|
||||
});
|
||||
|
||||
describe('confirmDeleteClaim()', () => {
|
||||
it('should call confirmDeleteClaim.show()', () => {
|
||||
controller.$.confirmDeleteClaim = {
|
||||
show: jasmine.createSpy('show')
|
||||
};
|
||||
controller.claim = {id: 2};
|
||||
controller.confirmDeleteClaim();
|
||||
|
||||
expect(controller.$.confirmDeleteClaim.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteClaime(response)', () => {
|
||||
describe('deleteClaim()', () => {
|
||||
it('should perform a query and call showSuccess if the response is accept', () => {
|
||||
let response = 'accept';
|
||||
controller.claim = {id: 2};
|
||||
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
jest.spyOn(controller.$state, 'go');
|
||||
$httpBackend.when('DELETE', `Claims/2`).respond(200);
|
||||
$httpBackend.expect('DELETE', `Claims/2`);
|
||||
controller.deleteClaim(response);
|
||||
|
||||
$httpBackend.expectDELETE(`Claims/${claim.id}`).respond();
|
||||
controller.deleteClaim();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Claim deleted!');
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('claim.index');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -65,4 +65,3 @@
|
|||
claim="$ctrl.claimSelected">
|
||||
</vn-claim-summary>
|
||||
</vn-popup>
|
||||
<vn-scroll-up></vn-scroll-up>
|
|
@ -1,6 +1,3 @@
|
|||
<slot-descriptor>
|
||||
<vn-client-descriptor
|
||||
client="$ctrl.client"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
</vn-client-descriptor>
|
||||
<vn-client-descriptor></vn-client-descriptor>
|
||||
</slot-descriptor>
|
|
@ -1,16 +1,7 @@
|
|||
import ngModule from '../module';
|
||||
import DescriptorPopover from 'salix/components/descriptor-popover';
|
||||
|
||||
class Controller extends DescriptorPopover {
|
||||
get client() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
loadData() {
|
||||
return this.getData(`Clients/${this.id}/getCard`)
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
class Controller extends DescriptorPopover {}
|
||||
|
||||
ngModule.vnComponent('vnClientDescriptorPopover', {
|
||||
slotTemplate: require('./index.html'),
|
||||
|
|
|
@ -1,21 +1,30 @@
|
|||
<slot-body>
|
||||
<div class="header">
|
||||
<a
|
||||
translate-attr="{title: 'Return to module index'}"
|
||||
ui-sref="client.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a
|
||||
translate-attr="{title: 'Preview'}"
|
||||
ui-sref="client.card.summary({id: $ctrl.client.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-button
|
||||
icon="more_vert"
|
||||
vn-popover="menu">
|
||||
</vn-icon-button>
|
||||
</div>
|
||||
<div class="body">
|
||||
<vn-descriptor-content module="client">
|
||||
<slot-menu>
|
||||
<ul class="vn-list">
|
||||
<li>
|
||||
<a class="vn-item"
|
||||
ui-sref="ticket.create({clientFk: $ctrl.client.id})"
|
||||
translate>
|
||||
Simple ticket
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="$ctrl.showSMSDialog()"
|
||||
translate>
|
||||
Send SMS
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="consumerReportDialog.show()"
|
||||
translate>
|
||||
Send consumer report
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<h5>{{$ctrl.client.name}}</h5>
|
||||
<vn-label-value
|
||||
|
@ -66,85 +75,55 @@
|
|||
ng-class="{bright: $ctrl.client.isTaxDataChecked == false}">
|
||||
</vn-icon>
|
||||
</div>
|
||||
<div class="quicklinks" >
|
||||
<div class="quicklinks">
|
||||
<div ng-transclude="btnOne">
|
||||
<vn-quick-link
|
||||
tooltip="Client ticket list"
|
||||
state="ticket.index({ q: '{{ {clientFk: $ctrl.client.id} }}' })"
|
||||
state="['ticket.index', {q: $ctrl.filter}]"
|
||||
icon="icon-ticket">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnTwo">
|
||||
<vn-quick-link
|
||||
tooltip="New order"
|
||||
state="order.create({ clientFk: {{ $ctrl.client.id }} })"
|
||||
state="['order.create', {clientFk: $ctrl.id}]"
|
||||
icon="icon-basketadd">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnThree">
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<vn-quick-links
|
||||
links="$ctrl.quicklinks">
|
||||
</vn-quick-links>
|
||||
-->
|
||||
</div>
|
||||
<vn-menu vn-id="menu">
|
||||
<ul class="vn-list">
|
||||
<li>
|
||||
<a class="vn-item"
|
||||
ui-sref="ticket.create({clientFk: $ctrl.client.id})"
|
||||
translate>
|
||||
Simple ticket
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="$ctrl.showSMSDialog()"
|
||||
translate>
|
||||
Send SMS
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="consumerReportDialog.show()"
|
||||
translate>
|
||||
Send consumer report
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</vn-menu>
|
||||
<vn-client-sms
|
||||
vn-id="sms"
|
||||
sms="$ctrl.newSMS">
|
||||
</vn-client-sms>
|
||||
<vn-dialog
|
||||
vn-id="consumerReportDialog"
|
||||
on-accept="$ctrl.onConsumerReportAccept()">
|
||||
<tpl-body>
|
||||
<div>
|
||||
<h5 style="text-align: center">
|
||||
<span translate>Send consumer report</span>
|
||||
</h5>
|
||||
<vn-date-picker
|
||||
vn-id="from"
|
||||
vn-one
|
||||
ng-model="$ctrl.from"
|
||||
label="From date"
|
||||
vn-focus>
|
||||
</vn-date-picker>
|
||||
<vn-date-picker
|
||||
vn-id="to"
|
||||
vn-one
|
||||
ng-model="$ctrl.to"
|
||||
label="To date">
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-client-sms
|
||||
vn-id="sms"
|
||||
sms="$ctrl.newSMS">
|
||||
</vn-client-sms>
|
||||
<vn-dialog
|
||||
vn-id="consumerReportDialog"
|
||||
on-accept="$ctrl.onConsumerReportAccept()">
|
||||
<tpl-body>
|
||||
<div>
|
||||
<h5 style="text-align: center">
|
||||
<span translate>Send consumer report</span>
|
||||
</h5>
|
||||
<vn-date-picker
|
||||
vn-id="from"
|
||||
vn-one
|
||||
ng-model="$ctrl.from"
|
||||
label="From date"
|
||||
vn-focus>
|
||||
</vn-date-picker>
|
||||
</div>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="accept" translate>Accept</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
||||
</slot-body>
|
||||
<vn-date-picker
|
||||
vn-id="to"
|
||||
vn-one
|
||||
ng-model="$ctrl.to"
|
||||
label="To date">
|
||||
</vn-date-picker>
|
||||
</div>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="accept" translate>Accept</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
|
@ -2,9 +2,15 @@ import ngModule from '../module';
|
|||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
constructor($element, $, $transclude, $httpParamSerializer) {
|
||||
super($element, $, $transclude);
|
||||
this.$httpParamSerializer = $httpParamSerializer;
|
||||
get entity() {
|
||||
return super.entity;
|
||||
}
|
||||
|
||||
set entity(value) {
|
||||
super.entity = value;
|
||||
|
||||
if (this.$params.sendSMS)
|
||||
this.showSMSDialog();
|
||||
}
|
||||
|
||||
get client() {
|
||||
|
@ -13,33 +19,21 @@ class Controller extends Descriptor {
|
|||
|
||||
set client(value) {
|
||||
this.entity = value;
|
||||
if (!value) return;
|
||||
|
||||
if (this.$params.sendSMS)
|
||||
this.showSMSDialog();
|
||||
|
||||
this._quicklinks = {
|
||||
btnOne: {
|
||||
icon: 'icon-ticket',
|
||||
state: `ticket.index({q: '{"clientFk": ${value.id}}'})`,
|
||||
tooltip: 'Client ticket list'
|
||||
},
|
||||
btnTwo: {
|
||||
icon: 'icon-basketadd',
|
||||
state: `order.create({clientFk: ${value.id}})`,
|
||||
tooltip: 'New order'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
get filter() {
|
||||
return JSON.stringify({clientFk: this.client.id});
|
||||
return JSON.stringify({clientFk: this.id});
|
||||
}
|
||||
|
||||
loadData() {
|
||||
return this.getData(`Clients/${this.id}/getCard`)
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
|
||||
showSMSDialog() {
|
||||
const client = this.client || {};
|
||||
this.newSMS = {
|
||||
destinationFk: client.id,
|
||||
destinationFk: this.id,
|
||||
destination: this.$params.phone || client.mobile || client.phone,
|
||||
message: this.$params.message || ''
|
||||
};
|
||||
|
@ -47,21 +41,18 @@ class Controller extends Descriptor {
|
|||
}
|
||||
|
||||
onConsumerReportAccept() {
|
||||
const params = this.$httpParamSerializer({
|
||||
authorization: this.vnToken.token,
|
||||
clientId: this.client.id,
|
||||
this.showReport('campaign-metrics', {
|
||||
clientId: this.id,
|
||||
from: this.from,
|
||||
to: this.to,
|
||||
});
|
||||
window.open(`api/report/campaign-metrics?${params}`);
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$element', '$scope', '$transclude', '$httpParamSerializer'];
|
||||
|
||||
ngModule.vnComponent('vnClientDescriptor', {
|
||||
slotTemplate: require('./index.html'),
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
client: '<'
|
||||
},
|
||||
controller: Controller
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import './index';
|
||||
|
||||
describe('vnClientDescriptorPopover', () => {
|
||||
describe('vnClientDescriptor', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
|
@ -8,10 +8,7 @@ describe('vnClientDescriptorPopover', () => {
|
|||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnClientDescriptorPopover', {
|
||||
$element: null,
|
||||
$transclude: null
|
||||
});
|
||||
controller = $componentController('vnClientDescriptor', {$element: null});
|
||||
}));
|
||||
|
||||
describe('loadData()', () => {
|
|
@ -1,23 +1,16 @@
|
|||
<div class="vn-descriptor">
|
||||
<div class="header">
|
||||
<a translate-attr="{title: 'Return to module index'}" ui-sref="entry.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a translate-attr="{title: 'Preview'}" ui-sref="entry.card.summary({id: $ctrl.entry.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-menu
|
||||
vn-id="more-button"
|
||||
icon="more_vert"
|
||||
show-filter="false"
|
||||
value-field="callback"
|
||||
translate-fields="['name']"
|
||||
data="$ctrl.moreOptions"
|
||||
on-change="$ctrl.onMoreChange(value)"
|
||||
on-open="$ctrl.onMoreOpen()">
|
||||
</vn-icon-menu>
|
||||
</div>
|
||||
<div class="body">
|
||||
<vn-descriptor-content module="entry">
|
||||
<slot-menu>
|
||||
<ul class="vn-list">
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="$ctrl.showEntryReport()"
|
||||
translate>
|
||||
Show entry report
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<vn-label-value label="Id"
|
||||
value="{{$ctrl.entry.id}}">
|
||||
|
@ -47,8 +40,23 @@
|
|||
ng-class="{bright: $ctrl.entry.isRaid}">
|
||||
</vn-icon>
|
||||
</div>
|
||||
<vn-quick-links
|
||||
links="$ctrl.quicklinks">
|
||||
</vn-quick-links>
|
||||
</div>
|
||||
</div>
|
||||
<div class="quicklinks">
|
||||
<div ng-transclude="btnOne">
|
||||
<vn-quick-link
|
||||
tooltip="All travels with current agency"
|
||||
state="['travel.index', {q: $ctrl.travelFilter}]"
|
||||
icon="local_airport">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnTwo">
|
||||
<vn-quick-link
|
||||
tooltip="All entries with current supplier"
|
||||
state="['entry.index', {q: $ctrl.entryFilter}]"
|
||||
icon="icon-entry">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnThree">
|
||||
</div>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
|
|
|
@ -2,74 +2,47 @@ import ngModule from '../module';
|
|||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
constructor($element, $, $httpParamSerializer) {
|
||||
super($element, $);
|
||||
this.$httpParamSerializer = $httpParamSerializer;
|
||||
|
||||
this.moreOptions = [
|
||||
{name: 'Show entry report', callback: this.showEntryReport}
|
||||
];
|
||||
}
|
||||
|
||||
onMoreChange(callback) {
|
||||
callback.call(this);
|
||||
}
|
||||
|
||||
get entry() {
|
||||
return this._entry;
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set entry(value) {
|
||||
this._entry = value;
|
||||
if (!value) return;
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
const date = value.travel.landed;
|
||||
let to = new Date(date);
|
||||
let from = new Date(date);
|
||||
get travelFilter() {
|
||||
return JSON.stringify({agencyFk: this.entry.travel.agencyFk});
|
||||
}
|
||||
|
||||
get entryFilter() {
|
||||
const date = new Date(this.entry.travel.landed);
|
||||
date.setHours(0, 0, 0, 0);
|
||||
|
||||
const from = new Date(date.getTime());
|
||||
from.setDate(from.getDate() - 10);
|
||||
|
||||
const to = new Date(date.getTime());
|
||||
to.setDate(to.getDate() + 10);
|
||||
|
||||
to.setHours(0, 0, 0, 0);
|
||||
|
||||
from.setDate(from.getDate() - 10);
|
||||
from.setHours(0, 0, 0, 0);
|
||||
|
||||
let links = {
|
||||
btnOne: {
|
||||
icon: 'local_airport',
|
||||
state: `travel.index({q: '{"agencyFk": ${value.travel.agencyFk}}'})`,
|
||||
tooltip: 'All travels with current agency'
|
||||
}};
|
||||
|
||||
links.btnTwo = {
|
||||
icon: 'icon-entry',
|
||||
state: `entry.index({q: '{"supplierFk": ${value.supplierFk}, "to": "${to}", "from": "${from}"}'})`,
|
||||
tooltip: 'All entries with current supplier'
|
||||
};
|
||||
|
||||
this._quicklinks = links;
|
||||
return JSON.stringify({
|
||||
supplierFk: this.entry.travel.supplierFk,
|
||||
from,
|
||||
to
|
||||
});
|
||||
}
|
||||
|
||||
showEntryReport() {
|
||||
const params = {
|
||||
authorization: this.vnToken.token,
|
||||
this.showReport('entry-order', {
|
||||
clientId: this.vnConfig.storage.currentUserWorkerId,
|
||||
entryId: this.entry.id
|
||||
};
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
let url = `api/report/entry-order?${serializedParams}`;
|
||||
window.open(url);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$element', '$scope', '$httpParamSerializer'];
|
||||
|
||||
ngModule.vnComponent('vnEntryDescriptor', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
entry: '<'
|
||||
},
|
||||
require: {
|
||||
card: '^?vnEntryCard'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,35 +1,26 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Entry Component vnEntryDescriptor', () => {
|
||||
let $httpParamSerializer;
|
||||
let controller;
|
||||
let $element;
|
||||
const entry = {id: 2};
|
||||
|
||||
beforeEach(ngModule('entry'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $rootScope, _$httpParamSerializer_) => {
|
||||
$httpParamSerializer = _$httpParamSerializer_;
|
||||
$element = angular.element(`<vn-entry-descriptor></vn-entry-descriptor>`);
|
||||
controller = $componentController('vnEntryDescriptor', {$element});
|
||||
controller._entry = {id: 2};
|
||||
controller.vnConfig.storage = {currentUserWorkerId: 9};
|
||||
controller.cardReload = ()=> {
|
||||
return true;
|
||||
};
|
||||
beforeEach(inject($componentController => {
|
||||
controller = $componentController('vnEntryDescriptor', {$element: null}, {entry});
|
||||
}));
|
||||
|
||||
describe('showEntryReport()', () => {
|
||||
it('should open a new window showing a delivery note PDF document', () => {
|
||||
controller.showReport = jest.fn();
|
||||
|
||||
const params = {
|
||||
clientId: controller.vnConfig.storage.currentUserWorkerId,
|
||||
entryId: controller.entry.id
|
||||
entryId: entry.id
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
let expectedPath = `api/report/entry-order?${serializedParams}`;
|
||||
jest.spyOn(window, 'open').mockReturnThis();
|
||||
controller.showEntryReport();
|
||||
|
||||
expect(window.open).toHaveBeenCalledWith(expectedPath);
|
||||
expect(controller.showReport).toHaveBeenCalledWith('entry-order', params);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
<slot-descriptor>
|
||||
<vn-invoice-out-descriptor
|
||||
invoice-out="$ctrl.invoiceOut"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
<vn-invoice-out-descriptor>
|
||||
</vn-invoice-out-descriptor>
|
||||
</slot-descriptor>
|
|
@ -1,32 +1,7 @@
|
|||
import ngModule from '../module';
|
||||
import DescriptorPopover from 'salix/components/descriptor-popover';
|
||||
|
||||
class Controller extends DescriptorPopover {
|
||||
get invoiceOut() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'company',
|
||||
scope: {
|
||||
fields: ['id', 'code']
|
||||
}
|
||||
}, {
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`InvoiceOuts/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
class Controller extends DescriptorPopover {}
|
||||
|
||||
ngModule.vnComponent('vnInvoiceOutDescriptorPopover', {
|
||||
slotTemplate: require('./index.html'),
|
||||
|
|
|
@ -1,43 +1,70 @@
|
|||
<div class="vn-descriptor">
|
||||
<div class="header">
|
||||
<a translate-attr="{title: 'Return to module index'}" ui-sref="invoiceOut.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a translate-attr="{title: 'Preview'}" ui-sref="invoiceOut.card.summary({id: $ctrl.invoiceOut.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-menu
|
||||
vn-id="more-button"
|
||||
icon="more_vert"
|
||||
show-filter="false"
|
||||
value-field="callback"
|
||||
translate-fields="['name']"
|
||||
data="$ctrl.moreOptions"
|
||||
on-change="$ctrl.onMoreChange(value)"
|
||||
on-open="$ctrl.onMoreOpen()">
|
||||
</vn-icon-menu>
|
||||
</div>
|
||||
<div class="body">
|
||||
<vn-descriptor-content module="invoiceOut">
|
||||
<slot-menu>
|
||||
<ul class="vn-list">
|
||||
<li>
|
||||
<a class="vn-item"
|
||||
href="api/InvoiceOuts/{{$ctrl.id}}/download?access_token={{$ctrl.vnToken.token}}"
|
||||
target="_blank"
|
||||
translate>
|
||||
Show invoice PDF
|
||||
</a>
|
||||
</li>
|
||||
<li vn-acl="invoicing">
|
||||
<div class="vn-item"
|
||||
ng-click="deleteConfirmation.show()"
|
||||
translate>
|
||||
Delete Invoice
|
||||
</div>
|
||||
</li>
|
||||
<li vn-acl="invoicing">
|
||||
<div class="vn-item"
|
||||
ng-click="bookConfirmation.show()"
|
||||
translate>
|
||||
Book invoice
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<h5>{{$ctrl.invoiceOut.ref}}</h5>
|
||||
<vn-label-value label="Date"
|
||||
<vn-label-value
|
||||
label="Date"
|
||||
value="{{$ctrl.invoiceOut.issued | date: 'dd/MM/yyyy'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Import"
|
||||
<vn-label-value
|
||||
label="Import"
|
||||
value="{{$ctrl.invoiceOut.amount | currency: 'EUR': 2}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Client"
|
||||
value="{{$ctrl.invoiceOut.client.name}}">
|
||||
<vn-label-value
|
||||
label="Client"
|
||||
value="{{$ctrl.invoiceOut.client.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Company"
|
||||
<vn-label-value
|
||||
label="Company"
|
||||
value="{{$ctrl.invoiceOut.company.code}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
<vn-quick-links
|
||||
links="$ctrl.quicklinks">
|
||||
</vn-quick-links>
|
||||
</div>
|
||||
</div>
|
||||
<div class="quicklinks">
|
||||
<div ng-transclude="btnOne">
|
||||
<vn-quick-link
|
||||
tooltip="Client card"
|
||||
state="['client.card.summary', {id: $ctrl.invoiceOut.clientFk}]"
|
||||
icon="person">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnTwo">
|
||||
<vn-quick-link
|
||||
tooltip="Invoice ticket list"
|
||||
state="['ticket.card.summary', {id: $ctrl.invoiceOut.ref}]"
|
||||
icon="icon-ticket">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnThree">
|
||||
</div>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-confirm
|
||||
vn-id="deleteConfirmation"
|
||||
on-accept="$ctrl.deleteInvoiceOut()"
|
||||
|
|
|
@ -2,86 +2,46 @@ import ngModule from '../module';
|
|||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.moreOptions = [
|
||||
{
|
||||
name: 'Show invoice PDF',
|
||||
callback: this.showInvoiceOutPdf
|
||||
}, {
|
||||
name: 'Delete Invoice',
|
||||
callback: this.showDeleteInvoiceOutDialog,
|
||||
acl: 'invoicing'
|
||||
}, {
|
||||
name: 'Book invoice',
|
||||
callback: this.showBookInvoiceOutDialog,
|
||||
acl: 'invoicing'
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
onMoreOpen() {
|
||||
let options = this.moreOptions.filter(option => {
|
||||
const hasAclProperty = Object.hasOwnProperty.call(option, 'acl');
|
||||
|
||||
return !hasAclProperty || (hasAclProperty && this.aclService.hasAny([option.acl]));
|
||||
});
|
||||
this.$.moreButton.data = options;
|
||||
}
|
||||
|
||||
onMoreChange(callback) {
|
||||
callback.call(this);
|
||||
get invoiceOut() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set invoiceOut(value) {
|
||||
this._invoiceOut = value;
|
||||
|
||||
if (value) {
|
||||
this._quicklinks = {
|
||||
btnOne: {
|
||||
icon: 'icon-person',
|
||||
state: `client.card.summary({id: ${value.clientFk}})`,
|
||||
tooltip: 'Client card'
|
||||
},
|
||||
btnTwo: {
|
||||
icon: 'icon-ticket',
|
||||
state: `ticket.index({q: '{"refFk": "${value.ref}"}'})`,
|
||||
tooltip: 'Invoice ticket list'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
get invoiceOut() {
|
||||
return this._invoiceOut;
|
||||
}
|
||||
|
||||
showInvoiceOutPdf() {
|
||||
let url = `api/InvoiceOuts/${this.invoiceOut.id}/download?access_token=${this.accessToken}`;
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
|
||||
showDeleteInvoiceOutDialog() {
|
||||
this.$.deleteConfirmation.show();
|
||||
}
|
||||
|
||||
showBookInvoiceOutDialog() {
|
||||
this.$.bookConfirmation.show();
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
deleteInvoiceOut() {
|
||||
const query = `InvoiceOuts/${this.invoiceOut.id}/delete`;
|
||||
return this.$http.post(query)
|
||||
return this.$http.post(`InvoiceOuts/${this.id}/delete`)
|
||||
.then(() => this.$state.go('invoiceOut.index'))
|
||||
.then(() => this.vnApp.showSuccess(this.$t('InvoiceOut deleted')));
|
||||
}
|
||||
|
||||
bookInvoiceOut() {
|
||||
const query = `InvoiceOuts/${this.invoiceOut.ref}/book`;
|
||||
return this.$http.post(query)
|
||||
return this.$http.post(`InvoiceOuts/${this.invoiceOut.ref}/book`)
|
||||
.then(() => this.$state.reload())
|
||||
.then(() => this.vnApp.showSuccess(this.$t('InvoiceOut booked')));
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'company',
|
||||
scope: {
|
||||
fields: ['id', 'code']
|
||||
}
|
||||
}, {
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`InvoiceOuts/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnInvoiceOutDescriptor', {
|
||||
|
|
|
@ -65,4 +65,3 @@
|
|||
<vn-client-descriptor-popover
|
||||
vn-id="clientDescriptor">
|
||||
</vn-client-descriptor-popover>
|
||||
<vn-scroll-up></vn-scroll-up>
|
|
@ -1,6 +1,11 @@
|
|||
<slot-descriptor>
|
||||
<vn-item-descriptor
|
||||
item="$ctrl.item"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
<vn-item-descriptor warehouse-fk="$ctrl.warehouseFk">
|
||||
<btn-three>
|
||||
<vn-quick-link
|
||||
tooltip="Item diary"
|
||||
state="['item.card.diary']"
|
||||
icon="icon-transaction">
|
||||
</vn-quick-link>
|
||||
</btn-three>
|
||||
</vn-item-descriptor>
|
||||
</slot-descriptor>
|
||||
|
|
|
@ -2,28 +2,20 @@ import ngModule from '../module';
|
|||
import DescriptorPopover from 'salix/components/descriptor-popover';
|
||||
|
||||
class Controller extends DescriptorPopover {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this._quicklinks = {
|
||||
btnThree: {
|
||||
icon: 'icon-transaction',
|
||||
state: `item.card.diary({id: $ctrl.id})`,
|
||||
tooltip: 'Item diary'
|
||||
}
|
||||
get diaryParams() {
|
||||
return {
|
||||
id: this.descriptor && this.descriptor.id,
|
||||
warehouseFk: this.warehouseFk,
|
||||
ticketFk: this.ticketFk
|
||||
};
|
||||
}
|
||||
|
||||
get item() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
loadData() {
|
||||
return this.getData(`Items/${this.id}/getCard`)
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnItemDescriptorPopover', {
|
||||
slotTemplate: require('./index.html'),
|
||||
controller: Controller
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
warehouseFk: '<?',
|
||||
ticketFk: '<?'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
import './index';
|
||||
|
||||
describe('vnItemDescriptorPopover', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('item'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnItemDescriptorPopover', {
|
||||
$element: null,
|
||||
$transclude: null
|
||||
});
|
||||
}));
|
||||
|
||||
describe('loadData()', () => {
|
||||
it(`should perform a get query to store the item data into the controller`, () => {
|
||||
const id = 1;
|
||||
const response = 'foo';
|
||||
|
||||
$httpBackend.expectGET(`Items/${id}/getCard`).respond(response);
|
||||
controller.id = id;
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.item).toEqual(response);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,60 +1,56 @@
|
|||
<div class="vn-descriptor">
|
||||
<div class="header">
|
||||
<a translate-attr="{title: 'Return to module index'}" ui-sref="item.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a translate-attr="{title: 'Preview'}" ui-sref="item.card.summary({id: $ctrl.item.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-menu
|
||||
vn-id="more-button"
|
||||
icon="more_vert"
|
||||
show-filter="false"
|
||||
value-field="callback"
|
||||
translate-fields="['name']"
|
||||
data="$ctrl.moreOptions"
|
||||
on-change="$ctrl.onMoreChange(value)"
|
||||
on-open="$ctrl.onMoreOpen()">
|
||||
</vn-icon-menu>
|
||||
</div>
|
||||
<div>
|
||||
<div style="position: relative" text-center>
|
||||
<img
|
||||
ng-src="{{::$root.imagePath}}/catalog/200x200/{{$ctrl.item.image}}"
|
||||
zoom-image="{{::$root.imagePath}}/catalog/1600x900/{{$ctrl.item.image}}"
|
||||
on-error-src/>
|
||||
<a href="//verdnatura.es/#!form=admin/items&filter={{$ctrl.item.id}}" target="_blank">
|
||||
<vn-float-button
|
||||
icon="edit"
|
||||
style="position: absolute; margin: 1em; bottom: 0; right: 0;"
|
||||
vn-visible-by="marketing, buyer">
|
||||
</vn-float-button>
|
||||
</a>
|
||||
<vn-descriptor-content module="item">
|
||||
<slot-menu>
|
||||
<ul class="vn-list">
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="regularize.show()"
|
||||
translate>
|
||||
Regularize stock
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div>
|
||||
<div style="position: relative" text-center>
|
||||
<img
|
||||
ng-src="{{::$root.imagePath}}/catalog/200x200/{{$ctrl.item.image}}"
|
||||
zoom-image="{{::$root.imagePath}}/catalog/1600x900/{{$ctrl.item.image}}"
|
||||
on-error-src
|
||||
/>
|
||||
<a href="//verdnatura.es/#!form=admin/items&filter={{$ctrl.item.id}}" target="_blank">
|
||||
<vn-float-button
|
||||
icon="edit"
|
||||
style="position: absolute; margin: 1em; bottom: 0; right: 0;"
|
||||
vn-visible-by="marketing, buyer">
|
||||
</vn-float-button>
|
||||
</a>
|
||||
</div>
|
||||
<vn-horizontal class="item-state">
|
||||
<vn-one>
|
||||
<p translate>Visible</p>
|
||||
<p>{{$ctrl.visible | dashIfEmpty}}</p>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<p translate>Available</p>
|
||||
<p>{{$ctrl.available | dashIfEmpty}}</p>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</div>
|
||||
<vn-horizontal class="item-state">
|
||||
<vn-one>
|
||||
<p translate>Visible</p>
|
||||
<p>{{$ctrl.visible | dashIfEmpty}}</p>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<p translate>Available</p>
|
||||
<p>{{$ctrl.available | dashIfEmpty}}</p>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div class="attributes">
|
||||
<h5>{{$ctrl.item.id}}</h5>
|
||||
<vn-label-value label="Name"
|
||||
value="{{$ctrl.item.name}}">
|
||||
<vn-label-value
|
||||
label="Name"
|
||||
value="{{$ctrl.item.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Buyer"
|
||||
<vn-label-value
|
||||
label="Buyer"
|
||||
value="{{$ctrl.item.itemType.worker.user.nickname}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
ng-repeat="tag in $ctrl.item.tags | limitTo:4"
|
||||
label="{{tag.tag.name}}"
|
||||
value="{{tag.value}}">
|
||||
ng-repeat="tag in $ctrl.item.tags | limitTo:4"
|
||||
label="{{tag.tag.name}}"
|
||||
value="{{tag.value}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
<div class="icons">
|
||||
|
@ -64,36 +60,32 @@
|
|||
ng-class="{bright: $ctrl.item.isActive == false}">
|
||||
</vn-icon>
|
||||
</div>
|
||||
<vn-quick-links
|
||||
links="$ctrl.quicklinks">
|
||||
</vn-quick-links>
|
||||
</div>
|
||||
</div>
|
||||
<div class="quicklinks">
|
||||
<div ng-transclude="btnOne"></div>
|
||||
<div ng-transclude="btnTwo"></div>
|
||||
<div ng-transclude="btnThree"></div>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-dialog
|
||||
vn-id="regularize"
|
||||
on-open="$ctrl.clearRegularizeDialog()"
|
||||
on-response="$ctrl.saveRegularize($response)">
|
||||
on-open="$ctrl.warehouseFk = $ctrl.vnConfig.warehouseFk"
|
||||
on-close="$ctrl.clearRegularizeDialog()"
|
||||
on-accept="$ctrl.saveRegularize()">
|
||||
<tpl-title translate>
|
||||
Regularize stock
|
||||
</tpl-title>
|
||||
<tpl-body>
|
||||
<div>
|
||||
<h5 style="text-align: center">
|
||||
<span translate>Regularize stock</span>
|
||||
</h5>
|
||||
<vn-textfield
|
||||
label="Type the visible quantity"
|
||||
ng-model="$ctrl.quantity"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Warehouse"
|
||||
id="warehouse"
|
||||
ng-model="$ctrl.warehouseFk"
|
||||
url="Warehouses"
|
||||
select-fields="['id', 'name']"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
</div>
|
||||
<vn-textfield
|
||||
label="Type the visible quantity"
|
||||
ng-model="$ctrl.quantity"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
label="Warehouse"
|
||||
ng-model="$ctrl.warehouseFk"
|
||||
url="Warehouses">
|
||||
</vn-autocomplete>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
|
|
|
@ -3,85 +3,56 @@ import Descriptor from 'salix/components/descriptor';
|
|||
import './style.scss';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.moreOptions = [
|
||||
{callback: this.showRegularizeDialog, name: 'Regularize stock'}
|
||||
];
|
||||
}
|
||||
|
||||
set quantity(value) {
|
||||
this._quantity = parseInt(value);
|
||||
}
|
||||
|
||||
get quantity() {
|
||||
return this._quantity;
|
||||
}
|
||||
|
||||
set warehouseFk(value) {
|
||||
if (value)
|
||||
this._warehouseFk = value;
|
||||
}
|
||||
get warehouseFk() {
|
||||
if (!this._warehouseFk)
|
||||
this._warehouseFk = this.vnConfig.warehouseFk;
|
||||
|
||||
return this._warehouseFk;
|
||||
get item() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set item(value) {
|
||||
this._item = value;
|
||||
if (value && value.itemType && value.itemType.warehouseFk)
|
||||
this.updateStock(value.itemType.warehouseFk);
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
get item() {
|
||||
return this._item;
|
||||
get entity() {
|
||||
return super.entity;
|
||||
}
|
||||
|
||||
updateStock(warehouseFk) {
|
||||
set entity(value) {
|
||||
super.entity = value;
|
||||
this.updateStock();
|
||||
}
|
||||
|
||||
loadData() {
|
||||
return this.getData(`Items/${this.id}/getCard`)
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
|
||||
updateStock() {
|
||||
this.available = null;
|
||||
this.visible = null;
|
||||
if (this._item && this._item.id) {
|
||||
let options = {
|
||||
params: {
|
||||
warehouseFk: warehouseFk
|
||||
}
|
||||
};
|
||||
this.$http.get(`Items/${this._item.id}/getVisibleAvailable`, options).then(response => {
|
||||
this.available = response.data.available;
|
||||
this.visible = response.data.visible;
|
||||
if (!this.item) return;
|
||||
|
||||
const params = {
|
||||
warehouseFk: this.item.itemType.warehouseFk
|
||||
};
|
||||
|
||||
return this.$http.get(`Items/${this.id}/getVisibleAvailable`, {params})
|
||||
.then(res => {
|
||||
this.available = res.data.available;
|
||||
this.visible = res.data.visible;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onMoreChange(callback) {
|
||||
callback.call(this);
|
||||
}
|
||||
saveRegularize() {
|
||||
const params = {
|
||||
itemFk: this.id,
|
||||
quantity: parseInt(this.quantity),
|
||||
warehouseFk: this.warehouseFk
|
||||
};
|
||||
|
||||
showRegularizeDialog() {
|
||||
this.$.regularize.show();
|
||||
}
|
||||
|
||||
set quicklinks(value = {}) {
|
||||
this._quicklinks = Object.assign(value, this._quicklinks);
|
||||
}
|
||||
|
||||
get quicklinks() {
|
||||
return this._quicklinks;
|
||||
}
|
||||
|
||||
saveRegularize(response) {
|
||||
if (response == 'accept') {
|
||||
this.$http.post(`Items/regularize`, {
|
||||
itemFk: this.item.id,
|
||||
quantity: this.quantity,
|
||||
warehouseFk: this.warehouseFk
|
||||
}).then(res => {
|
||||
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||
this.updateStock(this.item.itemType.warehouseFk);
|
||||
return this.$http.post(`Items/regularize`, params)
|
||||
.then(() => {
|
||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||
this.updateStock();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
clearRegularizeDialog() {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import './index';
|
||||
|
||||
describe('vnItemDescriptor', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
const item = {
|
||||
id: 1,
|
||||
itemType: {
|
||||
warehouseFk: 1
|
||||
}
|
||||
};
|
||||
const stock = {
|
||||
visible: 1,
|
||||
available: 5
|
||||
};
|
||||
|
||||
beforeEach(ngModule('item'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.whenRoute('GET', `Items/${item.id}/getVisibleAvailable`).respond(stock);
|
||||
|
||||
controller = $componentController('vnItemDescriptor', {$element: null});
|
||||
}));
|
||||
|
||||
describe('loadData()', () => {
|
||||
it(`should perform a get query to store the item data into the controller`, () => {
|
||||
$httpBackend.expectGET(`Items/${item.id}/getCard`).respond(item);
|
||||
controller.id = item.id;
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.item).toEqual(item);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -86,5 +86,3 @@
|
|||
<vn-client-descriptor-popover
|
||||
vn-id="clientDescriptor">
|
||||
</vn-client-descriptor-popover>
|
||||
|
||||
<vn-scroll-up></vn-scroll-up>
|
|
@ -1,57 +1,57 @@
|
|||
<vn-data-viewer
|
||||
model="$ctrl.model">
|
||||
<vn-horizontal class="catalog-list">
|
||||
<section class="product" ng-repeat="item in $ctrl.model.data">
|
||||
<vn-card>
|
||||
<div class="image">
|
||||
<img
|
||||
ng-src="{{::$root.imagePath}}/catalog/200x200/{{::item.image}}"
|
||||
zoom-image="{{::$root.imagePath}}/catalog/1600x900/{{::item.image}}"
|
||||
on-error-src/>
|
||||
</div>
|
||||
<div class="description">
|
||||
<h3>
|
||||
{{::item.name}}
|
||||
</h3>
|
||||
<h4 class="ellipsize">
|
||||
<span translate-attr="::{title: item.subName}">{{::item.subName}}</span>
|
||||
</h4>
|
||||
<div class="tags">
|
||||
<vn-label-value
|
||||
ng-if="::item.value5"
|
||||
label="{{::item.tag5}}"
|
||||
value="{{::item.value5}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
ng-if="::item.value6"
|
||||
label="{{::item.tag6}}"
|
||||
value="{{::item.value6}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
ng-if="::item.value7"
|
||||
label="{{::item.tag7}}"
|
||||
value="{{::item.value7}}">
|
||||
</vn-label-value>
|
||||
<section ng-repeat="item in $ctrl.model.data" class="product">
|
||||
<vn-card>
|
||||
<div class="image">
|
||||
<img
|
||||
ng-src="{{::$root.imagePath}}/catalog/200x200/{{::item.image}}"
|
||||
zoom-image="{{::$root.imagePath}}/catalog/1600x900/{{::item.image}}"
|
||||
on-error-src/>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="price">
|
||||
<vn-one>
|
||||
<span>{{::item.available}}</span>
|
||||
<span translate>from</span>
|
||||
<span>{{::item.price | currency:'EUR':2}}</span>
|
||||
</vn-one>
|
||||
<vn-icon-button vn-none
|
||||
icon="add_circle"
|
||||
ng-click="$ctrl.preview($event, item)"
|
||||
vn-tooltip="Add">
|
||||
</vn-icon-button>
|
||||
<div class="description">
|
||||
<h3>
|
||||
{{::item.name}}
|
||||
</h3>
|
||||
<h4 class="ellipsize">
|
||||
<span translate-attr="::{title: item.subName}">{{::item.subName}}</span>
|
||||
</h4>
|
||||
<div class="tags">
|
||||
<vn-label-value
|
||||
ng-if="::item.value5"
|
||||
label="{{::item.tag5}}"
|
||||
value="{{::item.value5}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
ng-if="::item.value6"
|
||||
label="{{::item.tag6}}"
|
||||
value="{{::item.value6}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
ng-if="::item.value7"
|
||||
label="{{::item.tag7}}"
|
||||
value="{{::item.value7}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
<div class="priceKg" ng-show="::item.priceKg">
|
||||
<span>Precio por kilo {{::item.priceKg | currency: 'EUR'}}</span>
|
||||
<div class="footer">
|
||||
<div class="price">
|
||||
<vn-one>
|
||||
<span>{{::item.available}}</span>
|
||||
<span translate>from</span>
|
||||
<span>{{::item.price | currency:'EUR':2}}</span>
|
||||
</vn-one>
|
||||
<vn-icon-button vn-none
|
||||
icon="add_circle"
|
||||
ng-click="pricesPopover.show($event, item)"
|
||||
vn-tooltip="Add">
|
||||
</vn-icon-button>
|
||||
</div>
|
||||
<div class="priceKg" ng-show="::item.priceKg">
|
||||
<span>Precio por kilo {{::item.priceKg | currency: 'EUR'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</vn-card>
|
||||
</vn-card>
|
||||
</section>
|
||||
</vn-horizontal>
|
||||
</vn-data-viewer>
|
||||
|
|
|
@ -2,16 +2,7 @@ import ngModule from '../module';
|
|||
import Component from 'core/lib/component';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends Component {
|
||||
preview(event, item) {
|
||||
event.preventDefault();
|
||||
this.$.pricesPopover.show(event, item);
|
||||
}
|
||||
|
||||
onDescriptorLoad() {
|
||||
this.$.popover.relocate();
|
||||
}
|
||||
}
|
||||
class Controller extends Component {}
|
||||
|
||||
ngModule.component('vnOrderCatalogView', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -1,59 +1,77 @@
|
|||
<div class="vn-descriptor">
|
||||
<div class="header">
|
||||
<a translate-attr="{title: 'Return to module index'}" ui-sref="order.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a translate-attr="{title: 'Preview'}" ui-sref="order.card.summary">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-menu
|
||||
vn-id="more-button"
|
||||
icon="more_vert"
|
||||
show-filter="false"
|
||||
value-field="callback"
|
||||
translate-fields="['name']"
|
||||
data="$ctrl.moreOptions"
|
||||
on-change="value()">
|
||||
</vn-icon-menu>
|
||||
</div>
|
||||
<div class="body">
|
||||
<vn-descriptor-content module="order">
|
||||
<slot-menu>
|
||||
<ul class="vn-list">
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="deleteOrderConfirmation.show()"
|
||||
translate>
|
||||
Delete order
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<vn-label-value label="ID"
|
||||
<vn-label-value
|
||||
label="ID"
|
||||
value="{{$ctrl.order.id}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Client"
|
||||
<vn-label-value
|
||||
label="Client"
|
||||
value="{{$ctrl.order.client.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="State"
|
||||
value="{{$ctrl.order.isConfirmed ? $ctrl.$translate.instant('Confirmed') : $ctrl.$translate.instant('Not confirmed')}}">
|
||||
<vn-label-value
|
||||
label="State"
|
||||
value="{{$ctrl.$t($ctrl.order.isConfirmed ? 'Confirmed' : 'Not confirmed')}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Sales person"
|
||||
<vn-label-value
|
||||
label="Sales person"
|
||||
value="{{$ctrl.order.client.salesPerson.user.nickname}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Landed"
|
||||
<vn-label-value
|
||||
label="Landed"
|
||||
value="{{$ctrl.order.landed | date: 'dd/MM/yyyy' }}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Agency"
|
||||
<vn-label-value
|
||||
label="Agency"
|
||||
value="{{$ctrl.order.agencyMode.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Alias"
|
||||
<vn-label-value
|
||||
label="Alias"
|
||||
value="{{$ctrl.order.address.nickname}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Items"
|
||||
<vn-label-value
|
||||
label="Items"
|
||||
value="{{$ctrl.order.rows.length || 0}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Total"
|
||||
<vn-label-value
|
||||
label="Total"
|
||||
value="{{$ctrl.order.total | currency: 'EUR': 2}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
<vn-quick-links
|
||||
links="$ctrl.quicklinks">
|
||||
</vn-quick-links>
|
||||
</div>
|
||||
</div>
|
||||
<div class="quicklinks">
|
||||
<div ng-transclude="btnOne">
|
||||
<vn-quick-link
|
||||
tooltip="Order ticket list"
|
||||
state="['ticket.index', {q: $ctrl.ticketFilter}]"
|
||||
icon="icon-ticket">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnTwo">
|
||||
<vn-quick-link
|
||||
tooltip="Client card"
|
||||
state="['client.card.summary', {id: $ctrl.order.clientFk}]"
|
||||
icon="person">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnThree">
|
||||
</div>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-confirm
|
||||
vn-id="deleteOrderConfirmation"
|
||||
on-response="$ctrl.deleteOrder($response)"
|
||||
on-accept="$ctrl.deleteOrder()"
|
||||
message="You are going to delete this order"
|
||||
question="continue anyway?">
|
||||
</vn-confirm>
|
|
@ -2,49 +2,24 @@ import ngModule from '../module';
|
|||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.moreOptions = [
|
||||
{name: 'Delete order', callback: () => this.showDeleteOrderDialog()}
|
||||
];
|
||||
get order() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set order(value) {
|
||||
this._order = value;
|
||||
if (!value) return;
|
||||
|
||||
if (value.isConfirmed) {
|
||||
this._quicklinks = {
|
||||
btnOne: {
|
||||
icon: 'icon-ticket',
|
||||
state: `ticket.index({q: '{"orderFk": ${value.id}}'})`,
|
||||
tooltip: 'Order ticket list'
|
||||
},
|
||||
btnTwo: {
|
||||
icon: 'person',
|
||||
state: `client.card.summary({id: ${value.clientFk}})`,
|
||||
tooltip: 'Client card'
|
||||
}
|
||||
};
|
||||
}
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
get order() {
|
||||
return this._order;
|
||||
get ticketFilter() {
|
||||
return JSON.stringify({orderFk: this.id});
|
||||
}
|
||||
|
||||
deleteOrder(response) {
|
||||
if (response === 'accept') {
|
||||
const params = {id: this.order.id};
|
||||
this.$http.delete(`Orders/${params.id}`).then(() => {
|
||||
deleteOrder() {
|
||||
return this.$http.delete(`Orders/${this.id}`)
|
||||
.then(() => {
|
||||
this.$state.go('order.index');
|
||||
this.vnApp.showSuccess(this.$translate.instant('Order deleted'));
|
||||
this.vnApp.showSuccess(this.$t('Order deleted'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
showDeleteOrderDialog() {
|
||||
this.$.deleteOrderConfirmation.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,42 +2,26 @@ import './index.js';
|
|||
|
||||
describe('Order Component vnOrderDescriptor', () => {
|
||||
let $httpBackend;
|
||||
let $scope;
|
||||
let controller;
|
||||
const order = {id: 1};
|
||||
|
||||
beforeEach(ngModule('order'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $rootScope) => {
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$scope = $rootScope.$new();
|
||||
const $element = angular.element('<vn-order-descriptor></vn-order-descriptor>');
|
||||
controller = $componentController('vnOrderDescriptor', {$element, $scope});
|
||||
controller.order = {id: 1};
|
||||
controller = $componentController('vnOrderDescriptor', {$element: null}, {order});
|
||||
}));
|
||||
|
||||
describe('deleteOrder()', () => {
|
||||
it(`should do nothing if the response isn't accept`, () => {
|
||||
let response = 'WAGH!';
|
||||
|
||||
it(`should perform a DELETE query`, () => {
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
jest.spyOn(controller.$state, 'go');
|
||||
controller.deleteOrder(response);
|
||||
|
||||
expect(controller.vnApp.showSuccess).not.toHaveBeenCalledWith('Order deleted!');
|
||||
expect(controller.$state.go).not.toHaveBeenCalledWith('order.index');
|
||||
});
|
||||
|
||||
it(`should perform a DELETE query if the response was accept`, () => {
|
||||
let response = 'accept';
|
||||
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
jest.spyOn(controller.$state, 'go');
|
||||
$httpBackend.when('DELETE', `Orders/${controller.order.id}`).respond(200);
|
||||
$httpBackend.expect('DELETE', `Orders/${controller.order.id}`);
|
||||
controller.deleteOrder(response);
|
||||
$httpBackend.expectDELETE(`Orders/${order.id}`).respond();
|
||||
controller.deleteOrder();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Order deleted');
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('order.index');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -81,4 +81,3 @@
|
|||
order="$ctrl.selectedOrder">
|
||||
</vn-order-summary>
|
||||
</vn-popup>
|
||||
<vn-scroll-up></vn-scroll-up>
|
|
@ -1,6 +1,11 @@
|
|||
<slot-descriptor>
|
||||
<vn-route-descriptor
|
||||
route="$ctrl.route"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
<vn-route-descriptor>
|
||||
<btn-three>
|
||||
<vn-quick-link
|
||||
tooltip="Route summary"
|
||||
state="['route.card.summary', {id: $ctrl.descriptor.id}]"
|
||||
icon="icon-delivery">
|
||||
</vn-quick-link>
|
||||
</btn-three>
|
||||
</vn-route-descriptor>
|
||||
</slot-descriptor>
|
|
@ -1,70 +1,7 @@
|
|||
import ngModule from '../module';
|
||||
import DescriptorPopover from 'salix/components/descriptor-popover';
|
||||
|
||||
class Controller extends DescriptorPopover {
|
||||
get route() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
fields: [
|
||||
'id',
|
||||
'workerFk',
|
||||
'agencyModeFk',
|
||||
'created',
|
||||
'm3',
|
||||
'warehouseFk',
|
||||
'description',
|
||||
'vehicleFk',
|
||||
'kmStart',
|
||||
'kmEnd',
|
||||
'started',
|
||||
'finished',
|
||||
'cost',
|
||||
'zoneFk'
|
||||
],
|
||||
include: [
|
||||
{
|
||||
relation: 'agencyMode',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}, {
|
||||
relation: 'vehicle',
|
||||
scope: {
|
||||
fields: ['id', 'm3']
|
||||
}
|
||||
}, {
|
||||
relation: 'zone',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}, {
|
||||
relation: 'worker',
|
||||
scope: {
|
||||
fields: ['userFk'],
|
||||
include: {
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['id'],
|
||||
include: {
|
||||
relation: 'emailUser',
|
||||
scope: {
|
||||
fields: ['email']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Routes/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
class Controller extends DescriptorPopover {}
|
||||
|
||||
ngModule.vnComponent('vnRouteDescriptorPopover', {
|
||||
slotTemplate: require('./index.html'),
|
||||
|
|
|
@ -1,41 +1,54 @@
|
|||
<div class="vn-descriptor">
|
||||
<div class="header">
|
||||
<a translate-attr="{title: 'Return to module index'}" ui-sref="route.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a translate-attr="{title: 'Preview'}" ui-sref="route.card.summary({id: $ctrl.route.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-menu
|
||||
vn-id="more-button"
|
||||
icon="more_vert"
|
||||
show-filter="false"
|
||||
value-field="callback"
|
||||
translate-fields="['name']"
|
||||
data="$ctrl.moreOptions"
|
||||
on-change="$ctrl.onMoreChange(value)"
|
||||
on-open="$ctrl.onMoreOpen()">
|
||||
</vn-icon-menu>
|
||||
</div>
|
||||
<div class="body">
|
||||
<vn-descriptor-content module="route">
|
||||
<slot-menu>
|
||||
<ul class="vn-list">
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="$ctrl.showRouteReport()"
|
||||
translate>
|
||||
Show route report
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="$ctrl.sendRouteReport()"
|
||||
translate>
|
||||
Send route report
|
||||
</div>
|
||||
</li>
|
||||
<li vn-acl="deliveryBoss">
|
||||
<div class="vn-item"
|
||||
ng-click="updateVolumeConfirmation.show()"
|
||||
translate>
|
||||
Update volume
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<h5>{{$ctrl.route.name}}</h5>
|
||||
<vn-label-value label="Id"
|
||||
<vn-label-value
|
||||
label="Id"
|
||||
value="{{$ctrl.route.id}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Date"
|
||||
<vn-label-value
|
||||
label="Date"
|
||||
value="{{$ctrl.route.created | date: 'dd/MM/yyyy'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Agency"
|
||||
<vn-label-value
|
||||
label="Agency"
|
||||
value="{{$ctrl.route.agencyMode.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Zone"
|
||||
<vn-label-value
|
||||
label="Zone"
|
||||
value="{{$ctrl.route.zone.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Volume"
|
||||
<vn-label-value
|
||||
label="Volume"
|
||||
value="{{$ctrl.route.m3 | dashIfEmpty}} / {{$ctrl.route.vehicle.m3 | dashIfEmpty}} m³">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Description"
|
||||
<vn-label-value
|
||||
label="Description"
|
||||
value="{{$ctrl.route.description}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
|
@ -46,13 +59,15 @@
|
|||
ng-class="{bright: $ctrl.route.m3 > $ctrl.route.vehicle.m3 && $ctrl.route.vehicle.m3 != NULL}">
|
||||
</vn-icon>
|
||||
</div>
|
||||
<vn-quick-links
|
||||
links="$ctrl.quicklinks">
|
||||
</vn-quick-links>
|
||||
<div class="quicklinks">
|
||||
<div ng-transclude="btnOne"></div>
|
||||
<div ng-transclude="btnTwo"></div>
|
||||
<div ng-transclude="btnThree"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<vn-confirm
|
||||
vn-id="updateVolumeConfirmation"
|
||||
on-response="$ctrl.updateVolume($response)"
|
||||
on-accept="$ctrl.updateVolume()"
|
||||
question="Are you sure you want to update the volume?">
|
||||
</vn-confirm>
|
|
@ -2,69 +2,99 @@ import ngModule from '../module';
|
|||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
constructor($element, $, $httpParamSerializer) {
|
||||
super($element, $);
|
||||
|
||||
this.$httpParamSerializer = $httpParamSerializer;
|
||||
this.moreOptions = [
|
||||
{callback: this.showRouteReport, name: 'Show route report'},
|
||||
{callback: this.sendRouteReport, name: 'Send route report'},
|
||||
{callback: this.showUpdateVolumeDialog, name: 'Update volume', acl: 'deliveryBoss'}
|
||||
];
|
||||
get route() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
onMoreOpen() {
|
||||
let options = this.moreOptions.filter(option => {
|
||||
const hasAclProperty = Object.hasOwnProperty.call(option, 'acl');
|
||||
|
||||
return !hasAclProperty || (hasAclProperty && this.aclService.hasAny([option.acl]));
|
||||
});
|
||||
this.$.moreButton.data = options;
|
||||
}
|
||||
|
||||
onMoreChange(callback) {
|
||||
callback.call(this);
|
||||
set route(value) {
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
showRouteReport() {
|
||||
const params = {
|
||||
authorization: this.vnToken.token,
|
||||
this.showReport('driver-route', {
|
||||
clientId: this.vnConfig.storage.currentUserWorkerId,
|
||||
routeId: this.route.id
|
||||
};
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
let url = `api/report/driver-route?${serializedParams}`;
|
||||
window.open(url);
|
||||
routeId: this.id
|
||||
});
|
||||
}
|
||||
|
||||
sendRouteReport() {
|
||||
const params = {
|
||||
recipient: user.emailUser.email,
|
||||
clientId: this.vnConfig.storage.currentUserWorkerId,
|
||||
routeId: this.route.id
|
||||
routeId: this.id
|
||||
};
|
||||
this.$http.get(`email/driver-route`, {params}).then(() => {
|
||||
this.vnApp.showSuccess(this.$translate.instant('Report sent'));
|
||||
});
|
||||
return this.$http.get(`email/driver-route`, {params})
|
||||
.then(() => this.vnApp.showSuccess(this.$t('Report sent')));
|
||||
}
|
||||
|
||||
showUpdateVolumeDialog() {
|
||||
this.$.updateVolumeConfirmation.show();
|
||||
}
|
||||
|
||||
updateVolume(response) {
|
||||
if (response === 'accept') {
|
||||
let url = `Routes/${this.route.id}/updateVolume`;
|
||||
this.$http.post(url).then(() => {
|
||||
this.vnApp.showSuccess(this.$translate.instant('Volume updated'));
|
||||
this.cardReload();
|
||||
updateVolume() {
|
||||
this.$http.post(`Routes/${this.id}/updateVolume`)
|
||||
.then(() => {
|
||||
if (this.cardReload) this.cardReload();
|
||||
this.vnApp.showSuccess(this.$t('Volume updated'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
fields: [
|
||||
'id',
|
||||
'workerFk',
|
||||
'agencyModeFk',
|
||||
'created',
|
||||
'm3',
|
||||
'warehouseFk',
|
||||
'description',
|
||||
'vehicleFk',
|
||||
'kmStart',
|
||||
'kmEnd',
|
||||
'started',
|
||||
'finished',
|
||||
'cost',
|
||||
'zoneFk'
|
||||
],
|
||||
include: [
|
||||
{
|
||||
relation: 'agencyMode',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}, {
|
||||
relation: 'vehicle',
|
||||
scope: {
|
||||
fields: ['id', 'm3']
|
||||
}
|
||||
}, {
|
||||
relation: 'zone',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}, {
|
||||
relation: 'worker',
|
||||
scope: {
|
||||
fields: ['userFk'],
|
||||
include: {
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['id'],
|
||||
include: {
|
||||
relation: 'emailUser',
|
||||
scope: {
|
||||
fields: ['email']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Routes/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$element', '$scope', '$httpParamSerializer'];
|
||||
|
||||
ngModule.vnComponent('vnRouteDescriptor', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
|
|
|
@ -8,10 +8,7 @@ describe('vnRouteDescriptorPopover', () => {
|
|||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnRouteDescriptorPopover', {
|
||||
$element: null,
|
||||
$transclude: null
|
||||
});
|
||||
controller = $componentController('vnRouteDescriptor', {$element: null});
|
||||
}));
|
||||
|
||||
describe('loadData()', () => {
|
||||
|
@ -19,7 +16,7 @@ describe('vnRouteDescriptorPopover', () => {
|
|||
const id = 1;
|
||||
const response = 'foo';
|
||||
|
||||
$httpBackend.expectGET(`Routes/${id}`).respond(response);
|
||||
$httpBackend.expectRoute('GET', `Routes/${id}`).respond(response);
|
||||
controller.id = id;
|
||||
$httpBackend.flush();
|
||||
|
|
@ -104,4 +104,4 @@
|
|||
</vn-ticket-descriptor-popover>
|
||||
<vn-client-descriptor-popover
|
||||
vn-id="clientDescriptor">
|
||||
</vn-client-descriptor-popover>
|
||||
</vn-client-descriptor-popover>
|
||||
|
|
|
@ -176,4 +176,4 @@
|
|||
vn-acl-action="remove"
|
||||
vn-bind="+"
|
||||
fixed-bottom-right>
|
||||
</vn-float-button>
|
||||
</vn-float-button>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<tr style="height: initial;">
|
||||
<td rowspan="{{::sale.components.length + 1}}" number>
|
||||
<span
|
||||
ng-click="$ctrl.showDescriptor($event, sale.itemFk)"
|
||||
ng-click="descriptor.show($event, sale.itemFk)"
|
||||
class="link">
|
||||
{{sale.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
|
@ -66,5 +66,6 @@
|
|||
</vn-data-viewer>
|
||||
<vn-item-descriptor-popover
|
||||
vn-id="descriptor"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
warehouse-fk="$ctrl.ticket.warehouseFk"
|
||||
ticket-fk="$ctrl.ticket.id">
|
||||
</vn-item-descriptor-popover>
|
|
@ -45,27 +45,6 @@ class Controller extends Section {
|
|||
|
||||
return sum;
|
||||
}
|
||||
|
||||
showDescriptor(event, itemFk) {
|
||||
this.quicklinks = {
|
||||
btnThree: {
|
||||
icon: 'icon-transaction',
|
||||
state: `item.card.diary({
|
||||
id: ${itemFk},
|
||||
warehouseFk: ${this.ticket.warehouseFk},
|
||||
ticketFk: ${this.ticket.id}
|
||||
})`,
|
||||
tooltip: 'Item diary'
|
||||
}
|
||||
};
|
||||
this.$.descriptor.itemFk = itemFk;
|
||||
this.$.descriptor.parent = event.target;
|
||||
this.$.descriptor.show();
|
||||
}
|
||||
|
||||
onDescriptorLoad() {
|
||||
this.$.popover.relocate();
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnTicketComponents', {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
<slot-descriptor>
|
||||
<vn-ticket-descriptor
|
||||
ticket="$ctrl.ticket"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
<vn-ticket-descriptor>
|
||||
</vn-ticket-descriptor>
|
||||
</slot-descriptor>
|
|
@ -1,64 +1,7 @@
|
|||
import ngModule from '../module';
|
||||
import DescriptorPopover from 'salix/components/descriptor-popover';
|
||||
|
||||
class Controller extends DescriptorPopover {
|
||||
get ticket() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'warehouse',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}, {
|
||||
relation: 'agencyMode',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}, {
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: [
|
||||
'salesPersonFk',
|
||||
'name',
|
||||
'isActive',
|
||||
'isFreezed',
|
||||
'isTaxDataChecked'
|
||||
],
|
||||
include: {
|
||||
relation: 'salesPerson',
|
||||
scope: {
|
||||
fields: ['userFk'],
|
||||
include: {
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['nickname']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
relation: 'state',
|
||||
scope: {
|
||||
fields: ['stateFk'],
|
||||
include: {
|
||||
relation: 'state',
|
||||
fields: ['id', 'name'],
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Tickets/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
class Controller extends DescriptorPopover {}
|
||||
|
||||
ngModule.vnComponent('vnTicketDescriptorPopover', {
|
||||
slotTemplate: require('./index.html'),
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
import './index.js';
|
||||
|
||||
describe('vnTicketDescriptorPopover', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('ticket'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnTicketDescriptorPopover', {
|
||||
$element: null,
|
||||
$transclude: null
|
||||
});
|
||||
}));
|
||||
|
||||
describe('loadData()', () => {
|
||||
it(`should perform a get query to store the ticket data into the controller`, () => {
|
||||
const id = 1;
|
||||
const response = 'foo';
|
||||
|
||||
$httpBackend.expectGET(`Tickets/${id}`).respond(response);
|
||||
controller.id = id;
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.ticket).toEqual(response);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,80 +1,180 @@
|
|||
<div class="vn-descriptor">
|
||||
<div class="header">
|
||||
<a translate-attr="{title: 'Return to module index'}" ui-sref="ticket.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a translate-attr="{title: 'Preview'}" ui-sref="ticket.card.summary({id: $ctrl.ticket.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-menu
|
||||
vn-id="more-button"
|
||||
icon="more_vert"
|
||||
show-filter="false"
|
||||
value-field="callback"
|
||||
translate-fields="['name']"
|
||||
data="$ctrl.moreOptions"
|
||||
on-change="$ctrl.onMoreChange(value)"
|
||||
on-open="$ctrl.onMoreOpen()">
|
||||
</vn-icon-menu>
|
||||
</div>
|
||||
<div class="body">
|
||||
<vn-descriptor-content module="ticket">
|
||||
<slot-menu>
|
||||
<ul class="vn-list">
|
||||
<li vn-acl="buyer">
|
||||
<div class="vn-item"
|
||||
ng-click="addTurn.show()"
|
||||
translate>
|
||||
Add turn
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="$ctrl.showDeliveryNote()"
|
||||
translate>
|
||||
Show Delivery Note
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="confirmDeliveryNote.show()"
|
||||
translate>
|
||||
Send Delivery Note
|
||||
</div>
|
||||
</li>
|
||||
<li ng-show="$ctrl.isEditable">
|
||||
<div class="vn-item"
|
||||
ng-click="deleteConfirmation.show()"
|
||||
translate>
|
||||
Delete ticket
|
||||
</div>
|
||||
</li>
|
||||
<li ng-show="$ctrl.isEditable">
|
||||
<div class="vn-item"
|
||||
ng-click="$ctrl.showChangeShipped()"
|
||||
translate>
|
||||
Change shipped hour
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="$ctrl.sendPaymentSms()"
|
||||
translate>
|
||||
SMS Pending payment
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="$ctrl.sendImportSms()"
|
||||
translate>
|
||||
SMS Minimum import
|
||||
</div>
|
||||
</li>
|
||||
<li ng-show="$ctrl.canShowStowaway">
|
||||
<div class="vn-item"
|
||||
ng-click="addStowaway.show()"
|
||||
translate>
|
||||
Add stowaway
|
||||
</div>
|
||||
</li>
|
||||
<li ng-show="$ctrl.shouldShowDeleteStowaway">
|
||||
<div class="vn-item"
|
||||
ng-click="deleteStowaway.show()"
|
||||
translate>
|
||||
Delete stowaway
|
||||
</div>
|
||||
</li>
|
||||
<li ng-show="!$ctrl.isInvoiced" vn-acl="invoicing">
|
||||
<div class="vn-item"
|
||||
ng-click="makeInvoiceConfirmation.show()"
|
||||
translate>
|
||||
Make invoice
|
||||
</div>
|
||||
</li>
|
||||
<li ng-show="$ctrl.isInvoiced" vn-acl="invoicing">
|
||||
<div class="vn-item"
|
||||
ng-click="regenerateInvoiceConfirmation.show()"
|
||||
translate>
|
||||
Regenerate invoice
|
||||
</div>
|
||||
</li>
|
||||
<li ng-show="$ctrl.isEditable">
|
||||
<div class="vn-item"
|
||||
ng-click="recalculateComponentsConfirmation.show()"
|
||||
translate>
|
||||
Recalculate components
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<h5>{{::$ctrl.client.name}}</h5>
|
||||
<vn-label-value label="Id"
|
||||
<vn-label-value
|
||||
label="Id"
|
||||
value="{{$ctrl.ticket.id}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Client"
|
||||
<vn-label-value
|
||||
label="Client"
|
||||
value="{{$ctrl.ticket.client.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="State"
|
||||
<vn-label-value
|
||||
label="State"
|
||||
value="{{$ctrl.ticket.state.state.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Sales person"
|
||||
<vn-label-value
|
||||
label="Sales person"
|
||||
value="{{$ctrl.ticket.client.salesPerson.user.nickname}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Shipped"
|
||||
<vn-label-value
|
||||
label="Shipped"
|
||||
value="{{$ctrl.ticket.shipped | date: 'dd/MM/yyyy HH:mm' }}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Agency"
|
||||
<vn-label-value
|
||||
label="Agency"
|
||||
value="{{$ctrl.ticket.agencyMode.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Warehouse"
|
||||
<vn-label-value
|
||||
label="Warehouse"
|
||||
value="{{$ctrl.ticket.warehouse.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Alias"
|
||||
<vn-label-value
|
||||
label="Alias"
|
||||
value="{{$ctrl.ticket.nickname}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
<div class="icons">
|
||||
<vn-icon vn-one
|
||||
<vn-icon
|
||||
vn-tooltip="Client inactive"
|
||||
icon="icon-disabled"
|
||||
ng-class="{bright: $ctrl.ticket.client.isActive == false}">
|
||||
</vn-icon>
|
||||
<vn-icon vn-one
|
||||
<vn-icon
|
||||
vn-tooltip="Client frozen"
|
||||
icon="icon-frozen"
|
||||
ng-class="{bright: $ctrl.ticket.client.isFreezed == true}">
|
||||
</vn-icon>
|
||||
<vn-icon vn-one
|
||||
<vn-icon
|
||||
vn-tooltip="Client has debt"
|
||||
icon="icon-risk"
|
||||
ng-class="{bright: $ctrl.ticket.client.debt > $ctrl.ticket.client.credit}">
|
||||
</vn-icon>
|
||||
<vn-icon vn-one
|
||||
<vn-icon
|
||||
vn-tooltip="Client not checked"
|
||||
icon="icon-no036"
|
||||
ng-class="{bright: $ctrl.ticket.client.isTaxDataChecked == false}">
|
||||
</vn-icon>
|
||||
<vn-icon vn-one
|
||||
<vn-icon
|
||||
vn-tooltip="Deleted ticket"
|
||||
icon="icon-deletedTicket"
|
||||
ng-class="{bright: $ctrl.ticket.isDeleted == true}">
|
||||
</vn-icon>
|
||||
</div>
|
||||
<vn-quick-links
|
||||
links="$ctrl.quicklinks">
|
||||
</vn-quick-links>
|
||||
<div class="quicklinks">
|
||||
<div ng-transclude="btnOne">
|
||||
<vn-quick-link
|
||||
tooltip="Client card"
|
||||
state="['client.card.summary', {id: $ctrl.ticket.clientFk}]"
|
||||
icon="person">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnTwo">
|
||||
<vn-quick-link
|
||||
ng-if="$ctrl.ticket.stowaway"
|
||||
tooltip="Ship stowaways"
|
||||
state="['ticket.card.summary', {id: $ctrl.ticket.stowaway.shipFk}]"
|
||||
icon="icon-stowaway">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnThree">
|
||||
<vn-quick-link
|
||||
ng-if="$ctrl.ticket.ship"
|
||||
tooltip="Stowaway"
|
||||
state="['ticket.card.summary', {id: $ctrl.ticket.ship.id}]"
|
||||
icon="icon-stowaway">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
<vn-button-menu
|
||||
ng-if="$ctrl.ticket.ship.length > 1"
|
||||
|
@ -89,12 +189,12 @@
|
|||
on-change="$ctrl.goToTicket(value)">
|
||||
</vn-button-menu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-popup vn-id="addTurn">
|
||||
<div class="vn-pa-md">
|
||||
<h5 style="text-align: center">
|
||||
<span translate>In which day you want to add the ticket?</span>
|
||||
<h5 style="text-align: center" translate>
|
||||
In which day you want to add the ticket?
|
||||
</h5>
|
||||
<vn-tool-bar class="vn-mt-md">
|
||||
<vn-button
|
||||
|
@ -130,15 +230,10 @@
|
|||
</vn-popup>
|
||||
<vn-confirm
|
||||
vn-id="deleteConfirmation"
|
||||
on-response="$ctrl.deleteTicket($response)"
|
||||
on-accept="$ctrl.deleteTicket()"
|
||||
question="You are going to delete this ticket"
|
||||
message="This ticket will be removed from current route! Continue anyway?">
|
||||
</vn-confirm>
|
||||
<vn-add-stowaway
|
||||
vn-id="addStowaway"
|
||||
card-reload="$ctrl.cardReload()"
|
||||
ticket="$ctrl.ticket">
|
||||
</vn-add-stowaway>
|
||||
<vn-confirm
|
||||
vn-id="deleteStowaway"
|
||||
on-accept="$ctrl.deleteStowaway()"
|
||||
|
@ -146,11 +241,44 @@
|
|||
message="Are you sure you want to delete this stowaway?">
|
||||
</vn-confirm>
|
||||
<vn-confirm
|
||||
vn-id="confirm-dialog"
|
||||
on-response="$ctrl.returnDialog($response)"
|
||||
vn-id="confirmDialog"
|
||||
on-accept="$ctrl.returnDialog()"
|
||||
question="Pickup order"
|
||||
message="Do you want to send it directly?">
|
||||
</vn-confirm>
|
||||
<vn-confirm
|
||||
vn-id="makeInvoiceConfirmation"
|
||||
on-accept="$ctrl.makeInvoice()"
|
||||
question="You are going to invoice this ticket"
|
||||
message="Are you sure you want to invoice this ticket?">
|
||||
</vn-confirm>
|
||||
<vn-confirm
|
||||
vn-id="regenerateInvoiceConfirmation"
|
||||
on-accept="$ctrl.regenerateInvoice()"
|
||||
question="You are going to regenerate the invoice"
|
||||
message="Are you sure you want to regenerate the invoice?">
|
||||
</vn-confirm>
|
||||
<vn-confirm
|
||||
vn-id="confirmDeliveryNote"
|
||||
on-accept="$ctrl.sendDeliveryNote()"
|
||||
question="Are you sure you want to send it?"
|
||||
message="Send Delivery Note">
|
||||
</vn-confirm>
|
||||
<vn-confirm
|
||||
vn-id="recalculateComponentsConfirmation"
|
||||
on-accept="$ctrl.recalculateComponents()"
|
||||
question="Are you sure you want to recalculate the components?"
|
||||
message="Recalculate components">
|
||||
</vn-confirm>
|
||||
<vn-ticket-sms
|
||||
vn-id="sms"
|
||||
sms="$ctrl.newSMS">
|
||||
</vn-ticket-sms>
|
||||
<vn-add-stowaway
|
||||
vn-id="addStowaway"
|
||||
card-reload="$ctrl.cardReload()"
|
||||
ticket="$ctrl.ticket">
|
||||
</vn-add-stowaway>
|
||||
<vn-dialog
|
||||
vn-id="changeShippedDialog"
|
||||
on-accept="$ctrl.changeShipped()">
|
||||
|
@ -166,40 +294,4 @@
|
|||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="accept" translate>Save</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
||||
|
||||
<!-- Make invoice dialog -->
|
||||
<vn-confirm
|
||||
vn-id="makeInvoiceConfirmation"
|
||||
on-response="$ctrl.makeInvoice($response)"
|
||||
question="You are going to invoice this ticket"
|
||||
message="Are you sure you want to invoice this ticket?">
|
||||
</vn-confirm>
|
||||
<!-- Make invoice dialog -->
|
||||
|
||||
<!-- Regenerate invoice dialog -->
|
||||
<vn-confirm
|
||||
vn-id="regenerateInvoiceConfirmation"
|
||||
on-response="$ctrl.regenerateInvoice($response)"
|
||||
question="You are going to regenerate the invoice"
|
||||
message="Are you sure you want to regenerate the invoice?">
|
||||
</vn-confirm>
|
||||
<!-- Regenerate invoice dialog -->
|
||||
|
||||
<!-- SMS Dialog -->
|
||||
<vn-ticket-sms vn-id="sms" sms="$ctrl.newSMS"></vn-ticket-sms>
|
||||
<!-- SMS Dialog -->
|
||||
|
||||
<vn-confirm
|
||||
vn-id="confirm-delivery-note"
|
||||
on-accept="$ctrl.sendDeliveryNote()"
|
||||
question="Are you sure you want to send it?"
|
||||
message="Send Delivery Note">
|
||||
</vn-confirm>
|
||||
|
||||
<vn-confirm
|
||||
vn-id="recalculate-components-confirmation"
|
||||
on-accept="$ctrl.recalculateComponents()"
|
||||
question="Are you sure you want to recalculate the components?"
|
||||
message="Recalculate components">
|
||||
</vn-confirm>
|
||||
</vn-dialog>
|
|
@ -2,144 +2,24 @@ import ngModule from '../module';
|
|||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
constructor($element, $, $httpParamSerializer) {
|
||||
super($element, $);
|
||||
this.$httpParamSerializer = $httpParamSerializer;
|
||||
|
||||
this.moreOptions = [
|
||||
{
|
||||
name: 'Add turn',
|
||||
callback: this.showAddTurnDialog,
|
||||
acl: 'buyer'
|
||||
}, {
|
||||
name: 'Show Delivery Note',
|
||||
callback: this.showDeliveryNote
|
||||
}, {
|
||||
name: 'Send Delivery Note',
|
||||
callback: this.confirmDeliveryNote
|
||||
}, {
|
||||
name: 'Delete ticket',
|
||||
callback: this.showDeleteTicketDialog
|
||||
}, {
|
||||
name: 'Change shipped hour',
|
||||
callback: this.showChangeShipped
|
||||
}, {
|
||||
name: 'SMS Pending payment',
|
||||
callback: this.sendPaymentSms
|
||||
}, {
|
||||
name: 'SMS Minimum import',
|
||||
callback: this.sendImportSms
|
||||
}, {
|
||||
name: 'Add stowaway',
|
||||
callback: this.showAddStowaway,
|
||||
show: () => this.canShowStowaway
|
||||
}, {
|
||||
name: 'Delete stowaway',
|
||||
callback: this.showDeleteStowaway,
|
||||
show: () => this.shouldShowDeleteStowaway()
|
||||
}, {
|
||||
name: 'Make invoice',
|
||||
callback: this.showMakeInvoiceDialog,
|
||||
show: () => !this.hasInvoice(),
|
||||
acl: 'invoicing'
|
||||
}, {
|
||||
name: 'Regenerate invoice',
|
||||
callback: this.showRegenerateInvoiceDialog,
|
||||
show: () => this.hasInvoice(),
|
||||
acl: 'invoicing'
|
||||
}, {
|
||||
name: 'Recalculate components',
|
||||
callback: this.comfirmRecalculateComponents,
|
||||
show: () => this.isEditable
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
get ticket() {
|
||||
return this._ticket;
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set ticket(value) {
|
||||
this._ticket = value;
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
if (!value) return;
|
||||
|
||||
if (this.$params.sendSMS)
|
||||
this.showSMSDialog();
|
||||
get entity() {
|
||||
return super.entity;
|
||||
}
|
||||
|
||||
set entity(value) {
|
||||
super.entity = value;
|
||||
this.canStowaway();
|
||||
|
||||
let links = {
|
||||
btnOne: {
|
||||
icon: 'person',
|
||||
state: `client.card.summary({id: ${value.clientFk}})`,
|
||||
tooltip: 'Client card'
|
||||
}};
|
||||
|
||||
if (value.stowaway) {
|
||||
links.btnTwo = {
|
||||
icon: 'icon-stowaway',
|
||||
state: `ticket.card.summary({id: ${value.stowaway.shipFk}})`,
|
||||
tooltip: 'Ship stowaways'
|
||||
};
|
||||
}
|
||||
|
||||
if (value.ship) {
|
||||
links.btnThree = {
|
||||
icon: 'icon-stowaway',
|
||||
state: `ticket.card.summary({id: ${value.ship.id}})`,
|
||||
tooltip: 'Stowaway'
|
||||
};
|
||||
}
|
||||
|
||||
this._quicklinks = links;
|
||||
}
|
||||
|
||||
showChangeShipped() {
|
||||
if (!this.isEditable) {
|
||||
this.vnApp.showError(this.$t(`This ticket can't be modified`));
|
||||
return;
|
||||
}
|
||||
|
||||
this.newShipped = this.ticket.shipped;
|
||||
this.$.changeShippedDialog.show();
|
||||
}
|
||||
|
||||
changeShipped() {
|
||||
let data = {shipped: this.newShipped};
|
||||
let query = `Tickets/${this.ticket.id}/updateEditableTicket`;
|
||||
this.$http.post(query, data)
|
||||
.then(() => this.cardReload())
|
||||
.then(() => this.vnApp.showSuccess(this.$t('Shipped hour updated')));
|
||||
}
|
||||
|
||||
isTicketModule() {
|
||||
let path = this.$state.getCurrentPath();
|
||||
const isTicket = path[1].state.name === 'ticket';
|
||||
if (isTicket)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
onMoreChange(callback) {
|
||||
callback.call(this);
|
||||
}
|
||||
|
||||
goToTicket(ticketID) {
|
||||
this.$state.go('ticket.card.sale', {id: ticketID}, {absolute: true});
|
||||
}
|
||||
|
||||
onMoreOpen() {
|
||||
let options = this.moreOptions.filter(option => {
|
||||
const hasShowProperty = Object.hasOwnProperty.call(option, 'show');
|
||||
const hasAclProperty = Object.hasOwnProperty.call(option, 'acl');
|
||||
const hasAcl = !hasAclProperty || (hasAclProperty && this.aclService.hasAny([option.acl]));
|
||||
|
||||
return (!hasShowProperty || option.show === true ||
|
||||
typeof option.show === 'function' && option.show()) && hasAcl;
|
||||
});
|
||||
this.$.moreButton.data = options;
|
||||
if (value && this.$params.sendSMS)
|
||||
this.showSMSDialog();
|
||||
}
|
||||
|
||||
get isEditable() {
|
||||
|
@ -150,204 +30,204 @@ class Controller extends Descriptor {
|
|||
return true;
|
||||
}
|
||||
|
||||
showAddTurnDialog() {
|
||||
this.$.addTurn.show();
|
||||
get isInvoiced() {
|
||||
return this.ticket.refFk !== null;
|
||||
}
|
||||
|
||||
get isTicketModule() {
|
||||
return this.$state.getCurrentPath()[1].state.name === 'ticket';
|
||||
}
|
||||
|
||||
get shouldShowDeleteStowaway() {
|
||||
if (!this.ticket || !this.isTicketModule)
|
||||
return false;
|
||||
|
||||
return this.ticket.stowaway || this.ticket.ship;
|
||||
}
|
||||
|
||||
showChangeShipped() {
|
||||
this.newShipped = this.ticket.shipped;
|
||||
this.$.changeShippedDialog.show();
|
||||
}
|
||||
|
||||
changeShipped() {
|
||||
let data = {
|
||||
shipped: this.newShipped
|
||||
};
|
||||
return this.$http.post(`Tickets/${this.id}/updateEditableTicket`, data)
|
||||
.then(() => this.cardReload())
|
||||
.then(() => this.vnApp.showSuccess(this.$t('Shipped hour updated')));
|
||||
}
|
||||
|
||||
goToTicket(ticketId) {
|
||||
this.$state.go('ticket.card.sale', {id: ticketId}, {absolute: true});
|
||||
}
|
||||
|
||||
addTurn(day) {
|
||||
let params = {
|
||||
ticketFk: this.ticket.id,
|
||||
ticketFk: this.id,
|
||||
weekDay: day,
|
||||
agencyModeFk: this.ticket.agencyModeFk};
|
||||
this.$http.patch(`TicketWeeklies`, params).then(() => {
|
||||
this.$.addTurn.hide();
|
||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||
});
|
||||
agencyModeFk: this.ticket.agencyModeFk
|
||||
};
|
||||
return this.$http.patch(`TicketWeeklies`, params)
|
||||
.then(() => {
|
||||
this.$.addTurn.hide();
|
||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||
});
|
||||
}
|
||||
|
||||
showDeleteTicketDialog() {
|
||||
if (!this.isEditable) {
|
||||
this.vnApp.showError(this.$t('This ticket cant be deleted'));
|
||||
return;
|
||||
}
|
||||
|
||||
this.$.deleteConfirmation.show();
|
||||
}
|
||||
|
||||
deleteTicket(response) {
|
||||
if (response === 'accept') {
|
||||
const query = `Tickets/${this.ticket.id}/setDeleted`;
|
||||
this.$http.post(query).then(() => {
|
||||
deleteTicket() {
|
||||
return this.$http.post(`Tickets/${this.id}/setDeleted`)
|
||||
.then(() => {
|
||||
this.$state.go('ticket.index');
|
||||
this.vnApp.showSuccess(this.$t('Ticket deleted'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
canStowaway() {
|
||||
if (!this.isTicketModule()) return;
|
||||
this.canShowStowaway = false;
|
||||
if (!this.isTicketModule || !this.ticket) return;
|
||||
|
||||
this.$http.get(`Tickets/${this.ticket.id}/canHaveStowaway`).then(response => {
|
||||
if (response.data === true)
|
||||
return this.canShowStowaway = true;
|
||||
|
||||
return this.canShowStowaway = false;
|
||||
});
|
||||
}
|
||||
|
||||
shouldShowDeleteStowaway() {
|
||||
if (!this._ticket || !this.isTicketModule())
|
||||
return false;
|
||||
|
||||
return this._ticket.stowaway || this._ticket.ship;
|
||||
}
|
||||
|
||||
showAddStowaway() {
|
||||
this.$.addStowaway.show();
|
||||
}
|
||||
|
||||
showDeleteStowaway() {
|
||||
this.$.deleteStowaway.show();
|
||||
this.$http.get(`Tickets/${this.id}/canHaveStowaway`)
|
||||
.then(res => this.canShowStowaway = !!res.data);
|
||||
}
|
||||
|
||||
deleteStowaway() {
|
||||
const query = `Tickets/${this.ticket.id}/deleteStowaway`;
|
||||
this.$http.post(query).then(res => {
|
||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||
this.cardReload();
|
||||
});
|
||||
return this.$http.post(`Tickets/${this.id}/deleteStowaway`)
|
||||
.then(() => {
|
||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||
this.cardReload();
|
||||
});
|
||||
}
|
||||
|
||||
showDeliveryNote() {
|
||||
const params = {
|
||||
this.showReport('delivery-note', {
|
||||
clientId: this.ticket.client.id,
|
||||
ticketId: this.ticket.id,
|
||||
authorization: this.vnToken.token
|
||||
};
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
let url = `api/report/delivery-note?${serializedParams}`;
|
||||
window.open(url);
|
||||
ticketId: this.id,
|
||||
});
|
||||
}
|
||||
|
||||
sendDeliveryNote() {
|
||||
const params = {
|
||||
return this.sendEmail('delivery-note', {
|
||||
recipient: this.ticket.client.email,
|
||||
clientId: this.ticket.client.id,
|
||||
ticketId: this.ticket.id
|
||||
};
|
||||
this.$http.get(`email/delivery-note`, {params}).then(
|
||||
() => this.vnApp.showMessage(this.$t('Notification sent!'))
|
||||
);
|
||||
ticketId: this.id
|
||||
});
|
||||
}
|
||||
|
||||
sendImportSms() {
|
||||
const params = {
|
||||
ticketId: this.ticket.id,
|
||||
ticketId: this.id,
|
||||
created: this.ticket.created
|
||||
};
|
||||
const message = this.$params.message || this.$t('Minimum is needed', params);
|
||||
this.newSMS = {message};
|
||||
this.showSMSDialog();
|
||||
this.showSMSDialog({
|
||||
message: this.$params.message || this.$t('Minimum is needed', params)
|
||||
});
|
||||
}
|
||||
|
||||
sendPaymentSms() {
|
||||
const message = this.$params.message || this.$t('Make a payment');
|
||||
this.newSMS = {message};
|
||||
this.showSMSDialog();
|
||||
this.showSMSDialog({
|
||||
message: this.$params.message || this.$t('Make a payment')
|
||||
});
|
||||
}
|
||||
|
||||
showSMSDialog() {
|
||||
showSMSDialog(params) {
|
||||
const address = this.ticket.address;
|
||||
const client = this.ticket.client;
|
||||
const phone = this.$params.phone || address.mobile || address.phone ||
|
||||
client.mobile || client.phone;
|
||||
const phone = this.$params.phone
|
||||
|| address.mobile
|
||||
|| address.phone
|
||||
|| client.mobile
|
||||
|| client.phone;
|
||||
|
||||
this.newSMS.destinationFk = this.ticket.clientFk;
|
||||
this.newSMS.destination = phone;
|
||||
this.newSMS = Object.assign({
|
||||
destinationFk: this.ticket.clientFk,
|
||||
destination: phone
|
||||
}, params);
|
||||
this.$.sms.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows an invoice confirmation
|
||||
*/
|
||||
showMakeInvoiceDialog() {
|
||||
this.$.makeInvoiceConfirmation.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an invoice
|
||||
* from current ticket
|
||||
*
|
||||
* @param {String} response - Response result
|
||||
*/
|
||||
makeInvoice(response) {
|
||||
if (response === 'accept') {
|
||||
const query = `Tickets/${this.ticket.id}/makeInvoice`;
|
||||
this.$http.post(query).then(() => {
|
||||
makeInvoice() {
|
||||
return this.$http.post(`Tickets/${this.id}/makeInvoice`)
|
||||
.then(() => {
|
||||
this.vnApp.showSuccess(this.$t('Ticket invoiced'));
|
||||
this.$state.reload();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows an invoice confirmation
|
||||
*/
|
||||
showRegenerateInvoiceDialog() {
|
||||
this.$.regenerateInvoiceConfirmation.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an invoice to a regeneration queue
|
||||
* for the current ticket
|
||||
*
|
||||
* @param {String} response - Response result
|
||||
*/
|
||||
regenerateInvoice(response) {
|
||||
if (response === 'accept') {
|
||||
const invoiceId = this.ticket.invoiceOut.id;
|
||||
const query = `InvoiceOuts/${invoiceId}/regenerate`;
|
||||
this.$http.post(query).then(() => {
|
||||
regenerateInvoice() {
|
||||
const invoiceId = this.ticket.invoiceOut.id;
|
||||
return this.$http.post(`InvoiceOuts/${invoiceId}/regenerate`)
|
||||
.then(() => {
|
||||
const snackbarMessage = this.$t(
|
||||
`Invoice sent for a regeneration, will be available in a few minutes`);
|
||||
this.vnApp.showSuccess(snackbarMessage);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the current ticket
|
||||
* is already invoiced
|
||||
* @return {Boolean} - True if invoiced
|
||||
*/
|
||||
hasInvoice() {
|
||||
return this.ticket.refFk !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a delivery-note send confirmation
|
||||
*/
|
||||
confirmDeliveryNote() {
|
||||
this.$.confirmDeliveryNote.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows an invoice confirmation
|
||||
*/
|
||||
comfirmRecalculateComponents() {
|
||||
this.$.recalculateComponentsConfirmation.show();
|
||||
}
|
||||
|
||||
recalculateComponents() {
|
||||
const query = `Tickets/${this.ticket.id}/recalculateComponents`;
|
||||
this.$http.post(query).then(res => {
|
||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||
});
|
||||
return this.$http.post(`Tickets/${this.id}/recalculateComponents`)
|
||||
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
|
||||
}
|
||||
|
||||
cardReload() {
|
||||
// Prevents error when not defined
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'warehouse',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}, {
|
||||
relation: 'agencyMode',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}, {
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: [
|
||||
'salesPersonFk',
|
||||
'name',
|
||||
'isActive',
|
||||
'isFreezed',
|
||||
'isTaxDataChecked'
|
||||
],
|
||||
include: {
|
||||
relation: 'salesPerson',
|
||||
scope: {
|
||||
fields: ['userFk'],
|
||||
include: {
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['nickname']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
relation: 'state',
|
||||
scope: {
|
||||
fields: ['stateFk'],
|
||||
include: {
|
||||
relation: 'state',
|
||||
fields: ['id', 'name'],
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Tickets/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$element', '$scope', '$httpParamSerializer'];
|
||||
|
||||
ngModule.vnComponent('vnTicketDescriptor', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
|
|
|
@ -1,47 +1,40 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Ticket Component vnTicketDescriptor', () => {
|
||||
let $httpParamSerializer;
|
||||
let $httpBackend;
|
||||
let controller;
|
||||
let $state;
|
||||
|
||||
const ticket = {
|
||||
id: 2,
|
||||
clientFk: 101,
|
||||
invoiceOut: {id: 1},
|
||||
client: {
|
||||
id: 101,
|
||||
email: 'client@email'
|
||||
},
|
||||
address: {
|
||||
id: 101,
|
||||
mobile: 111111111,
|
||||
phone: 2222222222
|
||||
},
|
||||
tracking: {
|
||||
state: {alertLevel: 3}
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach(ngModule('ticket'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $rootScope, $compile, _$state_, _$httpParamSerializer_) => {
|
||||
let $element = $compile(`<vn-autocomplete></vn-autocomplete>`)($rootScope);
|
||||
$state = _$state_;
|
||||
$state.getCurrentPath = () => {
|
||||
return [
|
||||
{state: {}},
|
||||
{state: {name: 'ticket'}}
|
||||
];
|
||||
};
|
||||
beforeEach(angular.mock.inject(($componentController, _$httpBackend_, _$state_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpParamSerializer = _$httpParamSerializer_;
|
||||
controller = $componentController('vnTicketDescriptor', {$element});
|
||||
controller._ticket = {
|
||||
id: 2,
|
||||
clientFk: 101,
|
||||
invoiceOut: {id: 1},
|
||||
client: {id: 101, email: 'client@email'},
|
||||
address: {id: 101, mobile: 111111111, phone: 2222222222}
|
||||
};
|
||||
controller.cardReload = ()=> {
|
||||
return true;
|
||||
};
|
||||
$httpBackend.whenGET(`Tickets/${ticket.id}/canHaveStowaway`).respond(true);
|
||||
|
||||
$state = _$state_;
|
||||
$state.getCurrentPath = () => [null, {state: {name: 'ticket'}}];
|
||||
|
||||
controller = $componentController('vnTicketDescriptor', {$element: null}, {ticket});
|
||||
}));
|
||||
|
||||
describe('showAddTurnDialog()', () => {
|
||||
it('should call controller.$.addTurn.show()', () => {
|
||||
controller.$.addTurn = {show: () => {}};
|
||||
jest.spyOn(controller.$.addTurn, 'show');
|
||||
controller.showAddTurnDialog();
|
||||
|
||||
expect(controller.$.addTurn.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('addTurn()', () => {
|
||||
it('should make a query and call $.addTurn.hide() and vnApp.showSuccess()', () => {
|
||||
controller.$.addTurn = {hide: () => {}};
|
||||
|
@ -55,176 +48,114 @@ describe('Ticket Component vnTicketDescriptor', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('showDeleteTicketDialog()', () => {
|
||||
it('should call vnApp.showError() if the ticket isnt editable', () => {
|
||||
controller.ticket.tracking = {state: {alertLevel: 3}};
|
||||
jest.spyOn(controller.vnApp, 'showError');
|
||||
controller.showDeleteTicketDialog();
|
||||
|
||||
expect(controller.vnApp.showError).toHaveBeenCalledWith('This ticket cant be deleted');
|
||||
});
|
||||
|
||||
it('should call deleteConfirmation.show() if the ticket is editable', () => {
|
||||
controller.ticket.tracking = {state: {alertLevel: 0}};
|
||||
controller.$.deleteConfirmation = {show: () => {}};
|
||||
jest.spyOn(controller.$.deleteConfirmation, 'show');
|
||||
controller.showDeleteTicketDialog();
|
||||
|
||||
expect(controller.$.deleteConfirmation.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteTicket()', () => {
|
||||
it('should make a query and call vnApp.showSuccess() if the response is accept', () => {
|
||||
it('should make a query and call vnApp.showSuccess()', () => {
|
||||
jest.spyOn(controller.$state, 'go').mockReturnValue('ok');
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
|
||||
$httpBackend.expectPOST(`Tickets/2/setDeleted`).respond();
|
||||
controller.deleteTicket('accept');
|
||||
$httpBackend.expectPOST(`Tickets/${ticket.id}/setDeleted`).respond();
|
||||
controller.deleteTicket();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('ticket.index');
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Ticket deleted');
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('showDeliveryNote()', () => {
|
||||
it('should open a new window showing a delivery note PDF document', () => {
|
||||
jest.spyOn(controller, 'showReport');
|
||||
|
||||
const params = {
|
||||
clientId: controller.ticket.client.id,
|
||||
ticketId: controller.ticket.id
|
||||
clientId: ticket.client.id,
|
||||
ticketId: ticket.id
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
let expectedPath = `api/report/delivery-note?${serializedParams}`;
|
||||
jest.spyOn(window, 'open').mockReturnThis();
|
||||
controller.showDeliveryNote();
|
||||
|
||||
expect(window.open).toHaveBeenCalledWith(expectedPath);
|
||||
expect(controller.showReport).toHaveBeenCalledWith('delivery-note', params);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sendDeliveryNote()', () => {
|
||||
it('should make a query and call vnApp.showMessage()', () => {
|
||||
jest.spyOn(controller.vnApp, 'showMessage');
|
||||
jest.spyOn(controller, 'sendEmail');
|
||||
|
||||
const params = {
|
||||
recipient: 'client@email',
|
||||
clientId: controller.ticket.client.id,
|
||||
ticketId: controller.ticket.id
|
||||
recipient: ticket.client.email,
|
||||
clientId: ticket.client.id,
|
||||
ticketId: ticket.id
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
|
||||
$httpBackend.when('GET', `email/delivery-note?${serializedParams}`).respond();
|
||||
$httpBackend.expect('GET', `email/delivery-note?${serializedParams}`).respond();
|
||||
controller.sendDeliveryNote();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('Notification sent!');
|
||||
expect(controller.sendEmail).toHaveBeenCalledWith('delivery-note', params);
|
||||
});
|
||||
});
|
||||
|
||||
describe('makeInvoice()', () => {
|
||||
it('should make a query and call $state.reload() method if the response is accept', () => {
|
||||
it('should make a query and call $state.reload() method', () => {
|
||||
jest.spyOn(controller.$state, 'reload').mockReturnThis();
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
|
||||
$httpBackend.when('POST', 'Tickets/2/makeInvoice').respond();
|
||||
$httpBackend.expect('POST', 'Tickets/2/makeInvoice').respond();
|
||||
controller.makeInvoice('accept');
|
||||
$httpBackend.expectPOST(`Tickets/${ticket.id}/makeInvoice`).respond();
|
||||
controller.makeInvoice();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Ticket invoiced');
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
expect(controller.$state.reload).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('regenerateInvoice()', () => {
|
||||
it('should make a query and show a success snackbar if the response is accept', () => {
|
||||
it('should make a query and show a success snackbar', () => {
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
|
||||
$httpBackend.when('POST', 'InvoiceOuts/1/regenerate').respond();
|
||||
$httpBackend.expect('POST', 'InvoiceOuts/1/regenerate').respond();
|
||||
controller.regenerateInvoice('accept');
|
||||
$httpBackend.expectPOST(`InvoiceOuts/${ticket.invoiceOut.id}/regenerate`).respond();
|
||||
controller.regenerateInvoice();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Invoice sent for a regeneration, will be available in a few minutes');
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('changeShipped()', () => {
|
||||
it('should make a query and change the shipped hour if the response is accept', () => {
|
||||
controller.ticket.id = 12;
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
jest.spyOn(controller, 'cardReload');
|
||||
|
||||
$httpBackend.expectRoute('POST', 'Tickets/:id/updateEditableTicket').respond();
|
||||
controller.changeShipped('accept');
|
||||
$httpBackend.expectPOST(`Tickets/${ticket.id}/updateEditableTicket`).respond();
|
||||
controller.changeShipped();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Shipped hour updated');
|
||||
expect(controller.cardReload).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('showAddStowaway()', () => {
|
||||
it('should show a dialog with a list of tickets available for an stowaway', () => {
|
||||
controller.$.addStowaway = {};
|
||||
controller.$.addStowaway.show = jasmine.createSpy('show');
|
||||
controller.showAddStowaway();
|
||||
|
||||
expect(controller.$.addStowaway.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('showRemoveStowaway()', () => {
|
||||
it('should show a dialog for an stowaway removal', () => {
|
||||
controller.$.deleteStowaway = {};
|
||||
controller.$.deleteStowaway.show = jasmine.createSpy('show');
|
||||
controller.showDeleteStowaway();
|
||||
|
||||
expect(controller.$.deleteStowaway.show).toHaveBeenCalledWith();
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
expect(controller.cardReload).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('canStowaway()', () => {
|
||||
it('should make a query and return if the ticket can be stowawayed', () => {
|
||||
controller.ticket.id = 16;
|
||||
jest.spyOn(controller, 'isTicketModule');
|
||||
$httpBackend.when('GET', 'Tickets/16/canHaveStowaway').respond(true);
|
||||
$httpBackend.expect('GET', 'Tickets/16/canHaveStowaway').respond(true);
|
||||
fit('should make a query and return if the ticket can be stowawayed', () => {
|
||||
controller.canStowaway();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.canShowStowaway).toBeTruthy();
|
||||
expect(controller.isTicketModule).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should not make a query if is not on the ticket module', () => {
|
||||
controller.ticket.id = 16;
|
||||
$state.getCurrentPath = () => {
|
||||
return [
|
||||
{state: {}},
|
||||
{state: {name: 'client'}}
|
||||
];
|
||||
};
|
||||
jest.spyOn(controller, 'isTicketModule');
|
||||
$state.getCurrentPath = () => [null, {state: {name: 'client'}}];
|
||||
controller.canStowaway();
|
||||
|
||||
expect(controller.canShowStowaway).toBeUndefined();
|
||||
expect(controller.isTicketModule).toHaveBeenCalledWith();
|
||||
expect(controller.canShowStowaway).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('recalculateComponents()', () => {
|
||||
it('should make a query and show a success snackbar', () => {
|
||||
it('should make a query and show a success message', () => {
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
|
||||
$httpBackend.when('POST', 'Tickets/2/recalculateComponents').respond();
|
||||
$httpBackend.expect('POST', 'Tickets/2/recalculateComponents').respond();
|
||||
$httpBackend.expectPOST(`Tickets/${ticket.id}/recalculateComponents`).respond();
|
||||
controller.recalculateComponents();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -233,14 +164,25 @@ describe('Ticket Component vnTicketDescriptor', () => {
|
|||
controller.$.sms = {open: () => {}};
|
||||
jest.spyOn(controller.$.sms, 'open');
|
||||
|
||||
const clientId = 101;
|
||||
const expectedPhone = 111111111;
|
||||
controller.newSMS = {};
|
||||
controller.showSMSDialog();
|
||||
|
||||
expect(controller.newSMS.destinationFk).toEqual(clientId);
|
||||
expect(controller.newSMS.destination).toEqual(expectedPhone);
|
||||
expect(controller.$.sms.open).toHaveBeenCalledWith();
|
||||
expect(controller.newSMS).toEqual({
|
||||
destinationFk: ticket.clientFk,
|
||||
destination: ticket.address.mobile
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadData()', () => {
|
||||
it(`should perform a get query to store the ticket data into the controller`, () => {
|
||||
controller.ticket = null;
|
||||
|
||||
$httpBackend.expectRoute('GET', `Tickets/${ticket.id}`).respond(ticket);
|
||||
controller.id = ticket.id;
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.ticket).toEqual(ticket);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<vn-td number>
|
||||
<span
|
||||
ng-class="{link: expedition.itemFk}"
|
||||
ng-click="$ctrl.showItemDescriptor($event, expedition.itemFk)">
|
||||
ng-click="itemDescriptor.show($event, expedition.itemFk)">
|
||||
{{expedition.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
</vn-td>
|
||||
|
@ -60,7 +60,8 @@
|
|||
</vn-data-viewer>
|
||||
<vn-item-descriptor-popover
|
||||
vn-id="itemDescriptor"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
warehouse-fk="this.ticket.warehouseFk",
|
||||
ticket-fk="$ctrl.ticket.id">
|
||||
</vn-item-descriptor-popover>
|
||||
<vn-worker-descriptor-popover
|
||||
vn-id="workerDescriptor">
|
||||
|
|
|
@ -6,24 +6,6 @@ class Controller extends Section {
|
|||
return this.$http.delete(`Expeditions/${id}`)
|
||||
.then(() => this.$.model.refresh());
|
||||
}
|
||||
|
||||
showItemDescriptor(event, itemFk) {
|
||||
if (!itemFk) return;
|
||||
this.quicklinks = {
|
||||
btnThree: {
|
||||
icon: 'icon-transaction',
|
||||
state: `item.card.diary({
|
||||
id: ${itemFk},
|
||||
warehouseFk: ${this.ticket.warehouseFk},
|
||||
ticketFk: ${this.ticket.id}
|
||||
})`,
|
||||
tooltip: 'Item diary',
|
||||
},
|
||||
};
|
||||
this.$.itemDescriptor.itemFk = itemFk;
|
||||
this.$.itemDescriptor.parent = event.target;
|
||||
this.$.itemDescriptor.show();
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnTicketExpedition', {
|
||||
|
|
|
@ -151,4 +151,3 @@
|
|||
<vn-client-balance-create
|
||||
vn-id="balanceCreateDialog">
|
||||
</vn-client-balance-create>
|
||||
<vn-scroll-up></vn-scroll-up>
|
|
@ -15,7 +15,7 @@
|
|||
<span translate>No results</span>
|
||||
</vn-card>
|
||||
<vn-horizontal class="catalog-list">
|
||||
<section class="product" ng-repeat="sale in sales">
|
||||
<section ng-repeat="sale in sales" class="product">
|
||||
<vn-card>
|
||||
<div class="image">
|
||||
<img
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<vn-td number>
|
||||
<span
|
||||
ng-show="::request.saleFk"
|
||||
ng-click="$ctrl.showItemDescriptor($event, request.sale.itemFk)"
|
||||
ng-click="itemDescriptor.show($event, request.sale.itemFk)"
|
||||
class="link">
|
||||
{{::request.saleFk | zeroFill:6}}
|
||||
</span>
|
||||
|
@ -102,7 +102,7 @@
|
|||
</vn-data-viewer>
|
||||
<vn-item-descriptor-popover
|
||||
vn-id="itemDescriptor"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
ticket-fk="$ctrl.$params.id">
|
||||
</vn-item-descriptor-popover>
|
||||
<vn-worker-descriptor-popover
|
||||
vn-id="workerDescriptor">
|
||||
|
|
|
@ -42,22 +42,6 @@ class Controller extends Section {
|
|||
});
|
||||
}
|
||||
|
||||
showItemDescriptor(event, itemFk) {
|
||||
this.quicklinks = {
|
||||
btnThree: {
|
||||
icon: 'icon-transaction',
|
||||
state: `item.card.diary({
|
||||
id: ${itemFk},
|
||||
ticketFk: ${this.$params.id}
|
||||
})`,
|
||||
tooltip: 'Item diary'
|
||||
}
|
||||
};
|
||||
this.$.itemDescriptor.itemFk = itemFk;
|
||||
this.$.itemDescriptor.parent = event.target;
|
||||
this.$.itemDescriptor.show();
|
||||
}
|
||||
|
||||
getRequestState(state) {
|
||||
switch (state) {
|
||||
case null:
|
||||
|
|
|
@ -50,5 +50,6 @@
|
|||
</vn-data-viewer>
|
||||
<vn-item-descriptor-popover
|
||||
vn-id="descriptor"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
warehouse-fk="$ctrl.ticket.warehouseFk"
|
||||
ticket-fk="$ctrl.ticket.id">
|
||||
</vn-item-descriptor-popover>
|
||||
|
|
|
@ -5,34 +5,18 @@ class Controller extends Section {
|
|||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.filter = {
|
||||
include: [{
|
||||
relation: 'item'
|
||||
},
|
||||
{
|
||||
relation: 'isChecked',
|
||||
scope: {
|
||||
fields: ['isChecked']
|
||||
include: [
|
||||
{
|
||||
relation: 'item'
|
||||
}, {
|
||||
relation: 'isChecked',
|
||||
scope: {
|
||||
fields: ['isChecked']
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
showDescriptor(event, itemFk) {
|
||||
this.quicklinks = {
|
||||
btnThree: {
|
||||
icon: 'icon-transaction',
|
||||
state: `item.card.diary({
|
||||
id: ${itemFk},
|
||||
warehouseFk: ${this.ticket.warehouseFk},
|
||||
ticketFk: ${this.ticket.id}
|
||||
})`,
|
||||
tooltip: 'Item diary'
|
||||
}
|
||||
};
|
||||
this.$.descriptor.itemFk = itemFk;
|
||||
this.$.descriptor.parent = event.target;
|
||||
this.$.descriptor.show();
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnTicketSaleChecked', {
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
</vn-td>
|
||||
<vn-td number>
|
||||
<span
|
||||
ng-click="$ctrl.showItemDescriptor($event, sale.itemFk)"
|
||||
ng-click="itemDescriptor.show($event, sale.itemFk)"
|
||||
class="link">
|
||||
{{sale.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
|
@ -65,7 +65,8 @@
|
|||
</vn-data-viewer>
|
||||
<vn-item-descriptor-popover
|
||||
vn-id="itemDescriptor"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
warehouse-fk="$ctrl.ticket.warehouseFk",
|
||||
ticket-fk="$ctrl.ticket.id">
|
||||
</vn-item-descriptor-popover>
|
||||
<vn-worker-descriptor-popover
|
||||
vn-id="workerDescriptor">
|
||||
|
|
|
@ -1,24 +1,7 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
class Controller extends Section {
|
||||
showItemDescriptor(event, itemFk) {
|
||||
this.quicklinks = {
|
||||
btnThree: {
|
||||
icon: 'icon-transaction',
|
||||
state: `item.card.diary({
|
||||
id: ${itemFk},
|
||||
warehouseFk: ${this.ticket.warehouseFk},
|
||||
ticketFk: ${this.ticket.id}
|
||||
})`,
|
||||
tooltip: 'Item diary',
|
||||
},
|
||||
};
|
||||
this.$.itemDescriptor.itemFk = itemFk;
|
||||
this.$.itemDescriptor.parent = event.target;
|
||||
this.$.itemDescriptor.show();
|
||||
}
|
||||
}
|
||||
class Controller extends Section {}
|
||||
|
||||
ngModule.component('vnTicketSaleTracking', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
</vn-td>
|
||||
<vn-td vn-focus number>
|
||||
<span class="link" ng-if="sale.id"
|
||||
ng-click="$ctrl.showDescriptor($event, sale.itemFk)">
|
||||
ng-click="descriptor.show($event, sale.itemFk)">
|
||||
{{sale.itemFk}}
|
||||
</span>
|
||||
<vn-autocomplete
|
||||
|
@ -201,7 +201,8 @@
|
|||
</vn-float-button>
|
||||
<vn-item-descriptor-popover
|
||||
vn-id="descriptor"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
warehouse-fk="$ctrl.ticket.warehouseFk",
|
||||
ticket-fk="$ctrl.ticket.id">
|
||||
</vn-item-descriptor-popover>
|
||||
|
||||
<!-- Edit Price Popover -->
|
||||
|
|
|
@ -284,24 +284,6 @@ class Controller extends Section {
|
|||
});
|
||||
}
|
||||
|
||||
// Item Descriptor
|
||||
showDescriptor(event, itemFk) {
|
||||
this.quicklinks = {
|
||||
btnThree: {
|
||||
icon: 'icon-transaction',
|
||||
state: `item.card.diary({
|
||||
id: ${itemFk},
|
||||
warehouseFk: ${this.ticket.warehouseFk},
|
||||
ticketFk: ${this.ticket.id}
|
||||
})`,
|
||||
tooltip: 'Item diary'
|
||||
}
|
||||
};
|
||||
this.$.descriptor.itemFk = itemFk;
|
||||
this.$.descriptor.parent = event.target;
|
||||
this.$.descriptor.show();
|
||||
}
|
||||
|
||||
showEditPricePopover(event, sale) {
|
||||
if (!this.isEditable) return;
|
||||
this.sale = sale;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
</vn-label-value>
|
||||
<vn-label-value label="Route">
|
||||
<span
|
||||
ng-click="$ctrl.showRouteDescriptor($event)"
|
||||
ng-click="routeDescriptor.show($event, $ctrl.summary.routeFk)"
|
||||
class="link">
|
||||
{{$ctrl.summary.routeFk}}
|
||||
</span>
|
||||
|
@ -117,7 +117,7 @@
|
|||
</vn-td>
|
||||
<vn-td number shrink>
|
||||
<span
|
||||
ng-click="$ctrl.showDescriptor($event, sale.itemFk)"
|
||||
ng-click="descriptor.show($event, sale.itemFk)"
|
||||
class="link">
|
||||
{{sale.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
|
@ -208,7 +208,7 @@
|
|||
<vn-td number>
|
||||
<span
|
||||
ng-show="::request.saleFk"
|
||||
ng-click="$ctrl.showDescriptor($event, request.sale.itemFk)"
|
||||
ng-click="descriptor.show($event, request.sale.itemFk)"
|
||||
class="link">
|
||||
{{request.sale.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
|
@ -228,10 +228,10 @@
|
|||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-route-descriptor-popover
|
||||
vn-id="route-descriptor"
|
||||
quicklinks="$ctrl.routeQuicklinks">
|
||||
vn-id="routeDescriptor">
|
||||
</vn-route-descriptor-popover>
|
||||
<vn-item-descriptor-popover
|
||||
vn-id="descriptor"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
warehouse-fk="$ctrl.ticket.warehouseFk",
|
||||
ticket-fk="$ctrl.ticket.id">
|
||||
</vn-item-descriptor-popover>
|
||||
|
|
|
@ -29,38 +29,6 @@ class Controller extends Section {
|
|||
});
|
||||
}
|
||||
|
||||
showRouteDescriptor(event) {
|
||||
this.routeQuicklinks = {
|
||||
btnThree: {
|
||||
icon: 'icon-delivery',
|
||||
state: `route.card.summary({
|
||||
id: ${this.summary.routeFk},
|
||||
})`,
|
||||
tooltip: 'Route summary'
|
||||
}
|
||||
};
|
||||
this.$.routeDescriptor.routeFk = this.summary.routeFk;
|
||||
this.$.routeDescriptor.parent = event.target;
|
||||
this.$.routeDescriptor.show();
|
||||
}
|
||||
|
||||
showDescriptor(event, itemFk) {
|
||||
this.quicklinks = {
|
||||
btnThree: {
|
||||
icon: 'icon-transaction',
|
||||
state: `item.card.diary({
|
||||
id: ${itemFk},
|
||||
warehouseFk: ${this.ticket.warehouseFk},
|
||||
ticketFk: ${this.ticket.id}
|
||||
})`,
|
||||
tooltip: 'Item diary'
|
||||
}
|
||||
};
|
||||
this.$.descriptor.itemFk = itemFk;
|
||||
this.$.descriptor.parent = event.target;
|
||||
this.$.descriptor.show();
|
||||
}
|
||||
|
||||
get isEditable() {
|
||||
try {
|
||||
return !this.ticket.state.state.alertLevel;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<vn-tr ng-repeat="sale in $ctrl.sales">
|
||||
<vn-td number>
|
||||
<span
|
||||
ng-click="$ctrl.showDescriptor($event, sale.itemFk)"
|
||||
ng-click="descriptor.show($event, sale.itemFk)"
|
||||
class="link">
|
||||
{{sale.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
|
@ -60,6 +60,7 @@
|
|||
</vn-vertical>
|
||||
<vn-item-descriptor-popover
|
||||
vn-id="descriptor"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
warehouse-fk="$ctrl.ticket.warehouseFk",
|
||||
ticket-fk="$ctrl.ticket.id">
|
||||
</vn-item-descriptor-popover>
|
||||
|
||||
|
|
|
@ -43,23 +43,6 @@ class Controller extends Section {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
showDescriptor(event, itemFk) {
|
||||
this.quicklinks = {
|
||||
btnThree: {
|
||||
icon: 'icon-transaction',
|
||||
state: `item.card.diary({
|
||||
id: ${itemFk},
|
||||
warehouseFk: ${this.ticket.warehouseFk},
|
||||
ticketFk: ${this.ticket.id}
|
||||
})`,
|
||||
tooltip: 'Item diary'
|
||||
}
|
||||
};
|
||||
this.$.descriptor.itemFk = itemFk;
|
||||
this.$.descriptor.parent = event.target;
|
||||
this.$.descriptor.show();
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnTicketVolume', {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
<slot-descriptor>
|
||||
<vn-travel-descriptor
|
||||
travel="$ctrl.travel"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
<vn-travel-descriptor>
|
||||
</vn-travel-descriptor>
|
||||
</slot-descriptor>
|
|
@ -1,41 +1,7 @@
|
|||
import ngModule from '../module';
|
||||
import DescriptorPopover from 'salix/components/descriptor-popover';
|
||||
|
||||
class Controller extends DescriptorPopover {
|
||||
get travel() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
fields: [
|
||||
'id',
|
||||
'ref',
|
||||
'shipped',
|
||||
'landed',
|
||||
'totalEntries',
|
||||
'warehouseInFk',
|
||||
'warehouseOutFk'
|
||||
],
|
||||
include: [
|
||||
{
|
||||
relation: 'warehouseIn',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}, {
|
||||
relation: 'warehouseOut',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Travels/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
class Controller extends DescriptorPopover {}
|
||||
|
||||
ngModule.vnComponent('vnTravelDescriptorPopover', {
|
||||
slotTemplate: require('./index.html'),
|
||||
|
|
|
@ -1,36 +1,34 @@
|
|||
<div class="vn-descriptor">
|
||||
<div class="header">
|
||||
<a translate-attr="{title: 'Return to module index'}" ui-sref="travel.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a translate-attr="{title: 'Preview'}" ui-sref="travel.card.summary({id: $ctrl.travel.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<span></span>
|
||||
</div>
|
||||
<div class="body">
|
||||
<vn-descriptor-content module="travel">
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<vn-label-value label="Id"
|
||||
<vn-label-value
|
||||
label="Id"
|
||||
value="{{$ctrl.travel.id}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Reference"
|
||||
<vn-label-value
|
||||
label="Reference"
|
||||
value="{{$ctrl.travel.ref}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Wh. In"
|
||||
<vn-label-value
|
||||
label="Wh. In"
|
||||
value="{{$ctrl.travel.warehouseOut.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Wh. Out"
|
||||
<vn-label-value
|
||||
label="Wh. Out"
|
||||
value="{{$ctrl.travel.warehouseIn.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Shipped"
|
||||
<vn-label-value
|
||||
label="Shipped"
|
||||
value="{{$ctrl.travel.shipped | date: 'dd/MM/yyyy'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Landed"
|
||||
<vn-label-value
|
||||
label="Landed"
|
||||
value="{{$ctrl.travel.landed | date: 'dd/MM/yyyy'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Total entries"
|
||||
<vn-label-value
|
||||
label="Total entries"
|
||||
value="{{$ctrl.travel.totalEntries}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
|
|
|
@ -1,13 +1,50 @@
|
|||
import ngModule from '../module';
|
||||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
get travel() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set travel(value) {
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
fields: [
|
||||
'id',
|
||||
'ref',
|
||||
'shipped',
|
||||
'landed',
|
||||
'totalEntries',
|
||||
'warehouseInFk',
|
||||
'warehouseOutFk'
|
||||
],
|
||||
include: [
|
||||
{
|
||||
relation: 'warehouseIn',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}, {
|
||||
relation: 'warehouseOut',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Travels/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnTravelDescriptor', {
|
||||
template: require('./index.html'),
|
||||
controller: Descriptor,
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
travel: '<'
|
||||
},
|
||||
require: {
|
||||
card: '^?vnTravelCard'
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import './index.js';
|
||||
|
||||
describe('vnTravelDescriptorPopover', () => {
|
||||
describe('vnTravelDescriptor', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
|
@ -8,10 +8,7 @@ describe('vnTravelDescriptorPopover', () => {
|
|||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnTravelDescriptorPopover', {
|
||||
$element: null,
|
||||
$transclude: null
|
||||
});
|
||||
controller = $componentController('vnTravelDescriptor', {$element: null});
|
||||
}));
|
||||
|
||||
describe('loadData()', () => {
|
||||
|
@ -19,7 +16,7 @@ describe('vnTravelDescriptorPopover', () => {
|
|||
const id = 1;
|
||||
const response = 'foo';
|
||||
|
||||
$httpBackend.expectGET(`Travels/${id}`).respond(response);
|
||||
$httpBackend.expectRoute('GET', `Travels/${id}`).respond(response);
|
||||
controller.id = id;
|
||||
$httpBackend.flush();
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
<slot-descriptor>
|
||||
<vn-worker-descriptor
|
||||
worker="$ctrl.worker"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
<vn-worker-descriptor>
|
||||
</vn-worker-descriptor>
|
||||
</slot-descriptor>
|
|
@ -1,46 +1,7 @@
|
|||
import ngModule from '../module';
|
||||
import DescriptorPopover from 'salix/components/descriptor-popover';
|
||||
|
||||
class Controller extends DescriptorPopover {
|
||||
get worker() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
include: {
|
||||
relation: 'emailUser',
|
||||
scope: {
|
||||
fields: ['email']
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
relation: 'client',
|
||||
scope: {fields: ['fi']}
|
||||
}, {
|
||||
relation: 'sip',
|
||||
scope: {fields: ['extension']}
|
||||
}, {
|
||||
relation: 'department',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'department'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Workers/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
class Controller extends DescriptorPopover {}
|
||||
|
||||
ngModule.vnComponent('vnWorkerDescriptorPopover', {
|
||||
slotTemplate: require('./index.html'),
|
||||
|
|
|
@ -1,40 +1,45 @@
|
|||
<div class="vn-descriptor">
|
||||
<vn-horizontal class="header">
|
||||
<a translate-attr="{title: 'Return to module index'}" ui-sref="worker.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a translate-attr="{title: 'Preview'}" ui-sref="worker.card.summary({id: $ctrl.worker.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<span></span>
|
||||
</vn-horizontal>
|
||||
<div class="body">
|
||||
<vn-descriptor-content module="worker">
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<h5 title="{{$ctrl.worker.firstName}} {{$ctrl.worker.lastName}}">
|
||||
{{$ctrl.worker.firstName}} {{$ctrl.worker.lastName}}
|
||||
</h5>
|
||||
<vn-label-value label="Id"
|
||||
<vn-label-value
|
||||
label="Id"
|
||||
value="{{$ctrl.worker.id}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="User"
|
||||
<vn-label-value
|
||||
label="User"
|
||||
value="{{$ctrl.worker.user.name}}"
|
||||
title="{{$ctrl.worker.firstName}} {{$ctrl.worker.lastName}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Email"
|
||||
<vn-label-value
|
||||
label="Email"
|
||||
value="{{$ctrl.worker.user.emailUser.email}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Department"
|
||||
<vn-label-value
|
||||
label="Department"
|
||||
value="{{$ctrl.worker.department.department.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Phone"
|
||||
<vn-label-value
|
||||
label="Phone"
|
||||
value="{{$ctrl.worker.phone}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Extension"
|
||||
<vn-label-value
|
||||
label="Extension"
|
||||
value="{{$ctrl.worker.sip.extension}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
<vn-quick-links
|
||||
links="$ctrl.quicklinks">
|
||||
</vn-quick-links>
|
||||
</div>
|
||||
</div>
|
||||
<div class="quicklinks">
|
||||
<div ng-transclude="btnOne">
|
||||
<vn-quick-link
|
||||
tooltip="Go to client"
|
||||
state="['client.card.summary', {id: $ctrl.id}]"
|
||||
icon="person">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnTwo"></div>
|
||||
<div ng-transclude="btnThree"></div>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
|
@ -3,20 +3,50 @@ import Descriptor from 'salix/components/descriptor';
|
|||
|
||||
class Controller extends Descriptor {
|
||||
get worker() {
|
||||
return this._worker;
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set worker(value) {
|
||||
this._worker = value;
|
||||
if (!value) return;
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
this._quicklinks = {
|
||||
btnOne: {
|
||||
icon: 'person',
|
||||
state: `client.card.summary({id: ${value.userFk}})`,
|
||||
tooltip: 'Go to client'
|
||||
}
|
||||
loadData() {
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
include: {
|
||||
relation: 'emailUser',
|
||||
scope: {
|
||||
fields: ['email']
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['fi']
|
||||
}
|
||||
}, {
|
||||
relation: 'sip',
|
||||
scope: {
|
||||
fields: ['extension']
|
||||
}
|
||||
}, {
|
||||
relation: 'department',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'department'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Workers/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import './index.js';
|
||||
|
||||
describe('vnWorkerDescriptorPopover', () => {
|
||||
describe('vnWorkerDescriptor', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
|
@ -8,10 +8,7 @@ describe('vnWorkerDescriptorPopover', () => {
|
|||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnWorkerDescriptorPopover', {
|
||||
$element: null,
|
||||
$transclude: null
|
||||
});
|
||||
controller = $componentController('vnWorkerDescriptor', {$element: null});
|
||||
}));
|
||||
|
||||
describe('loadData()', () => {
|
||||
|
@ -19,7 +16,7 @@ describe('vnWorkerDescriptorPopover', () => {
|
|||
const id = 1;
|
||||
const response = 'foo';
|
||||
|
||||
$httpBackend.expectGET(`Workers/${id}`).respond(response);
|
||||
$httpBackend.expectRoute('GET', `Workers/${id}`).respond(response);
|
||||
controller.id = id;
|
||||
$httpBackend.flush();
|
||||
|
|
@ -1,22 +1,16 @@
|
|||
<div class="vn-descriptor">
|
||||
<vn-horizontal class="header">
|
||||
<a translate-attr="{title: 'Return to module index'}" ui-sref="zone.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<a translate-attr="{title: 'Preview'}" ui-sref="zone.card.summary({id: $ctrl.zone.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-menu
|
||||
vn-id="more-button"
|
||||
icon="more_vert"
|
||||
show-filter="false"
|
||||
value-field="callback"
|
||||
translate-fields="['name']"
|
||||
data="$ctrl.moreOptions"
|
||||
on-change="$ctrl.onMoreChange(value)">
|
||||
</vn-icon-menu>
|
||||
</vn-horizontal>
|
||||
<div class="body">
|
||||
<vn-descriptor-content module="zone">
|
||||
<slot-menu>
|
||||
<ul class="vn-list">
|
||||
<li>
|
||||
<div class="vn-item"
|
||||
ng-click="deleteZone.show()"
|
||||
translate>
|
||||
Delete
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<vn-label-value
|
||||
label="Id"
|
||||
|
@ -51,8 +45,8 @@
|
|||
value="{{$ctrl.zone.bonus | currency: 'EUR': 2}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-confirm
|
||||
vn-id="deleteZone"
|
||||
on-accept="$ctrl.onDeleteAccept()"
|
||||
|
|
|
@ -2,23 +2,17 @@ import ngModule from '../module';
|
|||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
$onInit() {
|
||||
this.moreOptions = [
|
||||
{
|
||||
name: 'Delete',
|
||||
callback: () => this.$.deleteZone.show(),
|
||||
}
|
||||
];
|
||||
get zone() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
onMoreChange(callback) {
|
||||
callback.call(this);
|
||||
set zone(value) {
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
onDeleteAccept() {
|
||||
return this.$http.delete(`Zones/${this.zone.id}`).then(() => {
|
||||
this.$state.go('zone.index');
|
||||
});
|
||||
return this.$http.delete(`Zones/${this.id}`)
|
||||
.then(() => this.$state.go('zone.index'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue