diff --git a/db/.gitignore b/db/.gitignore
index f26f7a0a6..162fe6938 100644
--- a/db/.gitignore
+++ b/db/.gitignore
@@ -1 +1,2 @@
-connect.ini
+config.production.ini
+config.test.ini
\ No newline at end of file
diff --git a/db/connect.tpl.ini b/db/config.ini
similarity index 100%
rename from db/connect.tpl.ini
rename to db/config.ini
index 2db13e969..cf1f36d7c 100644
--- a/db/connect.tpl.ini
+++ b/db/config.ini
@@ -1,7 +1,7 @@
[client]
-enable_cleartext_plugin = ON
host = localhost
port = 3306
user = root
password = password
ssl-mode = DISABLED
+enable_cleartext_plugin = ON
diff --git a/db/import-changes.js b/db/import-changes.js
deleted file mode 100644
index b72efaa3c..000000000
--- a/db/import-changes.js
+++ /dev/null
@@ -1,66 +0,0 @@
-const mysql = require('mysql2/promise');
-const fs = require('fs-extra');
-
-(async () => {
- try {
- const connection = await mysql.createConnection({
- host: 'localhost',
- user: 'root',
- multipleStatements: true
- });
- let changesDir = './install/changes';
- let results = await connection.query("SELECT dbVersion FROM util.config");
- if (results[0].length != 1)
- throw new Error('There must be exactly one row in the configuration table');
- let version = results[0][0].dbVersion;
- if (!version)
- throw new Error('Database version not defined');
- let dirs = await fs.readdir(changesDir);
- dirs.sort(compareVersions);
- let lastVersion;
-
- for (let dir of dirs) {
- if (compareVersions(dir, version) <= 0) continue;
- if (/^\./.test(dir)) continue;
- let path = `${changesDir}/${dir}`;
- let files = await fs.readdir(path);
- files.sort();
- console.log(dir);
- for (let file of files) {
- let sql = await fs.readFile(`${path}/${file}`, 'utf8');
- if (/^\s*$/.test(sql)) continue;
- await connection.query(sql);
- console.log(` - ${file}`);
- }
- lastVersion = dir;
- }
- if (lastVersion) {
- await connection.query("UPDATE util.config SET dbVersion = ?", [lastVersion]);
- console.log(`Database upgraded successfully to version ${lastVersion}`);
- } else {
- console.log("Database is alredy in the last version");
- }
- await connection.end();
- process.exit();
- } catch (err) {
- console.error(err);
- process.exit(1);
- }
-})();
-
-function compareVersions(ver1, ver2) {
- let diff;
- ver1 = ver1.split('.');
- ver2 = ver2.split('.');
-
- diff = parseInt(ver1[0]) - parseInt(ver2[0]);
- if (diff !== 0) return diff;
-
- diff = parseInt(ver1[1]) - parseInt(ver2[1]);
- if (diff !== 0) return diff;
-
- diff = parseInt(ver1[2]) - parseInt(ver2[2]);
- if (diff !== 0) return diff;
-
- return 0;
-}
diff --git a/db/import-changes.sh b/db/import-changes.sh
new file mode 100755
index 000000000..d9042cf3c
--- /dev/null
+++ b/db/import-changes.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+ENV=$1
+
+if [ "$ENV" == "production" ]; then
+ echo ""
+ echo " ( ( ) ( ( ) ) "
+ echo " )\ ))\ ) ( /( )\ ) ( * ))\ ) ( /( ( /( "
+ echo "(()/(()/( )\()|()/( ( )\ ) /(()/( )\()) )\())"
+ echo " /(_))(_)|(_)\ /(_)) )\ (((_) ( )(_))(_)|(_)\ ((_)\ "
+ echo "(_))(_)) ((_|_))_ _ ((_))\___(_(_()|_)) ((_) _((_)"
+ echo "| _ \ _ \ / _ \| \| | | ((/ __|_ _|_ _| / _ \| \| |"
+ echo "| _/ /| (_) | |) | |_| || (__ | | | | | (_) | . |"
+ echo "|_| |_|_\ \___/|___/ \___/ \___| |_| |___| \___/|_|\_|"
+ echo ""
+
+ read -p "Are you sure? (Default: no) [yes|no]: " ANSWER
+
+ if [ "$ANSWER" != "yes" ]; then
+ echo "Aborting"
+ exit;
+ fi
+fi
+if [ -z "$ENV" ]; then
+ ENV="test"
+fi
+
+INI_FILE="config.$ENV.ini"
+
+if [ ! -f "$INI_FILE" ]; then
+ echo "File $INI_FILE doesn't exists"
+ exit 1
+fi
+
+echo "[INFO] Config file: $INI_FILE"
+echo "[INFO] Importing changes."
+
+# Import changes
+for file in install/changes/*.sql; do
+ echo "[INFO] -> Applying $file"
+ mysql --defaults-file="$INI_FILE" < $file
+done
diff --git a/db/import-fixtures.js b/db/import-fixtures.js
deleted file mode 100644
index 8cd38a750..000000000
--- a/db/import-fixtures.js
+++ /dev/null
@@ -1,19 +0,0 @@
-const mysql = require('mysql2/promise');
-const fs = require('fs-extra');
-
-(async () => {
- try {
- const connection = await mysql.createConnection({
- host: 'localhost',
- user: 'root',
- multipleStatements: true
- });
- sql = await fs.readFile(`install/dump/fixtures.sql`, 'utf8');
- await connection.query(sql);
- await connection.end();
- process.exit();
- } catch (err) {
- console.error(err);
- process.exit(1);
- }
-})();
diff --git a/db/install/boot.sh b/db/install/boot.sh
index 02727e089..ebfdae87f 100755
--- a/db/install/boot.sh
+++ b/db/install/boot.sh
@@ -2,8 +2,6 @@
export MYSQL_PWD=root
# Dump structure
-echo "[INFO] -> Imported ./dump/truncateAll.sql"
- mysql -u root -f < ./dump/truncateAll.sql
echo "[INFO] -> Imported ./dump/structure.sql"
mysql -u root -f < ./dump/structure.sql
echo "[INFO] -> Imported ./dump/mysqlPlugins.sql"
diff --git a/db/install/changes/14-basketGetTax.sql b/db/install/changes/14-basketGetTax.sql
new file mode 100644
index 000000000..f74623275
--- /dev/null
+++ b/db/install/changes/14-basketGetTax.sql
@@ -0,0 +1,21 @@
+DROP procedure IF EXISTS `hedera`.`basketGetTax`;
+DELIMITER $$
+CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`basketGetTax`()
+ READS SQL DATA
+BEGIN
+/**
+ * Returns the taxes for the current client basket.
+ *
+ * @treturn tmp.orderTax
+ */
+ DROP TEMPORARY TABLE IF EXISTS tmp.order;
+ CREATE TEMPORARY TABLE tmp.order
+ ENGINE = MEMORY
+ SELECT myBasketGetId() orderFk;
+
+ CALL orderGetTax();
+
+ DROP TEMPORARY TABLE IF EXISTS tmp.order;
+END$$
+
+DELIMITER ;
diff --git a/db/install/dump/truncateAll.sql b/db/install/dump/truncateAll.sql
deleted file mode 100644
index 9135f7860..000000000
--- a/db/install/dump/truncateAll.sql
+++ /dev/null
@@ -1,37 +0,0 @@
-DROP PROCEDURE IF EXISTS mysql.truncateAll;
-DELIMITER $$
-CREATE PROCEDURE mysql.truncateAll()
-BEGIN
- DECLARE vSchema VARCHAR(255);
- DECLARE vTable VARCHAR(255);
- DECLARE vDone BOOL;
-
- DECLARE cTables CURSOR FOR
- SELECT `TABLE_SCHEMA`, `TABLE_NAME`
- FROM `information_schema`.`TABLES`
- WHERE `TABLE_TYPE` = 'BASE TABLE'
- AND `TABLE_SCHEMA` NOT IN ('information_schema', 'mysql', 'performance_schema');
-
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
-
- SET FOREIGN_KEY_CHECKS = FALSE;
- OPEN cTables;
-
- l: LOOP
- SET vDone = FALSE;
- FETCH cTables INTO vSchema, vTable;
-
- IF vDone THEN
- LEAVE l;
- END IF;
-
- SET @stmt = CONCAT('TRUNCATE TABLE `', vSchema, '`.`', vTable, '`');
- PREPARE stmt FROM @stmt;
- EXECUTE stmt;
- DEALLOCATE PREPARE stmt;
- END LOOP;
-
- CLOSE cTables;
- SET FOREIGN_KEY_CHECKS = TRUE;
-END$$
-DELIMITER ;
\ 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