diff --git a/GrocyDbMigrator.php b/GrocyDbMigrator.php index a62e4823..35e23ee1 100644 --- a/GrocyDbMigrator.php +++ b/GrocyDbMigrator.php @@ -131,6 +131,35 @@ class GrocyDbMigrator GROUP BY habit_id ORDER BY MAX(tracked_time) DESC;" ); + + self::ExecuteMigrationWhenNeeded($pdo, 13, " + CREATE TABLE batteries ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + name TEXT NOT NULL UNIQUE, + description TEXT, + used_in TEXT, + charge_interval_days INTEGER NOT NULL DEFAULT 0, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) + )" + ); + + self::ExecuteMigrationWhenNeeded($pdo, 14, " + CREATE TABLE battery_charge_cycles ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + battery_id TEXT NOT NULL, + tracked_time DATETIME, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) + )" + ); + + self::ExecuteMigrationWhenNeeded($pdo, 15, " + CREATE VIEW batteries_current + AS + SELECT battery_id, MAX(tracked_time) AS last_tracked_time + FROM battery_charge_cycles + GROUP BY battery_id + ORDER BY MAX(tracked_time) DESC;" + ); } private static function ExecuteMigrationWhenNeeded(PDO $pdo, int $migrationId, string $sql) diff --git a/GrocyDemoDataGenerator.php b/GrocyDemoDataGenerator.php index b015bfc2..95cee54c 100644 --- a/GrocyDemoDataGenerator.php +++ b/GrocyDemoDataGenerator.php @@ -9,11 +9,11 @@ class GrocyDemoDataGenerator { $sql = " UPDATE locations SET name = 'Vorratskammer', description = '' WHERE id = 1; - INSERT INTO locations (name) VALUES ('Süßigkeitenschrank'); --2 + INSERT INTO locations (name) VALUES ('S��igkeitenschrank'); --2 INSERT INTO locations (name) VALUES ('Konservenschrank'); --3 - INSERT INTO locations (name) VALUES ('Kühlschrank'); --4 + INSERT INTO locations (name) VALUES ('K�hlschrank'); --4 - UPDATE quantity_units SET name = 'Stück' WHERE id = 1; + UPDATE quantity_units SET name = 'St�ck' WHERE id = 1; INSERT INTO quantity_units (name) VALUES ('Packung'); --2 INSERT INTO quantity_units (name) VALUES ('Glas'); --3 INSERT INTO quantity_units (name) VALUES ('Dose'); --4 @@ -21,14 +21,14 @@ class GrocyDemoDataGenerator INSERT INTO quantity_units (name) VALUES ('Bund'); --6 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, min_stock_amount) VALUES ('Gummibärchen', 2, 2, 2, 1, 8); --3 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, min_stock_amount) VALUES ('Gummib�rchen', 2, 2, 2, 1, 8); --3 INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, min_stock_amount) VALUES ('Chips', 2, 2, 2, 1, 10); --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 ('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 @@ -38,6 +38,10 @@ class GrocyDemoDataGenerator INSERT INTO habits (name, period_type, period_days) VALUES ('Changed towels in the bathroom', 'manually', 5); --1 INSERT INTO habits (name, period_type, period_days) VALUES ('Cleaned the kitchen floor', 'dynamic-regular', 7); --2 + INSERT INTO batteries (name, description, used_in) VALUES ('Battery1', 'Warranty ends 2022', 'TV remote control'); --1 + INSERT INTO batteries (name, description, used_in) VALUES ('Battery2', 'Warranty ends 2022', 'Alarm clock'); --2 + INSERT INTO batteries (name, description, used_in, charge_interval_days) VALUES ('Battery3', 'Warranty ends 2022', 'Heat remote control', 60); --3 + INSERT INTO migrations (migration) VALUES (-1); "; @@ -63,6 +67,16 @@ class GrocyDemoDataGenerator GrocyLogicHabits::TrackHabit(1, date('Y-m-d H:i:s', strtotime('-15 days'))); GrocyLogicHabits::TrackHabit(2, date('Y-m-d H:i:s', strtotime('-10 days'))); GrocyLogicHabits::TrackHabit(2, date('Y-m-d H:i:s', strtotime('-20 days'))); + + GrocyLogicBatteries::TrackChargeCycle(1, date('Y-m-d H:i:s', strtotime('-200 days'))); + GrocyLogicBatteries::TrackChargeCycle(1, date('Y-m-d H:i:s', strtotime('-150 days'))); + GrocyLogicBatteries::TrackChargeCycle(1, date('Y-m-d H:i:s', strtotime('-100 days'))); + GrocyLogicBatteries::TrackChargeCycle(1, date('Y-m-d H:i:s', strtotime('-50 days'))); + GrocyLogicBatteries::TrackChargeCycle(2, date('Y-m-d H:i:s', strtotime('-200 days'))); + GrocyLogicBatteries::TrackChargeCycle(2, date('Y-m-d H:i:s', strtotime('-150 days'))); + GrocyLogicBatteries::TrackChargeCycle(2, date('Y-m-d H:i:s', strtotime('-100 days'))); + GrocyLogicBatteries::TrackChargeCycle(2, date('Y-m-d H:i:s', strtotime('-50 days'))); + GrocyLogicBatteries::TrackChargeCycle(3, date('Y-m-d H:i:s', strtotime('-65 days'))); } } diff --git a/GrocyLogicBatteries.php b/GrocyLogicBatteries.php new file mode 100644 index 00000000..08a9a677 --- /dev/null +++ b/GrocyLogicBatteries.php @@ -0,0 +1,57 @@ +fetchAll(PDO::FETCH_OBJ); + } + + public static function GetNextChargeTime(int $batteryId) + { + $db = Grocy::GetDbConnection(); + + $battery = $db->batteries($batteryId); + $batteryLastLogRow = Grocy::ExecuteDbQuery(Grocy::GetDbConnectionRaw(), "SELECT * from batteries_current WHERE battery_id = $batteryId LIMIT 1")->fetch(PDO::FETCH_OBJ); + + if ($battery->charge_interval_days > 0) + { + return date('Y-m-d H:i:s', strtotime('+' . $battery->charge_interval_days . ' day', strtotime($batteryLastLogRow->last_tracked_time))); + } + else + { + return date('Y-m-d H:i:s'); + } + + return null; + } + + public static function GetBatteryDetails(int $batteryId) + { + $db = Grocy::GetDbConnection(); + + $battery = $db->batteries($batteryId); + $batteryChargeCylcesCount = $db->battery_charge_cycles()->where('battery_id', $batteryId)->count(); + $batteryLastChargedTime = $db->battery_charge_cycles()->where('battery_id', $batteryId)->max('tracked_time'); + + return array( + 'battery' => $battery, + 'last_charged' => $batteryLastChargedTime, + 'charge_cycles_count' => $batteryChargeCylcesCount + ); + } + + public static function TrackChargeCycle(int $batteryId, string $trackedTime) + { + $db = Grocy::GetDbConnection(); + + $logRow = $db->battery_charge_cycles()->createRow(array( + 'battery_id' => $batteryId, + 'tracked_time' => $trackedTime + )); + $logRow->save(); + + return true; + } +} diff --git a/index.php b/index.php index 636c7d13..89fbd2b8 100644 --- a/index.php +++ b/index.php @@ -11,6 +11,7 @@ require_once __DIR__ . '/GrocyDbMigrator.php'; require_once __DIR__ . '/GrocyDemoDataGenerator.php'; require_once __DIR__ . '/GrocyLogicStock.php'; require_once __DIR__ . '/GrocyLogicHabits.php'; +require_once __DIR__ . '/GrocyLogicBatteries.php'; require_once __DIR__ . '/GrocyPhpHelper.php'; $app = new \Slim\App; @@ -122,6 +123,16 @@ $app->get('/habitsoverview', function(Request $request, Response $response) use( ]); }); +$app->get('/batteriesoverview', function(Request $request, Response $response) use($db) +{ + return $this->renderer->render($response, '/layout.php', [ + 'title' => 'Batteries overview', + 'contentPage' => 'batteriesoverview.php', + 'batteries' => $db->batteries(), + 'current' => GrocyLogicBatteries::GetCurrent(), + ]); +}); + $app->get('/purchase', function(Request $request, Response $response) use($db) { return $this->renderer->render($response, '/layout.php', [ @@ -170,6 +181,15 @@ $app->get('/habittracking', function(Request $request, Response $response) use($ ]); }); +$app->get('/batterytracking', function(Request $request, Response $response) use($db) +{ + return $this->renderer->render($response, '/layout.php', [ + 'title' => 'Battery tracking', + 'contentPage' => 'batterytracking.php', + 'batteries' => $db->batteries() + ]); +}); + $app->get('/products', function(Request $request, Response $response) use($db) { return $this->renderer->render($response, '/layout.php', [ @@ -208,6 +228,15 @@ $app->get('/habits', function(Request $request, Response $response) use($db) ]); }); +$app->get('/batteries', function(Request $request, Response $response) use($db) +{ + return $this->renderer->render($response, '/layout.php', [ + 'title' => 'Batteries', + 'contentPage' => 'batteries.php', + 'batteries' => $db->batteries() + ]); +}); + $app->get('/product/{productId}', function(Request $request, Response $response, $args) use($db) { @@ -299,6 +328,27 @@ $app->get('/habit/{habitId}', function(Request $request, Response $response, $ar } }); +$app->get('/battery/{batteryId}', function(Request $request, Response $response, $args) use($db) +{ + if ($args['batteryId'] == 'new') + { + return $this->renderer->render($response, '/layout.php', [ + 'title' => 'Create battery', + 'contentPage' => 'batteryform.php', + 'mode' => 'create' + ]); + } + else + { + return $this->renderer->render($response, '/layout.php', [ + 'title' => 'Edit battery', + 'contentPage' => 'batteryform.php', + 'battery' => $db->batteries($args['batteryId']), + 'mode' => 'edit' + ]); + } +}); + $app->get('/shoppinglistitem/{itemId}', function(Request $request, Response $response, $args) use($db) { if ($args['itemId'] == 'new') @@ -434,6 +484,22 @@ $app->group('/api', function() use($db) { echo json_encode(GrocyLogicHabits::GetHabitDetails($args['habitId'])); }); + + $this->get('/batteries/track-charge-cycle/{batteryId}', function(Request $request, Response $response, $args) + { + $trackedTime = date('Y-m-d H:i:s'); + if (isset($request->getQueryParams()['tracked_time']) && !empty($request->getQueryParams()['tracked_time'])) + { + $trackedTime = $request->getQueryParams()['tracked_time']; + } + + echo json_encode(array('success' => GrocyLogicBatteries::TrackChargeCycle($args['batteryId'], $trackedTime))); + }); + + $this->get('/batteries/get-battery-details/{batteryId}', function(Request $request, Response $response, $args) + { + echo json_encode(GrocyLogicBatteries::GetBatteryDetails($args['batteryId'])); + }); })->add(function($request, $response, $next) { $response = $next($request, $response); diff --git a/views/batteries.js b/views/batteries.js new file mode 100644 index 00000000..2350f98a --- /dev/null +++ b/views/batteries.js @@ -0,0 +1,43 @@ +$(document).on('click', '.battery-delete-button', function(e) +{ + bootbox.confirm({ + message: 'Delete battery ' + $(e.target).attr('data-battery-name') + '?', + buttons: { + confirm: { + label: 'Yes', + className: 'btn-success' + }, + cancel: { + label: 'No', + className: 'btn-danger' + } + }, + callback: function(result) + { + if (result === true) + { + Grocy.FetchJson('/api/delete-object/batteries/' + $(e.target).attr('data-battery-id'), + function(result) + { + window.location.href = '/batteries'; + }, + function(xhr) + { + console.error(xhr); + } + ); + } + } + }); +}); + +$(function() +{ + $('#batteries-table').DataTable({ + 'pageLength': 50, + 'order': [[1, 'asc']], + 'columnDefs': [ + { 'orderable': false, 'targets': 0 } + ] + }); +}); diff --git a/views/batteries.php b/views/batteries.php new file mode 100644 index 00000000..b46f3600 --- /dev/null +++ b/views/batteries.php @@ -0,0 +1,46 @@ +
Battery | +Last charged | +Next planned charge cycle | +
---|---|---|
+ battery_id)->name; ?> + | ++ last_tracked_time; ?> + + | ++ battery_id)->charge_interval_days > 0): ?> + battery_id); ?> + + + Whenever you want... + + | +
+ Charge cycles count:
+ Last charged:
+