diff --git a/db/install/changes/13-itemLog.sql b/db/install/changes/13-itemLog.sql new file mode 100644 index 000000000..43a1fcca2 --- /dev/null +++ b/db/install/changes/13-itemLog.sql @@ -0,0 +1,4 @@ +USE `vn`; + +ALTER TABLE vn.itemLog MODIFY COLUMN userFk int(10) unsigned NULL; +ALTER TABLE vn.itemLog MODIFY COLUMN id int(11) NOT NULL AUTO_INCREMENT; \ No newline at end of file diff --git a/modules/item/back/methods/item/specs/new.spec.js b/modules/item/back/methods/item/specs/new.spec.js index 793120514..007178c97 100644 --- a/modules/item/back/methods/item/specs/new.spec.js +++ b/modules/item/back/methods/item/specs/new.spec.js @@ -4,7 +4,12 @@ describe('item new()', () => { let item; afterAll(async done => { - await app.models.Item.destroyById(item.id); + let sql = 'DELETE FROM vn.itemLog WHERE originFk = ?'; + await app.models.Item.rawSql(sql, [item.id]); + + sql = 'DELETE FROM vn.item WHERE id = ?'; + await app.models.Item.rawSql(sql, [item.id]); + done(); }); diff --git a/modules/item/back/methods/item/updateTaxes.js b/modules/item/back/methods/item/updateTaxes.js index bbf4dc0f1..9b7ffd372 100644 --- a/modules/item/back/methods/item/updateTaxes.js +++ b/modules/item/back/methods/item/updateTaxes.js @@ -27,7 +27,7 @@ module.exports = Self => { if (!tax.taxClassFk) throw new UserError('Tax class cannot be blank'); - promises.push(Self.app.models.ItemTaxCountry.updateAll( + promises.push(Self.app.models.ItemTaxCountry.update( {id: tax.id}, {taxClassFk: tax.taxClassFk} )); diff --git a/modules/item/back/models/item-barcode.json b/modules/item/back/models/item-barcode.json index 324f23a6c..c2fa166e1 100644 --- a/modules/item/back/models/item-barcode.json +++ b/modules/item/back/models/item-barcode.json @@ -1,6 +1,11 @@ { "name": "ItemBarcode", - "base": "VnModel", + "base": "Loggable", + "log": { + "model": "ItemLog", + "relation": "item", + "changedModelValue": "code" + }, "options": { "mysql": { "table": "itemBarcode" diff --git a/modules/item/back/models/item-botanical.json b/modules/item/back/models/item-botanical.json index 655f0d48c..2a1234e36 100644 --- a/modules/item/back/models/item-botanical.json +++ b/modules/item/back/models/item-botanical.json @@ -1,6 +1,11 @@ { "name": "ItemBotanical", - "base": "VnModel", + "base": "Loggable", + "log": { + "model": "ItemLog", + "relation": "item", + "changedModelValue": "botanical" + }, "options": { "mysql": { "table": "itemBotanical" diff --git a/modules/item/back/models/item-log.json b/modules/item/back/models/item-log.json index 76fcc4104..b8e6f79a6 100644 --- a/modules/item/back/models/item-log.json +++ b/modules/item/back/models/item-log.json @@ -2,44 +2,54 @@ "name": "ItemLog", "base": "VnModel", "options": { - "mysql": { - "table": "itemLog" - } + "mysql": { + "table": "itemLog" + } }, "properties": { "id": { - "type": "Number", "id": true, - "description": "Identifier" + "type": "Number", + "forceId": false + }, + "originFk": { + "type": "Number", + "required": true + }, + "userFk": { + "type": "Number" + }, + "action": { + "type": "String", + "required": true + }, + "changedModel": { + "type": "String" + }, + "oldInstance": { + "type": "Object" + }, + "newInstance": { + "type": "Object" }, "creationDate": { "type": "Date" }, - "description": { + "changedModelId": { + "type": "Number" + }, + "changedModelValue": { "type": "String" }, - "action": { + "description": { "type": "String" } }, "relations": { - "item": { - "type": "belongsTo", - "model": "Item", - "foreignKey": "originFk" - }, "user": { "type": "belongsTo", "model": "Account", "foreignKey": "userFk" - } - }, - "acls": [ - { - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - } - ] + } + } } diff --git a/modules/item/back/models/item-niche.json b/modules/item/back/models/item-niche.json index 74fae2faa..aadcab28e 100644 --- a/modules/item/back/models/item-niche.json +++ b/modules/item/back/models/item-niche.json @@ -1,6 +1,11 @@ { "name": "ItemNiche", - "base": "VnModel", + "base": "Loggable", + "log": { + "model": "ItemLog", + "relation": "item", + "changedModelValue": "code" + }, "options": { "mysql": { "table": "itemPlacement" diff --git a/modules/item/back/models/item-tag.json b/modules/item/back/models/item-tag.json index 2dae3b174..d68e1a299 100644 --- a/modules/item/back/models/item-tag.json +++ b/modules/item/back/models/item-tag.json @@ -1,6 +1,11 @@ { "name": "ItemTag", - "base": "VnModel", + "base": "Loggable", + "log": { + "model": "ItemLog", + "relation": "item", + "changedModelValue": "value" + }, "options": { "mysql": { "table": "itemTag" diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json index 1ca2619e7..4496633e8 100644 --- a/modules/item/back/models/item.json +++ b/modules/item/back/models/item.json @@ -1,6 +1,9 @@ { "name": "Item", - "base": "VnModel", + "base": "Loggable", + "log": { + "model":"ItemLog" + }, "options": { "mysql": { "table": "item" diff --git a/modules/item/front/history/index.html b/modules/item/front/history/index.html deleted file mode 100644 index 83585f2b7..000000000 --- a/modules/item/front/history/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - Description - Action - Changed by - Date - - - - - {{::itemLog.description}} - {{::itemLog.action}} - {{::itemLog.user.name}} - {{::itemLog.creationDate | dateTime:'dd/MM/yyyy HH:mm'}} - - - - - - - diff --git a/modules/item/front/history/index.js b/modules/item/front/history/index.js deleted file mode 100644 index 910a4f488..000000000 --- a/modules/item/front/history/index.js +++ /dev/null @@ -1,25 +0,0 @@ -import ngModule from '../module'; - -class Controller { - constructor($stateParams) { - this.$stateParams = $stateParams; - this.filter = { - include: [{ - relation: "item" - }, - { - relation: "user", - scope: { - fields: ["name"] - } - }] - }; - } -} - -Controller.$inject = ['$stateParams']; - -ngModule.component('vnItemHistory', { - template: require('./index.html'), - controller: Controller -}); diff --git a/modules/item/front/index.js b/modules/item/front/index.js index aacaffe85..d6b3e5703 100644 --- a/modules/item/front/index.js +++ b/modules/item/front/index.js @@ -11,7 +11,7 @@ import './data'; import './fetched-tags'; import './tags'; import './tax'; -// import './history'; +import './log'; import './last-entries'; import './niche'; import './botanical'; diff --git a/modules/item/front/log/index.html b/modules/item/front/log/index.html new file mode 100644 index 000000000..3734ba056 --- /dev/null +++ b/modules/item/front/log/index.html @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/modules/item/front/log/index.js b/modules/item/front/log/index.js new file mode 100644 index 000000000..edb540760 --- /dev/null +++ b/modules/item/front/log/index.js @@ -0,0 +1,53 @@ +import ngModule from '../module'; + +class Controller { + constructor($scope, $stateParams) { + this.$scope = $scope; + this.$stateParams = $stateParams; + this.filter = { + include: [{ + relation: 'user', + scope: { + fields: ['name'], + }, + }], + }; + } + + get logs() { + return this._logs; + } + + set logs(value) { + this._logs = value; + + if (this.logs) { + this.logs.forEach(log => { + log.oldProperties = this.getInstance(log.oldInstance); + log.newProperties = this.getInstance(log.newInstance); + }); + } + } + + getInstance(instance) { + let validDate = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/; + const properties = []; + if (typeof instance == 'object' && instance != null) { + Object.keys(instance).forEach(property => { + if (validDate.test(instance[property])) + instance[property] = new Date(instance[property]).toLocaleString('es-ES'); + + properties.push({key: property, value: instance[property]}); + }); + return properties; + } + return null; + } +} + +Controller.$inject = ['$scope', '$stateParams']; + +ngModule.component('vnItemLog', { + template: require('./index.html'), + controller: Controller, +}); diff --git a/modules/item/front/routes.json b/modules/item/front/routes.json index 485bd2760..ec90aa2ba 100644 --- a/modules/item/front/routes.json +++ b/modules/item/front/routes.json @@ -12,7 +12,8 @@ {"state": "item.card.botanical", "icon": "local_florist"}, {"state": "item.card.itemBarcode", "icon": "icon-barcode"}, {"state": "item.card.diary", "icon": "icon-transaction"}, - {"state": "item.card.last-entries", "icon": "icon-regentry"} + {"state": "item.card.last-entries", "icon": "icon-regentry"}, + {"state": "item.card.log", "icon": "history"} ], "keybindings": [ {"key": "a", "state": "item.index"} @@ -116,6 +117,11 @@ "item": "$ctrl.item" }, "acl": ["employee"] + }, { + "url" : "/log", + "state": "item.card.log", + "component": "vn-item-log", + "description": "Log" } ] } \ No newline at end of file