This commit is contained in:
Bernd Bestel 2020-08-17 21:44:28 +02:00
parent 56ab8add27
commit 8d361992d8
No known key found for this signature in database
GPG Key ID: 71BD34C0D4891300
7 changed files with 169 additions and 92 deletions

View File

@ -1810,3 +1810,33 @@ msgstr ""
msgid "Save & return to recipes" msgid "Save & return to recipes"
msgstr "" msgstr ""
msgid "Stock value"
msgstr ""
msgid "Average price"
msgstr ""
msgid "Active"
msgstr ""
msgid "Barcodes"
msgstr ""
msgid "Barcode"
msgstr ""
msgid "Create Barcode"
msgstr ""
msgid "Barcode for product"
msgstr ""
msgid "Edit Barcode"
msgstr ""
msgid "Not enough in stock (not included in costs), %s ingredient missing"
msgstr ""
msgid "Based on the prices of the default consume rule which is \"First expiring first, then first in first out\""
msgstr ""

View File

@ -5,16 +5,16 @@ ALTER TABLE stock
ADD qu_factor_purchase_to_stock REAL NOT NULL DEFAULT 1.0; ADD qu_factor_purchase_to_stock REAL NOT NULL DEFAULT 1.0;
UPDATE stock UPDATE stock
SET qu_factor_purchase_to_stock = (select qu_factor_purchase_to_stock from products where product_id = id); SET qu_factor_purchase_to_stock = (SELECT qu_factor_purchase_to_stock FROM products WHERE product_id = id);
UPDATE stock_log UPDATE stock_log
SET qu_factor_purchase_to_stock = (select qu_factor_purchase_to_stock from products where product_id = id); SET qu_factor_purchase_to_stock = (SELECT qu_factor_purchase_to_stock FROM products WHERE product_id = id);
--Price is now going forward to be saved as 1 QU Stock --Price is now going forward to be saved as 1 QU Stock
update stock UPDATE stock
SET price = ROUND(price / qu_factor_purchase_to_stock, 2); SET price = ROUND(price / qu_factor_purchase_to_stock, 2);
update stock_log UPDATE stock_log
SET price = ROUND(price / qu_factor_purchase_to_stock, 2); SET price = ROUND(price / qu_factor_purchase_to_stock, 2);
CREATE TABLE product_barcodes ( CREATE TABLE product_barcodes (
@ -22,27 +22,36 @@ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
product_id INT NOT NULL, product_id INT NOT NULL,
barcode TEXT NOT NULL UNIQUE, barcode TEXT NOT NULL UNIQUE,
qu_factor_purchase_to_stock REAL NOT NULL DEFAULT 1, qu_factor_purchase_to_stock REAL NOT NULL DEFAULT 1,
shopping_location_id INTEGER shopping_location_id INTEGER,
row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime'))
); );
--Convert product table to new barcode table -- Convert product table to new product_barcodes table
INSERT INTO product_barcodes (product_id, barcode, qu_factor_purchase_to_stock, shopping_location_id) INSERT INTO product_barcodes
WITH split(id, barcode, str, qu_factor_purchase_to_stock, shopping_location_id) AS ( (product_id, barcode, qu_factor_purchase_to_stock, shopping_location_id)
select id as product_id, '', barcode||',' ,qu_factor_purchase_to_stock, shopping_location_id from products WITH barcodes_splitted(id, barcode, str, qu_factor_purchase_to_stock, shopping_location_id) AS (
UNION ALL SELECT SELECT id as product_id, '', barcode || ',', qu_factor_purchase_to_stock, shopping_location_id
FROM products
UNION ALL
SELECT
id as product_id, id as product_id,
substr(str, 0, instr(str, ',')), SUBSTR(str, 0, instr(str, ',')),
substr(str, instr(str, ',')+1), SUBSTR(str, instr(str, ',') + 1),
qu_factor_purchase_to_stock, qu_factor_purchase_to_stock,
shopping_location_id shopping_location_id
FROM split WHERE str!='' FROM barcodes_splitted
) SELECT id as product_id, barcode, qu_factor_purchase_to_stock, shopping_location_id FROM split WHERE barcode!=''; WHERE str != ''
)
SELECT id as product_id, barcode, qu_factor_purchase_to_stock, shopping_location_id
FROM barcodes_splitted
WHERE barcode != '';
PRAGMA legacy_alter_table = ON;
ALTER TABLE products RENAME TO products_old; ALTER TABLE products RENAME TO products_old;
-- Remove barcode column -- Remove barcode column
-- Reorder columns -- Reorder columns
CREATE TABLE products ( CREATE TABLE products (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
name TEXT NOT NULL UNIQUE, name TEXT NOT NULL UNIQUE,
@ -59,7 +68,6 @@ CREATE TABLE products (
default_best_before_days_after_open 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_freezing INTEGER NOT NULL DEFAULT 0,
default_best_before_days_after_thawing 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, picture_file_name TEXT,
allow_partial_units_in_stock TINYINT NOT NULL DEFAULT 0, allow_partial_units_in_stock TINYINT NOT NULL DEFAULT 0,
enable_tare_weight_handling TINYINT NOT NULL DEFAULT 0, enable_tare_weight_handling TINYINT NOT NULL DEFAULT 0,
@ -67,7 +75,9 @@ CREATE TABLE products (
not_check_stock_fulfillment_for_recipes TINYINT DEFAULT 0, not_check_stock_fulfillment_for_recipes TINYINT DEFAULT 0,
parent_product_id INT, parent_product_id INT,
calories INTEGER, calories INTEGER,
cumulate_min_stock_amount_of_sub_products TINYINT DEFAULT 0); cumulate_min_stock_amount_of_sub_products TINYINT DEFAULT 0,
row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime'))
);
INSERT INTO products 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) (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)
@ -89,7 +99,8 @@ SELECT
IFNULL((SELECT SUM(amount) FROM stock WHERE product_id = s.product_id AND location_id = s.location_id AND open = 1), 0) AS amount_opened IFNULL((SELECT SUM(amount) FROM stock WHERE product_id = s.product_id AND location_id = s.location_id AND open = 1), 0) AS amount_opened
FROM stock s FROM stock s
JOIN products p JOIN products p
ON s.product_id = p.id and p.active = 1 ON s.product_id = p.id
AND p.active = 1
GROUP BY IFNULL(s.location_id, p.location_id), s.product_id; GROUP BY IFNULL(s.location_id, p.location_id), s.product_id;
DROP VIEW stock_current; DROP VIEW stock_current;
@ -109,9 +120,11 @@ FROM products_resolved pr
JOIN stock s JOIN stock s
ON pr.sub_product_id = s.product_id ON pr.sub_product_id = s.product_id
JOIN products p_parent JOIN products p_parent
ON pr.parent_product_id = p_parent.id and p_parent.active = 1 ON pr.parent_product_id = p_parent.id
AND p_parent.active = 1
JOIN products p_sub JOIN products p_sub
ON pr.sub_product_id = p_sub.id and p_sub.active = 1 ON pr.sub_product_id = p_sub.id
AND p_sub.active = 1
LEFT JOIN quantity_unit_conversions_resolved qucr LEFT JOIN quantity_unit_conversions_resolved qucr
ON pr.sub_product_id = qucr.product_id ON pr.sub_product_id = qucr.product_id
AND p_sub.qu_id_stock = qucr.from_qu_id AND p_sub.qu_id_stock = qucr.from_qu_id
@ -146,7 +159,7 @@ SELECT
p.id as sub_product_id p.id as sub_product_id
FROM products p FROM products p
WHERE p.parent_product_id IS NOT NULL WHERE p.parent_product_id IS NOT NULL
and p.active = 1 AND p.active = 1
UNION UNION

View File

@ -1,54 +1,88 @@
-- Deprecate unused view to instead use products_last_purchased -- Deprecate unused view to instead use products_last_purchased
DROP VIEW products_current_price; DROP VIEW products_current_price;
CREATE VIEW products_last_purchased AS CREATE VIEW products_last_purchased
AS
select select
1 AS id, -- Dummy, LessQL needs an id column 1 AS id, -- Dummy, LessQL needs an id column
sw.product_id, sw.amount, sw.best_before_date, sw.purchased_date, sw.price, sw.qu_factor_purchase_to_stock, sw.location_id, sw.shopping_location_id sl.product_id,
from stock_log sw join sl.amount,
(select sl.best_before_date,
sl.purchased_date,
sl.price,
sl.qu_factor_purchase_to_stock,
sl.location_id,
sl.shopping_location_id
from stock_log sl
JOIN (
SELECT
s1.product_id, s1.product_id,
max(s1.id) max_stock_id MAX(s1.id) max_stock_id
from stock_log s1 FROM stock_log s1
join ( JOIN (
select s.product_id, SELECT
max(s.purchased_date) max_purchased_date s.product_id,
from stock_log s MAX(s.purchased_date) max_purchased_date
where undone = 0 FROM stock_log s
and transaction_type in ('purchase', 'stock-edit-new', 'inventory-correction') WHERE undone = 0
group by s.product_id) sp2 on s1.product_id = sp2.product_id and s1.purchased_date = sp2.max_purchased_date AND transaction_type in ('purchase', 'stock-edit-new', 'inventory-correction')
where undone = 0 GROUP BY s.product_id) sp2
and transaction_type in ('purchase', 'stock-edit-new', 'inventory-correction') ON s1.product_id = sp2.product_id
group by s1.product_id) sp3 on sw.product_id = sp3.product_id and sw.id = sp3.max_stock_id; AND s1.purchased_date = sp2.max_purchased_date
WHERE undone = 0
AND transaction_type in ('purchase', 'stock-edit-new', 'inventory-correction')
GROUP BY s1.product_id) sp3
ON sl.product_id = sp3.product_id
AND sl.id = sp3.max_stock_id;
CREATE VIEW products_average_price AS CREATE VIEW products_average_price
select AS
SELECT
1 AS id, -- Dummy, LessQL needs an id column 1 AS id, -- Dummy, LessQL needs an id column
s.product_id, s.product_id,
round(sum(s.amount * s.price) / sum(s.amount), 2) as price round(sum(s.amount * s.price) / sum(s.amount), 2) as price
from stock s group by s.product_id; FROM stock s
GROUP BY s.product_id;
CREATE VIEW products_oldest_stock_unit_price AS CREATE VIEW products_oldest_stock_unit_price
-- find oldest best_before_date then oldest purchased_date then make sure to return one stock row using max AS
select -- Find oldest best_before_date then oldest purchased_date then make sure to return one stock row using max
SELECT
1 AS id, -- Dummy, LessQL needs an id column 1 AS id, -- Dummy, LessQL needs an id column
sw.product_id, sw.amount, sw.best_before_date, sw.purchased_date, sw.price, sw.qu_factor_purchase_to_stock, sw.location_id, sw.shopping_location_id sw.product_id,
from stock sw join sw.amount,
(select sw.best_before_date,
sw.purchased_date,
sw.price, sw.qu_factor_purchase_to_stock,
sw.location_id,
sw.shopping_location_id
FROM stock sw
JOIN (
SELECT
s1.product_id, s1.product_id,
min(s1.id) min_stock_id MIN(s1.id) min_stock_id
from stock s1 FROM stock s1
join ( JOIN (
select s.product_id, SELECT
s.product_id,
sp.oldest_date, sp.oldest_date,
min(s.purchased_date) min_purchased_date MIN(s.purchased_date) min_purchased_date
from stock s join FROM stock s
(select product_id, JOIN (
min(best_before_date) as oldest_date SELECT
from stock product_id,
group by product_id) sp on s.product_id = sp.product_id and s.best_before_date = sp.oldest_date MIN(best_before_date) as oldest_date
group by s.product_id, sp.oldest_date) sp2 on s1.product_id = sp2.product_id and s1.best_before_date = sp2.oldest_date and s1.purchased_date = sp2.min_purchased_date FROM stock
group by s1.product_id) sp3 on sw.product_id = sp3.product_id and sw.id = sp3.min_stock_id; GROUP BY product_id) sp
ON s.product_id = sp.product_id
AND s.best_before_date = sp.oldest_date
GROUP BY s.product_id, sp.oldest_date) sp2
ON s1.product_id = sp2.product_id
AND s1.best_before_date = sp2.oldest_date
AND s1.purchased_date = sp2.min_purchased_date
GROUP BY s1.product_id) sp3
ON sw.product_id = sp3.product_id
AND sw.id = sp3.min_stock_id;
DROP VIEW recipes_pos_resolved; DROP VIEW recipes_pos_resolved;
CREATE VIEW recipes_pos_resolved CREATE VIEW recipes_pos_resolved

View File

@ -1,12 +1,12 @@
var stockOverviewTable = $('#stock-overview-table').DataTable({ var stockOverviewTable = $('#stock-overview-table').DataTable({
'order': [[3, 'asc']], 'order': [[4, 'asc']],
'colReorder': false, 'colReorder': false,
'columnDefs': [ 'columnDefs': [
{ 'orderable': false, 'targets': 0 }, { 'orderable': false, 'targets': 0 },
{ 'searchable': false, "targets": 0 }, { 'searchable': false, "targets": 0 },
{ 'searchable': false, "targets": 0 }, { 'searchable': false, "targets": 0 },
{ 'visible': false, 'targets': 4 }, { 'visible': false, 'targets': 5 },
{ 'visible': false, 'targets': 5 } { 'visible': false, 'targets': 6 }
], ],
}); });
$('#stock-overview-table tbody').removeClass("d-none"); $('#stock-overview-table tbody').removeClass("d-none");

View File

@ -1,9 +1,9 @@
@extends('layout.default') @extends('layout.default')
@if($mode == 'edit') @if($mode == 'edit')
@section('title', $__t('Edit Barcodes')) @section('title', $__t('Edit Barcode'))
@else @else
@section('title', $__t('Create Barcodes')) @section('title', $__t('Create Barcode'))
@endif @endif
@section('viewJsName', 'productbarcodesform') @section('viewJsName', 'productbarcodesform')
@ -49,7 +49,7 @@
'additionalCssClasses' => 'input-group-qu', 'additionalCssClasses' => 'input-group-qu',
)) ))
@if(GROCY_FEATURE_FLAG_PRICE_TRACKING) @if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
<div class="form-group"> <div class="form-group">
<label for="shopping_location_id_id">{{ $__t('Default store') }}</label> <label for="shopping_location_id_id">{{ $__t('Default store') }}</label>
<select class="form-control" id="shopping_location_id" name="shopping_location_id"> <select class="form-control" id="shopping_location_id" name="shopping_location_id">

