diff --git a/.gitignore b/.gitignore
index 3c60286a..3b1a7ff1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -198,6 +198,5 @@ FakesAssemblies/
/bower_components
/vendor
/.release
-/config.php
/composer.phar
/composer.lock
diff --git a/grocy.php b/Grocy.php
similarity index 100%
rename from grocy.php
rename to Grocy.php
diff --git a/GrocyDbMigrator.php b/GrocyDbMigrator.php
index f49645f9..d8e67f65 100644
--- a/GrocyDbMigrator.php
+++ b/GrocyDbMigrator.php
@@ -14,6 +14,8 @@ class GrocyDbMigrator
qu_id_stock INTEGER NOT NULL,
qu_factor_purchase_to_stock REAL NOT NULL,
barcode TEXT,
+ min_stock_amount INTEGER NOT NULL DEFAULT 0,
+ default_best_before_days INTEGER NOT NULL DEFAULT 0,
row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime'))
)"
);
diff --git a/GrocyDemoDataGenerator.php b/GrocyDemoDataGenerator.php
index 1831fd32..246e19d6 100644
--- a/GrocyDemoDataGenerator.php
+++ b/GrocyDemoDataGenerator.php
@@ -6,15 +6,31 @@ class GrocyDemoDataGenerator
{
$sql = "
UPDATE locations SET name = 'Vorratskammer', description = '' WHERE id = 1;
- INSERT INTO locations (name) VALUES ('Süßigkeitenschrank');
- INSERT INTO locations (name) VALUES ('Konvervenschrank');
+ INSERT INTO locations (name) VALUES ('Süßigkeitenschrank'); --2
+ INSERT INTO locations (name) VALUES ('Konservenschrank'); --3
+ INSERT INTO locations (name) VALUES ('Kühlschrank'); --4
UPDATE quantity_units SET name = 'Stück' WHERE id = 1;
- INSERT INTO quantity_units (name) VALUES ('Packung');
+ INSERT INTO quantity_units (name) VALUES ('Packung'); --2
+ INSERT INTO quantity_units (name) VALUES ('Glas'); --3
+ INSERT INTO quantity_units (name) VALUES ('Dose'); --4
+ INSERT INTO quantity_units (name) VALUES ('Becher'); --5
+ INSERT INTO quantity_units (name) VALUES ('Bund'); --6
- INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Gummibärchen', 2, 2, 2, 1);
- INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Chips', 2, 2, 2, 1);
- INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Eier', 1, 2, 1, 10);
+ DELETE FROM products WHERE id IN (1, 2);
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Gummibärchen', 2, 2, 2, 1); --3
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Chips', 2, 2, 2, 1); --4
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Eier', 1, 2, 1, 10); --5
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Nudeln', 1, 2, 2, 1); --6
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Essiggurken', 3, 3, 3, 1); --7
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Gulaschsuppe', 3, 4, 4, 1); --8
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Joghurt', 4, 5, 5, 1); --9
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Käse', 4, 2, 2, 1); --10
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Aufschnitt', 4, 2, 2, 1); --11
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Paprika', 4, 1, 1, 1); --12
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Gurke', 4, 1, 1, 1); --13
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Radieschen', 4, 6, 6, 1); --14
+ INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Tomate', 4, 1, 1, 1); --15
";
if ($pdo->exec(utf8_encode($sql)) === false)
@@ -24,6 +40,16 @@ class GrocyDemoDataGenerator
GrocyLogicStock::AddProduct(3, 5, date('Y-m-d', strtotime('+180 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
GrocyLogicStock::AddProduct(4, 5, date('Y-m-d', strtotime('+180 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
- GrocyLogicStock::AddProduct(5, 5, date('Y-m-d', strtotime('+25 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
+ GrocyLogicStock::AddProduct(5, 5, date('Y-m-d', strtotime('+20 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
+ GrocyLogicStock::AddProduct(6, 5, date('Y-m-d', strtotime('+600 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
+ GrocyLogicStock::AddProduct(7, 5, date('Y-m-d', strtotime('+800 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
+ GrocyLogicStock::AddProduct(8, 5, date('Y-m-d', strtotime('+900 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
+ GrocyLogicStock::AddProduct(9, 5, date('Y-m-d', strtotime('+14 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
+ GrocyLogicStock::AddProduct(10, 5, date('Y-m-d', strtotime('+21 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
+ GrocyLogicStock::AddProduct(11, 5, date('Y-m-d', strtotime('+10 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
+ GrocyLogicStock::AddProduct(12, 5, date('Y-m-d', strtotime('+2 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
+ GrocyLogicStock::AddProduct(13, 5, date('Y-m-d', strtotime('-2 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
+ GrocyLogicStock::AddProduct(14, 5, date('Y-m-d', strtotime('+2 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
+ GrocyLogicStock::AddProduct(15, 5, date('Y-m-d', strtotime('-2 days')), GrocyLogicStock::TRANSACTION_TYPE_PURCHASE);
}
}
diff --git a/GrocyLogicStock.php b/GrocyLogicStock.php
index 69179ed5..c4fb8fe1 100644
--- a/GrocyLogicStock.php
+++ b/GrocyLogicStock.php
@@ -35,88 +35,121 @@ class GrocyLogicStock
public static function AddProduct(int $productId, int $amount, string $bestBeforeDate, $transactionType)
{
- $db = Grocy::GetDbConnection();
- $stockId = uniqid();
+ if ($transactionType === self::TRANSACTION_TYPE_CONSUME || $transactionType === self::TRANSACTION_TYPE_PURCHASE || $transactionType === self::TRANSACTION_TYPE_INVENTORY_CORRECTION)
+ {
+ $db = Grocy::GetDbConnection();
+ $stockId = uniqid();
- $logRow = $db->stock_log()->createRow(array(
- 'product_id' => $productId,
- 'amount' => $amount,
- 'best_before_date' => $bestBeforeDate,
- 'purchased_date' => date('Y-m-d'),
- 'stock_id' => $stockId,
- 'transaction_type' => $transactionType
- ));
- $logRow->save();
+ $logRow = $db->stock_log()->createRow(array(
+ 'product_id' => $productId,
+ 'amount' => $amount,
+ 'best_before_date' => $bestBeforeDate,
+ 'purchased_date' => date('Y-m-d'),
+ 'stock_id' => $stockId,
+ 'transaction_type' => $transactionType
+ ));
+ $logRow->save();
- $stockRow = $db->stock()->createRow(array(
- 'product_id' => $productId,
- 'amount' => $amount,
- 'best_before_date' => $bestBeforeDate,
- 'purchased_date' => date('Y-m-d'),
- 'stock_id' => $stockId,
- ));
- $stockRow->save();
+ $stockRow = $db->stock()->createRow(array(
+ 'product_id' => $productId,
+ 'amount' => $amount,
+ 'best_before_date' => $bestBeforeDate,
+ 'purchased_date' => date('Y-m-d'),
+ 'stock_id' => $stockId,
+ ));
+ $stockRow->save();
- return true;
+ return true;
+ }
+ else
+ {
+ throw new Exception("Transaction type $transactionType is not valid (GrocyLogicStock.AddProduct)");
+ }
}
public static function ConsumeProduct(int $productId, int $amount, bool $spoiled, $transactionType)
{
- $db = Grocy::GetDbConnection();
-
- $productStockAmount = $db->stock()->where('product_id', $productId)->sum('amount');
- $potentialStockEntries = $db->stock()->where('product_id', $productId)->orderBy('purchased_date', 'ASC')->fetchAll(); //FIFO
-
- if ($amount > $productStockAmount)
+ if ($transactionType === self::TRANSACTION_TYPE_CONSUME || $transactionType === self::TRANSACTION_TYPE_PURCHASE || $transactionType === self::TRANSACTION_TYPE_INVENTORY_CORRECTION)
{
- return false;
+ $db = Grocy::GetDbConnection();
+
+ $productStockAmount = $db->stock()->where('product_id', $productId)->sum('amount');
+ $potentialStockEntries = $db->stock()->where('product_id', $productId)->orderBy('purchased_date', 'ASC')->fetchAll(); //FIFO
+
+ if ($amount > $productStockAmount)
+ {
+ return false;
+ }
+
+ foreach ($potentialStockEntries as $stockEntry)
+ {
+ if ($amount == 0)
+ {
+ break;
+ }
+
+ if ($amount >= $stockEntry->amount) //Take the whole stock entry
+ {
+ $logRow = $db->stock_log()->createRow(array(
+ 'product_id' => $stockEntry->product_id,
+ 'amount' => $stockEntry->amount * -1,
+ 'best_before_date' => $stockEntry->best_before_date,
+ 'purchased_date' => $stockEntry->purchased_date,
+ 'used_date' => date('Y-m-d'),
+ 'spoiled' => $spoiled,
+ 'stock_id' => $stockEntry->stock_id,
+ 'transaction_type' => $transactionType
+ ));
+ $logRow->save();
+
+ $amount -= $stockEntry->amount;
+ $stockEntry->delete();
+ }
+ else //Stock entry amount is > than needed amount -> split the stock entry resp. update the amount
+ {
+ $logRow = $db->stock_log()->createRow(array(
+ 'product_id' => $stockEntry->product_id,
+ 'amount' => $amount * -1,
+ 'best_before_date' => $stockEntry->best_before_date,
+ 'purchased_date' => $stockEntry->purchased_date,
+ 'used_date' => date('Y-m-d'),
+ 'spoiled' => $spoiled,
+ 'stock_id' => $stockEntry->stock_id,
+ 'transaction_type' => $transactionType
+ ));
+ $logRow->save();
+
+ $restStockAmount = $stockEntry->amount - $amount;
+ $amount = 0;
+
+ $stockEntry->update(array(
+ 'amount' => $restStockAmount
+ ));
+ }
+ }
+
+ return true;
}
-
- foreach ($potentialStockEntries as $stockEntry)
+ else
{
- if ($amount == 0)
- {
- break;
- }
+ throw new Exception("Transaction type $transactionType is not valid (GrocyLogicStock.ConsumeProduct)");
+ }
+ }
- if ($amount >= $stockEntry->amount) //Take the whole stock entry
- {
- $logRow = $db->stock_log()->createRow(array(
- 'product_id' => $stockEntry->product_id,
- 'amount' => $stockEntry->amount * -1,
- 'best_before_date' => $stockEntry->best_before_date,
- 'purchased_date' => $stockEntry->purchased_date,
- 'used_date' => date('Y-m-d'),
- 'spoiled' => $spoiled,
- 'stock_id' => $stockEntry->stock_id,
- 'transaction_type' => $transactionType
- ));
- $logRow->save();
+ public static function InventoryProduct(int $productId, int $newAmount, string $bestBeforeDate)
+ {
+ $db = Grocy::GetDbConnection();
+ $productStockAmount = $db->stock()->where('product_id', $productId)->sum('amount');
- $amount -= $stockEntry->amount;
- $stockEntry->delete();
- }
- else //Stock entry amount is > than needed amount -> split the stock entry resp. update the amount
- {
- $logRow = $db->stock_log()->createRow(array(
- 'product_id' => $stockEntry->product_id,
- 'amount' => $amount * -1,
- 'best_before_date' => $stockEntry->best_before_date,
- 'purchased_date' => $stockEntry->purchased_date,
- 'used_date' => date('Y-m-d H:i:s'),
- 'spoiled' => $spoiled,
- 'stock_id' => $stockEntry->stock_id,
- 'transaction_type' => $transactionType
- ));
- $logRow->save();
-
- $restStockAmount = $stockEntry->amount - $amount;
- $amount = 0;
-
- $stockEntry->update(array(
- 'amount' => $restStockAmount
- ));
- }
+ if ($newAmount > $productStockAmount)
+ {
+ $amountToAdd = $newAmount - $productStockAmount;
+ self::AddProduct($productId, $amountToAdd, $bestBeforeDate, self::TRANSACTION_TYPE_INVENTORY_CORRECTION);
+ }
+ else if ($newAmount < $productStockAmount)
+ {
+ $amountToRemove = $productStockAmount - $newAmount;
+ self::ConsumeProduct($productId, $amountToRemove, false, self::TRANSACTION_TYPE_INVENTORY_CORRECTION);
}
return true;
diff --git a/GrocyPhpHelper.php b/GrocyPhpHelper.php
index 9fb0dda9..bb6b6e45 100644
--- a/GrocyPhpHelper.php
+++ b/GrocyPhpHelper.php
@@ -14,4 +14,36 @@ class GrocyPhpHelper
return null;
}
+
+ public static function FindAllObjectsInArrayByPropertyValue($array, $propertyName, $propertyValue, $operator = '==')
+ {
+ $returnArray = array();
+
+ foreach($array as $object)
+ {
+ switch($operator)
+ {
+ case '==':
+ if($object->{$propertyName} == $propertyValue)
+ {
+ $returnArray[] = $object;
+ }
+ break;
+ case '>':
+ if($object->{$propertyName} > $propertyValue)
+ {
+ $returnArray[] = $object;
+ }
+ break;
+ case '<':
+ if($object->{$propertyName} < $propertyValue)
+ {
+ $returnArray[] = $object;
+ }
+ break;
+ }
+ }
+
+ return $returnArray;
+ }
}
diff --git a/README.md b/README.md
index 66f54e5d..e296212e 100644
--- a/README.md
+++ b/README.md
@@ -11,10 +11,7 @@ For now my main focus is on stock management, ERP your fridge!
Public demo of the latest version → [https://grocy.projectdemos.berrnd.org](https://grocy.projectdemos.berrnd.org)
## How to install
-Just unpack the [latest release](https://github.com/berrnd/grocy/releases/latest) on your PHP enabled webserver, copy `config-dist.php` to `config.php`, edit it to your needs, ensure that the `data` directory is writable and you're ready to go. Alternatively clone this repository and install Composer and Bower dependencies manually.
-
-## Todo
-A lot...
+Just unpack the [latest release](https://github.com/berrnd/grocy/releases/latest) on your PHP enabled webserver, copy `config-dist.php` to `data/config.php`, edit it to your needs, ensure that the `data` directory is writable and you're ready to go. Alternatively clone this repository and install Composer and Bower dependencies manually.
## License
The MIT License (MIT)
diff --git a/build.bat b/build.bat
index 97dc1a10..5835331b 100644
--- a/build.bat
+++ b/build.bat
@@ -8,4 +8,4 @@ for /f "tokens=*" %%a in ('type version.txt') do set version=%%a
del "%releasePath%\grocy_%version%.zip"
"build_tools\7za.exe" a -r "%releasePath%\grocy_%version%.zip" "%projectPath%\*" -xr!.* -xr!build_tools -xr!build.bat -xr!composer.json -xr!composer.lock -xr!composer.phar -xr!grocy.phpproj -xr!grocy.phpproj.user -xr!grocy.sln
-"build_tools\7za.exe" d "%releasePath%\grocy_%version%.zip" data\add_before_end_body.html data\demo.txt data\grocy.db data\.gitignore config.php bower.json
+"build_tools\7za.exe" d "%releasePath%\grocy_%version%.zip" data\add_before_end_body.html data\demo.txt data\config.php data\grocy.db data\.gitignore bower.json
diff --git a/grocy.phpproj b/grocy.phpproj
index 36db974b..89063966 100644
--- a/grocy.phpproj
+++ b/grocy.phpproj
@@ -24,6 +24,7 @@
product_id)->name; ?> | @@ -21,11 +28,13 @@ amount; ?>- best_before_date; ?> + best_before_date; ?> + |
+ Stock amount:
+ Last purchased:
+ Last used:
+