Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 2319_show_delivery_note
This commit is contained in:
commit
fb37e156d4
42
db/docker.js
42
db/docker.js
|
@ -39,7 +39,8 @@ module.exports = class Docker {
|
|||
|
||||
let runChown = process.platform != 'linux';
|
||||
|
||||
let container = await this.execP(`docker run --env RUN_CHOWN=${runChown} -d ${dockerArgs} salix-db`);
|
||||
const healthCheck = `--health-cmd='mysqladmin ping --silent'`;
|
||||
const container = await this.execP(`docker run ${healthCheck} --env RUN_CHOWN=${runChown} -d ${dockerArgs} salix-db`);
|
||||
this.id = container.stdout;
|
||||
|
||||
try {
|
||||
|
@ -53,7 +54,7 @@ module.exports = class Docker {
|
|||
this.dbConf.port = netSettings.Ports['3306/tcp'][0]['HostPort'];
|
||||
}
|
||||
|
||||
if (runChown) await this.wait();
|
||||
await this.waitForHealthy();
|
||||
} catch (err) {
|
||||
if (this.isRandom)
|
||||
await this.rm();
|
||||
|
@ -88,6 +89,43 @@ module.exports = class Docker {
|
|||
}
|
||||
}
|
||||
|
||||
waitForHealthy() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let interval = 100;
|
||||
let elapsedTime = 0;
|
||||
let maxInterval = 4 * 60 * 1000;
|
||||
|
||||
log('Waiting for MySQL init process...');
|
||||
|
||||
async function checker() {
|
||||
elapsedTime += interval;
|
||||
let status;
|
||||
|
||||
try {
|
||||
let result = await this.execP(`docker inspect -f "{{.State.Health.Status}}" ${this.id}`);
|
||||
status = result.stdout.trimEnd();
|
||||
} catch (err) {
|
||||
return reject(new Error(err.message));
|
||||
}
|
||||
|
||||
if (status == 'unhealthy')
|
||||
return reject(new Error('Docker exited, please see the docker logs for more info'));
|
||||
|
||||
if (status == 'healthy') {
|
||||
log('MySQL process ready.');
|
||||
return resolve();
|
||||
}
|
||||
|
||||
if (elapsedTime >= maxInterval)
|
||||
reject(new Error(`MySQL not initialized whithin ${elapsedTime / 1000} secs`));
|
||||
else
|
||||
setTimeout(bindedChecker, interval);
|
||||
}
|
||||
let bindedChecker = checker.bind(this);
|
||||
bindedChecker();
|
||||
});
|
||||
}
|
||||
|
||||
wait() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const mysql = require('mysql2');
|
||||
|
|
|
@ -83,6 +83,8 @@ async function backTestOnce(done) {
|
|||
port: container.dbConf.port
|
||||
});
|
||||
|
||||
log('[Debug] dataSources', dataSources.vn);
|
||||
|
||||
let bootOptions = {dataSources};
|
||||
|
||||
let app = require(`./loopback/server/server`);
|
||||
|
@ -90,6 +92,8 @@ async function backTestOnce(done) {
|
|||
try {
|
||||
app.boot(bootOptions);
|
||||
|
||||
log('[Debug] back started');
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
const jasmine = require('gulp-jasmine');
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
"NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros",
|
||||
"ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado",
|
||||
"The current ticket can't be modified": "El ticket actual no puede ser modificado",
|
||||
"The current claim can't be modified": "La reclamación actual no puede ser modificada",
|
||||
"The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas",
|
||||
"Please select at least one sale": "Por favor selecciona al menos una linea",
|
||||
"All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket",
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('isEditable', {
|
||||
description: 'Check if a claim is editable',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'the claim id',
|
||||
http: {source: 'path'}
|
||||
}],
|
||||
returns: {
|
||||
type: 'boolean',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:id/isEditable`,
|
||||
verb: 'get'
|
||||
}
|
||||
});
|
||||
|
||||
Self.isEditable = async(ctx, id) => {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
|
||||
const isSalesAssistant = await Self.app.models.Account.hasRole(userId, 'salesAssistant');
|
||||
|
||||
let claim = await Self.app.models.Claim.findById(id, {
|
||||
fields: ['claimStateFk'],
|
||||
include: [{
|
||||
relation: 'claimState'
|
||||
}]
|
||||
});
|
||||
|
||||
const isClaimResolved = claim && claim.claimState().code == 'resolved';
|
||||
|
||||
if (!claim || (isClaimResolved && !isSalesAssistant))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('claim isEditable()', () => {
|
||||
const salesPerdonId = 18;
|
||||
const salesAssistantId = 21;
|
||||
it('should return false if the given claim does not exist', async() => {
|
||||
let ctx = {req: {accessToken: {userId: salesAssistantId}}};
|
||||
let result = await app.models.Claim.isEditable(ctx, 99999);
|
||||
|
||||
expect(result).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not be able to edit a resolved claim for a salesPerson', async() => {
|
||||
let ctx = {req: {accessToken: {userId: salesPerdonId}}};
|
||||
let result = await app.models.Claim.isEditable(ctx, 4);
|
||||
|
||||
expect(result).toEqual(false);
|
||||
});
|
||||
|
||||
it('should be able to edit a resolved claim for a salesAssistant', async() => {
|
||||
let ctx = {req: {accessToken: {userId: salesAssistantId}}};
|
||||
let result = await app.models.Claim.isEditable(ctx, 4);
|
||||
|
||||
expect(result).toEqual(true);
|
||||
});
|
||||
|
||||
it('should be able to edit a claim for a salesAssistant', async() => {
|
||||
let ctx = {req: {accessToken: {userId: salesPerdonId}}};
|
||||
let result = await app.models.Claim.isEditable(ctx, 1);
|
||||
|
||||
expect(result).toEqual(true);
|
||||
});
|
||||
});
|
|
@ -1,7 +1,30 @@
|
|||
|
||||
const UserError = require('vn-loopback/util/user-error');
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
module.exports = Self => {
|
||||
require('../methods/claim-beginning/importToNewRefundTicket')(Self);
|
||||
|
||||
Self.validatesUniquenessOf('saleFk', {
|
||||
message: `A claim with that sale already exists`
|
||||
});
|
||||
|
||||
Self.observe('before save', async ctx => {
|
||||
if (ctx.isNewInstance) return;
|
||||
await claimIsEditable(ctx);
|
||||
});
|
||||
|
||||
Self.observe('before delete', async ctx => {
|
||||
if (ctx.isNewInstance) return;
|
||||
await claimIsEditable(ctx);
|
||||
});
|
||||
|
||||
async function claimIsEditable(ctx) {
|
||||
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||
const httpCtx = {req: loopBackContext.active};
|
||||
const isEditable = await Self.app.models.Claim.isEditable(httpCtx, ctx.where.id);
|
||||
|
||||
if (!isEditable)
|
||||
throw new UserError(`The current claim can't be modified`);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -6,4 +6,5 @@ module.exports = Self => {
|
|||
require('../methods/claim/regularizeClaim')(Self);
|
||||
require('../methods/claim/uploadFile')(Self);
|
||||
require('../methods/claim/updateClaimAction')(Self);
|
||||
require('../methods/claim/isEditable')(Self);
|
||||
};
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
<vn-input-number
|
||||
min="0"
|
||||
step="1"
|
||||
disabled="!$ctrl.isRewritable"
|
||||
ng-model="saleClaimed.quantity"
|
||||
on-change="$ctrl.setClaimedQuantity(saleClaimed.id, saleClaimed.quantity)"
|
||||
class="dense">
|
||||
|
@ -66,6 +67,7 @@
|
|||
<vn-td shrink>
|
||||
<vn-icon-button
|
||||
vn-tooltip="Remove sale"
|
||||
ng-if ="$ctrl.isRewritable"
|
||||
icon="delete"
|
||||
ng-click="$ctrl.deleteClaimedSale($index)"
|
||||
tabindex="-1">
|
||||
|
@ -76,9 +78,13 @@
|
|||
</vn-table>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
<a ng-click="$ctrl.openAddSalesDialog()" vn-tooltip="Add sale item" vn-bind="+" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
||||
<vn-float-button
|
||||
icon="add"
|
||||
ng-if="$ctrl.isRewritable"
|
||||
ng-click="$ctrl.openAddSalesDialog()"
|
||||
vn-tooltip="Add sale item" vn-bind="+"
|
||||
fixed-bottom-right>
|
||||
</vn-float-button>
|
||||
<!-- Add Lines Dialog -->
|
||||
<vn-dialog vn-id="add-sales" class="modal-form">
|
||||
<tpl-title>
|
||||
|
|
|
@ -28,6 +28,7 @@ class Controller extends Section {
|
|||
if (value) {
|
||||
this.calculateTotals();
|
||||
this.isClaimEditable();
|
||||
this.isTicketEditable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +135,7 @@ class Controller extends Section {
|
|||
});
|
||||
}
|
||||
|
||||
isClaimEditable() {
|
||||
isTicketEditable() {
|
||||
if (!this.claim) return;
|
||||
|
||||
this.$http.get(`Tickets/${this.claim.ticketFk}/isEditable`).then(res => {
|
||||
|
@ -142,6 +143,14 @@ class Controller extends Section {
|
|||
});
|
||||
}
|
||||
|
||||
isClaimEditable() {
|
||||
if (!this.claim) return;
|
||||
|
||||
this.$http.get(`Claims/${this.claim.id}/isEditable`).then(res => {
|
||||
this.isRewritable = res.data;
|
||||
});
|
||||
}
|
||||
|
||||
updateDiscount() {
|
||||
const claimedSale = this.saleClaimed.sale;
|
||||
if (this.newDiscount != claimedSale.discount) {
|
||||
|
|
|
@ -17,9 +17,13 @@ describe('claim', () => {
|
|||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.whenGET('Claims/ClaimBeginnings').respond({});
|
||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond(true);
|
||||
$httpBackend.whenGET(`Claims/2/isEditable`).respond(true);
|
||||
const $element = angular.element('<vn-claim-detail></vn-claim-detail>');
|
||||
controller = $componentController('vnClaimDetail', {$element, $scope});
|
||||
controller.claim = {ticketFk: 1};
|
||||
controller.claim = {
|
||||
ticketFk: 1,
|
||||
id: 2}
|
||||
;
|
||||
controller.salesToClaim = [{saleFk: 1}, {saleFk: 2}];
|
||||
controller.salesClaimed = [{id: 1, sale: {}}];
|
||||
controller.$.model = crudModel;
|
||||
|
@ -125,9 +129,9 @@ describe('claim', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('isClaimEditable()', () => {
|
||||
it('should check if the claim is editable', () => {
|
||||
controller.isClaimEditable();
|
||||
describe('isTicketEditable()', () => {
|
||||
it('should check if the ticket assigned to the claim is editable', () => {
|
||||
controller.isTicketEditable();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.isEditable).toBeTruthy();
|
||||
|
|
|
@ -16,4 +16,3 @@ Search claim by id or client name: Buscar reclamaciones por identificador o nomb
|
|||
Claim deleted!: Reclamación eliminada!
|
||||
claim: reclamación
|
||||
Photos: Fotos
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
// #2294 - TLS version error
|
||||
xdescribe('client sendSms()', () => {
|
||||
let createdLog;
|
||||
|
||||
afterAll(async done => {
|
||||
await app.models.ClientLog.destroyById(createdLog.id);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should send a message and log it', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let id = 101;
|
||||
let destination = 222222222;
|
||||
let message = 'this is the message created in a test';
|
||||
|
||||
let sms = await app.models.Client.sendSms(ctx, id, destination, message);
|
||||
|
||||
logId = sms.logId;
|
||||
|
||||
createdLog = await app.models.ClientLog.findById(logId);
|
||||
let json = JSON.parse(JSON.stringify(createdLog.newInstance));
|
||||
|
||||
expect(json.message).toEqual(message);
|
||||
});
|
||||
});
|
|
@ -1,38 +0,0 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const soap = require('soap');
|
||||
|
||||
// #2294 - TLS version error
|
||||
xdescribe('sms send()', () => {
|
||||
it('should return the expected message and status code', async() => {
|
||||
const code = 200;
|
||||
const smsConfig = await app.models.SmsConfig.findOne();
|
||||
const soapClient = await soap.createClientAsync(smsConfig.uri);
|
||||
spyOn(soap, 'createClientAsync').and.returnValue(soapClient);
|
||||
spyOn(soapClient, 'sendSMSAsync').and.returnValue([{
|
||||
result: {
|
||||
$value:
|
||||
`<xtratelecom-sms-response>
|
||||
<sms>
|
||||
<codigo>
|
||||
${code}
|
||||
</codigo>
|
||||
<descripcion>
|
||||
Envio en procesamiento
|
||||
</descripcion>
|
||||
<messageId>
|
||||
1
|
||||
</messageId>
|
||||
</sms>
|
||||
<procesoId>
|
||||
444328681
|
||||
</procesoId>
|
||||
</xtratelecom-sms-response>`
|
||||
}
|
||||
}]);
|
||||
let ctx = {req: {accessToken: {userId: 1}}};
|
||||
let result = await app.models.Sms.send(ctx, 105, 'destination', 'My SMS Body');
|
||||
|
||||
expect(result.statusCode).toEqual(200);
|
||||
expect(result.status).toContain('Fake response');
|
||||
});
|
||||
});
|
|
@ -1,28 +0,0 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
// #2294 - TLS version error
|
||||
xdescribe('ticket sendSms()', () => {
|
||||
let logId;
|
||||
|
||||
afterAll(async done => {
|
||||
await app.models.TicketLog.destroyById(logId);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should send a message and log it', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let id = 11;
|
||||
let destination = 222222222;
|
||||
let message = 'this is the message created in a test';
|
||||
|
||||
let sms = await app.models.Ticket.sendSms(ctx, id, destination, message);
|
||||
|
||||
logId = sms.logId;
|
||||
|
||||
let createdLog = await app.models.TicketLog.findById(logId);
|
||||
let json = JSON.parse(JSON.stringify(createdLog.newInstance));
|
||||
|
||||
expect(json.message).toEqual(message);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue