Merge branch 'dev' into 6067-vnUser_privileges_and_verifyEmail
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
3294937b54
|
@ -20,10 +20,6 @@
|
|||
"username": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"roleFk": {
|
||||
"type": "number",
|
||||
"mysql": {
|
||||
|
@ -39,9 +35,6 @@
|
|||
"active": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"created": {
|
||||
"type": "date"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
||||
VALUES
|
||||
('WorkerDepartment', '*', '*', 'ALLOW', 'ROLE', 'employee');
|
|
@ -1,15 +1,24 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('Client transactions', () => {
|
||||
const ctx = {};
|
||||
|
||||
it('should call transactions() method to receive a list of Web Payments from BRUCE WAYNE', async() => {
|
||||
const tx = await models.Client.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {};
|
||||
const filter = {where: {clientFk: 1101}};
|
||||
const result = await models.Client.transactions(ctx, filter, options);
|
||||
const result = await models.Client.transactions(
|
||||
ctx,
|
||||
filter,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
options
|
||||
);
|
||||
|
||||
expect(result[1].id).toBeTruthy();
|
||||
|
||||
|
@ -26,9 +35,17 @@ describe('Client transactions', () => {
|
|||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {args: {orderFk: 6}};
|
||||
const filter = {};
|
||||
const result = await models.Client.transactions(ctx, filter, options);
|
||||
const result = await models.Client.transactions(
|
||||
ctx,
|
||||
filter,
|
||||
6,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
options
|
||||
);
|
||||
|
||||
const firstRow = result[0];
|
||||
|
||||
|
@ -47,10 +64,17 @@ describe('Client transactions', () => {
|
|||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {args: {amount: 40}};
|
||||
const filter = {};
|
||||
const result = await models.Client.transactions(ctx, filter, options);
|
||||
const result = await models.Client.transactions(
|
||||
ctx,
|
||||
filter,
|
||||
undefined,
|
||||
undefined,
|
||||
40,
|
||||
undefined,
|
||||
undefined,
|
||||
options
|
||||
);
|
||||
|
||||
const randomIndex = Math.floor(Math.random() * result.length);
|
||||
const transaction = result[randomIndex];
|
||||
|
@ -63,4 +87,43 @@ describe('Client transactions', () => {
|
|||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should call transactions() method filtering by date', async() => {
|
||||
const tx = await models.Client.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const filter = {};
|
||||
const withResults = await models.Client.transactions(
|
||||
ctx,
|
||||
filter,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
'2000/12/31',
|
||||
undefined,
|
||||
options
|
||||
);
|
||||
|
||||
expect(withResults.length).toEqual(6);
|
||||
|
||||
const noResults = await models.Client.transactions(
|
||||
ctx,
|
||||
filter,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
'2099/12/31',
|
||||
undefined,
|
||||
options
|
||||
);
|
||||
|
||||
expect(noResults.length).toEqual(0);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,22 +12,26 @@ module.exports = Self => {
|
|||
arg: 'filter',
|
||||
type: 'object',
|
||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||
http: {source: 'query'}
|
||||
},
|
||||
{
|
||||
arg: 'orderFk',
|
||||
type: 'number',
|
||||
http: {source: 'query'}
|
||||
},
|
||||
{
|
||||
arg: 'clientFk',
|
||||
type: 'number',
|
||||
http: {source: 'query'}
|
||||
},
|
||||
{
|
||||
arg: 'amount',
|
||||
type: 'number',
|
||||
http: {source: 'query'}
|
||||
},
|
||||
{
|
||||
arg: 'from',
|
||||
type: 'date',
|
||||
},
|
||||
{
|
||||
arg: 'to',
|
||||
type: 'date',
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
|
@ -40,14 +44,15 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.transactions = async(ctx, filter, options) => {
|
||||
const args = ctx.args;
|
||||
Self.transactions = async(ctx, filter, orderFk, clientFk, amount, from, to, options) => {
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const where = buildFilter(args, (param, value) => {
|
||||
if (to) to.setHours(23, 59, 59, 999);
|
||||
|
||||
const where = buildFilter({orderFk, clientFk, amount, from, to}, (param, value) => {
|
||||
switch (param) {
|
||||
case 'orderFk':
|
||||
return {'t.id': value};
|
||||
|
@ -55,6 +60,10 @@ module.exports = Self => {
|
|||
return {'t.clientFk': value};
|
||||
case 'amount':
|
||||
return {'t.amount': (value * 100)};
|
||||
case 'from':
|
||||
return {'t.created': {gte: value}};
|
||||
case 'to':
|
||||
return {'t.created': {lte: value}};
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -138,14 +138,15 @@ module.exports = Self => {
|
|||
// Update original sale
|
||||
const rest = originalSale.quantity - sale.quantity;
|
||||
query = `UPDATE sale
|
||||
SET quantity = ?
|
||||
SET quantity = ?,
|
||||
originalQuantity = ?
|
||||
WHERE id = ?`;
|
||||
await Self.rawSql(query, [rest, sale.id], options);
|
||||
await Self.rawSql(query, [rest, rest, sale.id], options);
|
||||
|
||||
// Clone sale with new quantity
|
||||
query = `INSERT INTO sale (itemFk, ticketFk, concept, quantity, originalQuantity, price, discount, priceFixed,
|
||||
query = `INSERT INTO sale (itemFk, ticketFk, concept, quantity, price, discount, priceFixed,
|
||||
reserved, isPicked, isPriceFixed, isAdded)
|
||||
SELECT itemFk, ?, concept, ?, originalQuantity, price, discount, priceFixed,
|
||||
SELECT itemFk, ?, concept, ?, price, discount, priceFixed,
|
||||
reserved, isPicked, isPriceFixed, isAdded
|
||||
FROM sale
|
||||
WHERE id = ?`;
|
||||
|
|
|
@ -201,7 +201,7 @@ class Controller extends Section {
|
|||
sendImportSms() {
|
||||
const params = {
|
||||
ticketId: this.id,
|
||||
created: this.ticket.updated
|
||||
shipped: this.ticket.shipped
|
||||
};
|
||||
this.showSMSDialog({
|
||||
message: this.$t('Minimum is needed', params)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Make a payment: "Verdnatura communicates:\rYour order is pending of payment.\rPlease, enter the web page and make the payment with card.\rThank you."
|
||||
Minimum is needed: "Verdnatura communicates:\rA minimum import of 50€ (Without BAT) is needed for your order {{ticketId}} from date {{created | date: 'dd/MM/yyyy'}} to receive it with no extra fees."
|
||||
Minimum is needed: "Verdnatura communicates:\rA minimum import of 50€ (Without BAT) is needed for your order {{ticketId}} from date {{shipped | date: 'dd/MM/yyyy'}} to receive it with no extra fees."
|
||||
Send changes: "Verdnatura communicates:\rOrder {{ticketId}} date {{created | date: 'dd/MM/yyyy'}}\r{{changes}}"
|
||||
|
|
|
@ -4,7 +4,7 @@ Show pallet report: Ver hoja de pallet
|
|||
Change shipped hour: Cambiar hora de envío
|
||||
Shipped hour: Hora de envío
|
||||
Make a payment: "Verdnatura le comunica:\rSu pedido está pendiente de pago.\rPor favor, entre en la página web y efectúe el pago con tarjeta.\rMuchas gracias."
|
||||
Minimum is needed: "Verdnatura le recuerda:\rEs necesario un importe mínimo de 50€ (Sin IVA) en su pedido {{ticketId}} del día {{created | date: 'dd/MM/yyyy'}} para recibirlo sin portes adicionales."
|
||||
Minimum is needed: "Verdnatura le recuerda:\rEs necesario un importe mínimo de 50€ (Sin IVA) en su pedido {{ticketId}} del día {{shipped | date: 'dd/MM/yyyy'}} para recibirlo sin portes adicionales."
|
||||
Ticket invoiced: Ticket facturado
|
||||
Make invoice: Crear factura
|
||||
Regenerate invoice PDF: Regenerar PDF factura
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('updateWorkerTimeControlMail()', () => {
|
||||
it('should update WorkerTimeControlMail if exist record', async() => {
|
||||
const tx = await models.WorkerTimeControlMail.beginTransaction({});
|
||||
const args = {
|
||||
workerId: 9,
|
||||
week: 50,
|
||||
year: 2000,
|
||||
state: 'CONFIRMED'
|
||||
};
|
||||
const ctx = {args};
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const beforeMail = await models.WorkerTimeControlMail.findOne({
|
||||
where: {
|
||||
workerFk: args.workerId,
|
||||
year: args.year,
|
||||
week: args.week,
|
||||
}
|
||||
}, options);
|
||||
await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, options);
|
||||
const afterMail = await models.WorkerTimeControlMail.findOne({
|
||||
where: {
|
||||
workerFk: args.workerId,
|
||||
year: args.year,
|
||||
week: args.week,
|
||||
}
|
||||
}, options);
|
||||
|
||||
expect(beforeMail.state).toEqual('SENDED');
|
||||
expect(afterMail.state).toEqual(args.state);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should insert WorkerTimeControlMail if exist record', async() => {
|
||||
const tx = await models.WorkerTimeControlMail.beginTransaction({});
|
||||
const args = {
|
||||
workerId: 1,
|
||||
week: 51,
|
||||
year: 2000,
|
||||
state: 'SENDED'
|
||||
};
|
||||
const ctx = {args};
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const beforeMail = await models.WorkerTimeControlMail.find({
|
||||
where: {
|
||||
workerFk: args.workerId,
|
||||
year: args.year,
|
||||
week: args.week,
|
||||
}
|
||||
}, options);
|
||||
await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, options);
|
||||
const afterMail = await models.WorkerTimeControlMail.find({
|
||||
where: {
|
||||
workerFk: args.workerId,
|
||||
year: args.year,
|
||||
week: args.week,
|
||||
}
|
||||
}, options);
|
||||
|
||||
expect(beforeMail).toEqual([]);
|
||||
expect(afterMail.length).toEqual(1);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw error if not exist any record in this week', async() => {
|
||||
const tx = await models.WorkerTimeControlMail.beginTransaction({});
|
||||
const ctx = {args: {
|
||||
workerId: 1,
|
||||
week: 1,
|
||||
year: 0,
|
||||
state: 'SENDED'
|
||||
}};
|
||||
|
||||
let error;
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(`There aren't records for this week`);
|
||||
});
|
||||
});
|
||||
|
|
@ -40,30 +40,39 @@ module.exports = Self => {
|
|||
Self.updateWorkerTimeControlMail = async(ctx, options) => {
|
||||
const models = Self.app.models;
|
||||
const args = ctx.args;
|
||||
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const workerTimeControlMail = await models.WorkerTimeControlMail.findOne({
|
||||
const [sent] = await models.WorkerTimeControlMail.find({
|
||||
where: {
|
||||
workerFk: args.workerId,
|
||||
year: args.year,
|
||||
week: args.week
|
||||
}
|
||||
week: args.week,
|
||||
},
|
||||
limit: 1
|
||||
}, myOptions);
|
||||
|
||||
if (!workerTimeControlMail) throw new UserError(`There aren't records for this week`);
|
||||
if (!sent) throw new UserError(`There aren't records for this week`);
|
||||
|
||||
await workerTimeControlMail.updateAttributes({
|
||||
state: args.state,
|
||||
reason: args.reason || null
|
||||
}, myOptions);
|
||||
const workerTimeControlMail = await models.WorkerTimeControlMail.upsertWithWhere(
|
||||
{
|
||||
year: args.year,
|
||||
week: args.week,
|
||||
workerFk: args.workerId
|
||||
},
|
||||
{
|
||||
state: args.state,
|
||||
reason: args.workerId,
|
||||
year: args.year,
|
||||
week: args.week,
|
||||
workerFk: args.workerId
|
||||
},
|
||||
myOptions);
|
||||
|
||||
if (args.state == 'SENDED') {
|
||||
await workerTimeControlMail.updateAttributes({
|
||||
sendedCounter: workerTimeControlMail.sendedCounter + 1
|
||||
sendedCounter: workerTimeControlMail.sendedCounter ? workerTimeControlMail.sendedCounter + 1 : 1
|
||||
}, myOptions);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -61,9 +61,8 @@ module.exports = Self => {
|
|||
const url = `${salix.url}worker/${args.workerId}/time-control?timestamp=${timestamp}`;
|
||||
ctx.args.url = url;
|
||||
|
||||
await Self.sendTemplate(ctx, 'weekly-hour-record');
|
||||
|
||||
return models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, myOptions);
|
||||
await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, myOptions);
|
||||
return Self.sendTemplate(ctx, 'weekly-hour-record');
|
||||
};
|
||||
|
||||
function getMondayDateFromYearWeek(yearNumber, weekNumber) {
|
||||
|
|
|
@ -79,30 +79,32 @@
|
|||
</vn-table>
|
||||
</vn-card>
|
||||
|
||||
<vn-button-bar ng-show="$ctrl.state" class="vn-w-lg">
|
||||
<vn-button-bar class="vn-w-lg">
|
||||
<div ng-show="$ctrl.state">
|
||||
<vn-button
|
||||
label="Satisfied"
|
||||
disabled="$ctrl.state == 'CONFIRMED'"
|
||||
ng-show="$ctrl.isHimSelf"
|
||||
ng-click="$ctrl.isSatisfied()">
|
||||
</vn-button>
|
||||
<vn-button
|
||||
label="Not satisfied"
|
||||
disabled="$ctrl.state == 'REVISE'"
|
||||
ng-show="$ctrl.isHimSelf"
|
||||
ng-click="reason.show()">
|
||||
</vn-button>
|
||||
<vn-button
|
||||
label="Reason"
|
||||
ng-show="$ctrl.reason && ($ctrl.isHimSelf || $ctrl.isHr)"
|
||||
ng-click="reason.show()">
|
||||
</vn-button>
|
||||
</div>
|
||||
<vn-button
|
||||
label="Satisfied"
|
||||
disabled="$ctrl.state == 'CONFIRMED'"
|
||||
ng-if="$ctrl.isHimSelf"
|
||||
ng-click="$ctrl.isSatisfied()">
|
||||
</vn-button>
|
||||
<vn-button
|
||||
label="Not satisfied"
|
||||
disabled="$ctrl.state == 'REVISE'"
|
||||
ng-if="$ctrl.isHimSelf"
|
||||
ng-click="reason.show()">
|
||||
</vn-button>
|
||||
<vn-button
|
||||
label="Reason"
|
||||
ng-if="$ctrl.reason && ($ctrl.isHimSelf || $ctrl.isHr)"
|
||||
ng-click="reason.show()">
|
||||
</vn-button>
|
||||
<vn-button
|
||||
label="Resend"
|
||||
label="{{$ctrl.state ? 'Resend' : 'Send'}}"
|
||||
ng-click="sendEmailConfirmation.show()"
|
||||
class="right"
|
||||
vn-tooltip="Resend email of this week to the user"
|
||||
ng-show="::$ctrl.isHr">
|
||||
vn-tooltip="{{$ctrl.state ? 'Resend' : 'Send'}} email of this week to the user"
|
||||
ng-if="$ctrl.isHr && $ctrl.state != 'CONFIRMED' && $ctrl.canResend">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</div>
|
||||
|
|
|
@ -53,6 +53,8 @@ class Controller extends Section {
|
|||
set worker(value) {
|
||||
this._worker = value;
|
||||
this.fetchHours();
|
||||
if (this.date)
|
||||
this.getWeekData();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,7 +112,8 @@ class Controller extends Section {
|
|||
}
|
||||
|
||||
if (!this.weekTotalHours) this.fetchHours();
|
||||
this.getWeekData();
|
||||
if (this.worker)
|
||||
this.getWeekData();
|
||||
}
|
||||
|
||||
set weekTotalHours(totalHours) {
|
||||
|
@ -127,17 +130,34 @@ class Controller extends Section {
|
|||
workerFk: this.$params.id,
|
||||
year: this._date.getFullYear(),
|
||||
week: this.getWeekNumber(this._date)
|
||||
}
|
||||
},
|
||||
};
|
||||
this.$http.get('WorkerTimeControlMails', {filter})
|
||||
.then(res => {
|
||||
const mail = res.data;
|
||||
if (!mail.length) {
|
||||
if (!res.data.length) {
|
||||
this.state = null;
|
||||
return;
|
||||
}
|
||||
this.state = mail[0].state;
|
||||
this.reason = mail[0].reason;
|
||||
const [mail] = res.data;
|
||||
this.state = mail.state;
|
||||
this.reason = mail.reason;
|
||||
});
|
||||
this.canBeResend();
|
||||
}
|
||||
|
||||
canBeResend() {
|
||||
this.canResend = false;
|
||||
const filter = {
|
||||
where: {
|
||||
year: this._date.getFullYear(),
|
||||
week: this.getWeekNumber(this._date)
|
||||
},
|
||||
limit: 1
|
||||
};
|
||||
this.$http.get('WorkerTimeControlMails', {filter})
|
||||
.then(res => {
|
||||
if (res.data.length)
|
||||
this.canResend = true;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -356,30 +376,25 @@ class Controller extends Section {
|
|||
}
|
||||
|
||||
isSatisfied() {
|
||||
const params = {
|
||||
workerId: this.worker.id,
|
||||
year: this.date.getFullYear(),
|
||||
week: this.weekNumber,
|
||||
state: 'CONFIRMED'
|
||||
};
|
||||
const query = `WorkerTimeControls/updateWorkerTimeControlMail`;
|
||||
this.$http.post(query, params).then(() => {
|
||||
this.getMailStates(this.date);
|
||||
this.getWeekData();
|
||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||
});
|
||||
this.updateWorkerTimeControlMail('CONFIRMED');
|
||||
}
|
||||
|
||||
isUnsatisfied() {
|
||||
if (!this.reason) throw new UserError(`You must indicate a reason`);
|
||||
this.updateWorkerTimeControlMail('REVISE', this.reason);
|
||||
}
|
||||
|
||||
updateWorkerTimeControlMail(state, reason) {
|
||||
const params = {
|
||||
workerId: this.worker.id,
|
||||
year: this.date.getFullYear(),
|
||||
week: this.weekNumber,
|
||||
state: 'REVISE',
|
||||
reason: this.reason
|
||||
state
|
||||
};
|
||||
|
||||
if (reason)
|
||||
params.reason = reason;
|
||||
|
||||
const query = `WorkerTimeControls/updateWorkerTimeControlMail`;
|
||||
this.$http.post(query, params).then(() => {
|
||||
this.getMailStates(this.date);
|
||||
|
|
Loading…
Reference in New Issue