Merge branch 'dev' of http://git.verdnatura.es/salix into dev
This commit is contained in:
commit
b6ba23282c
|
@ -4,4 +4,5 @@ Attended by: Atendida por
|
|||
Landed: Recibido
|
||||
Price: Precio
|
||||
Claimable sales from ticket: Lineas reclamables del ticket
|
||||
Detail: Detalles
|
||||
Detail: Detalles
|
||||
Add sale item: Añadir artículo
|
|
@ -339,7 +339,7 @@
|
|||
"component": "vn-client-web-payment",
|
||||
"description": "Web Payment",
|
||||
"menu": {
|
||||
"icon": "web"
|
||||
"icon": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -14,24 +14,19 @@
|
|||
ng-class="{'bg-main': address.isDefaultAddress,'bg-opacity-item': !address.isActive && !address.isDefaultAddress}">
|
||||
<vn-horizontal style="align-items: center;">
|
||||
<vn-none pad-medium-h>
|
||||
<i class="material-icons"
|
||||
orange
|
||||
<vn-icon-button icon="star"
|
||||
ng-if="address.isDefaultAddress">
|
||||
star
|
||||
</i>
|
||||
<i class="material-icons"
|
||||
orange
|
||||
</vn-icon-button>
|
||||
<vn-icon-button icon="star_border"
|
||||
ng-if="!address.isActive"
|
||||
vn-tooltip="Active first to set as default">
|
||||
star_border
|
||||
</i>
|
||||
<i class="material-icons pointer"
|
||||
orange
|
||||
ng-if="address.isActive && !address.isDefaultAddress"
|
||||
</vn-icon-button>
|
||||
<vn-icon-button orange
|
||||
icon="star_border"
|
||||
vn-tooltip="Set as default"
|
||||
ng-click="$ctrl.setDefault(address)">
|
||||
star_border
|
||||
</i>
|
||||
ng-click="$ctrl.setDefault(address)"
|
||||
ng-if="address.isActive && !address.isDefaultAddress">
|
||||
</vn-icon-button>
|
||||
</vn-none>
|
||||
<vn-one border-solid-right>
|
||||
<vn-horizontal>
|
||||
|
|
|
@ -8,20 +8,14 @@ export default class Controller {
|
|||
this.translate = $translate;
|
||||
}
|
||||
|
||||
set client(value) {
|
||||
this._client = value;
|
||||
|
||||
if (value)
|
||||
this.orgData = Object.assign({}, value);
|
||||
}
|
||||
|
||||
get client() {
|
||||
return this._client;
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
let shouldNotify = false;
|
||||
|
||||
if (this.hasPaymethodChanges())
|
||||
shouldNotify = true;
|
||||
|
||||
this.$scope.watcher.submit().then(() => {
|
||||
if (this.hasPaymethodChanged())
|
||||
if (shouldNotify)
|
||||
this.notifyChanges();
|
||||
});
|
||||
}
|
||||
|
@ -32,10 +26,12 @@ export default class Controller {
|
|||
);
|
||||
}
|
||||
|
||||
hasPaymethodChanged() {
|
||||
let payMethod = this.orgData.payMethodFk != this.client.payMethodFk;
|
||||
let iban = this.orgData.iban != this.client.iban;
|
||||
let dueDay = this.orgData.dueDay != this.client.dueDay;
|
||||
hasPaymethodChanges() {
|
||||
let orgData = this.$scope.watcher.orgData;
|
||||
|
||||
let payMethod = orgData.payMethodFk != this.client.payMethodFk;
|
||||
let iban = orgData.iban != this.client.iban;
|
||||
let dueDay = orgData.dueDay != this.client.dueDay;
|
||||
|
||||
return payMethod || iban || dueDay;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import './index';
|
||||
import {watcher} from '../../../helpers/watcherHelper';
|
||||
|
||||
describe('Client', () => {
|
||||
describe('Component vnClientBillingData', () => {
|
||||
|
@ -16,38 +17,24 @@ describe('Client', () => {
|
|||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
$scope = $rootScope.$new();
|
||||
$scope.watcher = {
|
||||
submit: () => {
|
||||
return {
|
||||
then: callback => {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
$scope.watcher = watcher;
|
||||
controller = $componentController('vnClientBillingData', {$scope: $scope});
|
||||
controller.client = {id: 101, name: 'Client name', payMethodFk: 4};
|
||||
$scope.watcher.orgData = {id: 101, name: 'Client name', payMethodFk: 4};
|
||||
}));
|
||||
|
||||
describe('client()', () => {
|
||||
it(`should call setter client`, () => {
|
||||
expect(controller.orgData).toEqual(controller.client);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSubmit()', () => {
|
||||
it(`should call notifyChanges() if there are changes on payMethod data`, () => {
|
||||
spyOn(controller, 'notifyChanges');
|
||||
controller.client.payMethodFk = 5;
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.hasPaymethodChanged()).toBeTruthy();
|
||||
expect(controller.notifyChanges).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('notifyChanges()', () => {
|
||||
it(`should call notifyChanges() and perform a GET query`, () => {
|
||||
it(`should perform a GET query`, () => {
|
||||
$httpBackend.when('GET', `/mailer/notification/payment-update/101`).respond(true);
|
||||
$httpBackend.expect('GET', `/mailer/notification/payment-update/101`);
|
||||
controller.notifyChanges();
|
||||
|
@ -55,17 +42,17 @@ describe('Client', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('hasPaymethodChanged()', () => {
|
||||
it(`should call hasPaymethodChanged() and return true if there are changes on payMethod data`, () => {
|
||||
describe('hasPaymethodChanges()', () => {
|
||||
it(`should return true if there are changes on payMethod data`, () => {
|
||||
controller.client.payMethodFk = 5;
|
||||
|
||||
expect(controller.hasPaymethodChanged()).toBeTruthy();
|
||||
expect(controller.hasPaymethodChanges()).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should call hasPaymethodChanged() and return false if there are no changes on payMethod data`, () => {
|
||||
it(`should return false if there are no changes on payMethod data`, () => {
|
||||
controller.client.payMethodFk = 4;
|
||||
|
||||
expect(controller.hasPaymethodChanged()).toBeFalsy();
|
||||
expect(controller.hasPaymethodChanges()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
<vn-one border-radius class="pad-small border-solid" ng-class="{'bg-main': !classification.finished,'bg-opacity-item': classification.finished}">
|
||||
<vn-horizontal style="align-items: center;">
|
||||
<vn-none pad-medium-h orange>
|
||||
<i class="material-icons pointer"
|
||||
<vn-icon-button icon="lock" orange
|
||||
ng-if="!classification.finished"
|
||||
vn-tooltip="Close contract"
|
||||
ng-click="$ctrl.closeContract(classification)">lock_outline</i>
|
||||
ng-click="$ctrl.closeContract(classification)">
|
||||
</vn-icon-button>
|
||||
</vn-none>
|
||||
<vn-one border-solid-right>
|
||||
<div><vn-label translate>Since</vn-label> {{::classification.started | date:'dd/MM/yyyy'}}</div>
|
||||
|
|
|
@ -24,13 +24,13 @@
|
|||
<vn-tbody>
|
||||
<vn-tr ng-repeat="recovery in recoveries">
|
||||
<vn-td>
|
||||
<vn-icon
|
||||
class="bright pointer"
|
||||
icon="lock"
|
||||
<vn-icon-button icon="lock"
|
||||
vn-acl="administrative"
|
||||
vn-acl-action="remove"
|
||||
vn-tooltip="Finish that recovery period"
|
||||
ng-if="!recovery.finished"
|
||||
ng-click="$ctrl.setFinished(recovery)">
|
||||
</vn-icon>
|
||||
on-click="$ctrl.setFinished(recovery)">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
<vn-td>{{::recovery.started | date:'dd/MM/yyyy' }}</vn-td>
|
||||
<vn-td>{{recovery.finished | date:'dd/MM/yyyy' }}</vn-td>
|
||||
|
@ -49,7 +49,11 @@
|
|||
</vn-pagination>
|
||||
</vn-card>
|
||||
</vn-vertical>
|
||||
<a vn-tooltip="New recovery" ui-sref="client.card.recovery.create"
|
||||
vn-bind="+" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
||||
|
||||
<vn-float-button icon="add" fixed-bottom-right
|
||||
vn-tooltip="New recovery"
|
||||
vn-bind="+"
|
||||
vn-acl="administrative"
|
||||
vn-acl-action="remove"
|
||||
ui-sref="client.card.recovery.create">
|
||||
</vn-float-button>
|
|
@ -24,12 +24,13 @@
|
|||
<vn-tbody>
|
||||
<vn-tr ng-repeat="transaction in transactions">
|
||||
<vn-td style="width: 3em; text-align: center">
|
||||
<vn-icon orange pointer
|
||||
<vn-icon-button
|
||||
icon="check"
|
||||
vn-acl="administrative"
|
||||
vn-tooltip="Confirm transaction"
|
||||
ng-click="$ctrl.confirm(transaction)"
|
||||
ng-show="::!transaction.isConfirmed"
|
||||
icon="check">
|
||||
</vn-icon>
|
||||
ng-show="::!transaction.isConfirmed"
|
||||
on-click="$ctrl.confirm(transaction)">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
<vn-td>{{::transaction.id}}</vn-td>
|
||||
<vn-td number>{{::transaction.amount | currency: '€ '}}</vn-td>
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
<vn-icon icon="{{::$ctrl.icon}}"></vn-icon>
|
||||
<button ng-click="$ctrl.onClick()">
|
||||
<vn-icon icon="{{::$ctrl.icon}}">
|
||||
</button>
|
|
@ -23,6 +23,7 @@ ngModule.component('vnIconButton', {
|
|||
template: require('./icon-button.html'),
|
||||
bindings: {
|
||||
icon: '@',
|
||||
onClick: '&?',
|
||||
enabled: '<?'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
@import "colors";
|
||||
|
||||
vn-icon-button {
|
||||
display: inline-block;
|
||||
color: rgba($main-01, 0.7);
|
||||
font-size: 18pt;
|
||||
transition: color 200ms ease-in-out;
|
||||
cursor: pointer;
|
||||
|
||||
& > vn-icon {
|
||||
display: block;
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
margin: 0 auto;
|
||||
}
|
||||
&:not(.button):hover {
|
||||
outline: 0;
|
||||
|
||||
button {
|
||||
background: transparent !important;
|
||||
background-color: transparent !important;
|
||||
display: inline-block;
|
||||
color: $main-01;
|
||||
border: 0
|
||||
}
|
||||
|
||||
button.mdl-button--colored {
|
||||
color: orange
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ function vnAcl(aclService, $timeout) {
|
|||
input.setAttribute("disabled", "true");
|
||||
updateMaterial(input);
|
||||
});
|
||||
$element[0].querySelectorAll('i, vn-drop-down').forEach(element => {
|
||||
$element[0].querySelectorAll('vn-drop-down').forEach(element => {
|
||||
element.parentNode.removeChild(element);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -46,10 +46,10 @@ describe('Directive acl', () => {
|
|||
expect(input.attr('disabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should delete any element with the tag i and vn-drop-down', () => {
|
||||
let html = `<div vn-acl="administrative,client" vn-acl-action="disabled"><label><i/></label><input/></div>`;
|
||||
it('should delete any element with the tag vn-drop-down', () => {
|
||||
let html = `<div vn-acl="administrative,client" vn-acl-action="disabled"><vn-drop-down></vn-drop-down><input/></div>`;
|
||||
compile(false, html);
|
||||
|
||||
expect(element.find('i').length).toBe(0);
|
||||
expect(element.find('vn-drop-down').length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
module.exports.watcher = {
|
||||
submit: () => {
|
||||
return new Promise(accept => {
|
||||
accept();
|
||||
});
|
||||
return {
|
||||
then: callback => {
|
||||
callback({data: {id: 1234}});
|
||||
}
|
||||
};
|
||||
},
|
||||
realSubmit: () => {
|
||||
return new Promise(accept => {
|
||||
accept();
|
||||
});
|
||||
return {
|
||||
then: callback => {
|
||||
callback({data: {id: 1234}});
|
||||
}
|
||||
};
|
||||
},
|
||||
check: () => {},
|
||||
notifySaved: () => {},
|
||||
|
|
|
@ -17,12 +17,10 @@ vn-item-diary {
|
|||
|
||||
.balanceNegative .balance {
|
||||
background-color: $main-01;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.isIn .in {
|
||||
background-color: $main-02;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.truncate {
|
||||
|
|
|
@ -39,6 +39,7 @@ Worker: Trabajador
|
|||
Available: Disponible
|
||||
Create: Crear
|
||||
Client card: Ficha del cliente
|
||||
Shipped: F. envio
|
||||
|
||||
#Sections
|
||||
Items: Artículos
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
"url": "/index?q",
|
||||
"state": "order.index",
|
||||
"component": "vn-order-index",
|
||||
"description": "List",
|
||||
"acl": ["developer"]
|
||||
"description": "List"
|
||||
},
|
||||
{
|
||||
"url": "/:id",
|
||||
|
|
|
@ -47,7 +47,7 @@ class Controller {
|
|||
let query = `/order/api/Orders/${this.$state.params.id}/getTotal`;
|
||||
this.$http.get(query).then(res => {
|
||||
if (res.data) {
|
||||
this.order.total = res.data.total;
|
||||
this.order.total = res.data;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('Order', () => {
|
|||
|
||||
describe('getTotal()', () => {
|
||||
it(`should make a query and save the data in order.total`, () => {
|
||||
$httpBackend.expectGET(`/order/api/Orders/${controller.$state.params.id}/getTotal`).respond({total: '20M'});
|
||||
$httpBackend.expectGET(`/order/api/Orders/${controller.$state.params.id}/getTotal`).respond('20M');
|
||||
controller.getTotal();
|
||||
$httpBackend.flush();
|
||||
|
||||
|
|
|
@ -75,8 +75,6 @@ class Controller {
|
|||
this.$http.post(`order/api/Orders/new`, params).then(res => {
|
||||
this.vnApp.showSuccess(this.translate.instant('Data saved!'));
|
||||
this.$state.go("order.card.catalog", {id: res.data});
|
||||
}).catch(e => {
|
||||
this.vnApp.showError(this.translate.instant(e.data.error.message));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,21 +12,37 @@
|
|||
<vn-tr>
|
||||
<vn-th field="id" default-order="DESC">Id</vn-th>
|
||||
<vn-th field="clientFk">Client</vn-th>
|
||||
<vn-th field="companyFk">Company</vn-th>
|
||||
<vn-th field="isConfirmed">Confirmed</vn-th>
|
||||
<vn-th field="sourceApp">Created from</vn-th>
|
||||
<vn-th field="created">Created</vn-th>
|
||||
<vn-th field="companyFk">Company</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="order in orders" class="clickable"
|
||||
ui-sref="order.card.catalog({id: {{::order.id}}})">
|
||||
ui-sref="order.card.summary({id: {{::order.id}}})">
|
||||
<vn-td>{{::order.id}}</vn-td>
|
||||
<vn-td>
|
||||
<span class="link" ng-click="$ctrl.showDescriptor($event, order.clientFk)">
|
||||
{{::order.client.name}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<vn-check
|
||||
field="order.isConfirmed"
|
||||
disabled="true">
|
||||
</vn-check>
|
||||
</vn-td>
|
||||
<vn-td>{{::order.sourceApp}}</vn-td>
|
||||
<vn-td>{{::order.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
|
||||
<vn-td>{{::order.company.code}}</vn-td>
|
||||
<vn-td>{{::order.created | date:'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td>
|
||||
<vn-icon-button
|
||||
ng-click="$ctrl.preview($event, order)"
|
||||
vn-tooltip="Preview"
|
||||
icon="desktop_windows">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
|
@ -39,7 +55,13 @@
|
|||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
</div>
|
||||
<a ui-sref="order.create" vn-bind="+" vn-tooltip="New order" fixed-bottom-right>
|
||||
<a ui-sref="order.create" vn-bind="+" vn-tooltip="New order" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
||||
<vn-client-descriptor-popover vn-id="descriptor"></vn-client-descriptor-popover>
|
||||
<vn-client-descriptor-popover vn-id="descriptor"></vn-client-descriptor-popover>
|
||||
<vn-dialog class="dialog-summary"
|
||||
vn-id="order-summary-dialog">
|
||||
<tpl-body>
|
||||
<vn-order-summary order="$ctrl.order"></vn-order-summary>
|
||||
</tpl-body>
|
||||
</vn-dialog>
|
|
@ -18,26 +18,6 @@ export default class Controller {
|
|||
};
|
||||
}
|
||||
|
||||
/* exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
? {id: value}
|
||||
: {nickname: {regexp: value}};
|
||||
case 'from':
|
||||
return {shipped: {gte: value}};
|
||||
case 'to':
|
||||
return {shipped: {lte: value}};
|
||||
case 'nickname':
|
||||
return {[param]: {regexp: value}};
|
||||
case 'id':
|
||||
case 'clientFk':
|
||||
case 'agencyModeFk':
|
||||
case 'warehouseFk':
|
||||
return {[param]: value};
|
||||
}
|
||||
} */
|
||||
|
||||
showDescriptor(event, clientFk) {
|
||||
this.$scope.descriptor.clientFk = clientFk;
|
||||
this.$scope.descriptor.parent = event.target;
|
||||
|
@ -50,11 +30,11 @@ export default class Controller {
|
|||
this.$scope.popover.relocate();
|
||||
}
|
||||
|
||||
preview(event, ticket) {
|
||||
preview(event, order) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
this.$scope.dialogSummaryTicket.show();
|
||||
this.ticketSelected = ticket;
|
||||
this.$scope.orderSummaryDialog.show();
|
||||
this.order = order;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,10 +48,10 @@ class Controller {
|
|||
}
|
||||
|
||||
getVAT() {
|
||||
let query = `/order/api/Orders/${this.$state.params.id}/getTaxes`;
|
||||
let query = `/order/api/Orders/${this.$state.params.id}/getVAT`;
|
||||
|
||||
this.$http.get(query).then(res => {
|
||||
this.VAT = res.data.tax;
|
||||
this.VAT = res.data;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -56,9 +56,9 @@ describe('Order', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('getTaxes()', () => {
|
||||
it('should make a query to get the taxes of a given order', () => {
|
||||
$httpBackend.expectGET(`/order/api/Orders/1/getTaxes`).respond({data: {tax: 3}});
|
||||
describe('getVAT()', () => {
|
||||
it('should make a query to get the VAT of a given order', () => {
|
||||
$httpBackend.expectGET(`/order/api/Orders/1/getVAT`).respond({data: {tax: 3}});
|
||||
controller.getVAT();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
|
|
@ -15,4 +15,5 @@ Default order: Orden predeterminado
|
|||
Ascendant name: Nombre ascendiente
|
||||
Descendant name: Nombre descendiente
|
||||
Ascendant price: Precio ascendiente
|
||||
Descendant price: Precio descendiente
|
||||
Descendant price: Precio descendiente
|
||||
Created from: Creado desde
|
|
@ -1,9 +1,94 @@
|
|||
<vn-vertical vn-one>
|
||||
<vn-card class="summary" pad-medium>
|
||||
<vn-vertical margin-medium>
|
||||
<vn-auto>
|
||||
<h5 text-center pad-small-v class="title">Order</h5>
|
||||
</vn-auto>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
</vn-vertical>
|
||||
<vn-card class="summary ticketSummary" pad-medium>
|
||||
<vn-vertical margin-medium>
|
||||
<vn-auto>
|
||||
<h5 text-center pad-small-v class="title">{{$ctrl.summary.id}} - {{$ctrl.summary.client.name}} - {{$ctrl.summary.client.salesPerson.id}}</h5>
|
||||
</vn-auto>
|
||||
<vn-horizontal class="ticketSummary__data" pad-medium-v>
|
||||
<vn-one>
|
||||
<vn-label-value label="Id"
|
||||
value="{{::$ctrl.summary.id}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Nickname"
|
||||
value="{{::$ctrl.summary.address.nickname}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Confirmed"
|
||||
value="{{::$ctrl.summary.isConfirmed}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Warehouse"
|
||||
value="{{::$ctrl.summary.sourceApp}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
|
||||
<vn-one>
|
||||
<vn-label-value label="Created"
|
||||
value="{{::$ctrl.summary.created | date: 'dd/MM/yyyy HH:mm'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Confirmed"
|
||||
value="{{::$ctrl.summary.confirmed | date: 'dd/MM/yyyy'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Address"
|
||||
value="{{::$ctrl.formattedAddress}}">
|
||||
<vn-label-value label="Phone"
|
||||
value="{{::$ctrl.summary.address.phone}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
|
||||
<vn-one>
|
||||
<vn-label-value label="{{'Notes'}}"
|
||||
value="{{::$ctrl.summary.note}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one class="ticketSummary__taxes">
|
||||
<section>
|
||||
<p><vn-label translate>Subtotal</vn-label> {{::$ctrl.summary.subTotal | currency:' €':2}}</p>
|
||||
<p><vn-label translate>VAT</vn-label> {{::$ctrl.summary.VAT | currency:' €':2}}</p>
|
||||
<p><vn-label><strong>Total</strong></vn-label> <strong>{{::$ctrl.summary.total | currency:' €':2}}</strong></p>
|
||||
</section>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<table class="vn-grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th number translate>Item</th>
|
||||
<th translate>Description</th>
|
||||
<th number translate>Quantity</th>
|
||||
<th number translate>Price</th>
|
||||
<th number translate>Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="row in $ctrl.summary.rows track by row.id">
|
||||
<td>
|
||||
<vn-icon
|
||||
ng-show="row.visible || row.available"
|
||||
orange
|
||||
icon="warning"
|
||||
vn-tooltip="Visible: {{::row.visible || 0}} <br> {{::$ctrl.translate.instant('Available')}} {{::row.available || 0}}">
|
||||
</vn-icon>
|
||||
<vn-icon ng-show="row.reserved" icon="icon-reserva"></vn-icon>
|
||||
</td>
|
||||
<td number>
|
||||
<span
|
||||
ng-click="$ctrl.showDescriptor($event, row)"
|
||||
class="link" pointer>
|
||||
{{("000000"+row.itemFk).slice(-6)}}
|
||||
</span>
|
||||
</td>
|
||||
<td><vn-fetched-tags concept="row.item.name" tags="row.item.tags"/></td>
|
||||
<td number>{{::row.quantity}}</td>
|
||||
<td number>{{::row.price | currency:'€':2}}</td>
|
||||
<td number>{{::row.quantity * row.price | currency:'€':2}}</td>
|
||||
</tr>
|
||||
<tr ng-if="!$ctrl.summary.rows" class="list list-element">
|
||||
<td colspan="8" style="text-align: center" translate>No results</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</vn-horizontal>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-item-descriptor-popover vn-id="descriptor"
|
||||
quicklinks="$ctrl.quicklinks">
|
||||
</vn-item-descriptor-popover>
|
||||
|
|
|
@ -1,12 +1,57 @@
|
|||
import ngModule from '../module';
|
||||
import './style.scss';
|
||||
|
||||
class Controller {
|
||||
constructor($http) {
|
||||
constructor($scope, $http, $state) {
|
||||
this.$scope = $scope;
|
||||
this.$http = $http;
|
||||
this.$state = $state;
|
||||
this.order = {};
|
||||
}
|
||||
|
||||
setSummary() {
|
||||
this.$http.get(`/order/api/Orders/${this.order.id}/summary`).then(res => {
|
||||
if (res && res.data) {
|
||||
this.summary = res.data;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get formattedAddress() {
|
||||
if (!this.summary) return;
|
||||
|
||||
let address = this.summary.address;
|
||||
let province = address.province ? `(${address.province.name})` : '';
|
||||
|
||||
return `${address.street} - ${address.city} ${province}`;
|
||||
}
|
||||
|
||||
$onChanges() {
|
||||
if (this.order && this.order.id)
|
||||
this.setSummary();
|
||||
}
|
||||
|
||||
showDescriptor(event, item) {
|
||||
this.quicklinks = {
|
||||
btnThree: {
|
||||
icon: 'icon-transaction',
|
||||
state: `item.card.diary({
|
||||
id: ${item.id},
|
||||
})`,
|
||||
tooltip: 'Item diary'
|
||||
}
|
||||
};
|
||||
this.$scope.descriptor.itemFk = item.id;
|
||||
this.$scope.descriptor.parent = event.target;
|
||||
this.$scope.descriptor.show();
|
||||
}
|
||||
|
||||
onDescriptorLoad() {
|
||||
this.$scope.popover.relocate();
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$http'];
|
||||
Controller.$inject = ['$scope', '$http', '$state'];
|
||||
|
||||
ngModule.component('vnOrderSummary', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import './index';
|
||||
|
||||
describe('Order', () => {
|
||||
describe('Component vnOrderSummary', () => {
|
||||
let $componentController;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('order');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_) => {
|
||||
$componentController = _$componentController_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
controller = $componentController('vnOrderSummary');
|
||||
controller.order = {id: 1};
|
||||
}));
|
||||
|
||||
describe('getSummary()', () => {
|
||||
it('should perform a GET query and define summary property', () => {
|
||||
let res = {id: 1, nickname: 'Batman'};
|
||||
$httpBackend.when('GET', `/order/api/Orders/1/summary`).respond(200, res);
|
||||
$httpBackend.expect('GET', `/order/api/Orders/1/summary`);
|
||||
controller.setSummary();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.summary).toBeDefined();
|
||||
expect(controller.summary.nickname).toEqual('Batman');
|
||||
});
|
||||
});
|
||||
|
||||
describe('formattedAddress()', () => {
|
||||
it('should return a full fromatted address with city and province', () => {
|
||||
controller.summary = {
|
||||
address: {
|
||||
province: {
|
||||
name: 'Gotham'
|
||||
},
|
||||
street: '1007 Mountain Drive',
|
||||
city: 'Gotham'
|
||||
}
|
||||
};
|
||||
|
||||
expect(controller.formattedAddress).toEqual('1007 Mountain Drive - Gotham (Gotham)');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
.ticketSummary {
|
||||
.ticketSummary__data {
|
||||
vn-one {
|
||||
padding-right: 20px
|
||||
}
|
||||
|
||||
vn-one:last-child {
|
||||
padding-right: 0
|
||||
}
|
||||
}
|
||||
|
||||
.ticketSummary__notes {
|
||||
max-width: 18em
|
||||
}
|
||||
|
||||
.ticketSummary__taxes {
|
||||
max-width: 15em;
|
||||
|
||||
& section {
|
||||
border: 1px solid #CCC;
|
||||
text-align: right;
|
||||
padding: 10px
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@ describe('Salix', () => {
|
|||
|
||||
describe('localBank() setter', () => {
|
||||
it('should set window.localStorage.localBank and call showOk', () => {
|
||||
spyOn(controller, 'showOk')
|
||||
spyOn(controller, 'showOk');
|
||||
controller.localBank = 4;
|
||||
|
||||
expect(window.localStorage.localBank).toBe('4');
|
||||
|
@ -31,7 +31,7 @@ describe('Salix', () => {
|
|||
|
||||
describe('localWarehouse() setter', () => {
|
||||
it('should set window.localStorage.localWarehouse and call showOk', () => {
|
||||
spyOn(controller, 'showOk')
|
||||
spyOn(controller, 'showOk');
|
||||
controller.localWarehouse = 4;
|
||||
|
||||
expect(window.localStorage.localWarehouse).toBe('4');
|
||||
|
@ -41,7 +41,7 @@ describe('Salix', () => {
|
|||
|
||||
describe('localCompany() setter', () => {
|
||||
it('should set window.localStorage.localCompany and call showOk', () => {
|
||||
spyOn(controller, 'showOk')
|
||||
spyOn(controller, 'showOk');
|
||||
controller.localCompany = 4;
|
||||
|
||||
expect(window.localStorage.localCompany).toBe('4');
|
||||
|
@ -51,7 +51,7 @@ describe('Salix', () => {
|
|||
|
||||
describe('warehouseFk() setter', () => {
|
||||
it('should set warehouse and call setUserConfig', () => {
|
||||
spyOn(controller, 'setUserConfig')
|
||||
spyOn(controller, 'setUserConfig');
|
||||
controller.warehouseFk = 4;
|
||||
|
||||
expect(controller.warehouse).toBe(4);
|
||||
|
@ -61,7 +61,7 @@ describe('Salix', () => {
|
|||
|
||||
describe('companyFk() setter', () => {
|
||||
it('should set company and call setUserConfig', () => {
|
||||
spyOn(controller, 'setUserConfig')
|
||||
spyOn(controller, 'setUserConfig');
|
||||
controller.companyFk = 4;
|
||||
|
||||
expect(controller.company).toBe(4);
|
||||
|
@ -71,11 +71,11 @@ describe('Salix', () => {
|
|||
|
||||
describe('getUserConfig()', () => {
|
||||
it('should make a query, set company and not set warehouse if its not in the response', () => {
|
||||
$httpBackend.when('GET', `/api/UserConfigs/getUserConfig`).respond({response: {companyFk: 2}});
|
||||
$httpBackend.when('GET', `/api/UserConfigs/getUserConfig`).respond({companyFk: 2});
|
||||
$httpBackend.expect('GET', `/api/UserConfigs/getUserConfig`);
|
||||
controller.getUserConfig();
|
||||
$httpBackend.flush();
|
||||
|
||||
|
||||
expect(controller.warehouse).toBeUndefined();
|
||||
expect(controller.company).toEqual(2);
|
||||
});
|
||||
|
@ -89,7 +89,7 @@ describe('Salix', () => {
|
|||
$httpBackend.expect('POST', `/api/UserConfigs/setUserConfig`, {companyFk: 1});
|
||||
controller.setUserConfig('companyFk');
|
||||
$httpBackend.flush();
|
||||
|
||||
|
||||
expect(controller.showOk).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,11 +26,10 @@
|
|||
<vn-tbody>
|
||||
<vn-tr ng-repeat="expedition in expeditions">
|
||||
<vn-td pad-medium-h style="width:30px;color:#FFA410;">
|
||||
<i
|
||||
pointer
|
||||
class="material-icons"
|
||||
vn-tooltip="Delete expedition"
|
||||
ng-click="$ctrl.deleteExpedition(expedition)">delete</i>
|
||||
<vn-icon-button icon="delete"
|
||||
on-click="$ctrl.deleteExpedition(expedition)"
|
||||
vn-tooltip="Delete expedition">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
<vn-td number>
|
||||
<span
|
||||
|
|
|
@ -189,7 +189,7 @@ class Controller {
|
|||
let sales = this.getCheckedLines();
|
||||
|
||||
this.$http.post(`/api/Sales/MoveToNewTicket`, {ticket: ticket, sales: sales}).then(res => {
|
||||
let url = this.$state.href("ticket.card.sale", {id: res.data}, {absolute: true});
|
||||
let url = this.$state.href("ticket.card.sale", {id: res.data.id}, {absolute: true});
|
||||
window.open(url, '_blank');
|
||||
this.$scope.transfer.hide();
|
||||
this.$scope.model.refresh();
|
||||
|
|
|
@ -97,7 +97,7 @@ export default {
|
|||
phoneInput: `${components.vnTextfield}[name="phone"]`,
|
||||
mobileInput: `${components.vnTextfield}[name="mobile"]`,
|
||||
defaultAddress: 'vn-client-address-index vn-horizontal:nth-child(2) div[name="street"]',
|
||||
secondMakeDefaultStar: 'vn-client-address-index > vn-vertical > vn-card > div > vn-horizontal:nth-child(3) > vn-one > vn-horizontal > vn-none > i',
|
||||
secondMakeDefaultStar: 'vn-client-address-index > vn-vertical > vn-card > div > vn-horizontal:nth-child(3) vn-icon-button[icon="star_border"]',
|
||||
firstEditButton: `vn-client-address-index vn-icon-button[icon='edit']`,
|
||||
secondEditButton: `vn-client-address-index vn-horizontal:nth-child(3) vn-icon-button[icon='edit']`,
|
||||
activeCheckbox: `vn-check[label='Enabled'] > label > input`,
|
||||
|
@ -291,7 +291,7 @@ export default {
|
|||
},
|
||||
ticketExpedition: {
|
||||
expeditionButton: `vn-menu-item a[ui-sref="ticket.card.expedition"]`,
|
||||
secondExpeditionRemoveButton: `vn-ticket-expedition vn-table div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(1) > i`,
|
||||
secondExpeditionRemoveButton: `vn-ticket-expedition vn-table div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(1) > vn-icon-button[icon="delete"]`,
|
||||
secondExpeditionText: `vn-ticket-expedition vn-table div > vn-tbody > vn-tr:nth-child(2)`
|
||||
},
|
||||
ticketPackages: {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Client', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should access to the clients index by clicking the clients button', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Client', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('administrative');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
|
|
|
@ -6,7 +6,7 @@ describe('Client Edit fiscalData path', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('administrative');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Client', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('administrative');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Client', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
|
@ -137,7 +137,7 @@ describe('Client', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it(`should click on the active checkbox and receive an error to save it becouse it is the default address`, () => {
|
||||
it(`should click on the active checkbox and receive an error to save it because it is the default address`, () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.clientAddresses.activeCheckbox)
|
||||
.waitToClick(selectors.clientAddresses.saveButton)
|
||||
|
|
|
@ -6,7 +6,7 @@ describe('Client add address notes path', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Client', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Client', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Client', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('salesAssistant');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
|
@ -73,7 +73,7 @@ describe('Client', () => {
|
|||
.getInnerText(selectors.clientCredit.firstCreditText)
|
||||
.then(value => {
|
||||
expect(value).toContain(999);
|
||||
expect(value).toContain('developer');
|
||||
expect(value).toContain('salesAssistant');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Client', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Client', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('salesPerson');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Client', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Item', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should access to the items index by clicking the items button', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Item', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('buyer');
|
||||
});
|
||||
|
||||
it('should access to the items index by clicking the items button', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Item', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('buyer');
|
||||
});
|
||||
|
||||
it('should access to the items index by clicking the items button', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Item', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('buyer');
|
||||
});
|
||||
|
||||
it('should access to the items index by clicking the items button', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Item', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('buyer');
|
||||
});
|
||||
|
||||
it('should access to the items index by clicking the items button', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Item', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('buyer');
|
||||
});
|
||||
|
||||
it('should access to the items index by clicking the items button', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Item', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('buyer');
|
||||
});
|
||||
|
||||
it('should access to the items index by clicking the items button', () => {
|
||||
|
|
|
@ -6,7 +6,7 @@ describe('Item', () => {
|
|||
describe('Create path', () => {
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('buyer');
|
||||
});
|
||||
|
||||
it('should access to the items index by clicking the items button', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Ticket', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should access to the tickets index by clicking the tickets button', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Ticket', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('production');
|
||||
});
|
||||
|
||||
it('should access to the tickets index by clicking the tickets button', () => {
|
||||
|
|
|
@ -6,7 +6,7 @@ describe('Ticket List sale path', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should click on the Tickets button of the top bar menu', () => {
|
||||
|
|
|
@ -6,7 +6,7 @@ describe('Ticket Create packages path', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should click on the Tickets button of the top bar menu', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Ticket', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('production');
|
||||
});
|
||||
|
||||
it('should click on the Tickets button of the top bar menu', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Ticket', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should click on the Tickets button of the top bar menu', () => {
|
||||
|
|
|
@ -265,7 +265,7 @@ describe('Ticket Edit sale path', () => {
|
|||
.waitToClick(selectors.ticketSales.firstSaleCheckbox)
|
||||
.waitToClick(selectors.ticketSales.moreMenuButton)
|
||||
.waitToClick(selectors.ticketSales.moreMenuCreateClaim)
|
||||
.waitForLogin('Developer')
|
||||
.waitForLogin('salesPerson')
|
||||
.waitToClick(selectors.globalItems.applicationsMenuButton)
|
||||
.wait(selectors.globalItems.applicationsMenuVisible)
|
||||
.waitToClick(selectors.globalItems.claimsButton)
|
||||
|
|
|
@ -6,7 +6,7 @@ describe('create client path', () => {
|
|||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
.waitForLogin('employee');
|
||||
});
|
||||
|
||||
it('should access to the clients index by clicking the clients button', () => {
|
||||
|
|
|
@ -48,7 +48,7 @@ xdescribe('Auth routes', () => {
|
|||
|
||||
describe('when the user exists and the password is correct', () => {
|
||||
it('should login and return the token', done => {
|
||||
req.body.user = 'developer';
|
||||
req.body.user = 'employee';
|
||||
req.body.password = 'nightmare';
|
||||
res.json = response => {
|
||||
expect(response.token).toBeDefined();
|
||||
|
@ -58,7 +58,7 @@ xdescribe('Auth routes', () => {
|
|||
});
|
||||
|
||||
it('should define the url to continue upon login', done => {
|
||||
req.body.user = 'developer';
|
||||
req.body.user = 'employee';
|
||||
req.body.password = 'nightmare';
|
||||
req.body.location = 'http://localhost:5000/auth/?apiKey=salix&continue="continueURL"';
|
||||
res.json = response => {
|
||||
|
@ -69,7 +69,7 @@ xdescribe('Auth routes', () => {
|
|||
});
|
||||
|
||||
it('should define the loginUrl upon login', done => {
|
||||
req.body.user = 'developer';
|
||||
req.body.user = 'employee';
|
||||
req.body.password = 'nightmare';
|
||||
req.body.location = 'http://localhost:5000/auth/?apiKey=salix';
|
||||
res.json = response => {
|
||||
|
|
|
@ -19,12 +19,12 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
async function addSalesToTicket(salesToRefund, newRefundTicket, transaction) {
|
||||
async function addSalesToTicket(salesToRefund, ticketFk, transaction) {
|
||||
let formatedSales = [];
|
||||
salesToRefund.forEach(sale => {
|
||||
let formatedSale = {
|
||||
itemFk: sale.sale().itemFk,
|
||||
ticketFk: newRefundTicket,
|
||||
ticketFk: ticketFk,
|
||||
concept: sale.sale().concept,
|
||||
quantity: -Math.abs(sale.quantity),
|
||||
price: sale.sale().price,
|
||||
|
@ -113,14 +113,30 @@ module.exports = Self => {
|
|||
|
||||
try {
|
||||
let newRefundTicket = await models.Ticket.new(params, {transaction: transaction});
|
||||
let observation = {description: `Reclama ticket: ${claim.ticketFk}`, ticketFk: newRefundTicket, observationTypeFk: obsevationType.id};
|
||||
|
||||
let observation = {
|
||||
description: `Reclama ticket: ${claim.ticketFk}`,
|
||||
ticketFk: newRefundTicket.id,
|
||||
observationTypeFk: obsevationType.id
|
||||
};
|
||||
await saveObservation(observation, {transaction: transaction});
|
||||
await models.TicketTracking.create({ticketFk: newRefundTicket, stateFk: state.id, workerFk: worker.id}, {transaction: transaction});
|
||||
|
||||
await models.TicketTracking.create({
|
||||
ticketFk: newRefundTicket.id,
|
||||
stateFk: state.id,
|
||||
workerFk: worker.id
|
||||
}, {transaction: transaction});
|
||||
|
||||
let salesToRefund = await models.ClaimBeginning.find(salesFilter);
|
||||
let createdSales = await addSalesToTicket(salesToRefund, newRefundTicket, {transaction: transaction});
|
||||
let createdSales = await addSalesToTicket(salesToRefund, newRefundTicket.id, {transaction: transaction});
|
||||
insertIntoClaimEnd(createdSales, id, worker.id, {transaction: transaction});
|
||||
await Self.rawSql('CALL vn.ticketCalculateClon(?, ?)', [newRefundTicket, claim.ticketFk], {transaction: transaction});
|
||||
|
||||
await Self.rawSql('CALL vn.ticketCalculateClon(?, ?)', [
|
||||
newRefundTicket.id, claim.ticketFk
|
||||
], {transaction: transaction});
|
||||
|
||||
await transaction.commit();
|
||||
|
||||
return newRefundTicket;
|
||||
} catch (e) {
|
||||
await transaction.rollback();
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
const app = require(`${servicesDir}/claim/server/server`);
|
||||
|
||||
describe('claimBeginning', () => {
|
||||
let ticketId;
|
||||
let ticket;
|
||||
let refundTicketObservations;
|
||||
let refundTicketSales;
|
||||
let salesInsertedInClaimEnd;
|
||||
|
||||
afterAll(async() => {
|
||||
let promises = [];
|
||||
promises.push(app.models.Ticket.destroyById(ticketId));
|
||||
promises.push(app.models.Ticket.destroyById(ticket.id));
|
||||
|
||||
promises.push(app.models.Ticket.rawSql(`DELETE FROM vn.orderTicket WHERE ticketFk ='${ticketId}';`));
|
||||
promises.push(app.models.Ticket.rawSql(`DELETE FROM vn.orderTicket WHERE ticketFk ='${ticket.id}';`));
|
||||
|
||||
await Promise.all(promises);
|
||||
});
|
||||
|
@ -19,11 +19,13 @@ describe('claimBeginning', () => {
|
|||
it('should create a new ticket with negative sales, save an observation, update the state and insert the negative sales into claimEnd', async() => {
|
||||
let ctxOfSalesAssistant = {req: {accessToken: {userId: 21}}};
|
||||
let claimId = 1;
|
||||
ticketId = await app.models.ClaimBeginning.importToNewRefundTicket(ctxOfSalesAssistant, claimId);
|
||||
await app.models.Ticket.findById(ticketId);
|
||||
refundTicketSales = await app.models.Sale.find({where: {ticketFk: ticketId}});
|
||||
refundTicketObservations = await app.models.TicketObservation.find({where: {ticketFk: ticketId}});
|
||||
let refundTicketState = await app.models.TicketState.findById(ticketId);
|
||||
ticket = await app.models.ClaimBeginning.importToNewRefundTicket(ctxOfSalesAssistant, claimId);
|
||||
|
||||
await app.models.Ticket.findById(ticket.id);
|
||||
|
||||
refundTicketSales = await app.models.Sale.find({where: {ticketFk: ticket.id}});
|
||||
refundTicketObservations = await app.models.TicketObservation.find({where: {ticketFk: ticket.id}});
|
||||
let refundTicketState = await app.models.TicketState.findById(ticket.id);
|
||||
salesInsertedInClaimEnd = await app.models.ClaimEnd.find({where: {claimFk: claimId}});
|
||||
|
||||
expect(refundTicketSales.length).toEqual(2);
|
||||
|
|
|
@ -133,7 +133,7 @@ module.exports = Self => {
|
|||
}
|
||||
|
||||
async function createTicket(params, transaction) {
|
||||
return await Self.app.models.Ticket.new({
|
||||
let ticket = await Self.app.models.Ticket.new({
|
||||
shipped: new Date(),
|
||||
landed: new Date(),
|
||||
clientFk: params.clientFk,
|
||||
|
@ -142,6 +142,8 @@ module.exports = Self => {
|
|||
addressFk: params.addressFk,
|
||||
userId: params.userId
|
||||
}, {transaction: transaction});
|
||||
|
||||
return ticket.id;
|
||||
}
|
||||
|
||||
async function sendMessage(ctx, params, transaction) {
|
||||
|
|
|
@ -36,7 +36,7 @@ module.exports = Self => {
|
|||
let notModifiable = ['responsibility', 'isChargedToMana'];
|
||||
let changedFields = diff(oldClaim, params);
|
||||
let changedFieldsPicked = pick(changedFields, notModifiable);
|
||||
let statesViables = ['Gestionado', 'Pendiente'];
|
||||
let statesViables = ['Gestionado', 'Pendiente', 'Anulado'];
|
||||
let oldState = await models.ClaimState.findOne({where: {id: oldClaim.claimStateFk}});
|
||||
let newState = await models.ClaimState.findOne({where: {id: params.claimStateFk}});
|
||||
let canChangeState = statesViables.includes(oldState.description)
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "Defaulter",
|
||||
"description": "defaulters client",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "defaulter",
|
||||
"database": "vn"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "Date"
|
||||
},
|
||||
"amount": {
|
||||
"type": "Number"
|
||||
},
|
||||
"defaulterSinced": {
|
||||
"type": "Number"
|
||||
},
|
||||
"hasChanged": {
|
||||
"type": "Number"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"client": {
|
||||
"type": "belongsTo",
|
||||
"model": "Client",
|
||||
"foreignKey": "clientFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,5 +52,8 @@
|
|||
},
|
||||
"TpvResponse": {
|
||||
"dataSource": "hedera"
|
||||
},
|
||||
"Defaulter": {
|
||||
"dataSource": "vn"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,24 +3,30 @@ export MYSQL_PWD=root
|
|||
|
||||
if [ -d /data/mysql ]; then
|
||||
cp -R /data/mysql /var/lib
|
||||
echo "Restored database to default state"
|
||||
echo "[INFO] -> Restored database to default state"
|
||||
else
|
||||
# Dump structure
|
||||
for file in dump/*-*.sql; do
|
||||
echo "Imported $file"
|
||||
mysql -u root -fc < $file
|
||||
done
|
||||
echo "[INFO] -> Imported ./dump/truncateAll.sql"
|
||||
mysql -u root -f < ./dump/truncateAll.sql
|
||||
echo "[INFO] -> Imported ./dump/structure.sql"
|
||||
mysql -u root -f < ./dump/structure.sql
|
||||
echo "[INFO] -> Imported ./dump/mysqlPlugins.sql"
|
||||
mysql -u root -f < ./dump/mysqlPlugins.sql
|
||||
|
||||
# Import changes
|
||||
for file in changes/*/*.sql; do
|
||||
echo "Imported $file"
|
||||
echo "[INFO] -> Imported ./$file"
|
||||
mysql -u root -fc < $file
|
||||
done
|
||||
|
||||
# Import fixtures
|
||||
echo "Imported fixtures.sql"
|
||||
mysql -u root -f < dump/fixtures.sql
|
||||
echo "[INFO] -> Imported ./dump/dumpedFixtures.sql"
|
||||
mysql -u root -f < ./dump/dumpedFixtures.sql
|
||||
echo "[INFO] -> Imported ./dump/fixtures.sql"
|
||||
mysql -u root -f < ./dump/fixtures.sql
|
||||
|
||||
# Copy dumpted data to volume
|
||||
cp -R /var/lib/mysql /data
|
||||
|
||||
echo "[INFO] -> Dumped database"
|
||||
fi
|
|
@ -5,7 +5,6 @@ DELIMITER $$
|
|||
USE `vn`$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `ticketCalculateClon`(IN vTicketNew INT, vTicketOld INT)
|
||||
BEGIN
|
||||
|
||||
/*
|
||||
* @vTicketNew id del nuevo ticket clonado
|
||||
* @vTicketOld id ticket original, a partir del qual se clonara el nuevo
|
||||
|
@ -41,7 +40,7 @@ BEGIN
|
|||
SELECT vWarehouse warehouseFk,NULL available,s.itemFk, bu.buyFk
|
||||
FROM sale s
|
||||
LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = s.itemFk
|
||||
WHERE s.ticketFk = vTicketNew GROUP BY s.itemFk;
|
||||
WHERE s.ticketFk = vTicketOld GROUP BY s.itemFk;
|
||||
|
||||
CALL ticketComponentCalculate(vAddress,vAgencyMode);
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ VALUES
|
|||
(107, 'ItemNiche', '*', 'WRITE', 'ALLOW', 'ROLE', 'marketingBoss'),
|
||||
(108, 'ItemPlacement', '*', 'WRITE', 'ALLOW', 'ROLE', 'marketingBoss'),
|
||||
(109, 'UserConfig', '*', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||
(110, 'Bank', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
|
||||
|
||||
|
||||
(110, 'Bank', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||
(111, 'ClientLog', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||
(112, 'Defaulter', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
|
||||
UPDATE salix.ACL
|
||||
SET model='ItemTag', property='*', accessType='WRITE', permission='ALLOW', principalType='ROLE', principalId='marketingBoss'
|
||||
WHERE id=52;
|
|
@ -0,0 +1,14 @@
|
|||
USE `vn`;
|
||||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`defaulter` AS
|
||||
SELECT
|
||||
`d`.`client` AS `clientFk`,
|
||||
`d`.`date` AS `created`,
|
||||
`d`.`amount` AS `amount`,
|
||||
`d`.`defaulterSince` AS `defaulterSinced`,
|
||||
`d`.`hasChanged` AS `hasChanged`
|
||||
FROM
|
||||
`bi`.`defaulters` `d`;
|
|
@ -207,35 +207,35 @@ INSERT INTO `vn`.`clientManaCache`(`clientFk`, `mana`, `dated`)
|
|||
|
||||
INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `isDefaultAddress`, `clientFk`, `agencyModeFk`, `longitude`, `latitude`, `isEqualizated`)
|
||||
VALUES
|
||||
(101, 'address 01', 'Somewhere in Thailand', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(102, 'address 02', 'Somewhere in Poland', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(103, 'address 03', 'Somewhere in Japan', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(104, 'address 04', 'Somewhere in Spain', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(105, 'address 05', 'Somewhere in Potugal', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(106, 'address 06', 'Somewhere in UK', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(107, 'address 07', 'Somewhere in Valencia', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(108, 'address 08', 'Somewhere in Silla', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(109, 'address 09', 'Somewhere in London', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(110, 'address 10', 'Somewhere in Algemesi', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(111, 'address 11', 'Somewhere in Carlet', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(112, 'address 12', 'Somewhere in Campanar', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(113, 'address 13', 'Somewhere in Malilla', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(114, 'address 14', 'Somewhere in France', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(115, 'address 15', 'Somewhere in Birmingham', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(116, 'address 16', 'Somewhere in Scotland', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(117, 'address 17', 'Somewhere in nowhere', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(118, 'address 18', 'Somewhere over the rainbow', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(119, 'address 19', 'Somewhere in Alberic', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(120, 'address 20', 'Somewhere in Montortal', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(121, 'address 21', 'the bat cave', 'Silla', 46460, 1, NULL, NULL, 1, 0, 101, 2, NULL, NULL, 0),
|
||||
(122, 'address 22', 'NY roofs', 'Silla', 46460, 1, NULL, NULL, 1, 0, 102, 2, NULL, NULL, 0),
|
||||
(123, 'address 23', 'The phone box', 'Silla', 46460, 1, NULL, NULL, 1, 0, 103, 2, NULL, NULL, 0),
|
||||
(124, 'address 24', 'Stark tower', 'Silla', 46460, 1, NULL, NULL, 1, 0, 104, 2, NULL, NULL, 0),
|
||||
(125, 'address 25', 'The plastic cell', 'Silla', 46460, 1, NULL, NULL, 1, 0, 105, 2, NULL, NULL, 0),
|
||||
(126, 'address 26', 'Many places', 'Silla', 46460, 1, NULL, NULL, 1, 0, 106, 2, NULL, NULL, 0),
|
||||
(127, 'address 27', 'Your pocket', 'Silla', 46460, 1, NULL, NULL, 1, 0, 107, 2, NULL, NULL, 0),
|
||||
(128, 'address 28', 'Cerebro', 'Silla', 46460, 1, NULL, NULL, 1, 0, 108, 2, NULL, NULL, 0),
|
||||
(129, 'address 29', 'Luke Cages Bar', 'Silla', 46460, 1, NULL, NULL, 1, 0, 110, 2, NULL, NULL, 0);
|
||||
(101, 'address 01', 'Somewhere in Thailand', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(102, 'address 02', 'Somewhere in Poland', 'Silla', 46460, 1, 3333333333, 444444444, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(103, 'address 03', 'Somewhere in Japan', 'Silla', 46460, 1, 3333333333, 444444444, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(104, 'address 04', 'Somewhere in Spain', 'Silla', 46460, 1, 3333333333, 444444444, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(105, 'address 05', 'Somewhere in Potugal', 'Silla', 46460, 1, 5555555555, 666666666, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(106, 'address 06', 'Somewhere in UK', 'Silla', 46460, 1, 5555555555, 666666666, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(107, 'address 07', 'Somewhere in Valencia', 'Silla', 46460, 1, 5555555555, 666666666, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(108, 'address 08', 'Somewhere in Silla', 'Silla', 46460, 1, 5555555555, 666666666, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(109, 'address 09', 'Somewhere in London', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(110, 'address 10', 'Somewhere in Algemesi', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(111, 'address 11', 'Somewhere in Carlet', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(112, 'address 12', 'Somewhere in Campanar', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(113, 'address 13', 'Somewhere in Malilla', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(114, 'address 14', 'Somewhere in France', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(115, 'address 15', 'Somewhere in Birmingham', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(116, 'address 16', 'Somewhere in Scotland', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(117, 'address 17', 'Somewhere in nowhere', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(118, 'address 18', 'Somewhere over the rainbow', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(119, 'address 19', 'Somewhere in Alberic', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(120, 'address 20', 'Somewhere in Montortal', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0),
|
||||
(121, 'address 21', 'the bat cave', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 101, 2, NULL, NULL, 0),
|
||||
(122, 'address 22', 'NY roofs', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 102, 2, NULL, NULL, 0),
|
||||
(123, 'address 23', 'The phone box', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 103, 2, NULL, NULL, 0),
|
||||
(124, 'address 24', 'Stark tower', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 104, 2, NULL, NULL, 0),
|
||||
(125, 'address 25', 'The plastic cell', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 105, 2, NULL, NULL, 0),
|
||||
(126, 'address 26', 'Many places', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 106, 2, NULL, NULL, 0),
|
||||
(127, 'address 27', 'Your pocket', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 107, 2, NULL, NULL, 0),
|
||||
(128, 'address 28', 'Cerebro', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 108, 2, NULL, NULL, 0),
|
||||
(129, 'address 29', 'Luke Cages Bar', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 110, 2, NULL, NULL, 0);
|
||||
|
||||
INSERT INTO `vn`.`clientCredit`(`id`, `clientFk`, `workerFk`, `amount`, `created`)
|
||||
VALUES
|
||||
|
@ -529,12 +529,12 @@ INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`,
|
|||
|
||||
INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `price`, `discount`, `reserved`, `isPicked`, `created`)
|
||||
VALUES
|
||||
( 1, 1, 1 , 'Gem of Time', 5, 9.10, 0, 0, 0, CURDATE()),
|
||||
( 2, 2, 1 , 'Gem of Mind', 10, 1.07, 0, 0, 0, CURDATE()),
|
||||
( 3, 1, 1 , 'Gem of Time', 2, 9.10, 0, 0, 0, CURDATE()),
|
||||
( 4, 4, 1 , 'Mark I' , 20, 3.06, 0, 0, 0, CURDATE()),
|
||||
( 5, 1, 2 , 'Gem of Time', 10, 9.10, 0, 0, 0, CURDATE()),
|
||||
( 6, 1, 3 , 'Gem of Time', 15, 6.50, 0, 0, 0, CURDATE()),
|
||||
( 1, 1, 1 , 'Gem of Time', 5, 9.10, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
( 2, 2, 1 , 'Gem of Mind', 10, 1.07, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
( 3, 1, 1 , 'Gem of Time', 2, 9.10, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
( 4, 4, 1 , 'Mark I' , 20, 3.06, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
( 5, 1, 2 , 'Gem of Time', 10, 9.10, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -10 DAY)),
|
||||
( 6, 1, 3 , 'Gem of Time', 15, 6.50, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -5 DAY)),
|
||||
( 7, 2, 11, 'Gem of Mind', 15, 1.30, 0, 0, 0, CURDATE()),
|
||||
( 8, 4, 11, 'Mark I' , 10, 3.26, 0, 0, 0, CURDATE()),
|
||||
( 9, 1, 16, 'Gem of Time', 5, 9.10, 0, 0, 0, CURDATE()),
|
||||
|
@ -837,9 +837,79 @@ INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_
|
|||
|
||||
INSERT INTO `hedera`.`orderRow`(`id`, `orderFk`, `itemFk`, `warehouseFk`, `shipment`, `amount`, `price`, `rate`, `created`, `saleFk`)
|
||||
VALUES
|
||||
( 1, 1, 1, 1 , NULL , 9, 1.5 , 1, CURDATE(), 1),
|
||||
( 2, 2, 2, 1 , NULL , 5, 1.23, 2, CURDATE(), 2),
|
||||
( 3, 3, 3, 2 , CURDATE(), 3, 0.50, 3, CURDATE(), 3);
|
||||
( 1, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 5, 9.10, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 1),
|
||||
( 2, 1, 2, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 10, 1.07, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 2),
|
||||
( 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 2, 9.10, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 3),
|
||||
( 4, 1, 4, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 20, 3.06, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 4),
|
||||
( 5, 2, 1, 1, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 10, 9.10, 0, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 5),
|
||||
( 6, 3, 1, 2, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 15, 6.50, 0, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 6),
|
||||
( 7, 11, 2, 1, CURDATE(), 15, 1.30, 0, CURDATE(), 7),
|
||||
( 8, 11, 4, 1, CURDATE(), 10, 3.26, 0, CURDATE(), 8),
|
||||
( 9, 16, 1, 1, CURDATE(), 5, 9.10, 0, CURDATE(), 9),
|
||||
( 10, 16, 2, 1, CURDATE(), 10, 1.07, 0, CURDATE(), 10),
|
||||
( 11, 16, 1, 1, CURDATE(), 2, 9.10, 0, CURDATE(), 11),
|
||||
( 12, 16, 4, 1, CURDATE(), 20, 3.06, 0, CURDATE(), 12);
|
||||
|
||||
INSERT INTO `hedera`.`orderRowComponent`(`rowFk`, `componentFk`, `price`)
|
||||
VALUES
|
||||
( 1, 15, 0.58),
|
||||
( 1, 23, 6.5),
|
||||
( 1, 28, 20.72),
|
||||
( 1, 29, -18.72),
|
||||
( 1, 39, 0.02),
|
||||
( 2, 15, 0.058),
|
||||
( 2, 21, 0.002),
|
||||
( 2, 28, 5.6),
|
||||
( 2, 29, -4.6),
|
||||
( 2, 39, 0.01),
|
||||
( 3, 15, 0.58),
|
||||
( 3, 23, 6.5),
|
||||
( 3, 28, 20.72),
|
||||
( 3, 29, -18.72),
|
||||
( 3, 39, 0.02),
|
||||
( 4, 15, 0.051),
|
||||
( 4, 21, -0.001),
|
||||
( 4, 28, 20.72),
|
||||
( 4, 29, -19.72),
|
||||
( 4, 37, 2),
|
||||
( 4, 39, 0.01),
|
||||
( 5, 15, 0.58),
|
||||
( 5, 23, 6.5),
|
||||
( 5, 28, 20.72),
|
||||
( 5, 29, -18.72),
|
||||
( 5, 39, 0.02),
|
||||
( 6, 23, 6.5),
|
||||
( 7, 15, 0.29),
|
||||
( 7, 28, 5.6),
|
||||
( 7, 29, -4.6),
|
||||
( 7, 39, 0.01),
|
||||
( 8, 15, 0.254),
|
||||
( 8, 21, -0.004),
|
||||
( 8, 28, 20.72),
|
||||
( 8, 29, -19.72),
|
||||
( 8, 37, 2),
|
||||
( 8, 39, 0.01),
|
||||
( 9, 15, 0.58),
|
||||
( 9, 23, 6.5),
|
||||
( 9, 28, 20.72),
|
||||
( 9, 29, -18.72),
|
||||
( 9, 39, 0.02),
|
||||
( 10, 15, 0.058),
|
||||
( 10, 21, 0.002),
|
||||
( 10, 28, 5.6),
|
||||
( 10, 29, -4.6),
|
||||
( 10, 39, 0.01),
|
||||
( 11, 15, 0.58),
|
||||
( 11, 23, 6.5),
|
||||
( 11, 28, 20.72),
|
||||
( 11, 29, -18.72),
|
||||
( 11, 39, 0.02),
|
||||
( 12, 15, 0.051),
|
||||
( 12, 22, -0.001),
|
||||
( 12, 28, 20.72),
|
||||
( 12, 29, -19.72),
|
||||
( 12, 37, 2),
|
||||
( 12, 39, 0.01);
|
||||
|
||||
INSERT INTO `vn`.`clientContact`(`id`, `clientFk`, `name`, `phone`)
|
||||
VALUES
|
||||
|
|
|
@ -52,5 +52,8 @@
|
|||
"Warehouse cannot be blank": "El almacén no puede quedar en blanco",
|
||||
"Agency cannot be blank": "La agencia no puede quedar en blanco",
|
||||
"You don't have enough privileges to do that": "No tienes permisos para para hacer esto",
|
||||
"This address doesn't exist": "This address doesn't exist"
|
||||
"This address doesn't exist": "Este consignatario no existe",
|
||||
"The sales of this ticket can't be modified": "Los movimientos de este tiquet no pueden ser modificadas",
|
||||
"You can't create an order for a inactive client": "You can't create an order for a inactive client",
|
||||
"You can't create an order for a client that doesn't has tax data verified": "You can't create an order for a client that doesn't has tax data verified"
|
||||
}
|
|
@ -51,14 +51,26 @@ module.exports = Self => {
|
|||
userId: userId
|
||||
};
|
||||
|
||||
let newTicket = await model.Ticket.new(newTicketParams);
|
||||
let transaction = await Self.beginTransaction({});
|
||||
try {
|
||||
let newTicket = await model.Ticket.new(newTicketParams, {transaction: transaction});
|
||||
|
||||
let promises = [];
|
||||
for (let i = 0; i < params.sales.length; i++) {
|
||||
promises.push(model.Sale.update({id: params.sales[i].id}, {ticketFk: newTicket}));
|
||||
let selectedSalesId = [];
|
||||
params.sales.forEach(sale => {
|
||||
selectedSalesId.push(sale.id);
|
||||
});
|
||||
|
||||
await model.Sale.updateAll(
|
||||
{id: {inq: selectedSalesId}},
|
||||
{ticketFk: newTicket.id},
|
||||
{transaction: transaction});
|
||||
|
||||
await transaction.commit();
|
||||
|
||||
return newTicket;
|
||||
} catch (e) {
|
||||
await transaction.rollback();
|
||||
throw e;
|
||||
}
|
||||
await Promise.all(promises);
|
||||
|
||||
return newTicket;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const app = require(`${servicesDir}/ticket/server/server`);
|
||||
|
||||
describe('ticket listSaleTracking()', () => {
|
||||
xdescribe('ticket listSaleTracking()', () => {
|
||||
it('should throw an error if the ticket is not editable and the user isnt production', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 110}}};
|
||||
let params = {ticketFk: 2, stateFk: 3};
|
||||
|
|
|
@ -22,7 +22,12 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
Self.new = async(params, transaction) => {
|
||||
let existsAddress = await Self.app.models.Address.findOne({where: {id: params.addressFk, clientFk: params.clientFk}});
|
||||
let existsAddress = await Self.app.models.Address.findOne({
|
||||
where: {
|
||||
id: params.addressFk,
|
||||
clientFk: params.clientFk}
|
||||
});
|
||||
|
||||
if (!existsAddress)
|
||||
throw new UserError(`This address doesn't exist`);
|
||||
|
||||
|
@ -40,6 +45,8 @@ module.exports = Self => {
|
|||
params.userId
|
||||
], transaction);
|
||||
|
||||
return result[1][0].newTicketId;
|
||||
return await Self.findOne({
|
||||
where: {id: result[1][0].newTicketId}
|
||||
}, transaction);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
const app = require(`${servicesDir}/ticket/server/server`);
|
||||
|
||||
describe('ticket new()', () => {
|
||||
let ticketId;
|
||||
let ticket;
|
||||
let today = new Date();
|
||||
|
||||
afterAll(async() => {
|
||||
await app.models.Ticket.destroyById(ticketId);
|
||||
await app.models.Ticket.destroyById(ticket.id);
|
||||
});
|
||||
|
||||
it('should throw an error if the address doesnt exist', async() => {
|
||||
|
@ -33,10 +33,10 @@ describe('ticket new()', () => {
|
|||
landed: today
|
||||
};
|
||||
|
||||
ticketId = await app.models.Ticket.new(params);
|
||||
ticket = await app.models.Ticket.new(params);
|
||||
|
||||
let newestTicketIdInFixtures = 21;
|
||||
|
||||
expect(ticketId).toBeGreaterThan(newestTicketIdInFixtures);
|
||||
expect(ticket.id).toBeGreaterThan(newestTicketIdInFixtures);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -187,8 +187,8 @@ module.exports = function(Self) {
|
|||
});
|
||||
};
|
||||
|
||||
Self.rawStmt = function(stmt) {
|
||||
return this.rawSql(stmt.sql, stmt.params);
|
||||
Self.rawStmt = function(stmt, options = {}) {
|
||||
return this.rawSql(stmt.sql, stmt.params, options);
|
||||
};
|
||||
|
||||
Self.escapeName = function(name) {
|
||||
|
|
|
@ -23,7 +23,7 @@ module.exports = Self => {
|
|||
let query = `CALL hedera.orderGetTax(?);
|
||||
SELECT * FROM tmp.orderTax;`;
|
||||
let res = await Self.rawSql(query, [orderFk]);
|
||||
let [taxes] = res[1];
|
||||
let taxes = res[1];
|
||||
|
||||
return taxes;
|
||||
};
|
||||
|
|
|
@ -23,6 +23,6 @@ module.exports = Self => {
|
|||
let query = `SELECT hedera.orderGetTotal(?) total;`;
|
||||
let [total] = await Self.rawSql(query, [orderFk]);
|
||||
|
||||
return total;
|
||||
return total.total;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('getVAT', {
|
||||
description: 'Returns order total VAT',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'order id',
|
||||
http: {source: 'path'}
|
||||
}],
|
||||
returns: {
|
||||
type: 'number',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:id/getVAT`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.getVAT = async orderId => {
|
||||
let totalTax = 0.00;
|
||||
let taxes = await Self.app.models.Order.getTaxes(orderId);
|
||||
taxes.forEach(tax => {
|
||||
totalTax += tax.tax;
|
||||
});
|
||||
|
||||
return Math.round(totalTax * 100) / 100;
|
||||
};
|
||||
};
|
|
@ -20,8 +20,11 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
Self.new = async params => {
|
||||
let clientFkByAddress = await Self.app.models.Address.findOne({where: {id: params.addressFk}, fields: 'clientFk'});
|
||||
let clientFk = clientFkByAddress.clientFk;
|
||||
let address = await Self.app.models.Address.findOne({
|
||||
where: {id: params.addressFk},
|
||||
fields: 'clientFk'
|
||||
});
|
||||
let clientFk = address.clientFk;
|
||||
|
||||
let client = await Self.app.models.Client.findOne({
|
||||
where: {id: clientFk},
|
||||
|
|
|
@ -4,18 +4,19 @@ describe('order getTaxes()', () => {
|
|||
it('should call the getTaxes method and return undefined if its called with a string', async() => {
|
||||
let result = await app.models.Order.getTaxes('pepinillos');
|
||||
|
||||
expect(result).toEqual(undefined);
|
||||
expect(result.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should call the getTaxes method and return undefined if its called with unknown id', async() => {
|
||||
let result = await app.models.Order.getTaxes(99999999999999999999999);
|
||||
|
||||
expect(result).toEqual(undefined);
|
||||
expect(result.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should call the getTaxes method and return the taxes if its called with a known id', async() => {
|
||||
let result = await app.models.Order.getTaxes(1);
|
||||
|
||||
expect(result.tax).toEqual(0.95);
|
||||
expect(result[0].tax).toEqual(9.49);
|
||||
expect(result.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,7 +4,7 @@ describe('order getTotalVolume()', () => {
|
|||
it('should return the total', async() => {
|
||||
let result = await app.models.Order.getTotalVolume(1);
|
||||
|
||||
expect(result.totalVolume).toEqual(0.072);
|
||||
expect(result.totalVolume).toEqual(0.078);
|
||||
expect(result.totalBoxes).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
const app = require(`${servicesDir}/order/server/server`);
|
||||
|
||||
describe('order getVAT()', () => {
|
||||
it('should call the getVAT method and return the response', async() => {
|
||||
await app.models.Order.getVAT(1)
|
||||
.then(response => {
|
||||
expect(response).toEqual(9.49);
|
||||
});
|
||||
});
|
||||
|
||||
it(`should call the getVAT method and return zero if doesn't have lines`, async() => {
|
||||
await app.models.Order.getVAT(13)
|
||||
.then(response => {
|
||||
expect(response).toEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -4,6 +4,6 @@ describe('order getVolumes()', () => {
|
|||
it('should return the volumes of a given order id', async() => {
|
||||
let [result] = await app.models.Order.getVolumes(1);
|
||||
|
||||
expect(result.volume).toEqual(0.072);
|
||||
expect(result.volume).toEqual(0.04);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
const app = require(`${servicesDir}/order/server/server`);
|
||||
|
||||
describe('order summary()', () => {
|
||||
it('should return a summary object containing data from 1 order', async() => {
|
||||
let result = await app.models.Order.summary(1);
|
||||
|
||||
expect(result.id).toEqual(1);
|
||||
expect(result.clientFk).toEqual(101);
|
||||
});
|
||||
|
||||
it('should return a summary object containing sales from 1 order', async() => {
|
||||
let result = await app.models.Order.summary(1);
|
||||
|
||||
expect(result.rows.length).toEqual(3);
|
||||
});
|
||||
|
||||
it('should return a summary object containing subTotal for 1 order', async() => {
|
||||
let result = await app.models.Order.summary(1);
|
||||
|
||||
expect(Math.round(result.subTotal * 100) / 100).toEqual(135.60);
|
||||
});
|
||||
|
||||
it('should return a summary object containing VAT for 1 order', async() => {
|
||||
let result = await app.models.Order.summary(1);
|
||||
|
||||
expect(Math.round(result.VAT * 100) / 100).toEqual(9.49);
|
||||
});
|
||||
|
||||
it('should return a summary object containing total for 1 order', async() => {
|
||||
let result = await app.models.Order.summary(1);
|
||||
let total = result.subTotal + result.VAT;
|
||||
let expectedTotal = Math.round(total * 100) / 100;
|
||||
|
||||
expect(result.total).toEqual(expectedTotal);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,87 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('summary', {
|
||||
description: 'Returns a summary for a given order id',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'order id',
|
||||
http: {source: 'path'}
|
||||
}],
|
||||
returns: {
|
||||
type: [this.modelName],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:id/summary`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.summary = async orderId => {
|
||||
let models = Self.app.models;
|
||||
let summary = await getOrderData(Self, orderId);
|
||||
summary.subTotal = getSubTotal(summary.rows);
|
||||
summary.VAT = await models.Order.getVAT(orderId);
|
||||
summary.total = await models.Order.getTotal(orderId);
|
||||
|
||||
return summary;
|
||||
};
|
||||
|
||||
async function getOrderData(Self, orderId) {
|
||||
let filter = {
|
||||
include: [
|
||||
{relation: 'agencyMode', scope: {fields: ['name']}},
|
||||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['salesPersonFk', 'name'],
|
||||
include: {
|
||||
relation: 'salesPerson',
|
||||
fields: ['firstName', 'name']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'address',
|
||||
scope: {
|
||||
fields: ['street', 'city', 'provinceFk', 'phone', 'nickname'],
|
||||
include: {
|
||||
relation: 'province',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'rows',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'item',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'tags'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
where: {id: orderId}
|
||||
};
|
||||
|
||||
return await Self.findOne(filter);
|
||||
}
|
||||
|
||||
function getSubTotal(rows) {
|
||||
let subTotal = 0.00;
|
||||
|
||||
rows().forEach(row => {
|
||||
subTotal += row.quantity * row.price;
|
||||
});
|
||||
|
||||
return subTotal;
|
||||
}
|
||||
};
|
|
@ -6,4 +6,6 @@ module.exports = Self => {
|
|||
require('../methods/order/isEditable')(Self);
|
||||
require('../methods/order/getTotal')(Self);
|
||||
require('../methods/order/catalogFilter')(Self);
|
||||
require('../methods/order/summary')(Self);
|
||||
require('../methods/order/getVAT')(Self);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const app = require(`${servicesDir}/ticket/server/server`);
|
||||
|
||||
describe('ticket listSaleTracking()', () => {
|
||||
xdescribe('ticket listSaleTracking()', () => {
|
||||
it('should call the listSaleTracking method and return the response', async() => {
|
||||
let filter = {where: {ticketFk: 1}};
|
||||
let result = await app.models.SaleTracking.listSaleTracking(filter);
|
||||
|
|
Loading…
Reference in New Issue