mirror of
https://github.com/grocy/grocy.git
synced 2026-04-05 20:36:15 +02:00
Products allowed in meal plan
This commit is contained in:
parent
5c602ce74e
commit
52698e43b0
|
|
@ -132,6 +132,7 @@ class RecipesController extends BaseController
|
|||
public function MealPlan(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||
{
|
||||
$recipes = $this->Database->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->fetchAll();
|
||||
$products = $this->Database->products()->orderBy('name');
|
||||
|
||||
$events = array();
|
||||
foreach($this->Database->meal_plan() as $mealPlanEntry)
|
||||
|
|
@ -141,22 +142,39 @@ class RecipesController extends BaseController
|
|||
if ($recipe !== null)
|
||||
{
|
||||
$title = $recipe->name;
|
||||
|
||||
$events[] = array(
|
||||
'id' => $mealPlanEntry['id'],
|
||||
'title' => $title,
|
||||
'start' => $mealPlanEntry['day'],
|
||||
'date_format' => 'date',
|
||||
'recipe' => json_encode($recipe),
|
||||
'mealPlanEntry' => json_encode($mealPlanEntry),
|
||||
'type' => $mealPlanEntry['type']
|
||||
);
|
||||
}
|
||||
|
||||
$events[] = array(
|
||||
'id' => $mealPlanEntry['id'],
|
||||
'title' => $title,
|
||||
'start' => $mealPlanEntry['day'],
|
||||
'date_format' => 'date',
|
||||
'recipe' => json_encode($recipe),
|
||||
'mealPlanEntry' => json_encode($mealPlanEntry),
|
||||
'type' => $mealPlanEntry['type']
|
||||
);
|
||||
$product = FindObjectInArrayByPropertyValue($products, 'id', $mealPlanEntry['product_id']);
|
||||
if ($product !== null)
|
||||
{
|
||||
$title = $product->name;
|
||||
|
||||
$events[] = array(
|
||||
'id' => $mealPlanEntry['id'],
|
||||
'title' => $title,
|
||||
'start' => $mealPlanEntry['day'],
|
||||
'date_format' => 'date',
|
||||
'product' => json_encode($product),
|
||||
'mealPlanEntry' => json_encode($mealPlanEntry),
|
||||
'type' => $mealPlanEntry['type']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->AppContainer->view->render($response, 'mealplan', [
|
||||
'fullcalendarEventSources' => $events,
|
||||
'recipes' => $recipes,
|
||||
'products' => $products,
|
||||
'internalRecipes' => $this->Database->recipes()->whereNot('type', RecipesService::RECIPE_TYPE_NORMAL)->fetchAll(),
|
||||
'recipesResolved' => $this->RecipesService->GetRecipesResolved()
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ CREATE TABLE meal_plan (
|
|||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||
day DATE NOT NULL,
|
||||
type TEXT DEFAULT 'recipe',
|
||||
product_id INTEGER,
|
||||
recipe_id INTEGER,
|
||||
recipe_servings INTEGER DEFAULT 1,
|
||||
note TEXT,
|
||||
|
|
|
|||
|
|
@ -157,6 +157,33 @@ var calendar = $("#calendar").fullCalendar({
|
|||
}
|
||||
}
|
||||
}
|
||||
if (event.type == "product")
|
||||
{
|
||||
var product = JSON.parse(event.product);
|
||||
if (product === null || product === undefined)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
element.attr("data-product", event.product);
|
||||
|
||||
var productConsumeButtonDisabledClasses = "";
|
||||
element.html('\
|
||||
<div> \
|
||||
<h5 class="text-truncate">' + product.name + '<h5> \
|
||||
<h5 class="small text-truncate">' + __n(mealPlanEntry.recipe_servings, "%s serving", "%s servings") + '</h5> \
|
||||
<h5> \
|
||||
<a class="ml-1 btn btn-outline-danger btn-xs remove-recipe-button" href="#"><i class="fas fa-trash"></i></a> \
|
||||
<a class="ml-1 btn btn-outline-success btn-xs product-consume-button ' + productConsumeButtonDisabledClasses + '" href="#" data-toggle="tooltip" title="' + __t("Consume product") + '" data-product-id="' + product.id.toString() + '" data-product-name="' + product.name + '" data-servings-amount="' + mealPlanEntry.recipe_servings + '"><i class="fas fa-utensils"></i></a> \
|
||||
</h5> \
|
||||
</div>');
|
||||
|
||||
if (product.picture_file_name && !product.picture_file_name.isEmpty())
|
||||
{
|
||||
element.html(element.html() + '<div class="mx-auto"><img data-src="' + U("/api/files/productpictures/") + btoa(product.picture_file_name) + '?force_serve_as=picture&best_fit_width=400" class="img-fluid lazy"></div>')
|
||||
}
|
||||
}
|
||||
else if (event.type == "note")
|
||||
{
|
||||
element.html('\
|
||||
|
|
@ -254,7 +281,18 @@ $('#save-add-recipe-button').on('click', function(e)
|
|||
return false;
|
||||
}
|
||||
|
||||
Grocy.Api.Post('objects/meal_plan', $('#add-recipe-form').serializeJSON(),
|
||||
var jsonData = $('#add-recipe-form').serializeJSON();
|
||||
|
||||
if (Grocy.Components.RecipePicker.GetValue() != "")
|
||||
{
|
||||
jsonData.type = "recipe";
|
||||
}
|
||||
else if (Grocy.Components.ProductPicker.GetValue() != "")
|
||||
{
|
||||
jsonData.type = "product";
|
||||
}
|
||||
|
||||
Grocy.Api.Post('objects/meal_plan', jsonData,
|
||||
function(result)
|
||||
{
|
||||
window.location.reload();
|
||||
|
|
@ -376,6 +414,45 @@ $(document).on('click', '.recipe-order-missing-button', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.product-consume-button', function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
// Remove the focus from the current button
|
||||
// to prevent that the tooltip stays until clicked anywhere else
|
||||
document.activeElement.blur();
|
||||
|
||||
Grocy.FrontendHelpers.BeginUiBusy();
|
||||
|
||||
var productId = $(e.currentTarget).attr('data-product-id');
|
||||
var consumeAmount = $(e.currentTarget).attr('data-servings-amount');
|
||||
|
||||
Grocy.Api.Post('stock/products/' + productId + '/consume', { 'amount': consumeAmount, 'spoiled': false },
|
||||
function(bookingResponse)
|
||||
{
|
||||
Grocy.Api.Get('stock/products/' + productId,
|
||||
function(result)
|
||||
{
|
||||
var toastMessage = __t('Removed %1$s of %2$s from stock', consumeAmount.toString() + " " + __n(consumeAmount, result.quantity_unit_stock.name, result.quantity_unit_stock.name_plural), result.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + bookingResponse.transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>';
|
||||
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
toastr.success(toastMessage);
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$(document).on('click', '.recipe-consume-button', function(e)
|
||||
{
|
||||
// Remove the focus from the current button
|
||||
|
|
@ -461,3 +538,16 @@ $(window).on("resize", function()
|
|||
calendar.fullCalendar("changeView", "basicWeek");
|
||||
}
|
||||
});
|
||||
function UndoStockTransaction(transactionId)
|
||||
{
|
||||
Grocy.Api.Post('stock/transactions/' + transactionId.toString() + '/undo', { },
|
||||
function (result)
|
||||
{
|
||||
toastr.success(__t("Transaction successfully undone"));
|
||||
},
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,7 +45,14 @@
|
|||
|
||||
@include('components.recipepicker', array(
|
||||
'recipes' => $recipes,
|
||||
'isRequired' => true,
|
||||
'isRequired' => false,
|
||||
'nextInputSelector' => '#recipe_servings'
|
||||
))
|
||||
|
||||
@include('components.productpicker', array(
|
||||
'products' => $products,
|
||||
'isRequired' => false,
|
||||
'disallowAllProductWorkflows' => true,
|
||||
'nextInputSelector' => '#recipe_servings'
|
||||
))
|
||||
|
||||
|
|
@ -58,7 +65,6 @@
|
|||
))
|
||||
|
||||
<input type="hidden" id="day" name="day" value="">
|
||||
<input type="hidden" name="type" value="recipe">
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user