diff --git a/GrocyDbMigrator.php b/GrocyDbMigrator.php index e0293963..f49645f9 100644 --- a/GrocyDbMigrator.php +++ b/GrocyDbMigrator.php @@ -13,8 +13,8 @@ class GrocyDbMigrator qu_id_purchase INTEGER NOT NULL, qu_id_stock INTEGER NOT NULL, qu_factor_purchase_to_stock REAL NOT NULL, - barcode TEXT UNIQUE, - created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) + barcode TEXT, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) )" ); @@ -23,7 +23,7 @@ class GrocyDbMigrator id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, name TEXT NOT NULL UNIQUE, description TEXT, - created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) )" ); @@ -32,7 +32,7 @@ class GrocyDbMigrator id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, name TEXT NOT NULL UNIQUE, description TEXT, - created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) )" ); @@ -43,20 +43,23 @@ class GrocyDbMigrator amount INTEGER NOT NULL, best_before_date DATE, purchased_date DATE DEFAULT (datetime('now', 'localtime')), - stock_id TEXT NOT NULL + stock_id TEXT NOT NULL, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) )" ); self::ExecuteMigrationWhenNeeded($pdo, 5, " - CREATE TABLE consumptions ( + CREATE TABLE stock_log ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, product_id INTEGER NOT NULL, amount INTEGER NOT NULL, best_before_date DATE, purchased_date DATE, - used_date DATE DEFAULT (datetime('now', 'localtime')), + used_date DATE, spoiled INTEGER NOT NULL DEFAULT 0, - stock_id TEXT NOT NULL + stock_id TEXT NOT NULL, + transaction_type TEXT NOT NULL, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) )" ); diff --git a/GrocyDemoDataGenerator.php b/GrocyDemoDataGenerator.php index c6b801c0..1831fd32 100644 --- a/GrocyDemoDataGenerator.php +++ b/GrocyDemoDataGenerator.php @@ -15,15 +15,15 @@ class GrocyDemoDataGenerator 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); - - INSERT INTO stock (product_id, amount, best_before_date, stock_id) VALUES (3, 5, date('now', '+180 day'), '".uniqid()."'); - INSERT INTO stock (product_id, amount, best_before_date, stock_id) VALUES (4, 5, date('now', '+180 day'), '".uniqid()."'); - INSERT INTO stock (product_id, amount, best_before_date, stock_id) VALUES (5, 5, date('now', '+25 day'), '".uniqid()."'); "; if ($pdo->exec(utf8_encode($sql)) === false) { throw new Exception($pdo->errorInfo()); } + + 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); } } diff --git a/GrocyLogicStock.php b/GrocyLogicStock.php index 97f38650..69179ed5 100644 --- a/GrocyLogicStock.php +++ b/GrocyLogicStock.php @@ -2,6 +2,10 @@ class GrocyLogicStock { + const TRANSACTION_TYPE_PURCHASE = 'purchase'; + const TRANSACTION_TYPE_CONSUME = 'consume'; + const TRANSACTION_TYPE_INVENTORY_CORRECTION = 'inventory-correction'; + public static function GetCurrentStock() { $db = Grocy::GetDbConnectionRaw(); @@ -15,7 +19,7 @@ class GrocyLogicStock $product = $db->products($productId); $productStockAmount = $db->stock()->where('product_id', $productId)->sum('amount'); $productLastPurchased = $db->stock()->where('product_id', $productId)->max('purchased_date'); - $productLastUsed = $db->consumptions()->where('product_id', $productId)->max('used_date'); + $productLastUsed = $db->stock_log()->where('product_id', $productId)->where('transaction_type', self::TRANSACTION_TYPE_CONSUME)->max('used_date'); $quPurchase = $db->quantity_units($product->qu_id_purchase); $quStock = $db->quantity_units($product->qu_id_stock); @@ -29,7 +33,34 @@ class GrocyLogicStock ); } - public static function ConsumeProduct(int $productId, int $amount, bool $spoiled) + public static function AddProduct(int $productId, int $amount, string $bestBeforeDate, $transactionType) + { + $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(); + + $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; + } + + public static function ConsumeProduct(int $productId, int $amount, bool $spoiled, $transactionType) { $db = Grocy::GetDbConnection(); @@ -50,30 +81,34 @@ class GrocyLogicStock if ($amount >= $stockEntry->amount) //Take the whole stock entry { - $consumptionRow = $db->consumptions()->createRow(array( + $logRow = $db->stock_log()->createRow(array( 'product_id' => $stockEntry->product_id, - 'amount' => $stockEntry->amount, + '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 + 'stock_id' => $stockEntry->stock_id, + 'transaction_type' => $transactionType )); - $consumptionRow->save(); + $logRow->save(); $amount -= $stockEntry->amount; $stockEntry->delete(); } else //Stock entry amount is > than needed amount -> split the stock entry resp. update the amount { - $consumptionRow = $db->consumptions()->createRow(array( + $logRow = $db->stock_log()->createRow(array( 'product_id' => $stockEntry->product_id, - 'amount' => $amount, + '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 + 'stock_id' => $stockEntry->stock_id, + 'transaction_type' => $transactionType )); - $consumptionRow->save(); + $logRow->save(); $restStockAmount = $stockEntry->amount - $amount; $amount = 0; diff --git a/index.php b/index.php index 6ec0dedd..d6e24fe8 100644 --- a/index.php +++ b/index.php @@ -32,10 +32,10 @@ if (!Grocy::IsDemoInstallation()) ])); } -$app->get('/', function(Request $request, Response $response) -{ - $db = Grocy::GetDbConnection(); +$db = Grocy::GetDbConnection(); +$app->get('/', function(Request $request, Response $response) use($db) +{ return $this->renderer->render($response, '/layout.php', [ 'title' => 'Dashboard', 'contentPage' => 'dashboard.php', @@ -44,10 +44,8 @@ $app->get('/', function(Request $request, Response $response) ]); }); -$app->get('/purchase', function(Request $request, Response $response) +$app->get('/purchase', function(Request $request, Response $response) use($db) { - $db = Grocy::GetDbConnection(); - return $this->renderer->render($response, '/layout.php', [ 'title' => 'Purchase', 'contentPage' => 'purchase.php', @@ -55,10 +53,8 @@ $app->get('/purchase', function(Request $request, Response $response) ]); }); -$app->get('/consumption', function(Request $request, Response $response) +$app->get('/consumption', function(Request $request, Response $response) use($db) { - $db = Grocy::GetDbConnection(); - return $this->renderer->render($response, '/layout.php', [ 'title' => 'Consumption', 'contentPage' => 'consumption.php', @@ -66,10 +62,8 @@ $app->get('/consumption', function(Request $request, Response $response) ]); }); -$app->get('/products', function(Request $request, Response $response) +$app->get('/products', function(Request $request, Response $response) use($db) { - $db = Grocy::GetDbConnection(); - return $this->renderer->render($response, '/layout.php', [ 'title' => 'Products', 'contentPage' => 'products.php', @@ -79,10 +73,8 @@ $app->get('/products', function(Request $request, Response $response) ]); }); -$app->get('/locations', function(Request $request, Response $response) +$app->get('/locations', function(Request $request, Response $response) use($db) { - $db = Grocy::GetDbConnection(); - return $this->renderer->render($response, '/layout.php', [ 'title' => 'Locations', 'contentPage' => 'locations.php', @@ -90,10 +82,8 @@ $app->get('/locations', function(Request $request, Response $response) ]); }); -$app->get('/quantityunits', function(Request $request, Response $response) +$app->get('/quantityunits', function(Request $request, Response $response) use($db) { - $db = Grocy::GetDbConnection(); - return $this->renderer->render($response, '/layout.php', [ 'title' => 'Quantity units', 'contentPage' => 'quantityunits.php', @@ -101,10 +91,8 @@ $app->get('/quantityunits', function(Request $request, Response $response) ]); }); -$app->get('/product/{productId}', function(Request $request, Response $response, $args) +$app->get('/product/{productId}', function(Request $request, Response $response, $args) use($db) { - $db = Grocy::GetDbConnection(); - if ($args['productId'] == 'new') { return $this->renderer->render($response, '/layout.php', [ @@ -128,10 +116,8 @@ $app->get('/product/{productId}', function(Request $request, Response $response, } }); -$app->get('/location/{locationId}', function(Request $request, Response $response, $args) +$app->get('/location/{locationId}', function(Request $request, Response $response, $args) use($db) { - $db = Grocy::GetDbConnection(); - if ($args['locationId'] == 'new') { return $this->renderer->render($response, '/layout.php', [ @@ -151,10 +137,8 @@ $app->get('/location/{locationId}', function(Request $request, Response $respons } }); -$app->get('/quantityunit/{quantityunitId}', function(Request $request, Response $response, $args) +$app->get('/quantityunit/{quantityunitId}', function(Request $request, Response $response, $args) use($db) { - $db = Grocy::GetDbConnection(); - if ($args['quantityunitId'] == 'new') { return $this->renderer->render($response, '/layout.php', [ @@ -174,67 +158,57 @@ $app->get('/quantityunit/{quantityunitId}', function(Request $request, Response } }); -$app->group('/api', function() +$app->group('/api', function() use($db, $app) { - $this->get('/get-objects/{entity}', function(Request $request, Response $response, $args) + $this->get('/get-objects/{entity}', function(Request $request, Response $response, $args) use($db) { - $db = Grocy::GetDbConnection(); echo json_encode($db->{$args['entity']}()); - - return $response->withHeader('Content-Type', 'application/json'); }); - $this->get('/get-object/{entity}/{objectId}', function(Request $request, Response $response, $args) + $this->get('/get-object/{entity}/{objectId}', function(Request $request, Response $response, $args) use($db) { - $db = Grocy::GetDbConnection(); echo json_encode($db->{$args['entity']}($args['objectId'])); - - return $response->withHeader('Content-Type', 'application/json'); }); - $this->post('/add-object/{entity}', function(Request $request, Response $response, $args) + $this->post('/add-object/{entity}', function(Request $request, Response $response, $args) use($db) { - $db = Grocy::GetDbConnection(); $newRow = $db->{$args['entity']}()->createRow($request->getParsedBody()); $newRow->save(); $success = $newRow->isClean(); echo json_encode(array('success' => $success)); - - return $response->withHeader('Content-Type', 'application/json'); }); - $this->post('/edit-object/{entity}/{objectId}', function(Request $request, Response $response, $args) + $this->post('/edit-object/{entity}/{objectId}', function(Request $request, Response $response, $args) use($db) { - $db = Grocy::GetDbConnection(); $row = $db->{$args['entity']}($args['objectId']); $row->update($request->getParsedBody()); $success = $row->isClean(); echo json_encode(array('success' => $success)); - - return $response->withHeader('Content-Type', 'application/json'); }); - $this->get('/delete-object/{entity}/{objectId}', function(Request $request, Response $response, $args) + $this->get('/delete-object/{entity}/{objectId}', function(Request $request, Response $response, $args) use($db) { - $db = Grocy::GetDbConnection(); $row = $db->{$args['entity']}($args['objectId']); $row->delete(); $success = $row->isClean(); echo json_encode(array('success' => $success)); - - return $response->withHeader('Content-Type', 'application/json'); }); - $this->get('/stock/get-product-details/{productId}', function(Request $request, Response $response, $args) + $this->get('/stock/add-product/{productId}/{amount}', function(Request $request, Response $response, $args) { - echo json_encode(GrocyLogicStock::GetProductDetails($args['productId'])); - return $response->withHeader('Content-Type', 'application/json'); - }); + $bestBeforeDate = date('Y-m-d'); + if (isset($request->getQueryParams()['bestbeforedate']) && !empty($request->getQueryParams()['bestbeforedate'])) + { + $bestBeforeDate = $request->getQueryParams()['bestbeforedate']; + } - $this->get('/stock/get-current-stock', function(Request $request, Response $response) - { - echo json_encode(GrocyLogicStock::GetCurrentStock()); - return $response->withHeader('Content-Type', 'application/json'); + $transactionType = GrocyLogicStock::TRANSACTION_TYPE_PURCHASE; + if (isset($request->getQueryParams()['transactiontype']) && !empty($request->getQueryParams()['transactiontype'])) + { + $transactionType = $request->getQueryParams()['transactiontype']; + } + + echo json_encode(array('success' => GrocyLogicStock::AddProduct($args['productId'], $args['amount'], $bestBeforeDate, $transactionType))); }); $this->get('/stock/consume-product/{productId}/{amount}', function(Request $request, Response $response, $args) @@ -245,15 +219,28 @@ $app->group('/api', function() $spoiled = true; } - echo json_encode(array('success' => GrocyLogicStock::ConsumeProduct($args['productId'], $args['amount'], $spoiled))); - return $response->withHeader('Content-Type', 'application/json'); + $transactionType = GrocyLogicStock::TRANSACTION_TYPE_CONSUME; + if (isset($request->getQueryParams()['transactiontype']) && !empty($request->getQueryParams()['transactiontype'])) + { + $transactionType = $request->getQueryParams()['transactiontype']; + } + + echo json_encode(array('success' => GrocyLogicStock::ConsumeProduct($args['productId'], $args['amount'], $spoiled, $transactionType))); }); - $this->get('/helper/uniqid', function(Request $request, Response $response) + $this->get('/stock/get-product-details/{productId}', function(Request $request, Response $response, $args) { - echo json_encode(array('uniqid' => uniqid())); - return $response->withHeader('Content-Type', 'application/json'); + echo json_encode(GrocyLogicStock::GetProductDetails($args['productId'])); }); + + $this->get('/stock/get-current-stock', function(Request $request, Response $response) + { + echo json_encode(GrocyLogicStock::GetCurrentStock()); + }); +})->add(function($request, $response, $next) +{ + $response = $next($request, $response); + return $response->withHeader('Content-Type', 'application/json'); }); $app->run(); diff --git a/views/consumption.php b/views/consumption.php index bb5bfb4b..bb46fe93 100644 --- a/views/consumption.php +++ b/views/consumption.php @@ -2,6 +2,7 @@