Merge branch 'dev' of http://git.verdnatura.es/salix into dev
This commit is contained in:
commit
f9bb1128a2
|
@ -332,6 +332,15 @@
|
|||
"params": {
|
||||
"client": "$ctrl.client"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "/web-payment",
|
||||
"state": "client.card.webPayment",
|
||||
"component": "vn-client-web-payment",
|
||||
"description": "Web Payment",
|
||||
"menu": {
|
||||
"icon": "web"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -31,3 +31,4 @@ import './credit-insurance/insurance/create';
|
|||
import './contact';
|
||||
import './sample/index';
|
||||
import './sample/create';
|
||||
import './web-payment';
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/client/api/clients/getTransactions"
|
||||
filter="{}"
|
||||
link="{clientFk: $ctrl.$stateParams.id}"
|
||||
limit="20"
|
||||
data="transactions">
|
||||
</vn-crud-model>
|
||||
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-title>Web Payment</vn-title>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th></vn-th>
|
||||
<vn-th field="id">Id</vn-th>
|
||||
<vn-th field="amount" number>Amount</vn-th>
|
||||
<vn-th field="created" default-order="DESC">Payed</vn-th>
|
||||
<vn-th></vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="transaction in transactions">
|
||||
<vn-td style="width: 3em; text-align: center">
|
||||
<vn-icon orange pointer
|
||||
vn-tooltip="Confirm transaction"
|
||||
ng-click="$ctrl.confirm(transaction)"
|
||||
ng-show="::!transaction.isConfirmed"
|
||||
icon="check">
|
||||
</vn-icon>
|
||||
</vn-td>
|
||||
<vn-td>{{::transaction.id}}</vn-td>
|
||||
<vn-td number>{{::transaction.amount | currency: '€ '}}</vn-td>
|
||||
<vn-td>{{::transaction.created | date:'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td>
|
||||
<vn-icon orange
|
||||
vn-tooltip="{{$ctrl.getFormattedMessage(transaction)}}"
|
||||
ng-show="::(transaction.errorMessage || transaction.responseMessage)"
|
||||
icon="warning">
|
||||
</vn-icon>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
</vn-card>
|
||||
</vn-vertical>
|
|
@ -0,0 +1,33 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, $http, $stateParams) {
|
||||
this.$scope = $scope;
|
||||
this.$http = $http;
|
||||
this.$stateParams = $stateParams;
|
||||
}
|
||||
|
||||
confirm(transaction) {
|
||||
const path = '/client/api/Clients/confirmTransaction';
|
||||
let data = {id: transaction.id};
|
||||
this.$http.post(path, data).then(res => {
|
||||
this.$scope.model.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
getFormattedMessage(transaction) {
|
||||
const errorMessage = transaction.errorMessage ? transaction.errorMessage : '';
|
||||
const separator = transaction.errorMessage && transaction.responseMessage ? '<br/>' : '';
|
||||
const responseMessage = transaction.responseMessage ? transaction.responseMessage : '';
|
||||
return `<strong style="font-size:13px">${errorMessage}</strong>`
|
||||
+ separator
|
||||
+ `<span style="font-size:13px">${responseMessage}</span>`;
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$http', '$stateParams'];
|
||||
|
||||
ngModule.component('vnClientWebPayment', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -0,0 +1,50 @@
|
|||
import './index';
|
||||
import {crudModel} from '../../../helpers/crudModelHelper';
|
||||
|
||||
describe('Component vnClientWebPayment', () => {
|
||||
let $componentController;
|
||||
let $httpBackend;
|
||||
let $scope;
|
||||
let vnApp;
|
||||
let controller;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('client');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_, _vnApp_) => {
|
||||
$componentController = _$componentController_;
|
||||
$scope = $rootScope.$new();
|
||||
$scope.model = crudModel;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
vnApp = _vnApp_;
|
||||
spyOn(vnApp, 'showError');
|
||||
controller = $componentController('vnClientWebPayment', {$scope: $scope});
|
||||
}));
|
||||
|
||||
describe('confirm()', () => {
|
||||
it(`should confirm a transaction`, () => {
|
||||
let transaction = {id: 1};
|
||||
let query = '/client/api/Clients/confirmTransaction';
|
||||
|
||||
controller.confirm(transaction);
|
||||
$httpBackend.when('POST', query, transaction).respond('ok');
|
||||
$httpBackend.expect('POST', query, transaction);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFormattedMessage()', () => {
|
||||
it(`should return error message and response Message`, () => {
|
||||
let transaction = {
|
||||
errorMessage: 'My error message',
|
||||
responseMessage: 'My response message'
|
||||
};
|
||||
let result = controller.getFormattedMessage(transaction);
|
||||
|
||||
expect(result).toContain('My error message');
|
||||
expect(result).toContain('My response message');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
Web Payment: Pago Web
|
||||
Confirmed: Confirmado
|
||||
Payed: Pagado
|
||||
Confirm transaction: Confirmar transacción
|
|
@ -4,8 +4,7 @@
|
|||
filter="{}"
|
||||
link="{ticketFk: $ctrl.$stateParams.id}"
|
||||
limit="20"
|
||||
data="sales"
|
||||
on-data-change="$ctrl.getTags()">
|
||||
data="sales">
|
||||
</vn-crud-model>
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
|
|
|
@ -50,5 +50,6 @@
|
|||
"A claim with that sale already exists": "Ya existe una reclamación para esta línea",
|
||||
"You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo",
|
||||
"Warehouse cannot be blank": "El almacén no puede quedar en blanco",
|
||||
"Agency cannot be blank": "La agencia 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"
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
const UserError = require('../../../common/helpers').UserError;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('confirmTransaction', {
|
||||
description: 'Returns last entries',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'Transaction id'
|
||||
}],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/confirmTransaction`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.confirmTransaction = async(ctx, id) => {
|
||||
let userId = ctx.req.accessToken.userId;
|
||||
let isAdministrative = await Self.app.models.Account.hasRole(userId, 'administrative');
|
||||
|
||||
if (!isAdministrative)
|
||||
throw new UserError(`You don't have enough privileges to do that`);
|
||||
|
||||
return await Self.rawSql('CALL hedera.tpvTransactionConfirmById(?)', [id]);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('getTransactions', {
|
||||
description: 'Returns last entries',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'filter',
|
||||
type: 'Object',
|
||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||
http: {source: 'query'}
|
||||
}],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/getTransactions`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.getTransactions = async filter => {
|
||||
let stmt = new ParameterizedSQL(`
|
||||
SELECT
|
||||
t.id,
|
||||
t.clientFk,
|
||||
t.created,
|
||||
t.amount / 100 amount,
|
||||
t.receiptFk IS NOT NULL AS isConfirmed,
|
||||
tt.message responseMessage,
|
||||
te.message errorMessage
|
||||
FROM hedera.tpvTransaction t
|
||||
JOIN hedera.tpvMerchant m ON m.id = t.merchantFk
|
||||
LEFT JOIN hedera.tpvResponse tt ON tt.id = t.response
|
||||
LEFT JOIN hedera.tpvError te ON te.code = errorCode`);
|
||||
|
||||
stmt.merge(Self.buildSuffix(filter, 't'));
|
||||
|
||||
return await Self.rawStmt(stmt);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
const app = require(`${servicesDir}/client/server/server`);
|
||||
|
||||
describe('Client confirmTransaction', () => {
|
||||
const transactionId = 2;
|
||||
|
||||
afterAll(async() => {
|
||||
await app.models.Client.rawSql(`
|
||||
CALL hedera.tpvTransactionUndo(?)`, [transactionId]);
|
||||
});
|
||||
|
||||
it('should call confirmTransaction() method and throw error for a non administrative person', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 1}}};
|
||||
let error;
|
||||
await app.models.Client.confirmTransaction(ctx, transactionId).catch(e => {
|
||||
error = e;
|
||||
}).finally(() => {
|
||||
expect(error.message).toEqual(`You don't have enough privileges to do that`);
|
||||
});
|
||||
});
|
||||
|
||||
it('should call confirmTransaction() method to mark transaction as confirmed', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 5}}};
|
||||
await app.models.Client.confirmTransaction(ctx, transactionId);
|
||||
|
||||
let [receipt] = await app.models.Client.rawSql(
|
||||
`SELECT receiptFk
|
||||
FROM hedera.tpvTransaction
|
||||
WHERE id = ?`, [transactionId]);
|
||||
|
||||
expect(receipt.receiptFk).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
const app = require(`${servicesDir}/client/server/server`);
|
||||
|
||||
describe('Client getTransations', () => {
|
||||
it('should call getTransations() method to receive a list of Web Payments from Bruce Wayne', async() => {
|
||||
let filter = {where: {clientFk: 101}};
|
||||
let result = await app.models.Client.getTransactions(filter);
|
||||
|
||||
expect(result[1].id).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -19,6 +19,8 @@ module.exports = Self => {
|
|||
require('../methods/client/updateFiscalData')(Self);
|
||||
require('../methods/client/updateBillingData')(Self);
|
||||
require('../methods/client/updateBasicData')(Self);
|
||||
require('../methods/client/getTransactions')(Self);
|
||||
require('../methods/client/confirmTransaction')(Self);
|
||||
|
||||
// Validations
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
|
||||
const ParameterizedSQL = require('vn-loopback/node_modules/loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('listSaleTracking', {
|
||||
description: 'Returns all ticket sale trackings',
|
||||
|
@ -20,40 +23,27 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
Self.listSaleTracking = async filter => {
|
||||
let where = '';
|
||||
let limit = '';
|
||||
let order = '';
|
||||
let params;
|
||||
let stmt = new ParameterizedSQL(`
|
||||
SELECT
|
||||
st.id,
|
||||
s.ticketFk,
|
||||
s.quantity,
|
||||
s.concept,
|
||||
s.itemFk,
|
||||
st.originalQuantity,
|
||||
st.created,
|
||||
st.workerFk,
|
||||
w.firstName,
|
||||
w.name,
|
||||
ste.name AS state
|
||||
FROM saleTracking st
|
||||
JOIN sale s ON s.id = st.saleFk
|
||||
JOIN worker w ON w.id = st.workerFk
|
||||
JOIN state ste ON ste.id = st.stateFk`);
|
||||
|
||||
if (filter) {
|
||||
let connector = Self.dataSource.connector;
|
||||
if (filter.where) {
|
||||
where = 'WHERE s.ticketFk = ?';
|
||||
params = [filter.where.ticketFk];
|
||||
}
|
||||
stmt.merge(Self.buildSuffix(filter));
|
||||
|
||||
limit = connector._buildLimit(null, filter.limit, filter.skip);
|
||||
order = connector.buildOrderBy('Item', filter.order);
|
||||
}
|
||||
|
||||
let query = `SELECT
|
||||
st.id,
|
||||
s.quantity,
|
||||
s.concept,
|
||||
s.itemFk,
|
||||
st.originalQuantity,
|
||||
st.created,
|
||||
st.workerFk,
|
||||
w.firstName,
|
||||
w.name,
|
||||
ste.name AS state
|
||||
FROM saleTracking st
|
||||
JOIN sale s ON s.id = st.saleFK
|
||||
JOIN worker w ON w.id = st.workerFk
|
||||
JOIN ticketState ts ON ts.ticketFk = s.ticketFk
|
||||
JOIN state ste ON ste.id = ts.stateFK ${where} ${order} ${limit}`;
|
||||
|
||||
let trackings = await Self.rawSql(query, params);
|
||||
let trackings = await Self.rawStmt(stmt);
|
||||
|
||||
let salesFilter = {
|
||||
include: [
|
||||
|
|
Loading…
Reference in New Issue