diff --git a/changelog/60_UNRELEASED_2020-xx-xx.md b/changelog/60_UNRELEASED_2020-xx-xx.md index 6ca5ec77..0ba4a87e 100644 --- a/changelog/60_UNRELEASED_2020-xx-xx.md +++ b/changelog/60_UNRELEASED_2020-xx-xx.md @@ -141,7 +141,8 @@ - All tables are now customizable (new little eye icon on the top left corner on each table) - Table columns be shown/hidden - There are also new columns on some pages, hidden by default - - Stock overview: Value, product group, calories + - Stock overview: Value, product group, calories, last purchased, last price + - Products list: Default store - Row grouping can be customized to use any available column (thanks @edenhaus) - Table states (visible columns, sorting, column order and so on) are now saved server side (in user settings) means that this stays the same when using different browsers - Dialogs are now used everywhere where appropriate instead of jumping between pages (for exampel when adding/editing shopping list items) diff --git a/controllers/StockController.php b/controllers/StockController.php index 2ff38b14..7879a891 100644 --- a/controllers/StockController.php +++ b/controllers/StockController.php @@ -221,6 +221,7 @@ class StockController extends BaseController 'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'), 'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'), 'productGroups' => $this->getDatabase()->product_groups()->orderBy('name', 'COLLATE NOCASE'), + 'shoppingLocations' => $this->getDatabase()->shopping_locations()->orderBy('name', 'COLLATE NOCASE'), 'userfields' => $this->getUserfieldsService()->GetFields('products'), 'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products') ]); diff --git a/migrations/0122.sql b/migrations/0122.sql new file mode 100644 index 00000000..8141f972 --- /dev/null +++ b/migrations/0122.sql @@ -0,0 +1,93 @@ +DROP VIEW uihelper_stock_current_overview_including_opened; +CREATE VIEW uihelper_stock_current_overview_including_opened +AS +SELECT + p.id, + sc.amount_opened AS amount_opened, + p.tare_weight AS tare_weight, + p.enable_tare_weight_handling AS enable_tare_weight_handling, + sc.amount AS amount, + sc.value as value, + sc.product_id AS product_id, + sc.best_before_date AS best_before_date, + EXISTS(SELECT id FROM stock_missing_products_including_opened WHERE id = sc.product_id) AS product_missing, + (SELECT name FROM quantity_units WHERE quantity_units.id = p.qu_id_stock) AS qu_unit_name, + (SELECT name_plural FROM quantity_units WHERE quantity_units.id = p.qu_id_stock) AS qu_unit_name_plural, + p.name AS product_name, + (SELECT name FROM product_groups WHERE product_groups.id = product_group_id) AS product_group_name, + EXISTS(SELECT * FROM shopping_list WHERE shopping_list.product_id = sc.product_id) AS on_shopping_list, + (SELECT name FROM quantity_units WHERE quantity_units.id = p.qu_id_purchase) AS qu_purchase_unit_name, + (SELECT name_plural FROM quantity_units WHERE quantity_units.id = p.qu_id_purchase) AS qu_purchase_unit_name_plural, + sc.is_aggregated_amount, + sc.amount_opened_aggregated, + sc.amount_aggregated, + p.calories AS product_calories, + sc.amount * p.calories AS calories, + sc.amount_aggregated * p.calories AS calories_aggregated, + p.quick_consume_amount, + p.due_type, + plp.purchased_date AS last_purchased, + plp.price AS last_price +FROM ( + SELECT * + FROM stock_current + WHERE best_before_date IS NOT NULL + UNION + SELECT m.id, 0, 0, 0, null, 0, 0, 0, p.due_type + FROM stock_missing_products_including_opened m + JOIN products p + ON m.id = p.id + WHERE m.id NOT IN (SELECT product_id FROM stock_current) + ) sc +LEFT JOIN products_last_purchased plp + ON sc.product_id = plp.product_id +LEFT JOIN products p + ON sc.product_id = p.id +WHERE p.show_on_stock_overview = 1; + +DROP VIEW uihelper_stock_current_overview; +CREATE VIEW uihelper_stock_current_overview +AS +SELECT + p.id, + sc.amount_opened AS amount_opened, + p.tare_weight AS tare_weight, + p.enable_tare_weight_handling AS enable_tare_weight_handling, + sc.amount AS amount, + sc.value as value, + sc.product_id AS product_id, + sc.best_before_date AS best_before_date, + EXISTS(SELECT id FROM stock_missing_products WHERE id = sc.product_id) AS product_missing, + (SELECT name FROM quantity_units WHERE quantity_units.id = p.qu_id_stock) AS qu_unit_name, + (SELECT name_plural FROM quantity_units WHERE quantity_units.id = p.qu_id_stock) AS qu_unit_name_plural, + p.name AS product_name, + (SELECT name FROM product_groups WHERE product_groups.id = product_group_id) AS product_group_name, + EXISTS(SELECT * FROM shopping_list WHERE shopping_list.product_id = sc.product_id) AS on_shopping_list, + (SELECT name FROM quantity_units WHERE quantity_units.id = p.qu_id_purchase) AS qu_purchase_unit_name, + (SELECT name_plural FROM quantity_units WHERE quantity_units.id = p.qu_id_purchase) AS qu_purchase_unit_name_plural, + sc.is_aggregated_amount, + sc.amount_opened_aggregated, + sc.amount_aggregated, + p.calories AS product_calories, + sc.amount * p.calories AS calories, + sc.amount_aggregated * p.calories AS calories_aggregated, + p.quick_consume_amount, + p.due_type, + plp.purchased_date AS last_purchased, + plp.price AS last_price +FROM ( + SELECT * + FROM stock_current + WHERE best_before_date IS NOT NULL + UNION + SELECT m.id, 0, 0, 0, null, 0, 0, 0, p.due_type + FROM stock_missing_products m + JOIN products p + ON m.id = p.id + WHERE m.id NOT IN (SELECT product_id FROM stock_current) + ) sc +LEFT JOIN products_last_purchased plp + ON sc.product_id = plp.product_id +LEFT JOIN products p + ON sc.product_id = p.id +WHERE p.show_on_stock_overview = 1; diff --git a/public/viewjs/productform.js b/public/viewjs/productform.js index 8e7dfef8..08f46c23 100644 --- a/public/viewjs/productform.js +++ b/public/viewjs/productform.js @@ -287,7 +287,8 @@ var barcodeTable = $('#barcode-table').DataTable({ "orderFixed": [[1, 'asc']], 'columnDefs': [ { 'orderable': false, 'targets': 0 }, - { 'searchable': false, "targets": 0 } + { 'searchable': false, "targets": 0 }, + { 'visible': false, 'targets': 5 } ].concat($.fn.dataTable.defaults.columnDefs) }); $('#barcode-table tbody').removeClass("d-none"); diff --git a/public/viewjs/products.js b/public/viewjs/products.js index b1de33ec..7ac0d093 100644 --- a/public/viewjs/products.js +++ b/public/viewjs/products.js @@ -3,6 +3,7 @@ 'columnDefs': [ { 'orderable': false, 'targets': 0 }, { 'searchable': false, "targets": 0 }, + { 'visible': false, 'targets': 7 }, { "type": "html-num-fmt", "targets": 3 } ].concat($.fn.dataTable.defaults.columnDefs) }); diff --git a/public/viewjs/stockoverview.js b/public/viewjs/stockoverview.js index 8b42d340..f9d06977 100755 --- a/public/viewjs/stockoverview.js +++ b/public/viewjs/stockoverview.js @@ -11,10 +11,14 @@ { 'visible': false, 'targets': 4 }, { 'visible': false, 'targets': 9 }, { 'visible': false, 'targets': 10 }, + { 'visible': false, 'targets': 11 }, + { 'visible': false, 'targets': 12 }, { "type": "num", "targets": 3 }, { "type": "html-num-fmt", "targets": 9 }, { "type": "html-num-fmt", "targets": 10 }, - { "type": "html", "targets": 5 } + { "type": "html", "targets": 5 }, + { "type": "html", "targets": 11 }, + { "type": "html-num-fmt", "targets": 12 }, ].concat($.fn.dataTable.defaults.columnDefs) }); diff --git a/views/productform.blade.php b/views/productform.blade.php index 0c734526..a013f7a2 100644 --- a/views/productform.blade.php +++ b/views/productform.blade.php @@ -478,6 +478,7 @@ @endif {{ $__t('Quantity unit') }} {{ $__t('Amount') }} + {{ $__t('Last price') }} @include('components.userfields_thead', array( 'userfields' => $productBarcodeUserfields @@ -523,6 +524,9 @@ {{ $barcode->amount }} @endif + + {{ $barcode->last_price }} + @include('components.userfields_tbody', array( 'userfields' => $productBarcodeUserfields, diff --git a/views/products.blade.php b/views/products.blade.php index b60cd1e7..15f6a7bb 100644 --- a/views/products.blade.php +++ b/views/products.blade.php @@ -112,6 +112,7 @@ {{ $__t('Default quantity unit purchase') }} {{ $__t('Quantity unit stock') }} {{ $__t('Product group') }} + {{ $__t('Default store') }} @include('components.userfields_thead', array( 'userfields' => $userfields @@ -167,6 +168,11 @@ @if(!empty($product->product_group_id)) {{ FindObjectInArrayByPropertyValue($productGroups, 'id', $product->product_group_id)->name }} @endif + + @if(!empty($product->shopping_location_id)) + {{ FindObjectInArrayByPropertyValue($shoppingLocations, 'id', $product->shopping_location_id)->name }} + @endif + @include('components.userfields_tbody', array( 'userfields' => $userfields, diff --git a/views/stockoverview.blade.php b/views/stockoverview.blade.php index 2fd97809..eb8ab17d 100755 --- a/views/stockoverview.blade.php +++ b/views/stockoverview.blade.php @@ -166,6 +166,8 @@ Hidden product group {{ $__t('Calories') }} ({{ $__t('Per stock quantity unit') }}) {{ $__t('Calories') }} + {{ $__t('Last purchased') }} + {{ $__t('Last price') }} @include('components.userfields_thead', array( 'userfields' => $userfields @@ -370,6 +372,14 @@ {{ $currentStockEntry->calories }} + + {{ $currentStockEntry->last_purchased }} + + + + {{ $currentStockEntry->last_price }} + @include('components.userfields_tbody', array( 'userfields' => $userfields,