From a23c636c167f4c49a1f0cc0213a69c4a6ec39d2b Mon Sep 17 00:00:00 2001 From: Gerard Date: Tue, 2 Apr 2019 14:36:49 +0200 Subject: [PATCH] #1279 loggable rawSql --- loopback/common/models/loggable.js | 5 +- .../back/methods/client/confirmTransaction.js | 36 +++++++- .../client/specs/confirmTransaction.spec.js | 3 +- modules/client/back/model-config.json | 3 + .../client/back/models/tpv-transaction.json | 48 +++++++++++ modules/item/back/methods/item/clone.js | 64 ++++++++++---- modules/item/back/methods/item/regularize.js | 4 +- modules/item/back/models/item-tag.json | 74 +++++++++------- .../item/back/models/item-tax-country.json | 16 +++- .../ticket/back/methods/sale/updatePrice.js | 20 ++++- modules/ticket/back/methods/ticket/new.js | 86 ++++++++++++------- 11 files changed, 262 insertions(+), 97 deletions(-) create mode 100644 modules/client/back/models/tpv-transaction.json diff --git a/loopback/common/models/loggable.js b/loopback/common/models/loggable.js index 0c09d5f13..9ad1fcdd5 100644 --- a/loopback/common/models/loggable.js +++ b/loopback/common/models/loggable.js @@ -171,7 +171,7 @@ module.exports = function(Self) { if (ctx.where && ctx.where[primaryKey]) originId = ctx.where[primaryKey]; - else { + else if (ctx.instance) { originId = ctx.instance[primaryKey]; changedModelId = ctx.instance.id; } @@ -186,10 +186,11 @@ module.exports = function(Self) { if (showField && (!ctx.instance || !ctx.instance[showField]) && ctx.where) { changedModelId = []; where = []; - let changedInstances = await ctx.Model.app.models[definition.name].find({where: ctx.where, fields: ['id', showField]}, options); + let changedInstances = await ctx.Model.app.models[definition.name].find({where: ctx.where, fields: ['id', showField, primaryKey]}, options); changedInstances.forEach(element => { where.push(element[showField]); changedModelId.push(element.id); + originId = element[primaryKey]; }); } else if (ctx.hookState.oldInstance) where = ctx.instance[showField]; diff --git a/modules/client/back/methods/client/confirmTransaction.js b/modules/client/back/methods/client/confirmTransaction.js index b2acf24d4..30a09c5a1 100644 --- a/modules/client/back/methods/client/confirmTransaction.js +++ b/modules/client/back/methods/client/confirmTransaction.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('confirmTransaction', { + Self.remoteMethodCtx('confirmTransaction', { description: 'Confirm a web payment', accessType: 'WRITE', accepts: [{ @@ -18,7 +18,37 @@ module.exports = Self => { } }); - Self.confirmTransaction = async id => { - return await Self.rawSql('CALL hedera.tpvTransactionConfirmById(?)', [id]); + Self.confirmTransaction = async(ctx, id) => { + let transaction = await Self.beginTransaction({}); + let userId = ctx.req.accessToken.userId; + + try { + let oldTpvTransaction = await Self.app.models.TpvTransaction.findById(id, {options: transaction}); + + let confirm = await Self.rawSql('CALL hedera.tpvTransactionConfirmById(?)', [id], {options: transaction}); + + let tpvTransaction = await Self.app.models.TpvTransaction.findById(id, {options: transaction}); + + let oldInstance = {status: oldTpvTransaction.status}; + let newInstance = {status: tpvTransaction.status}; + + let logRecord = { + originFk: tpvTransaction.clientFk, + userFk: userId, + action: 'update', + changedModel: 'TpvTransaction', + changedModelId: id, + oldInstance: oldInstance, + newInstance: newInstance + }; + + await Self.app.models.ClientLog.create(logRecord, {options: transaction}); + + await transaction.commit(); + return confirm; + } catch (e) { + await transaction.rollback(); + throw e; + } }; }; diff --git a/modules/client/back/methods/client/specs/confirmTransaction.spec.js b/modules/client/back/methods/client/specs/confirmTransaction.spec.js index 797ceab4d..3b5410231 100644 --- a/modules/client/back/methods/client/specs/confirmTransaction.spec.js +++ b/modules/client/back/methods/client/specs/confirmTransaction.spec.js @@ -11,7 +11,8 @@ describe('Client confirmTransaction', () => { }); it('should call confirmTransaction() method to mark transaction as confirmed', async() => { - await app.models.Client.confirmTransaction(transactionId); + let ctx = {req: {accessToken: {userId: 1}}}; + await app.models.Client.confirmTransaction(ctx, transactionId); let [receipt] = await app.models.Client.rawSql( `SELECT receiptFk diff --git a/modules/client/back/model-config.json b/modules/client/back/model-config.json index 76d60abca..3a587107a 100644 --- a/modules/client/back/model-config.json +++ b/modules/client/back/model-config.json @@ -88,5 +88,8 @@ }, "TpvResponse": { "dataSource": "vn" + }, + "TpvTransaction": { + "dataSource": "vn" } } diff --git a/modules/client/back/models/tpv-transaction.json b/modules/client/back/models/tpv-transaction.json new file mode 100644 index 000000000..011616d98 --- /dev/null +++ b/modules/client/back/models/tpv-transaction.json @@ -0,0 +1,48 @@ +{ + "name": "TpvTransaction", + "base": "VnModel", + "options": { + "mysql": { + "table": "hedera.tpvTransaction" + } + }, + "properties": { + "id": { + "type": "Number", + "id": true, + "description": "Identifier" + }, + "merchantFk": { + "type": "Number" + }, + "clientFk": { + "type": "Number" + }, + "receiptFk": { + "type": "Number" + }, + "amount": { + "type": "Number" + }, + "response": { + "type": "Number" + }, + "errorCode": { + "type": "String" + }, + "status": { + "type": "String" + }, + "created": { + "type": "Date" + } + }, + "relations": { + "client": { + "type": "belongsTo", + "model": "Client", + "foreignKey": "clientFk" + } + } +} + \ No newline at end of file diff --git a/modules/item/back/methods/item/clone.js b/modules/item/back/methods/item/clone.js index d40865870..b8c1727cd 100644 --- a/modules/item/back/methods/item/clone.js +++ b/modules/item/back/methods/item/clone.js @@ -1,5 +1,3 @@ -let UserError = require('vn-loopback/util/user-error'); - module.exports = Self => { Self.remoteMethod('clone', { description: 'clone item', @@ -22,6 +20,8 @@ module.exports = Self => { }); Self.clone = async itemId => { + let $ = Self.app.models; + let transaction = await Self.beginTransaction({}); let filter = { where: { id: itemId @@ -42,28 +42,54 @@ module.exports = Self => { delete copy.comment; let newItem = await Self.create(copy); - let promises = []; - let createBotanical = `INSERT INTO vn.itemBotanical (itemFk, botanical, genusFk, specieFk) - SELECT ?, botanical, genusFk, specieFk - FROM vn.itemBotanical ib WHERE itemFk = ?`; - promises.push(Self.rawSql(createBotanical, [newItem.id, origin.id])); + let botanical = await $.ItemBotanical.findOne({ + where: {itemFk: origin.id}, + fields: ['botanical', 'genusFk', 'specieFk'] + }, {options: transaction}); - let createTags = `INSERT INTO vn.itemTag(itemFk, tagFk, value, priority) - SELECT ?, i.tagFk, i.value,i.priority - FROM vn.itemTag i WHERE i.itemFk = ? - ON DUPLICATE KEY UPDATE value = i.value, priority = i.priority`; - promises.push(Self.rawSql(createTags, [newItem.id, origin.id])); + if (botanical) { + botanical.itemFk = newItem.id; + await $.ItemBotanical.create(botanical); + } - let createTax = `REPLACE INTO vn.itemTaxCountry (itemFk, countryFk, taxClassFk) - SELECT ?, countryFk, taxClassFk - FROM vn.itemTaxCountry WHERE itemFk = ?`; - promises.push(Self.rawSql(createTax, [newItem.id, origin.id])); - await Promise.all(promises); + let copyTags = await $.ItemTag.find({ + where: { + itemFk: origin.id + }, + fields: ['tagFk', 'value', 'priority'] + }, {options: transaction}); + + for (let i = 0; i < copyTags.length; i++) { + copyTags[i].itemFk = newItem.id; + await $.ItemTag.upsert(copyTags[i], {options: transaction}); + } + + let copyTaxes = await Self.app.models.ItemTaxCountry.find({ + where: {itemFk: origin.id}, + fields: ['botanical', 'countryFk', 'taxClassFk'] + }, {options: transaction}); + + for (let i = 0; i < copyTaxes.length; i++) { + let tax = copyTaxes[i]; + tax.itemFk = newItem.id; + await Self.app.models.ItemTaxCountry.upsertWithWhere( + { + itemFk: tax.itemFk, + countryFk: tax.countryFk, + taxClassFk: tax.taxClassFk, + }, + tax, + {options: transaction} + ); + } + + await transaction.commit(); return newItem.id; - } catch (err) { - throw new UserError(err); + } catch (e) { + await transaction.rollback(); + throw e; } }; }; diff --git a/modules/item/back/methods/item/regularize.js b/modules/item/back/methods/item/regularize.js index a9644cc1d..9dc619877 100644 --- a/modules/item/back/methods/item/regularize.js +++ b/modules/item/back/methods/item/regularize.js @@ -53,7 +53,7 @@ module.exports = Self => { }, transaction); if (!ticketFk) { - ticketFk = await createTicket({ + ticketFk = await createTicket(ctx, { clientFk: itemDestination.address().clientFk, addressFk: itemDestination.addressFk, warehouseFk: warehouseFk, @@ -85,7 +85,7 @@ module.exports = Self => { throw e; } - async function createTicket(params, transaction) { + async function createTicket(ctx, params, transaction) { let ticket = await Self.app.models.Ticket.new( ctx, { diff --git a/modules/item/back/models/item-tag.json b/modules/item/back/models/item-tag.json index e276703a6..6beeb29d3 100644 --- a/modules/item/back/models/item-tag.json +++ b/modules/item/back/models/item-tag.json @@ -2,47 +2,55 @@ "name": "ItemTag", "base": "Loggable", "log": { - "model": "ItemLog", - "relation": "item", - "showField": "value" + "model": "ItemLog", + "relation": "item", + "showField": "value" }, "options": { "mysql": { - "table": "itemTag" + "table": "itemTag" } }, "properties": { - "id": { - "type": "Number", - "id": true, - "description": "Identifier" - }, - "value": { - "type": "String" - }, - "priority": { - "type": "Number", - "required": true - } + "id": { + "type": "Number", + "id": true, + "description": "Identifier" + }, + "value": { + "type": "String" + }, + "itemFk": { + "type": "Number", + "required": true + }, + "tagFk": { + "type": "Number", + "required": true + }, + "priority": { + "type": "Number", + "required": true + } }, "relations": { - "item": { - "type": "belongsTo", - "model": "Item", - "foreignKey": "itemFk" - }, - "tag": { - "type": "belongsTo", - "model": "Tag", - "foreignKey": "tagFk" - } + "item": { + "type": "belongsTo", + "model": "Item", + "foreignKey": "itemFk" + }, + "tag": { + "type": "belongsTo", + "model": "Tag", + "foreignKey": "tagFk" + } }, "acls": [ - { - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - } + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } ] - } +} diff --git a/modules/item/back/models/item-tax-country.json b/modules/item/back/models/item-tax-country.json index 7f67a271e..24c621518 100644 --- a/modules/item/back/models/item-tax-country.json +++ b/modules/item/back/models/item-tax-country.json @@ -1,6 +1,11 @@ { "name": "ItemTaxCountry", - "base": "VnModel", + "base": "Loggable", + "log": { + "model": "ItemLog", + "relation": "item", + "showField": "countryFk" + }, "options": { "mysql": { "table": "itemTaxCountry" @@ -14,6 +19,15 @@ }, "effectived": { "type": "Boolean" + }, + "itemFk": { + "type": "Number" + }, + "countryFk": { + "type": "Number" + }, + "taxClassFk": { + "type": "Number" } }, "relations": { diff --git a/modules/ticket/back/methods/sale/updatePrice.js b/modules/ticket/back/methods/sale/updatePrice.js index 0cb90041d..a49d194e4 100644 --- a/modules/ticket/back/methods/sale/updatePrice.js +++ b/modules/ticket/back/methods/sale/updatePrice.js @@ -1,7 +1,7 @@ let UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethod('updatePrice', { + Self.remoteMethodCtx('updatePrice', { description: 'Changes the discount of a sale', accessType: '', accepts: [{ @@ -62,10 +62,22 @@ module.exports = Self => { let value = (params.price - currentLine.price); - let query = `INSERT INTO vn.saleComponent(saleFk, componentFk, value) - VALUES(?, ?, ?) ON DUPLICATE KEY UPDATE value = value + ?`; + let saleComponent = await Self.app.models.SaleComponent.findOne({ + where: { + componentFk: componentToUse, + saleFk: params.id + } + }); - await Self.rawSql(query, [params.id, componentToUse, value, value]); + if (saleComponent) + saleComponent.updateAttributes({value: saleComponent.value + value}); + else { + await Self.app.models.SaleComponent.create({ + saleFk: params.id, + componentFk: componentToUse, + value: value + }); + } await currentLine.updateAttributes({price: params.price}); diff --git a/modules/ticket/back/methods/ticket/new.js b/modules/ticket/back/methods/ticket/new.js index db25fe715..3c3a4a8d4 100644 --- a/modules/ticket/back/methods/ticket/new.js +++ b/modules/ticket/back/methods/ticket/new.js @@ -58,43 +58,65 @@ module.exports = Self => { throw new UserError(`You can't create a ticket for a client that has a debt`); } - if (!params.shipped && params.landed) { - params.shipped = await Self.app.models.Agency.getShipped({ - landed: params.landed, - addressFk: address.id, - agencyModeFk: agency.agencyFk - }); - } + if (!transaction || !transaction.commit) + transaction = await Self.beginTransaction({}); - if (params.shipped && !params.landed) { - params.landed = await Self.app.models.Agency.getLanded({ - shipped: params.shipped, - addressFk: address.id, - agencyModeFk: agency.agencyFk, - warehouseFk: params.warehouseFk - }); - } + try { + if (!params.shipped && params.landed) { + params.shipped = await Self.app.models.Agency.getShipped({ + landed: params.landed, + addressFk: address.id, + agencyModeFk: agency.agencyFk + }); + } + + if (params.shipped && !params.landed) { + params.landed = await Self.app.models.Agency.getLanded({ + shipped: params.shipped, + addressFk: address.id, + agencyModeFk: agency.agencyFk, + warehouseFk: params.warehouseFk + }); + } - if (!params.userId && ctx.req && ctx.req.accessToken.userId) - params.userId = ctx.req.accessToken.userId; + if (!params.userId && ctx.req && ctx.req.accessToken.userId) + params.userId = ctx.req.accessToken.userId; - query = `CALL vn.ticketCreateWithUser(?, ?, ?, ?, ?, ?, ?, ?, ?, @result); + query = `CALL vn.ticketCreateWithUser(?, ?, ?, ?, ?, ?, ?, ?, ?, @result); SELECT @result newTicketId;`; - let result = await Self.rawSql(query, [ - params.clientFk, - params.shipped, - params.warehouseFk, - params.companyFk || 442, - params.addressFk, - params.agencyModeFk || null, - params.routeFk || null, - params.landed, - params.userId - ], {options: transaction}); + let result = await Self.rawSql(query, [ + params.clientFk, + params.shipped, + params.warehouseFk, + params.companyFk || 442, + params.addressFk, + params.agencyModeFk || null, + params.routeFk || null, + params.landed, + params.userId + ], {options: transaction}); - return await Self.findOne({ - where: {id: result[1][0].newTicketId} - }, {options: transaction}); + let ticket = await Self.app.models.Ticket.findById(result[1][0].newTicketId, {options: transaction}); + let cleanInstance = JSON.parse(JSON.stringify(ticket)); + + let logRecord = { + originFk: cleanInstance.id, + userFk: params.userId, + action: 'create', + changedModel: 'Ticket', + changedModelId: cleanInstance.id, + oldInstance: {}, + newInstance: cleanInstance + }; + + await Self.app.models.TicketLog.create(logRecord, {options: transaction}); + + await transaction.commit(); + return await ticket; + } catch (e) { + await transaction.rollback(); + throw e; + } }; };