diff --git a/controllers/BaseController.php b/controllers/BaseController.php index e062f793..ec34b7ff 100644 --- a/controllers/BaseController.php +++ b/controllers/BaseController.php @@ -229,7 +229,10 @@ class BaseController } // Allow some special chars - $value = str_replace('&', '&', $value); + if (!is_array($value)) + { + $value = str_replace('&', '&', $value); + } } return $requestBody; diff --git a/migrations/0143.sql b/migrations/0143.sql new file mode 100644 index 00000000..32631f50 --- /dev/null +++ b/migrations/0143.sql @@ -0,0 +1,18 @@ +CREATE VIEW stock_splits +AS + +/* +Helper view which shows splitted stock rows which could be compacted +*/ + +SELECT + product_id, + SUM(amount) AS total_amount, + MIN(stock_id) AS stock_id_to_keep, + MIN(id) AS id_to_keep, + GROUP_CONCAT(id) AS id_group, + GROUP_CONCAT(stock_id) AS stock_id_group, + id -- Dummy +FROM stock +GROUP BY product_id, best_before_date, purchased_date, price, open, opened_date, location_id, shopping_location_id +HAVING COUNT(*) > 1; diff --git a/migrations/0144.php b/migrations/0144.php new file mode 100644 index 00000000..36a0ebb7 --- /dev/null +++ b/migrations/0144.php @@ -0,0 +1,7 @@ +getStockService()->CompactStockEntries(); diff --git a/services/StockService.php b/services/StockService.php index 5e3a7f18..a43dc177 100644 --- a/services/StockService.php +++ b/services/StockService.php @@ -219,6 +219,8 @@ class StockService extends BaseService } } + $this->CompactStockEntries($productId); + return $transactionId; } else @@ -413,6 +415,8 @@ class StockService extends BaseService } } + $this->CompactStockEntries($productId); + return $transactionId; } else @@ -490,6 +494,8 @@ class StockService extends BaseService ]); $logNewRowForStockUpdate->save(); + $this->CompactStockEntries($stockRow->product_id); + return $transactionId; } @@ -1294,7 +1300,7 @@ class StockService extends BaseService return; } - $hasSubsequentBookings = $this->getDatabase()->stock_log()->where('stock_id = :1 AND id != :2 AND (correlation_id is not null OR correlation_id != :3) AND id > :2 AND undone = 0', $logRow->stock_id, $logRow->id, $logRow->correlation_id)->count() > 0; + $hasSubsequentBookings = $this->getDatabase()->stock_log()->where('stock_id = :1 AND id != :2 AND (correlation_id IS NOT NULL OR correlation_id != :3) AND id > :2 AND undone = 0', $logRow->stock_id, $logRow->id, $logRow->correlation_id)->count() > 0; if ($hasSubsequentBookings) { throw new \Exception('Booking has subsequent dependent bookings, undo not possible'); @@ -1514,6 +1520,54 @@ class StockService extends BaseService $this->getDatabaseService()->GetDbConnectionRaw()->commit(); } + public function CompactStockEntries($productId = null) + { + if ($productId == null) + { + $splittedStockEntries = $this->getDatabase()->stock_splits(); + } + else + { + $splittedStockEntries = $this->getDatabase()->stock_splits()->where('product_id = :1', $productId); + } + + foreach ($splittedStockEntries as $splittedStockEntry) + { + $this->getDatabaseService()->GetDbConnectionRaw()->beginTransaction(); + try + { + $stockIds = explode(',', $splittedStockEntry->stock_id_group); + foreach ($stockIds as $stockId) + { + if ($stockId != $splittedStockEntry->stock_id_to_keep) + { + $this->getDatabaseService()->ExecuteDbStatement('UPDATE stock SET stock_id = \'' . $splittedStockEntry->stock_id_to_keep . '\' WHERE stock_id = \'' . $stockId . '\''); + $this->getDatabaseService()->ExecuteDbStatement('UPDATE stock_log SET stock_id = \'' . $splittedStockEntry->stock_id_to_keep . '\' WHERE stock_id = \'' . $stockId . '\''); + } + } + + $stockEntryIds = explode(',', $splittedStockEntry->id_group); + foreach ($stockEntryIds as $stockEntryId) + { + if ($stockEntryId != $splittedStockEntry->id_to_keep) + { + $this->getDatabaseService()->ExecuteDbStatement('DELETE FROM stock WHERE id = ' . $stockEntryId); + } + else + { + $this->getDatabaseService()->ExecuteDbStatement('UPDATE stock SET amount = ' . $splittedStockEntry->total_amount . ' WHERE id = ' . $splittedStockEntry->id_to_keep); + } + } + } + catch (Exception $ex) + { + $this->getDatabaseService()->GetDbConnectionRaw()->rollback(); + throw $ex; + } + $this->getDatabaseService()->GetDbConnectionRaw()->commit(); + } + } + private function LoadBarcodeLookupPlugin() { $pluginName = defined('GROCY_STOCK_BARCODE_LOOKUP_PLUGIN') ? GROCY_STOCK_BARCODE_LOOKUP_PLUGIN : '';