diff --git a/config-dist.php b/config-dist.php index bc8f003e..91c61503 100644 --- a/config-dist.php +++ b/config-dist.php @@ -182,7 +182,8 @@ Setting('FEATURE_FLAG_STOCK_PRODUCT_FREEZING', true); Setting('FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_FIELD_NUMBER_PAD', true); // Activate the number pad in due date fields on (supported) mobile browsers Setting('FEATURE_FLAG_SHOPPINGLIST_MULTIPLE_LISTS', true); Setting('FEATURE_FLAG_CHORES_ASSIGNMENTS', true); +Setting('FEATURE_FLAG_THERMAL_PRINTER', true); // Feature settings Setting('FEATURE_SETTING_STOCK_COUNT_OPENED_PRODUCTS_AGAINST_MINIMUM_STOCK_AMOUNT', true); // When set to true, opened items will be counted as missing for calculating if a product is below its minimum stock amount -Setting('FEATURE_FLAG_AUTO_TORCH_ON_WITH_CAMERA', true); // Enables the torch automaticaly (if the device has one) +Setting('FEATURE_FLAG_AUTO_TORCH_ON_WITH_CAMERA', true); // Enables the torch automatically (if the device has one) diff --git a/controllers/BaseController.php b/controllers/BaseController.php index f50cff07..57ec8dbb 100644 --- a/controllers/BaseController.php +++ b/controllers/BaseController.php @@ -11,6 +11,7 @@ use Grocy\Services\ChoresService; use Grocy\Services\DatabaseService; use Grocy\Services\FilesService; use Grocy\Services\LocalizationService; +use Grocy\Services\PrintService; use Grocy\Services\RecipesService; use Grocy\Services\SessionService; use Grocy\Services\StockService; @@ -93,6 +94,12 @@ class BaseController return StockService::getInstance(); } + protected function getPrintService() + { + return PrintService::getInstance(); + } + + protected function getTasksService() { return TasksService::getInstance(); diff --git a/controllers/PrintApiController.php b/controllers/PrintApiController.php new file mode 100644 index 00000000..b9048b67 --- /dev/null +++ b/controllers/PrintApiController.php @@ -0,0 +1,39 @@ +getQueryParams(); + + $listId = 1; + if (isset($params['list'])) { + $listId = $params['list']; + } + + $printHeader = true; + if (isset($params['printHeader'])) { + $printHeader = $params['printHeader']; + } + $items = $this->getStockService()->GetShoppinglistInPrintableStrings($listId); + return $this->ApiResponse($response, $this->getPrintService()->printShoppingList($printHeader, $items)); + } catch (\Exception $ex) { + return $this->GenericErrorResponse($response, $ex->getMessage()); + } + } + + +// @formatter:off + public function __construct(\DI\Container $container) + { + parent::__construct($container); + } +} diff --git a/controllers/StockApiController.php b/controllers/StockApiController.php index 542631ba..64c502ec 100644 --- a/controllers/StockApiController.php +++ b/controllers/StockApiController.php @@ -1,5 +1,4 @@ getUsersService(); diff --git a/routes.php b/routes.php index 4ce72312..cdb14c61 100644 --- a/routes.php +++ b/routes.php @@ -228,6 +228,9 @@ $app->group('/api', function (RouteCollectorProxy $group) { $group->post('/chores/executions/{executionId}/undo', '\Grocy\Controllers\ChoresApiController:UndoChoreExecution'); $group->post('/chores/executions/calculate-next-assignments', '\Grocy\Controllers\ChoresApiController:CalculateNextExecutionAssignments'); + //Printing + $group->get('/print/shoppinglist/thermal', '\Grocy\Controllers\PrintApiController:PrintShoppingListThermal'); + // Batteries $group->get('/batteries', '\Grocy\Controllers\BatteriesApiController:Current'); $group->get('/batteries/{batteryId}', '\Grocy\Controllers\BatteriesApiController:BatteryDetails'); diff --git a/services/BaseService.php b/services/BaseService.php index 86a4a5d4..ef04ec81 100644 --- a/services/BaseService.php +++ b/services/BaseService.php @@ -66,4 +66,10 @@ class BaseService { return UsersService::getInstance(); } + + protected function getPrintService() + { + return PrintService::getInstance(); + } + } diff --git a/services/PrintService.php b/services/PrintService.php new file mode 100644 index 00000000..a7eb886d --- /dev/null +++ b/services/PrintService.php @@ -0,0 +1,79 @@ +setJustification(Printer::JUSTIFY_CENTER); + $printer->selectPrintMode(Printer::MODE_DOUBLE_WIDTH); + $printer->setTextSize(4, 4); + $printer->setReverseColors(true); + $printer->text("grocy"); + $printer->setJustification(); + $printer->setTextSize(1, 1); + $printer->setReverseColors(false); + $printer->selectPrintMode(); + $printer->feed(6); + } + + /** + * @param bool $printHeader Printing of Grocy logo + * @param string[] $items Items to print + * @return string[] + * @throws Exception + */ + public function printShoppingList(bool $printHeader, array $items): array { + if (!self::isThermalPrinterEnabled()) { + throw new Exception("Printer is not setup enabled in configuration"); + } + $printer = self::getPrinterHandle(); + if ($printer === false) + throw new Exception("Unable to connect to printer"); + + if ($printHeader) { + self::printHeader($printer); + } + + foreach ($items as $item) { + $printer->text($item); + $printer->feed(); + } + + $printer->feed(2); + $printer->cut(); + $printer->close(); + return [ + 'result' => "OK", + 'printed' => $items + ]; + } +} diff --git a/services/StockService.php b/services/StockService.php index 6cad4592..6c7785e2 100644 --- a/services/StockService.php +++ b/services/StockService.php @@ -1,5 +1,6 @@ ShoppingListExists($listId)) { + throw new \Exception('Shopping list does not exist'); + } + + $result = array(); + $rowsShoppingListProducts = $this->getDatabase()->shopping_list()->where('shopping_list_id = :1', $listId)->fetchAll(); + foreach ($rowsShoppingListProducts as $row) { + $product = $this->getDatabase()->products()->where('id = :1', $row['product_id'])->fetch(); + array_push($result, $row["amount"] . " " . $product["name"]); + } + return $result; + } + public function TransferProduct(int $productId, float $amount, int $locationIdFrom, int $locationIdTo, $specificStockEntryId = 'default', &$transactionId = null) { if (!$this->ProductExists($productId)) @@ -1390,7 +1405,7 @@ class StockService extends BaseService private function LocationExists($locationId) { - $locationRow = $this->getDatabase()->locations()->where('id = :1', $locationId)->fetch(); + $locationRow = $this->getDatabase()->locations()->where('id = :1', $locationId)->fetchAll(); return $locationRow !== null; }