mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 17:45:39 +00:00
Add a "consume all ingredients of this recipe" button (this now closes #32)
This commit is contained in:
parent
9a8c61497b
commit
324487d395
@ -19,4 +19,17 @@ class RecipesApiController extends BaseApiController
|
||||
$this->RecipesService->AddNotFulfilledProductsToShoppingList($args['recipeId']);
|
||||
return $this->VoidApiActionResponse($response);
|
||||
}
|
||||
|
||||
public function ConsumeRecipe(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->RecipesService->ConsumeRecipe($args['recipeId']);
|
||||
return $this->VoidApiActionResponse($response);
|
||||
}
|
||||
catch (\Exception $ex)
|
||||
{
|
||||
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1010,6 +1010,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/recipes/consume-recipe/{recipeId}": {
|
||||
"get": {
|
||||
"description": "Consumes all products of the given recipe",
|
||||
"tags": [
|
||||
"Recipes"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "recipeId",
|
||||
"required": true,
|
||||
"description": "A valid recipe id",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A VoidApiActionResponse object",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/VoidApiActionResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/habits/track-habit-execution/{habitId}": {
|
||||
"get": {
|
||||
"description": "Tracks an execution of the given habit",
|
||||
|
@ -210,6 +210,9 @@ return array(
|
||||
'-1 means that this product never expires' => '-1 bedeuet, dass dieses Produkt niemals abläuft',
|
||||
'Quantity unit' => 'Mengeneinheit',
|
||||
'Only check if a single unit is in stock (a different quantity can then be used above)' => 'Nur prüfen, ob eine einzelne Einheit vorrätig ist (eine abweichende Mengeneinheit kann dann oben verwendet werden)',
|
||||
'Are you sure to consume all ingredients needed by recipe "#1" (ingredients marked with "check only if a single unit is in stock" will be ignored)?' => 'Sicher, dass alle Zutaten die vom Rezept "#1" benötigt werden aus dem Bestand entfernt werden sollen (Zutaten markiert mit "nur prüfen, ob eine einzelne Einheit vorrätig ist" werden ignoriert)?',
|
||||
'Removed all ingredients of recipe "#1" from stock' => 'Alle Zutaten, die vom Rezept "#1" benötigt werden, wurdem aus dem Bestand entfernt',
|
||||
'Consume all ingredients needed by this recipe' => 'Alle Zutaten, die von diesem Rezept benötigt werden, aus dem Bestand enternen',
|
||||
|
||||
//Constants
|
||||
'manually' => 'Manuell',
|
||||
|
@ -104,6 +104,42 @@ $(document).on('click', '.recipe-order-missing-button', function(e)
|
||||
});
|
||||
});
|
||||
|
||||
$("#selectedRecipeConsumeButton").on('click', function(e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-recipe-name');
|
||||
var objectId = $(e.currentTarget).attr('data-recipe-id');
|
||||
|
||||
bootbox.confirm({
|
||||
message: L('Are you sure to consume all ingredients needed by recipe "#1" (ingredients marked with "check only if a single unit is in stock" will be ignored)?', objectName),
|
||||
buttons: {
|
||||
confirm: {
|
||||
label: L('Yes'),
|
||||
className: 'btn-success'
|
||||
},
|
||||
cancel: {
|
||||
label: L('No'),
|
||||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Get('recipes/consume-recipe/' + objectId,
|
||||
function(result)
|
||||
{
|
||||
toastr.success(L('Removed all ingredients of recipe "#1" from stock', objectName));
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
recipesTables.on('select', function(e, dt, type, indexes)
|
||||
{
|
||||
if (type === 'row')
|
||||
|
@ -91,6 +91,7 @@ $app->group('/api', function()
|
||||
|
||||
// Recipes
|
||||
$this->get('/recipes/add-not-fulfilled-products-to-shopping-list/{recipeId}', '\Grocy\Controllers\RecipesApiController:AddNotFulfilledProductsToShoppingList');
|
||||
$this->get('/recipes/consume-recipe/{recipeId}', '\Grocy\Controllers\RecipesApiController:ConsumeRecipe');
|
||||
|
||||
// Habits
|
||||
$this->get('/habits/track-habit-execution/{habitId}', '\Grocy\Controllers\HabitsApiController:TrackHabitExecution');
|
||||
|
@ -2,8 +2,18 @@
|
||||
|
||||
namespace Grocy\Services;
|
||||
|
||||
use \Grocy\Services\StockService;
|
||||
|
||||
class RecipesService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->StockService = new StockService();
|
||||
}
|
||||
|
||||
protected $StockService;
|
||||
|
||||
public function GetRecipesFulfillment()
|
||||
{
|
||||
$sql = 'SELECT * from recipes_fulfillment';
|
||||
@ -38,4 +48,27 @@ class RecipesService extends BaseService
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function ConsumeRecipe($recipeId)
|
||||
{
|
||||
if (!$this->RecipeExists($recipeId))
|
||||
{
|
||||
throw new \Exception('Recipe does not exist');
|
||||
}
|
||||
|
||||
$recipePositions = $this->Database->recipes_pos()->where('recipe_id', $recipeId)->fetchAll();
|
||||
foreach ($recipePositions as $recipePosition)
|
||||
{
|
||||
if ($recipePosition->only_check_single_unit_in_stock == 0)
|
||||
{
|
||||
$this->StockService->ConsumeProduct($recipePosition->product_id, $recipePosition->amount, false, StockService::TRANSACTION_TYPE_CONSUME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function RecipeExists($recipeId)
|
||||
{
|
||||
$recipeRow = $this->Database->recipes()->where('id = :1', $recipeId)->fetch();
|
||||
return $recipeRow !== null;
|
||||
}
|
||||
}
|
||||
|
@ -39,9 +39,6 @@
|
||||
<a class="btn btn-sm btn-danger recipe-delete-button" href="#" data-recipe-id="{{ $recipe->id }}" data-recipe-name="{{ $recipe->name }}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-primary recipe-order-missing-button @if(FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1){{ disabled }}@endif" href="#" title="{{ $L('Put missing products on shopping list') }}" data-recipe-id="{{ $recipe->id }}" data-recipe-name="{{ $recipe->name }}">
|
||||
<i class="fas fa-cart-plus"></i>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ $recipe->name }}
|
||||
@ -60,7 +57,13 @@
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<div id="selectedRecipeCard" class="card">
|
||||
<div class="card-header">
|
||||
<i class="fas fa-cocktail"></i> {{ $selectedRecipe->name }}
|
||||
<i class="fas fa-cocktail"></i> {{ $selectedRecipe->name }}
|
||||
<a id="selectedRecipeConsumeButton" class="btn btn-sm btn-outline-success py-0" href="#" title="{{ $L('Consume all ingredients needed by this recipe') }}" data-recipe-id="{{ $selectedRecipe->id }}" data-recipe-name="{{ $selectedRecipe->name }}">
|
||||
<i class="fas fa-utensils"></i>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-outline-primary py-0 recipe-order-missing-button @if(FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $selectedRecipe->id)->need_fulfilled_with_shopping_list == 1){{ disabled }}@endif" href="#" title="{{ $L('Put missing products on shopping list') }}" data-recipe-id="{{ $selectedRecipe->id }}" data-recipe-name="{{ $selectedRecipe->name }}">
|
||||
<i class="fas fa-cart-plus"></i>
|
||||
</a>
|
||||
<a id="selectedRecipeToggleFullscreenButton" class="btn btn-sm btn-outline-secondary py-0 float-right" href="#" title="{{ $L('Expand to fullscreen') }}">
|
||||
<i class="fas fa-expand-arrows-alt"></i>
|
||||
</a>
|
||||
|
Loading…
x
Reference in New Issue
Block a user