diff --git a/GrocyDbMigrator.php b/GrocyDbMigrator.php index e99975e3..e0293963 100644 --- a/GrocyDbMigrator.php +++ b/GrocyDbMigrator.php @@ -72,7 +72,11 @@ class GrocyDbMigrator { if ($pdo->query("SELECT COUNT(*) FROM migrations WHERE migration = $migrationId")->fetchColumn() == 0) { - $pdo->exec(utf8_encode($sql)); + if ($pdo->exec(utf8_encode($sql)) === false) + { + throw new Exception($pdo->errorInfo()); + } + $pdo->exec('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')'); } } diff --git a/GrocyDemoDataGenerator.php b/GrocyDemoDataGenerator.php index 1ccea703..c6b801c0 100644 --- a/GrocyDemoDataGenerator.php +++ b/GrocyDemoDataGenerator.php @@ -4,7 +4,7 @@ class GrocyDemoDataGenerator { public static function PopulateDemoData(PDO $pdo) { - $pdo->exec(utf8_encode(" + $sql = " UPDATE locations SET name = 'Vorratskammer', description = '' WHERE id = 1; INSERT INTO locations (name) VALUES ('Süßigkeitenschrank'); INSERT INTO locations (name) VALUES ('Konvervenschrank'); @@ -19,6 +19,11 @@ class GrocyDemoDataGenerator INSERT INTO stock (product_id, amount, best_before_date, stock_id) VALUES (3, 5, date('now', '+180 day'), '".uniqid()."'); INSERT INTO stock (product_id, amount, best_before_date, stock_id) VALUES (4, 5, date('now', '+180 day'), '".uniqid()."'); INSERT INTO stock (product_id, amount, best_before_date, stock_id) VALUES (5, 5, date('now', '+25 day'), '".uniqid()."'); - ")); + "; + + if ($pdo->exec(utf8_encode($sql)) === false) + { + throw new Exception($pdo->errorInfo()); + } } } diff --git a/GrocyLogicStock.php b/GrocyLogicStock.php index cd729c30..97f38650 100644 --- a/GrocyLogicStock.php +++ b/GrocyLogicStock.php @@ -5,7 +5,7 @@ class GrocyLogicStock public static function GetCurrentStock() { $db = Grocy::GetDbConnectionRaw(); - return $db->query('SELECT product_id, SUM(amount) AS amount, MIN(best_before_date) AS best_before_date from stock GROUP BY product_id ORDER BY MIN(best_before_date) DESC')->fetchAll(PDO::FETCH_OBJ); + return $db->query('SELECT product_id, SUM(amount) AS amount, MIN(best_before_date) AS best_before_date from stock GROUP BY product_id ORDER BY MIN(best_before_date) ASC')->fetchAll(PDO::FETCH_OBJ); } public static function GetProductDetails(int $productId) @@ -63,7 +63,7 @@ class GrocyLogicStock $amount -= $stockEntry->amount; $stockEntry->delete(); } - else //Stock entry amount is > than need amount -> split the stock entry resp. update the amount + else //Stock entry amount is > than needed amount -> split the stock entry resp. update the amount { $consumptionRow = $db->consumptions()->createRow(array( 'product_id' => $stockEntry->product_id, diff --git a/bower.json b/bower.json index 8d2433e7..8eeeb40a 100644 --- a/bower.json +++ b/bower.json @@ -14,6 +14,7 @@ "datatables.net-bs": "2.1.1", "datatables.net-responsive": "2.1.1", "datatables.net-responsive-bs": "2.1.1", - "jquery-timeago": "1.5.4" + "jquery-timeago": "1.5.4", + "toastr": "2.1.3" } } diff --git a/grocy.php b/grocy.php index 4ffeaeae..ea363ee7 100644 --- a/grocy.php +++ b/grocy.php @@ -2,9 +2,7 @@ class Grocy { - private static $DbConnection; private static $DbConnectionRaw; - /** * @return PDO */ @@ -33,6 +31,7 @@ class Grocy return self::$DbConnectionRaw; } + private static $DbConnection; /** * @return LessQL\Database */ @@ -50,4 +49,15 @@ class Grocy { return file_exists(__DIR__ . '/data/demo.txt'); } + + private static $InstalledVersion; + public static function GetInstalledVersion() + { + if (self::$InstalledVersion == null) + { + self::$InstalledVersion = file_get_contents(__DIR__ . '/version.txt'); + } + + return self::$InstalledVersion; + } } diff --git a/style.css b/style.css index d2a0e0ca..eb1a3752 100644 --- a/style.css +++ b/style.css @@ -104,4 +104,8 @@ .timeago-contextual { font-style: italic; font-size: 0.8em; -} \ No newline at end of file +} + +.disabled { + pointer-events: none; +} diff --git a/version.txt b/version.txt index 341cf11f..9325c3cc 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.2.0 \ No newline at end of file +0.3.0 \ No newline at end of file diff --git a/views/consumption.js b/views/consumption.js index 20cbde67..f0ea5660 100644 --- a/views/consumption.js +++ b/views/consumption.js @@ -10,14 +10,26 @@ spoiled = 1; } - Grocy.FetchJson('/api/stock/consume-product/' + jsonForm.product_id + '/' + jsonForm.amount + '?spoiled=' + spoiled, - function(result) + Grocy.FetchJson('/api/stock/get-product-details/' + jsonForm.product_id, + function (productDetails) { - $('#product_id_text_input').focus(); - $('#product_id_text_input').val(''); - $('#product_id_text_input').trigger('change'); - $('#amount').val(1); - $('#consumption-form').validator('validate'); + Grocy.FetchJson('/api/stock/consume-product/' + jsonForm.product_id + '/' + jsonForm.amount + '?spoiled=' + spoiled, + function(result) + { + toastr.success('Removed ' + jsonForm.amount + ' ' + productDetails.quantity_unit_stock.name + ' of ' + productDetails.product.name + ' from stock'); + + $('#amount').val(1); + $('#product_id').val(''); + $('#product_id_text_input').focus(); + $('#product_id_text_input').val(''); + $('#product_id_text_input').trigger('change'); + $('#consumption-form').validator('validate'); + }, + function(xhr) + { + console.error(xhr); + } + ); }, function(xhr) { @@ -47,6 +59,24 @@ $('#product_id').on('change', function(e) Grocy.EmptyElementWhenMatches('#selected-product-last-purchased-timeago', 'NaN years ago'); Grocy.EmptyElementWhenMatches('#selected-product-last-used-timeago', 'NaN years ago'); + + if ((productStatistics.stock_amount || 0) === 0) + { + $('#product_id').val(''); + $('#product_id_text_input').val(''); + $('#product_id_text_input').addClass('has-error'); + $('#product_id_text_input').parent('.input-group').addClass('has-error'); + $('#product_id_text_input').closest('.form-group').addClass('has-error'); + $('#product-error').text('This product is not in stock.'); + $('#product-error').show(); + } + else + { + $('#product_id_text_input').removeClass('has-error'); + $('#product_id_text_input').parent('.input-group').removeClass('has-error'); + $('#product_id_text_input').closest('.form-group').removeClass('has-error'); + $('#product-error').hide(); + } }, function(xhr) { @@ -58,23 +88,26 @@ $('#product_id').on('change', function(e) $(function() { - $('.datepicker').datepicker( - { - format: 'yyyy-mm-dd', - startDate: '-3d', - todayHighlight: true, - autoclose: true, - calendarWeeks: true, - orientation: 'bottom auto' - }); - $('.datepicker').val(moment().format('YYYY-MM-DD')); - $('.datepicker').trigger('change'); - $('.combobox').combobox({ appendId: '_text_input' }); + + $('#amount').val(1); + $('#product_id').val(''); $('#product_id_text_input').focus(); $('#product_id_text_input').val(''); $('#product_id_text_input').trigger('change'); $('#consumption-form').validator(); $('#consumption-form').validator('validate'); + + $('#consumption-form input').keydown(function(event) + { + if (event.keyCode === 13) //Enter + { + if ($('#consumption-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error + { + event.preventDefault(); + return false; + } + } + }); }); diff --git a/views/consumption.php b/views/consumption.php index 57b06296..6d237bec 100644 --- a/views/consumption.php +++ b/views/consumption.php @@ -1,22 +1,16 @@