From 502622da69d5f49bdb75425babcb09d80ceed012 Mon Sep 17 00:00:00 2001 From: Kurt Riddlesperger Date: Thu, 30 Apr 2020 16:53:01 -0500 Subject: [PATCH] remove column product barcode and use product_barcodes --- controllers/StockController.php | 16 ++++++++++ grocy.openapi.json | 13 +++++++++ migrations/0103.sql | 37 ++++++++++++++++++++++++ public/viewjs/consume.js | 25 ++-------------- public/viewjs/inventory.js | 25 ++-------------- public/viewjs/purchase.js | 27 ++--------------- public/viewjs/transfer.js | 25 ++-------------- services/DemoDataGeneratorService.php | 2 +- services/StockService.php | 4 ++- views/components/productpicker.blade.php | 2 +- views/consume.blade.php | 1 + views/inventory.blade.php | 1 + views/purchase.blade.php | 1 + views/transfer.blade.php | 1 + 14 files changed, 87 insertions(+), 93 deletions(-) diff --git a/controllers/StockController.php b/controllers/StockController.php index 3971f895..3cbcd174 100644 --- a/controllers/StockController.php +++ b/controllers/StockController.php @@ -50,8 +50,12 @@ class StockController extends BaseController public function Purchase(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args) { + $sql = 'select group_concat(barcode) barcodes, product_id from product_barcodes group by product_id'; + $productBarcodes = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ); + return $this->renderPage($response, 'purchase', [ 'products' => $this->getDatabase()->products()->orderBy('name'), + 'barcodes' => $productBarcodes, 'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'), 'locations' => $this->getDatabase()->locations()->orderBy('name') ]); @@ -59,8 +63,12 @@ class StockController extends BaseController public function Consume(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args) { + $sql = 'select group_concat(barcode) barcodes, product_id from product_barcodes group by product_id'; + $productBarcodes = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ); + return $this->renderPage($response, 'consume', [ 'products' => $this->getDatabase()->products()->orderBy('name'), + 'barcodes' => $productBarcodes, 'recipes' => $this->getDatabase()->recipes()->orderBy('name'), 'locations' => $this->getDatabase()->locations()->orderBy('name') ]); @@ -68,8 +76,12 @@ class StockController extends BaseController public function Transfer(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args) { + $sql = 'select group_concat(barcode) barcodes, product_id from product_barcodes group by product_id'; + $productBarcodes = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ); + return $this->renderPage($response, 'transfer', [ 'products' => $this->getDatabase()->products()->orderBy('name'), + 'barcodes' => $productBarcodes, 'recipes' => $this->getDatabase()->recipes()->orderBy('name'), 'locations' => $this->getDatabase()->locations()->orderBy('name') ]); @@ -77,8 +89,12 @@ class StockController extends BaseController public function Inventory(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args) { + $sql = 'select group_concat(barcode) barcodes, product_id from product_barcodes group by product_id'; + $productBarcodes = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ); + return $this->renderPage($response, 'inventory', [ 'products' => $this->getDatabase()->products()->orderBy('name'), + 'barcodes' => $productBarcodes, 'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'), 'locations' => $this->getDatabase()->locations()->orderBy('name') ]); diff --git a/grocy.openapi.json b/grocy.openapi.json index 12d38143..20af6b9f 100644 --- a/grocy.openapi.json +++ b/grocy.openapi.json @@ -3451,6 +3451,7 @@ "type": "string", "enum": [ "products", + "product_barcodes", "chores", "batteries", "locations", @@ -3800,6 +3801,9 @@ "product": { "$ref": "#/components/schemas/Product" }, + "product_barcodes": { + "$ref": "#/components/schemas/ProductBarcodeDetailsResponse" + }, "quantity_unit_purchase": { "$ref": "#/components/schemas/QuantityUnit" }, @@ -3873,6 +3877,15 @@ "not_check_stock_fulfillment_for_recipes": "0", "last_shopping_location_id": null }, + "product_barcodes": [ + { + "id": "1", + "product_id": "13", + "barcode": "01321230213", + "qu_factor_purchase_to_stock": "10.0", + "shopping_location_id": "2" + } + ], "last_purchased": null, "last_used": null, "stock_amount": "2", diff --git a/migrations/0103.sql b/migrations/0103.sql index e406ba7e..6e3efd1a 100644 --- a/migrations/0103.sql +++ b/migrations/0103.sql @@ -25,6 +25,43 @@ qu_factor_purchase_to_stock REAL NOT NULL DEFAULT 1, shopping_location_id INTEGER ); +ALTER TABLE products RENAME TO products_old; + +--Remove barcode column +--Reorder columns + +CREATE TABLE products ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + name TEXT NOT NULL UNIQUE, + description TEXT, + product_group_id INTEGER, + location_id INTEGER NOT NULL, + shopping_location_id INTEGER, + qu_id_purchase INTEGER NOT NULL, + qu_id_stock INTEGER NOT NULL, + qu_factor_purchase_to_stock REAL NOT NULL, + min_stock_amount INTEGER NOT NULL DEFAULT 0, + default_best_before_days INTEGER NOT NULL DEFAULT 0, + default_best_before_days_after_open INTEGER NOT NULL DEFAULT 0, + default_best_before_days_after_freezing INTEGER NOT NULL DEFAULT 0, + default_best_before_days_after_thawing INTEGER NOT NULL DEFAULT 0, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')), + picture_file_name TEXT, + allow_partial_units_in_stock TINYINT NOT NULL DEFAULT 0, + enable_tare_weight_handling TINYINT NOT NULL DEFAULT 0, + tare_weight REAL NOT NULL DEFAULT 0, + not_check_stock_fulfillment_for_recipes TINYINT DEFAULT 0, + parent_product_id INT, + calories INTEGER, + cumulate_min_stock_amount_of_sub_products TINYINT DEFAULT 0); + +INSERT INTO products + (id,name,description,location_id,qu_id_purchase,qu_id_stock,qu_factor_purchase_to_stock,min_stock_amount,default_best_before_days,row_created_timestamp,product_group_id,picture_file_name,default_best_before_days_after_open,allow_partial_units_in_stock,enable_tare_weight_handling,tare_weight,not_check_stock_fulfillment_for_recipes,parent_product_id,calories,cumulate_min_stock_amount_of_sub_products,default_best_before_days_after_freezing,default_best_before_days_after_thawing,shopping_location_id) +SELECT id,name,description,location_id,qu_id_purchase,qu_id_stock,qu_factor_purchase_to_stock,min_stock_amount,default_best_before_days,row_created_timestamp,product_group_id,picture_file_name,default_best_before_days_after_open,allow_partial_units_in_stock,enable_tare_weight_handling,tare_weight,not_check_stock_fulfillment_for_recipes,parent_product_id,calories,cumulate_min_stock_amount_of_sub_products,default_best_before_days_after_freezing,default_best_before_days_after_thawing,shopping_location_id +FROM products_old; + +DROP TABLE products_old; + DROP VIEW stock_current_location_content; CREATE VIEW stock_current_location_content AS diff --git a/public/viewjs/consume.js b/public/viewjs/consume.js index cd8a6c3c..eb6572cf 100644 --- a/public/viewjs/consume.js +++ b/public/viewjs/consume.js @@ -44,27 +44,6 @@ var addBarcode = GetUriParam('addbarcodetoselection'); if (addBarcode !== undefined) { - var existingBarcodes = productDetails.product.barcode || ''; - if (existingBarcodes.length === 0) - { - productDetails.product.barcode = addBarcode; - } - else - { - productDetails.product.barcode += ',' + addBarcode; - } - - Grocy.Api.Put('objects/products/' + productDetails.product.id, productDetails.product, - function(result) - { - $("#flow-info-addbarcodetoselection").addClass("d-none"); - $('#barcode-lookup-disabled-hint').addClass('d-none'); - }, - function(xhr) - { - console.error(xhr); - } - ); var jsonDataBarcode = {}; jsonDataBarcode.barcode = addBarcode; jsonDataBarcode.product_id = jsonForm.product_id; @@ -73,11 +52,13 @@ Grocy.Api.Post('objects/product_barcodes', jsonDataBarcode, function(result) { + $("#flow-info-addbarcodetoselection").addClass("d-none"); + $('#barcode-lookup-disabled-hint').addClass('d-none'); window.history.replaceState({ }, document.title, U("/consume")); }, function(xhr) { - Grocy.FrontendHelpers.EndUiBusy("barcode-form"); + Grocy.FrontendHelpers.EndUiBusy("consume-form"); Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response); } ); diff --git a/public/viewjs/inventory.js b/public/viewjs/inventory.js index 79b1a805..9f173f5d 100644 --- a/public/viewjs/inventory.js +++ b/public/viewjs/inventory.js @@ -37,27 +37,6 @@ var addBarcode = GetUriParam('addbarcodetoselection'); if (addBarcode !== undefined) { - var existingBarcodes = productDetails.product.barcode || ''; - if (existingBarcodes.length === 0) - { - productDetails.product.barcode = addBarcode; - } - else - { - productDetails.product.barcode += ',' + addBarcode; - } - - Grocy.Api.Put('objects/products/' + productDetails.product.id, productDetails.product, - function(result) - { - $("#flow-info-addbarcodetoselection").addClass("d-none"); - $('#barcode-lookup-disabled-hint').addClass('d-none'); - }, - function(xhr) - { - console.error(xhr); - } - ); var jsonDataBarcode = {}; jsonDataBarcode.barcode = addBarcode; jsonDataBarcode.product_id = jsonForm.product_id; @@ -67,11 +46,13 @@ Grocy.Api.Post('objects/product_barcodes', jsonDataBarcode, function(result) { + $("#flow-info-addbarcodetoselection").addClass("d-none"); + $('#barcode-lookup-disabled-hint').addClass('d-none'); window.history.replaceState({ }, document.title, U("/inventory")); }, function(xhr) { - Grocy.FrontendHelpers.EndUiBusy("barcode-form"); + Grocy.FrontendHelpers.EndUiBusy("inventory-form"); Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response); } ); diff --git a/public/viewjs/purchase.js b/public/viewjs/purchase.js index 8000c120..7fe1d843 100644 --- a/public/viewjs/purchase.js +++ b/public/viewjs/purchase.js @@ -51,29 +51,6 @@ var addBarcode = GetUriParam('addbarcodetoselection'); if (addBarcode !== undefined) { - var existingBarcodes = productDetails.product.barcode || ''; - if (existingBarcodes.length === 0) - { - productDetails.product.barcode = addBarcode; - } - else - { - productDetails.product.barcode += ',' + addBarcode; - } - - Grocy.Api.Put('objects/products/' + productDetails.product.id, productDetails.product, - function(result) - { - $("#flow-info-addbarcodetoselection").addClass("d-none"); - $('#barcode-lookup-disabled-hint').addClass('d-none'); - }, - function(xhr) - { - Grocy.FrontendHelpers.EndUiBusy("purchase-form"); - console.error(xhr); - } - ); - var jsonDataBarcode = {}; jsonDataBarcode.barcode = addBarcode; jsonDataBarcode.product_id = jsonForm.product_id; @@ -83,11 +60,13 @@ Grocy.Api.Post('objects/product_barcodes', jsonDataBarcode, function(result) { + $("#flow-info-addbarcodetoselection").addClass("d-none"); + $('#barcode-lookup-disabled-hint').addClass('d-none'); window.history.replaceState({ }, document.title, U("/purchase")); }, function(xhr) { - Grocy.FrontendHelpers.EndUiBusy("barcode-form"); + Grocy.FrontendHelpers.EndUiBusy("purchase-form"); Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response); } ); diff --git a/public/viewjs/transfer.js b/public/viewjs/transfer.js index fac54131..bc3dc3bf 100644 --- a/public/viewjs/transfer.js +++ b/public/viewjs/transfer.js @@ -30,27 +30,6 @@ if (addBarcode !== undefined) { - var existingBarcodes = productDetails.product.barcode || ''; - if (existingBarcodes.length === 0) - { - productDetails.product.barcode = addBarcode; - } - else - { - productDetails.product.barcode += ',' + addBarcode; - } - - Grocy.Api.Put('objects/products/' + productDetails.product.id, productDetails.product, - function(result) - { - $("#flow-info-addbarcodetoselection").addClass("d-none"); - $('#barcode-lookup-disabled-hint').addClass('d-none'); - }, - function(xhr) - { - console.error(xhr); - } - ); var jsonDataBarcode = {}; jsonDataBarcode.barcode = addBarcode; jsonDataBarcode.product_id = jsonForm.product_id; @@ -59,11 +38,13 @@ Grocy.Api.Post('objects/product_barcodes', jsonDataBarcode, function(result) { + $("#flow-info-addbarcodetoselection").addClass("d-none"); + $('#barcode-lookup-disabled-hint').addClass('d-none'); window.history.replaceState({ }, document.title, U("/transfer")); }, function(xhr) { - Grocy.FrontendHelpers.EndUiBusy("barcode-form"); + Grocy.FrontendHelpers.EndUiBusy("transfer-form"); Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response); } ); diff --git a/services/DemoDataGeneratorService.php b/services/DemoDataGeneratorService.php index 7221121c..bea6c23f 100644 --- a/services/DemoDataGeneratorService.php +++ b/services/DemoDataGeneratorService.php @@ -96,7 +96,7 @@ class DemoDataGeneratorService extends BaseService INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id, calories) VALUES ('{$this->__t_sql('Milk')}', 2, 10, 10, 1, 6, 1); --23 INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id, parent_product_id) VALUES ('{$this->__t_sql('Milk Chocolate')}', 4, 3, 3, 1, 1, 2); --24 INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id, parent_product_id) VALUES ('{$this->__t_sql('Dark Chocolate')}', 4, 3, 3, 1, 1, 2); --25 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id, barcode) VALUES ('{$this->__t_sql('Waffle rolls')}', 4, 3, 3, 1, 1, '22111289'); --26 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$this->__t_sql('Waffle rolls')}', 4, 3, 3, 1, 1); --26 UPDATE products SET calories = 123 WHERE IFNULL(calories, 0) = 0; /* Prevent invalid quantity unit assignments */ diff --git a/services/StockService.php b/services/StockService.php index adbe24f7..2f12c198 100644 --- a/services/StockService.php +++ b/services/StockService.php @@ -69,7 +69,7 @@ class StockService extends BaseService public function GetProductIdFromBarcode(string $barcode) { - $potentialProduct = $this->getDatabase()->products()->where("',' || barcode || ',' LIKE '%,' || :1 || ',%' AND IFNULL(barcode, '') != ''", $barcode)->limit(1)->fetch(); + $potentialProduct = $this->getDatabase()->product_barcodes()->where("barcode = :1", $barcode)->fetch(); if ($potentialProduct === null) { @@ -114,6 +114,7 @@ class StockService extends BaseService } $product = $this->getDatabase()->products($productId); + $productBarcodes = $this->getDatabase()->product_barcodes()->where('product_id', $productId)->fetchAll(); $productLastPurchased = $this->getDatabase()->products_last_purchased()->where('product_id', $productId)->fetch(); $productLastUsed = $this->getDatabase()->stock_log()->where('product_id', $productId)->where('transaction_type', self::TRANSACTION_TYPE_CONSUME)->where('undone', 0)->max('used_date'); $nextBestBeforeDate = $this->getDatabase()->stock()->where('product_id', $productId)->min('best_before_date'); @@ -138,6 +139,7 @@ class StockService extends BaseService return array( 'product' => $product, + 'product_barcodes' => $productBarcodes, 'last_purchased' => $productLastPurchased->purchased_date, 'last_used' => $productLastUsed, 'stock_amount' => $stockCurrentRow->amount, diff --git a/views/components/productpicker.blade.php b/views/components/productpicker.blade.php index 99998514..2d2cf033 100644 --- a/views/components/productpicker.blade.php +++ b/views/components/productpicker.blade.php @@ -21,7 +21,7 @@
{{ $__t('You have to select a product') }}
diff --git a/views/consume.blade.php b/views/consume.blade.php index c5234717..a0471b05 100644 --- a/views/consume.blade.php +++ b/views/consume.blade.php @@ -30,6 +30,7 @@ @include('components.productpicker', array( 'products' => $products, + 'barcodes' => $barcodes, 'nextInputSelector' => '#amount', 'disallowAddProductWorkflows' => true )) diff --git a/views/inventory.blade.php b/views/inventory.blade.php index ea1f885e..95b8e717 100644 --- a/views/inventory.blade.php +++ b/views/inventory.blade.php @@ -13,6 +13,7 @@ @include('components.productpicker', array( 'products' => $products, + 'barcodes' => $barcodes, 'nextInputSelector' => '#new_amount' )) diff --git a/views/purchase.blade.php b/views/purchase.blade.php index 1e398ead..10a579c7 100644 --- a/views/purchase.blade.php +++ b/views/purchase.blade.php @@ -30,6 +30,7 @@ @include('components.productpicker', array( 'products' => $products, + 'barcodes' => $barcodes, 'nextInputSelector' => '#amount' )) diff --git a/views/transfer.blade.php b/views/transfer.blade.php index f679dc7c..5f979481 100644 --- a/views/transfer.blade.php +++ b/views/transfer.blade.php @@ -14,6 +14,7 @@ @include('components.productpicker', array( 'products' => $products, + 'barcodes' => $barcodes, 'nextInputSelector' => '#location_id_from', 'disallowAddProductWorkflows' => true ))