added new shopping list api endpoints

This commit is contained in:
Mario Klug 2020-03-27 13:28:11 +01:00
parent d7738aa1ec
commit a59ae34998
4 changed files with 330 additions and 12 deletions

View File

@ -419,6 +419,59 @@ class StockApiController extends BaseApiController
));
}
public function CurrentShoppingLists(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
$lists = $this->getStockService()->GetCurrentShoppingLists();
return $this->ApiResponse($response, $lists);
}
public function ShoppingListDetails(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
try
{
return $this->ApiResponse($response, $this->getStockService()->GetShoppingListDetails($args['listId']));
}
catch (\Exception $ex)
{
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
public function ShoppingListEntries(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
try
{
return $this->ApiResponse($response, $this->getStockService()->GetShoppingListEntries($args['listId']));
}
catch (\Exception $ex)
{
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
public function ShoppingListSetDone(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
$entryId = $args['entryId'];
try {
$requestBody = $request->getParsedBody();
$done = 1;
if (array_key_exists('done', $requestBody) && is_numeric($requestBody['done']))
{
$done = intval($requestBody['done']);
}
$this->getStockService()->SetShoppingListEntryDone($entryId, $done);
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex) {
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
public function AddMissingProductsToShoppingList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
try
@ -548,7 +601,7 @@ class StockApiController extends BaseApiController
{
$addFoundProduct = true;
}
return $this->ApiResponse($response, $this->getStockService()->ExternalBarcodeLookup($args['barcode'], $addFoundProduct));
}
catch (\Exception $ex)
@ -614,7 +667,7 @@ class StockApiController extends BaseApiController
{
throw new \Exception('Stock booking does not exist');
}
return $this->ApiResponse($response, $stockLogRow);
}
catch (\Exception $ex)
@ -633,7 +686,7 @@ class StockApiController extends BaseApiController
{
throw new \Exception('No transaction was found by the given transaction id');
}
return $this->ApiResponse($response, $transactionRows);
}
catch (\Exception $ex)

View File

@ -2242,6 +2242,164 @@
}
}
},
"/stock/shoppinglist": {
"get": {
"summary": "Returns array of shopping lists",
"tags": [
"Stock"
],
"responses": {
"200": {
"description": "An array of shopping lists",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CurrentShoppingListResponse"
}
}
}
}
}
}
}
},
"/stock/shoppinglist/{listId}": {
"get": {
"summary": "Returns the given shopping list content",
"tags": [
"Stock"
],
"parameters": [
{
"in": "path",
"name": "listId",
"required": true,
"description": "A valid shopping list id",
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "A ShoppingList object",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CurrentShoppingListResponse"
}
}
}
},
"400": {
"description": "A shopping list with the provided id is not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenericErrorResponse"
}
}
}
}
}
}
},
"/stock/shoppinglist/{listId}/entries": {
"get": {
"summary": "Returns product in shopping list",
"tags": [
"Stock"
],
"parameters": [
{
"in": "path",
"name": "listId",
"required": true,
"description": "A valid shopping list id",
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "An array of shopping list entries",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ShoppingListEntryResponse"
}
}
}
},
"400": {
"description": "A shopping list with the provided id is not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenericErrorResponse"
}
}
}
}
}
}
},
"/stock/shoppinglist/set-done/{entryId}": {
"post": {
"summary": "Updates done state for shopping list entry",
"tags": [
"Stock"
],
"parameters": [
{
"in": "path",
"name": "entryId",
"required": true,
"description": "A valid shopping list entry id",
"schema": {
"type": "integer"
}
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"done": {
"type": "integer",
"description": "1 if entry is done, 0 if not, when omitted 1 is used"
}
},
"example": {
"done": 1
}
}
}
}
},
"responses": {
"204": {
"description": "The operation was successful"
},
"400": {
"description": "The operation was not successful (possible errors are: Not existing shopping list)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenericErrorResponse"
}
}
}
}
}
}
},
"/stock/shoppinglist/add-missing-products": {
"post": {
"summary": "Adds currently missing products (below defined min. stock amount) to the given shopping list",
@ -4203,6 +4361,55 @@
}
}
},
"CurrentShoppingListResponse": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"row_created_timestamp": {
"type": "string",
"format": "date-time"
}
}
},
"ShoppingListEntryResponse": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"product_id": {
"type": "integer"
},
"note": {
"type": "string"
},
"amount": {
"type": "integer"
},
"row_created_timestamp": {
"type": "string",
"format": "date-time"
},
"shopping_list_id": {
"type": "integer"
},
"done": {
"type": "integer",
"description": "0 or 1"
},
"product": {
"$ref": "#/components/schemas/Product"
}
}
},
"CurrentChoreResponse": {
"type": "object",
"properties": {

View File

@ -141,9 +141,9 @@ $app->group('/api', function(RouteCollectorProxy $group)
// System
$group->get('/system/info', '\Grocy\Controllers\SystemApiController:GetSystemInfo');
$group->get('/system/db-changed-time', '\Grocy\Controllers\SystemApiController:GetDbChangedTime');
$group->get('/system/db-changed-time', '\Grocy\Controllers\SystemApiController:GetDbChangedTime');
$group->post('/system/log-missing-localization', '\Grocy\Controllers\SystemApiController:LogMissingLocalization');
// Generic entity interaction
$group->get('/objects/{entity}', '\Grocy\Controllers\GenericEntityApiController:GetObjects');
$group->get('/objects/{entity}/{objectId}', '\Grocy\Controllers\GenericEntityApiController:GetObject');
@ -201,6 +201,10 @@ $app->group('/api', function(RouteCollectorProxy $group)
// Shopping list
if (GROCY_FEATURE_FLAG_SHOPPINGLIST)
{
$group->get('/stock/shoppinglist', '\Grocy\Controllers\StockApiController:CurrentShoppingLists');
$group->get('/stock/shoppinglist/{listId}', '\Grocy\Controllers\StockApiController:ShoppingListDetails');
$group->get('/stock/shoppinglist/{listId}/entries', '\Grocy\Controllers\StockApiController:ShoppingListEntries');
$group->post('/stock/shoppinglist/set-done/{entryId}', '\Grocy\Controllers\StockApiController:ShoppingListSetDone');
$group->post('/stock/shoppinglist/add-missing-products', '\Grocy\Controllers\StockApiController:AddMissingProductsToShoppingList');
$group->post('/stock/shoppinglist/clear', '\Grocy\Controllers\StockApiController:ClearShoppingList');
$group->post('/stock/shoppinglist/add-product', '\Grocy\Controllers\StockApiController:AddProductToShoppingList');

View File

@ -28,7 +28,7 @@ class StockService extends BaseService
$sql = 'SELECT * FROM stock_current WHERE best_before_date IS NOT NULL UNION SELECT id, 0, 0, null, 0, 0, 0 FROM ' . $missingProductsView . ' WHERE id NOT IN (SELECT product_id FROM stock_current)';
}
$currentStockMapped = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_OBJ);
$relevantProducts = $this->getDatabase()->products()->where('id IN (SELECT product_id FROM (' . $sql . ') x)');
foreach ($relevantProducts as $product)
{
@ -818,6 +818,53 @@ class StockService extends BaseService
return $this->getDatabase()->lastInsertId();
}
public function GetCurrentShoppingLists()
{
return $this->getDatabase()->shopping_lists()->fetchAll(\PDO::FETCH_OBJ);
}
public function GetShoppingListDetails($listId)
{
$shoppingListRow = $this->getDatabase()->shopping_lists()->where('id = :1', $listId)->fetch();
if ($shoppingListRow === null)
{
throw new \Exception('Shopping list does not exist');
}
return $shoppingListRow;
}
public function GetShoppingListEntries($listId)
{
if (!$this->ShoppingListExists($listId))
{
throw new \Exception('Shopping list does not exist');
}
$entries = $this->getDatabase()->shopping_list()->where('shopping_list_id', $listId)->fetchAll();
foreach ($entries as $entry) {
$entry->product = $this->getDatabase()->products()->where('id', $entry->product_id)->fetch();
}
return $entries;
}
public function SetShoppingListEntryDone($entryId, $done = 1)
{
if (!$this->ShoppingListEntryExists($entryId))
{
throw new \Exception('Entry does not exist');
}
$entry = $this->getDatabase()->shopping_list()->where('id', $entryId)->fetch();
$entry->update(array(
'done' => $done
));
}
public function AddMissingProductsToShoppingList($listId = 1)
{
if (!$this->ShoppingListExists($listId))
@ -929,18 +976,25 @@ class StockService extends BaseService
return $productRow !== null;
}
private function ShoppingListExists($listId)
{
$shoppingListRow = $this->getDatabase()->shopping_lists()->where('id = :1', $listId)->fetch();
return $shoppingListRow !== null;
}
private function ShoppingListEntryExists($listId)
{
$shoppingListEntryRow = $this->getDatabase()->shopping_list()->where('id = :1', $listId)->fetch();
return $shoppingListEntryRow !== null;
}
private function LocationExists($locationId)
{
$locationRow = $this->getDatabase()->locations()->where('id = :1', $locationId)->fetch();
return $locationRow !== null;
}
private function ShoppingListExists($listId)
{
$shoppingListRow = $this->getDatabase()->shopping_lists()->where('id = :1', $listId)->fetch();
return $shoppingListRow !== null;
}
private function LoadBarcodeLookupPlugin()
{
$pluginName = defined('GROCY_STOCK_BARCODE_LOOKUP_PLUGIN') ? GROCY_STOCK_BARCODE_LOOKUP_PLUGIN : '';