mirror of
https://github.com/grocy/grocy.git
synced 2026-04-07 05:16:15 +02:00
Review
This commit is contained in:
parent
56ab8add27
commit
8d361992d8
|
|
@ -1810,3 +1810,33 @@ msgstr ""
|
|||
|
||||
msgid "Save & return to recipes"
|
||||
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 ""
|
||||
|
|
|
|||
|
|
@ -5,44 +5,53 @@ ALTER TABLE stock
|
|||
ADD qu_factor_purchase_to_stock REAL NOT NULL DEFAULT 1.0;
|
||||
|
||||
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
|
||||
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
|
||||
update stock
|
||||
SET price = ROUND(price / qu_factor_purchase_to_stock,2);
|
||||
UPDATE stock
|
||||
SET price = ROUND(price / qu_factor_purchase_to_stock, 2);
|
||||
|
||||
update stock_log
|
||||
SET price = ROUND(price / qu_factor_purchase_to_stock,2);
|
||||
UPDATE stock_log
|
||||
SET price = ROUND(price / qu_factor_purchase_to_stock, 2);
|
||||
|
||||
CREATE TABLE product_barcodes (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||
product_id INT NOT NULL,
|
||||
barcode TEXT NOT NULL UNIQUE,
|
||||
qu_factor_purchase_to_stock REAL NOT NULL DEFAULT 1,
|
||||
shopping_location_id INTEGER
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||
product_id INT NOT NULL,
|
||||
barcode TEXT NOT NULL UNIQUE,
|
||||
qu_factor_purchase_to_stock REAL NOT NULL DEFAULT 1,
|
||||
shopping_location_id INTEGER,
|
||||
row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime'))
|
||||
);
|
||||
|
||||
--Convert product table to new barcode table
|
||||
INSERT INTO product_barcodes (product_id, barcode, qu_factor_purchase_to_stock, shopping_location_id)
|
||||
WITH split(id, barcode, str, qu_factor_purchase_to_stock, shopping_location_id) AS (
|
||||
select id as product_id, '', barcode||',' ,qu_factor_purchase_to_stock, shopping_location_id from products
|
||||
UNION ALL SELECT
|
||||
id as product_id,
|
||||
substr(str, 0, instr(str, ',')),
|
||||
substr(str, instr(str, ',')+1),
|
||||
qu_factor_purchase_to_stock,
|
||||
shopping_location_id
|
||||
FROM split WHERE str!=''
|
||||
) SELECT id as product_id, barcode, qu_factor_purchase_to_stock, shopping_location_id FROM split WHERE barcode!='';
|
||||
-- Convert product table to new product_barcodes table
|
||||
INSERT INTO product_barcodes
|
||||
(product_id, barcode, qu_factor_purchase_to_stock, shopping_location_id)
|
||||
WITH barcodes_splitted(id, barcode, str, qu_factor_purchase_to_stock, shopping_location_id) AS (
|
||||
SELECT id as product_id, '', barcode || ',', qu_factor_purchase_to_stock, shopping_location_id
|
||||
FROM products
|
||||
|
||||
UNION ALL
|
||||
SELECT
|
||||
id as product_id,
|
||||
SUBSTR(str, 0, instr(str, ',')),
|
||||
SUBSTR(str, instr(str, ',') + 1),
|
||||
qu_factor_purchase_to_stock,
|
||||
shopping_location_id
|
||||
FROM barcodes_splitted
|
||||
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;
|
||||
|
||||
--Remove barcode column
|
||||
--Reorder columns
|
||||
|
||||
-- Remove barcode column
|
||||
-- Reorder columns
|
||||
CREATE TABLE products (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT 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_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,
|
||||
|
|
@ -67,11 +75,13 @@ CREATE TABLE products (
|
|||
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);
|
||||
cumulate_min_stock_amount_of_sub_products TINYINT DEFAULT 0,
|
||||
row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime'))
|
||||
);
|
||||
|
||||
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
|
||||
(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;
|
||||
|
|
@ -84,12 +94,13 @@ SELECT
|
|||
s.product_id,
|
||||
SUM(s.amount) AS amount,
|
||||
ROUND(SUM(s.amount / s.qu_factor_purchase_to_stock),2) as factor_purchase_amount,
|
||||
ROUND(SUM(IFNULL(s.price, 0) * s.amount),2) AS value,
|
||||
ROUND(SUM(IFNULL(s.price, 0) * s.amount), 2) AS value,
|
||||
MIN(s.best_before_date) AS best_before_date,
|
||||
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
|
||||
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;
|
||||
|
||||
DROP VIEW stock_current;
|
||||
|
|
@ -98,9 +109,9 @@ AS
|
|||
SELECT
|
||||
pr.parent_product_id AS product_id,
|
||||
IFNULL((SELECT SUM(amount) FROM stock WHERE product_id = pr.parent_product_id), 0) AS amount,
|
||||
IFNULL(ROUND((SELECT SUM(amount / qu_factor_purchase_to_stock) FROM stock WHERE product_id = pr.parent_product_id),2), 0) as factor_purchase_amount,
|
||||
IFNULL(ROUND((SELECT SUM(amount / qu_factor_purchase_to_stock) FROM stock WHERE product_id = pr.parent_product_id), 2), 0) as factor_purchase_amount,
|
||||
SUM(s.amount) * IFNULL(qucr.factor, 1) AS amount_aggregated,
|
||||
IFNULL(ROUND((SELECT SUM(IFNULL(price,0) * amount) FROM stock WHERE product_id = pr.parent_product_id),2), 0) AS value,
|
||||
IFNULL(ROUND((SELECT SUM(IFNULL(price,0) * amount) FROM stock WHERE product_id = pr.parent_product_id), 2), 0) AS value,
|
||||
MIN(s.best_before_date) AS best_before_date,
|
||||
IFNULL((SELECT SUM(amount) FROM stock WHERE product_id = pr.parent_product_id AND open = 1), 0) AS amount_opened,
|
||||
IFNULL((SELECT SUM(amount) FROM stock WHERE product_id IN (SELECT sub_product_id FROM products_resolved WHERE parent_product_id = pr.parent_product_id) AND open = 1), 0) * IFNULL(qucr.factor, 1) AS amount_opened_aggregated,
|
||||
|
|
@ -109,9 +120,11 @@ FROM products_resolved pr
|
|||
JOIN stock s
|
||||
ON pr.sub_product_id = s.product_id
|
||||
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
|
||||
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
|
||||
ON pr.sub_product_id = qucr.product_id
|
||||
AND p_sub.qu_id_stock = qucr.from_qu_id
|
||||
|
|
@ -125,9 +138,9 @@ UNION
|
|||
SELECT
|
||||
pr.sub_product_id AS product_id,
|
||||
SUM(s.amount) AS amount,
|
||||
ROUND(SUM(s.amount / s.qu_factor_purchase_to_stock),2) as factor_purchase_amount,
|
||||
SUM(s.amount) AS amount_aggregated,
|
||||
ROUND(SUM(IFNULL(s.price, 0) * s.amount),2) AS value,
|
||||
ROUND(SUM(s.amount / s.qu_factor_purchase_to_stock), 2) as factor_purchase_amount,
|
||||
SUM(s.amount) AS amount_aggregated,
|
||||
ROUND(SUM(IFNULL(s.price, 0) * s.amount), 2) AS value,
|
||||
MIN(s.best_before_date) AS best_before_date,
|
||||
IFNULL((SELECT SUM(amount) FROM stock WHERE product_id = s.product_id AND open = 1), 0) AS amount_opened,
|
||||
IFNULL((SELECT SUM(amount) FROM stock WHERE product_id = s.product_id AND open = 1), 0) AS amount_opened_aggregated,
|
||||
|
|
@ -146,7 +159,7 @@ SELECT
|
|||
p.id as sub_product_id
|
||||
FROM products p
|
||||
WHERE p.parent_product_id IS NOT NULL
|
||||
and p.active = 1
|
||||
AND p.active = 1
|
||||
|
||||
UNION
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
CREATE VIEW products_last_purchased AS
|
||||
CREATE VIEW products_last_purchased
|
||||
AS
|
||||
select
|
||||
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
|
||||
from stock_log sw join
|
||||
(select
|
||||
s1.product_id,
|
||||
max(s1.id) max_stock_id
|
||||
from stock_log s1
|
||||
join (
|
||||
select s.product_id,
|
||||
max(s.purchased_date) max_purchased_date
|
||||
from stock_log s
|
||||
where undone = 0
|
||||
and transaction_type in ('purchase', 'stock-edit-new', 'inventory-correction')
|
||||
group by s.product_id) sp2 on s1.product_id = sp2.product_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 sw.product_id = sp3.product_id and sw.id = sp3.max_stock_id;
|
||||
1 AS id, -- Dummy, LessQL needs an id column
|
||||
sl.product_id,
|
||||
sl.amount,
|
||||
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,
|
||||
MAX(s1.id) max_stock_id
|
||||
FROM stock_log s1
|
||||
JOIN (
|
||||
SELECT
|
||||
s.product_id,
|
||||
MAX(s.purchased_date) max_purchased_date
|
||||
FROM stock_log s
|
||||
WHERE undone = 0
|
||||
AND transaction_type in ('purchase', 'stock-edit-new', 'inventory-correction')
|
||||
GROUP BY s.product_id) sp2
|
||||
ON s1.product_id = sp2.product_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
|
||||
select
|
||||
CREATE VIEW products_average_price
|
||||
AS
|
||||
SELECT
|
||||
1 AS id, -- Dummy, LessQL needs an id column
|
||||
s.product_id,
|
||||
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
|
||||
-- find oldest best_before_date then oldest purchased_date then make sure to return one stock row using max
|
||||
select
|
||||
CREATE VIEW products_oldest_stock_unit_price
|
||||
AS
|
||||
-- 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
|
||||
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
|
||||
from stock sw join
|
||||
(select
|
||||
s1.product_id,
|
||||
min(s1.id) min_stock_id
|
||||
from stock s1
|
||||
join (
|
||||
select s.product_id,
|
||||
sp.oldest_date,
|
||||
min(s.purchased_date) min_purchased_date
|
||||
from stock s join
|
||||
(select product_id,
|
||||
min(best_before_date) as oldest_date
|
||||
from stock
|
||||
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;
|
||||
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
|
||||
FROM stock sw
|
||||
JOIN (
|
||||
SELECT
|
||||
s1.product_id,
|
||||
MIN(s1.id) min_stock_id
|
||||
FROM stock s1
|
||||
JOIN (
|
||||
SELECT
|
||||
s.product_id,
|
||||
sp.oldest_date,
|
||||
MIN(s.purchased_date) min_purchased_date
|
||||
FROM stock s
|
||||
JOIN (
|
||||
SELECT
|
||||
product_id,
|
||||
MIN(best_before_date) as oldest_date
|
||||
FROM stock
|
||||
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;
|
||||
CREATE VIEW recipes_pos_resolved
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
var stockOverviewTable = $('#stock-overview-table').DataTable({
|
||||
'order': [[3, 'asc']],
|
||||
'order': [[4, 'asc']],
|
||||
'colReorder': false,
|
||||
'columnDefs': [
|
||||
{ 'orderable': 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");
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
@extends('layout.default')
|
||||
|
||||
@if($mode == 'edit')
|
||||
@section('title', $__t('Edit Barcodes'))
|
||||
@section('title', $__t('Edit Barcode'))
|
||||
@else
|
||||
@section('title', $__t('Create Barcodes'))
|
||||
@section('title', $__t('Create Barcode'))
|
||||
@endif
|
||||
|
||||
@section('viewJsName', 'productbarcodesform')
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
'additionalCssClasses' => 'input-group-qu',
|
||||
))
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_PRICE_TRACKING)
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
|
||||
<div class="form-group">
|
||||
<label for="shopping_location_id_id">{{ $__t('Default store') }}</label>
|
||||
<select class="form-control" id="shopping_location_id" name="shopping_location_id">
|
||||
|
|
|
|||
|
|
@ -347,7 +347,7 @@
|
|||
</table>
|
||||
|
||||
<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 ) }}">
|
||||
<i class="fas fa-plus"></i> {{ $__t('Add') }}
|
||||
</a>
|
||||
|
|
@ -358,8 +358,8 @@
|
|||
<tr>
|
||||
<th class="border-right"></th>
|
||||
<th>{{ $__t('Barcode') }}</th>
|
||||
<th>{{ $__t('QU Factor Purchase To Stock') }}</th>
|
||||
<th>{{ $__t('Shopping Location') }}</th>
|
||||
<th>{{ $__t('Factor purchase to stock quantity unit') }}</th>
|
||||
<th>{{ $__t('Store') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="d-none">
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@
|
|||
<tr>
|
||||
<th class="border-right"></th>
|
||||
<th>{{ $__t('Product') }}</th>
|
||||
<th>{{ $__t('Product Group') }}</th>
|
||||
<th>{{ $__t('Product group') }}</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="d-none">Hidden location</th>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user