View File

@ -347,7 +347,7 @@
</table> </table>
<h2> <h2>
{{ $__t('Barcode Details') }} {{ $__t('Barcodes') }}
<a class="btn btn-outline-dark show-as-dialog-link" type="button" href="{{ $U('/productbarcodes/new?embedded&product=' . $product->id ) }}"> <a class="btn btn-outline-dark show-as-dialog-link" type="button" href="{{ $U('/productbarcodes/new?embedded&product=' . $product->id ) }}">
<i class="fas fa-plus"></i> {{ $__t('Add') }} <i class="fas fa-plus"></i> {{ $__t('Add') }}
</a> </a>
@ -358,8 +358,8 @@
<tr> <tr>
<th class="border-right"></th> <th class="border-right"></th>
<th>{{ $__t('Barcode') }}</th> <th>{{ $__t('Barcode') }}</th>
<th>{{ $__t('QU Factor Purchase To Stock') }}</th> <th>{{ $__t('Factor purchase to stock quantity unit') }}</th>
<th>{{ $__t('Shopping Location') }}</th> <th>{{ $__t('Store') }}</th>
</tr> </tr>
</thead> </thead>
<tbody class="d-none"> <tbody class="d-none">

View File

@ -104,7 +104,7 @@
<tr> <tr>
<th class="border-right"></th> <th class="border-right"></th>
<th>{{ $__t('Product') }}</th> <th>{{ $__t('Product') }}</th>
<th>{{ $__t('Product Group') }}</th> <th>{{ $__t('Product group') }}</th>
<th>{{ $__t('Amount') }}</th> <th>{{ $__t('Amount') }}</th>
<th class="@if(!GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING) d-none @endif">{{ $__t('Next best before date') }}</th> <th class="@if(!GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING) d-none @endif">{{ $__t('Next best before date') }}</th>
<th class="d-none">Hidden location</th> <th class="d-none">Hidden location</th>