Tarea #445 claim.detail
This commit is contained in:
parent
e698d84a4f
commit
61b9b0c7bc
|
@ -20,10 +20,10 @@
|
|||
<vn-label-value label="Created"
|
||||
value="{{$ctrl.claim.created | dateTime: 'dd/MM/yyyy'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Buyer"
|
||||
<vn-label-value label="Salesperson"
|
||||
value="{{$ctrl.claim.client.salesPerson.firstName}} {{$ctrl.claim.client.salesPerson.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Attended"
|
||||
<vn-label-value label="Attended by"
|
||||
value="{{$ctrl.claim.worker.firstName}} {{$ctrl.claim.worker.name}}">
|
||||
</vn-label-value>
|
||||
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="claim/api/ClaimBeginnings"
|
||||
filter="$ctrl.filter"
|
||||
data="$ctrl.salesClaimed" on-data-change="$ctrl.onDataChange()">
|
||||
</vn-crud-model>
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-title>Detail</vn-title>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number>Id</vn-th>
|
||||
<vn-th number>Landed</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th number>Claimed</vn-th>
|
||||
<vn-th number>Description</vn-th>
|
||||
<vn-th number>Price</vn-th>
|
||||
<vn-th number>Disc.</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="saleClaimed in $ctrl.salesClaimed" vn-repeat-last on-last="$ctrl.focusLastInput()">
|
||||
<vn-td number>{{saleClaimed.sale.id}}</vn-td>
|
||||
<vn-td number>{{saleClaimed.sale.ticket.landed | dateTime: 'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{saleClaimed.sale.quantity}}</vn-td>
|
||||
<vn-td number>
|
||||
<vn-textfield
|
||||
id="claimedQuantity"
|
||||
model="saleClaimed.quantity"
|
||||
on-change="$ctrl.setClaimedQuantity(saleClaimed.id, saleClaimed.quantity)"
|
||||
type="text">
|
||||
</vn-textfield>
|
||||
</vn-td>
|
||||
<vn-td number>{{saleClaimed.sale.concept}}</vn-td>
|
||||
<vn-td number>{{saleClaimed.sale.price | currency:'€':2}}</vn-td>
|
||||
<vn-td number>{{saleClaimed.sale.discount}} %</vn-td>
|
||||
<vn-td number>
|
||||
{{(saleClaimed.sale.quantity * saleClaimed.sale.price) -
|
||||
((saleClaimed.sale.discount *
|
||||
(saleClaimed.sale.quantity * saleClaimed.sale.price))/100) | currency:'€':2
|
||||
}}
|
||||
</vn-td>
|
||||
<vn-td number>
|
||||
<vn-icon-button
|
||||
medium-grey
|
||||
margin-medium-v
|
||||
vn-tooltip="Remove tag"
|
||||
icon="remove_circle_outline"
|
||||
ng-click="$ctrl.deleteClaimedSale(saleClaimed.id)"
|
||||
tabindex="-1">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
<vn-one pad-medium-top>
|
||||
<vn-icon-button
|
||||
vn-bind="+"
|
||||
vn-tooltip="Add tag"
|
||||
icon="add_circle"
|
||||
ng-click="$ctrl.openAddSalesDialog()">
|
||||
</vn-icon-button>
|
||||
</vn-one>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
|
||||
<!-- Add Lines Dialog -->
|
||||
<vn-dialog
|
||||
vn-id="addSales">
|
||||
<tpl-body>
|
||||
<h3 translate>Claimable sales from ticket</h3><h3> {{$ctrl.claim.ticketFk}}</h3>
|
||||
<vn-table>
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number>Id</vn-th>
|
||||
<vn-th number>Landed</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th number>Description</vn-th>
|
||||
<vn-th number>Price</vn-th>
|
||||
<vn-th number>Disc.</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="sale in $ctrl.salesToClaim" class="clickable" ng-click="$ctrl.addClaimedSale(sale.saleFk)">
|
||||
<vn-td number>{{sale.saleFk}}</vn-td>
|
||||
<vn-td number>{{sale.landed | dateTime: 'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{sale.quantity}}</vn-td>
|
||||
<vn-td number>{{sale.concept}}</vn-td>
|
||||
<vn-td number>{{sale.price | currency:'€':2}}</vn-td>
|
||||
<vn-td number>{{sale.discount}} %</vn-td>
|
||||
<vn-td number>
|
||||
{{(sale.quantity * sale.price) - ((sale.discount * (sale.quantity * sale.price))/100) | currency:'€':2}}
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</tpl-body>
|
||||
</vn-dialog>
|
|
@ -0,0 +1,84 @@
|
|||
import ngModule from '../module';
|
||||
import './style.scss';
|
||||
|
||||
class Controller {
|
||||
constructor($state, $scope, $http, $translate, vnApp) {
|
||||
this.$state = $state;
|
||||
this.$ = $scope;
|
||||
this.$http = $http;
|
||||
this.$translate = $translate;
|
||||
this.vnApp = vnApp;
|
||||
this.filter = {
|
||||
where: {claimFk: $state.params.id},
|
||||
include: [
|
||||
{relation: 'sale',
|
||||
scope: {
|
||||
fields: ['concept', 'ticketFk', 'price', 'quantity', 'discount'],
|
||||
include: {
|
||||
relation: 'ticket'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
openAddSalesDialog() {
|
||||
this.getClaimableFromTicket();
|
||||
this.$.addSales.show();
|
||||
}
|
||||
|
||||
getClaimableFromTicket() {
|
||||
let json = encodeURIComponent(JSON.stringify(this.claim.ticketFk));
|
||||
|
||||
let query = `/api/Sales/getClaimableFromTicket?ticketFk=${json}`;
|
||||
this.$http.get(query).then(res => {
|
||||
if (res.data) {
|
||||
this.salesToClaim = res.data;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addClaimedSale(saleFk) {
|
||||
let saleToAdd = {saleFk: saleFk, claimFk: this.claim.id, quantity: 0};
|
||||
let query = `claim/api/ClaimBeginnings/`;
|
||||
this.$http.post(query, saleToAdd).then(() => {
|
||||
this.$.model.refresh();
|
||||
this.$.addSales.hide();
|
||||
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||
});
|
||||
}
|
||||
|
||||
deleteClaimedSale(id) {
|
||||
let json = encodeURIComponent(JSON.stringify(id));
|
||||
let query = `claim/api/ClaimBeginnings/${json}`;
|
||||
this.$http.delete(query).then(() => {
|
||||
this.$.model.refresh();
|
||||
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||
});
|
||||
}
|
||||
|
||||
focusLastInput() {
|
||||
let inputs = document.querySelectorAll("#claimedQuantity");
|
||||
inputs[inputs.length - 1].querySelector("input").select();
|
||||
}
|
||||
|
||||
setClaimedQuantity(id, claimedQuantity) {
|
||||
let params = {id: id, quantity: claimedQuantity};
|
||||
let query = `claim/api/ClaimBeginnings/`;
|
||||
this.$http.patch(query, params).then(() => {
|
||||
this.$.model.refresh();
|
||||
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$state', '$scope', '$http', '$translate', 'vnApp'];
|
||||
|
||||
ngModule.component('vnClaimDetail', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
claim: '<'
|
||||
}
|
||||
});
|
|
@ -0,0 +1,94 @@
|
|||
import './index.js';
|
||||
|
||||
describe('claim', () => {
|
||||
describe('Component vnClaimDetail', () => {
|
||||
let $componentController;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
let $state;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('claim');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, _$state_, _$httpBackend_, $rootScope) => {
|
||||
$componentController = _$componentController_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
$httpBackend.when('GET', 'claim/api/Claims/ClaimBeginnings').respond({});
|
||||
$state = _$state_;
|
||||
$state.params.id = 1;
|
||||
|
||||
controller = $componentController('vnClaimDetail', {$state: $state});
|
||||
controller.claim = {ticketFk: 1};
|
||||
controller.$.model = {refresh: () => {}};
|
||||
controller.$.addSales = {
|
||||
hide: () => {},
|
||||
show: () => {}
|
||||
};
|
||||
}));
|
||||
|
||||
describe('openAddSalesDialog()', () => {
|
||||
it('should call getClaimableFromTicket and $.addSales.show', () => {
|
||||
controller.$ = {addSales: {show: () => {}}};
|
||||
spyOn(controller, 'getClaimableFromTicket');
|
||||
spyOn(controller.$.addSales, 'show');
|
||||
controller.openAddSalesDialog();
|
||||
|
||||
expect(controller.getClaimableFromTicket).toHaveBeenCalledWith();
|
||||
expect(controller.$.addSales.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getClaimableFromTicket()', () => {
|
||||
it('should make a query and set salesToClaim', () => {
|
||||
$httpBackend.expectGET(`/api/Sales/getClaimableFromTicket?ticketFk=1`).respond(200, 1);
|
||||
controller.getClaimableFromTicket();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.salesToClaim).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addClaimedSale(saleFk)', () => {
|
||||
it('should make a post and call refresh, hide and showSuccess', () => {
|
||||
spyOn(controller.$.model, 'refresh');
|
||||
spyOn(controller.$.addSales, 'hide');
|
||||
spyOn(controller.vnApp, 'showSuccess');
|
||||
$httpBackend.expectPOST(`claim/api/ClaimBeginnings/`).respond({});
|
||||
controller.addClaimedSale(1);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.model.refresh).toHaveBeenCalledWith();
|
||||
expect(controller.$.addSales.hide).toHaveBeenCalledWith();
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteClaimedSale(id)', () => {
|
||||
it('should make a delete and call refresh and showSuccess', () => {
|
||||
spyOn(controller.$.model, 'refresh');
|
||||
spyOn(controller.vnApp, 'showSuccess');
|
||||
$httpBackend.expectDELETE(`claim/api/ClaimBeginnings/1`).respond({});
|
||||
controller.deleteClaimedSale(1);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.model.refresh).toHaveBeenCalledWith();
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('setClaimedQuantity(id, claimedQuantity)', () => {
|
||||
it('should make a patch and call refresh and showSuccess', () => {
|
||||
spyOn(controller.$.model, 'refresh');
|
||||
spyOn(controller.vnApp, 'showSuccess');
|
||||
$httpBackend.expectPATCH(`claim/api/ClaimBeginnings/`).respond({});
|
||||
controller.setClaimedQuantity(1, 1);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.model.refresh).toHaveBeenCalledWith();
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
Claimed: Reclamados
|
||||
Disc.: Dto.
|
||||
Attended by: Atendida por
|
||||
Landed: Recibido
|
||||
Price: Precio
|
||||
Claimable sales from ticket: Lineas reclamables del ticket
|
||||
Detail: Detalles
|
|
@ -0,0 +1,20 @@
|
|||
vn-claim-detail {
|
||||
vn-textfield {
|
||||
margin: 0!important;
|
||||
max-width: 100px;
|
||||
}
|
||||
vn-dialog[vn-id=addSales] {
|
||||
tpl-body {
|
||||
width: 950px;
|
||||
div {
|
||||
div.buttons {
|
||||
display: none;
|
||||
}
|
||||
vn-table{
|
||||
min-width: 950px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ export * from './module';
|
|||
|
||||
import './index/';
|
||||
import './card';
|
||||
import './detail';
|
||||
import './descriptor';
|
||||
import './basic-data';
|
||||
// import './summary';
|
||||
|
|
|
@ -9,4 +9,4 @@ import './zoom-image';
|
|||
import './visible-by';
|
||||
import './bind';
|
||||
import './repeat-last';
|
||||
import './title';
|
||||
import './title';
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
module.exports = Self => {
|
||||
// Validations
|
||||
|
||||
Self.validatesUniquenessOf('saleFk', {
|
||||
message: `A claim with that sale already exists`
|
||||
});
|
||||
};
|
|
@ -0,0 +1,44 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('getClaimableFromTicket', {
|
||||
description: 'Gets the claimable sales for a client',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'ticketFk',
|
||||
type: 'Number',
|
||||
required: true,
|
||||
description: 'ticketFk'
|
||||
}],
|
||||
returns: {
|
||||
type: 'string',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/getClaimableFromTicket`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.getClaimableFromTicket = async ticketFk => {
|
||||
let query = `SELECT
|
||||
s.id AS saleFk,
|
||||
t.id AS ticketFk,
|
||||
t.landed,
|
||||
s.concept,
|
||||
s.itemFk,
|
||||
s.quantity,
|
||||
s.price,
|
||||
s.discount,
|
||||
t.nickname
|
||||
FROM vn.ticket t
|
||||
INNER JOIN vn.sale s ON s.ticketFk = t.id
|
||||
LEFT JOIN vn.claimBeginning cb ON cb.saleFk = s.id
|
||||
|
||||
WHERE (t.landed) >= TIMESTAMPADD(DAY, -7, CURDATE())
|
||||
AND t.id = ? AND cb.id IS NULL
|
||||
ORDER BY t.landed DESC, t.id DESC`;
|
||||
|
||||
let claimableSales = await Self.rawSql(query, [ticketFk]);
|
||||
|
||||
return claimableSales;
|
||||
};
|
||||
};
|
|
@ -1,5 +1,6 @@
|
|||
module.exports = Self => {
|
||||
require('../methods/sale/filter')(Self);
|
||||
require('../methods/sale/getClaimableFromTicket')(Self);
|
||||
require('../methods/sale/saleComponentFilter')(Self);
|
||||
require('../methods/sale/priceDifference')(Self);
|
||||
require('../methods/sale/moveToTicket')(Self);
|
||||
|
|
Loading…
Reference in New Issue