2019-07-06 14:48:46 +02:00
var firstRender = true ;
2020-02-09 17:15:13 +01:00
Grocy . IsMealPlanEntryEditAction = false ;
2019-07-06 14:48:46 +02:00
2019-07-06 20:19:21 +02:00
var firstDay = null ;
2023-02-06 20:22:10 +01:00
if ( Grocy . CalendarFirstDayOfWeek )
2019-07-06 20:19:21 +02:00
{
2023-02-06 20:22:10 +01:00
firstDay = Number . parseInt ( Grocy . CalendarFirstDayOfWeek ) ;
2019-07-06 20:19:21 +02:00
}
2023-02-06 20:22:10 +01:00
if ( Grocy . MealPlanFirstDayOfWeek )
2020-01-25 20:01:40 +01:00
{
2023-02-06 20:22:10 +01:00
firstDay = Number . parseInt ( Grocy . MealPlanFirstDayOfWeek ) ;
2023-05-01 14:49:02 +02:00
if ( firstDay == - 1 )
{
firstDay = moment ( ) . day ( ) ;
}
2020-01-25 20:01:40 +01:00
}
2019-07-06 20:19:21 +02:00
2021-07-15 17:54:48 +02:00
$ ( ".calendar" ) . each ( function ( )
{
var container = $ ( this ) ;
var sectionId = container . attr ( "data-section-id" ) ;
var sectionName = container . attr ( "data-section-name" ) ;
var isPrimarySection = BoolVal ( container . attr ( "data-primary-section" ) ) ;
var isLastSection = BoolVal ( container . attr ( "data-last-section" ) ) ;
2022-02-08 18:08:26 +01:00
var rightButtonList = "agendaWeek,agendaDay,prev,today,next" ;
if ( $ ( window ) . width ( ) < 768 )
{
var rightButtonList = "prev,today,next" ;
}
2021-07-15 17:54:48 +02:00
var headerConfig = {
2019-05-06 19:38:47 +02:00
"left" : "title" ,
"center" : "" ,
2022-02-08 18:08:26 +01:00
"right" : rightButtonList
2021-07-15 17:54:48 +02:00
} ;
2022-02-08 18:08:26 +01:00
2021-07-15 17:54:48 +02:00
if ( ! isPrimarySection )
2019-05-06 19:38:47 +02:00
{
2021-07-15 17:54:48 +02:00
headerConfig = {
"left" : "" ,
"center" : "" ,
"right" : ""
} ;
}
container . fullCalendar ( {
"themeSystem" : "bootstrap4" ,
"header" : headerConfig ,
"weekNumbers" : false ,
"eventLimit" : false ,
"eventSources" : fullcalendarEventSources ,
2022-02-08 18:08:26 +01:00
"defaultView" : ( $ ( window ) . width ( ) < 768 || GetUriParam ( "days" ) == "0" ) ? "agendaDay" : "agendaWeek" ,
2021-07-15 17:54:48 +02:00
"allDayText" : sectionName ,
2021-07-15 20:07:31 +02:00
"allDayHtml" : sectionName ,
2021-07-15 17:54:48 +02:00
"minTime" : "00:00:00" ,
"maxTime" : "00:00:01" ,
"scrollTime" : "00:00:00" ,
"firstDay" : firstDay ,
"height" : "auto" ,
2021-07-16 17:32:08 +02:00
"defaultDate" : GetUriParam ( "start" ) ,
2021-07-15 17:54:48 +02:00
"viewRender" : function ( view )
{
if ( ! isPrimarySection )
{
return ;
}
$ ( ".calendar[data-primary-section='true'] .fc-day-header" ) . prepend ( ' \
2021-08-06 20:18:43 +02:00
< div class = "btn-group mr-2 my-1 d-print-none" > \
2022-04-04 20:10:29 +02:00
< button type = "button" class = "btn btn-outline-dark btn-xs add-recipe-button" data - toggle = "tooltip" title = "' + __t('Add recipe') + '" > < i class = "fa-solid fa-plus" > < / i > < / a > < / b u t t o n > \
2020-01-23 20:59:19 +01:00
< button type = "button" class = "btn btn-outline-dark btn-xs dropdown-toggle dropdown-toggle-split" data - toggle = "dropdown" > < / b u t t o n > \
2021-07-13 19:29:23 +02:00
< div class = "table-inline-menu dropdown-menu" > \
< a class = "dropdown-item add-note-button" href = "#" > < span class = "dropdown-item-text" > ' + __t(' Add note ') + ' < / s p a n > < / a > \
< a class = "dropdown-item add-product-button" href = "#" > < span class = "dropdown-item-text" > ' + __t(' Add product ') + ' < / s p a n > < / a > \
< a class = "dropdown-item copy-day-button" href = "#" > < span class = "dropdown-item-text" > ' + __t(' Copy this day ') + ' < / s p a n > < / a > \
2020-01-23 20:59:19 +01:00
< / d i v > \
< / d i v > ' ) ;
2019-05-07 19:48:14 +02:00
2021-07-15 17:54:48 +02:00
var weekCosts = 0 ;
2021-07-13 21:24:08 +02:00
var weekRecipeOrderMissingButtonHtml = "" ;
2021-07-15 17:54:48 +02:00
var weekRecipeConsumeButtonHtml = "" ;
var weekCostsHtml = "" ;
if ( weekRecipe !== null )
2021-07-13 21:24:08 +02:00
{
2023-04-01 22:04:30 +02:00
var weekRecipeResolved = FindObjectInArrayByPropertyValue ( recipesResolved , "recipe_id" , weekRecipe . id ) ;
2021-07-15 17:54:48 +02:00
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _STOCK _PRICE _TRACKING )
{
2023-04-01 22:04:30 +02:00
weekCosts = weekRecipeResolved . costs ;
2021-07-15 17:54:48 +02:00
weekCostsHtml = _ _t ( "Week costs" ) + ': <span class="locale-number locale-number-currency">' + weekCosts . toString ( ) + "</span> " ;
}
2021-07-13 21:24:08 +02:00
2021-07-15 17:54:48 +02:00
var weekRecipeOrderMissingButtonDisabledClasses = "" ;
2023-04-01 22:04:30 +02:00
if ( weekRecipeResolved . need _fulfilled _with _shopping _list == 1 )
2021-07-15 17:54:48 +02:00
{
weekRecipeOrderMissingButtonDisabledClasses = "disabled" ;
}
2020-01-23 21:57:47 +01:00
2021-07-15 17:54:48 +02:00
var weekRecipeConsumeButtonDisabledClasses = "" ;
2023-04-01 22:04:30 +02:00
if ( weekRecipeResolved . need _fulfilled == 0 || weekCosts == 0 )
2021-07-15 17:54:48 +02:00
{
weekRecipeConsumeButtonDisabledClasses = "disabled" ;
}
2019-05-07 19:48:14 +02:00
2021-07-15 17:54:48 +02:00
var weekRecipeOrderMissingButtonHtml = "" ;
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _SHOPPINGLIST )
{
2022-04-04 20:10:29 +02:00
weekRecipeOrderMissingButtonHtml = '<a class="ml-1 btn btn-outline-primary btn-xs recipe-order-missing-button d-print-none ' + weekRecipeOrderMissingButtonDisabledClasses + '" href="#" data-toggle="tooltip" title="' + _ _t ( "Put missing products on shopping list" ) + '" data-recipe-id="' + weekRecipe . id . toString ( ) + '" data-recipe-name="' + weekRecipe . name + '" data-recipe-type="' + weekRecipe . type + '"><i class="fa-solid fa-cart-plus"></i></a>' ;
2021-07-15 17:54:48 +02:00
}
2021-07-11 18:32:26 +02:00
2022-04-04 20:10:29 +02:00
weekRecipeConsumeButtonHtml = '<a class="ml-1 btn btn-outline-success btn-xs recipe-consume-button d-print-none ' + weekRecipeConsumeButtonDisabledClasses + '" href="#" data-toggle="tooltip" title="' + _ _t ( "Consume all ingredients needed by this weeks recipes or products" ) + '" data-recipe-id="' + weekRecipe . id . toString ( ) + '" data-recipe-name="' + weekRecipe . name + '" data-recipe-type="' + weekRecipe . type + '"><i class="fa-solid fa-utensils"></i></a>'
2020-01-23 20:59:19 +01:00
}
2021-07-15 17:54:48 +02:00
$ ( ".calendar[data-primary-section='true'] .fc-header-toolbar .fc-center" ) . html ( "<h4>" + weekCostsHtml + weekRecipeOrderMissingButtonHtml + weekRecipeConsumeButtonHtml + "</h4>" ) ;
} ,
"eventRender" : function ( event , element )
{
element . removeClass ( "fc-event" ) ;
element . addClass ( "text-center" ) ;
element . attr ( "data-meal-plan-entry" , event . mealPlanEntry ) ;
2019-05-07 19:48:14 +02:00
2021-07-15 17:54:48 +02:00
var mealPlanEntry = JSON . parse ( event . mealPlanEntry ) ;
2019-05-07 19:48:14 +02:00
2021-07-15 17:54:48 +02:00
if ( sectionId != mealPlanEntry . section _id )
2020-01-23 20:59:19 +01:00
{
2021-07-15 17:54:48 +02:00
return false ;
2020-01-23 20:59:19 +01:00
}
2019-09-24 01:13:42 -05:00
2021-07-15 17:54:48 +02:00
var additionalTitleCssClasses = "" ;
2022-04-04 20:10:29 +02:00
var doneButtonHtml = '<a class="ml-1 btn btn-outline-secondary btn-xs mealplan-entry-done-button" href="#" data-toggle="tooltip" title="' + _ _t ( "Mark this item as done" ) + '" data-mealplan-entry-id="' + mealPlanEntry . id . toString ( ) + '"><i class="fa-solid fa-check"></i></a>' ;
2021-07-15 17:54:48 +02:00
if ( BoolVal ( mealPlanEntry . done ) )
2020-01-23 20:59:19 +01:00
{
2021-07-15 17:54:48 +02:00
additionalTitleCssClasses = "text-strike-through text-muted" ;
2022-04-04 20:10:29 +02:00
doneButtonHtml = '<a class="ml-1 btn btn-outline-secondary btn-xs mealplan-entry-undone-button" href="#" data-toggle="tooltip" title="' + _ _t ( "Mark this item as undone" ) + '" data-mealplan-entry-id="' + mealPlanEntry . id . toString ( ) + '"><i class="fa-solid fa-undo"></i></a>' ;
2020-01-23 20:59:19 +01:00
}
2021-07-15 17:54:48 +02:00
if ( event . type == "recipe" )
2020-01-23 20:59:19 +01:00
{
2021-07-15 17:54:48 +02:00
var recipe = JSON . parse ( event . recipe ) ;
if ( recipe === null || recipe === undefined )
{
return false ;
}
2020-01-23 20:59:19 +01:00
2022-04-21 21:32:28 +02:00
recipe . name = recipe . name . escapeHTML ( ) ;
2021-07-15 17:54:48 +02:00
var internalShadowRecipe = FindObjectInArrayByPropertyValue ( internalRecipes , "name" , mealPlanEntry . day + "#" + mealPlanEntry . id ) ;
var resolvedRecipe = FindObjectInArrayByPropertyValue ( recipesResolved , "recipe_id" , internalShadowRecipe . id ) ;
2020-12-21 20:13:49 +01:00
2021-07-15 17:54:48 +02:00
element . attr ( "data-recipe" , event . recipe ) ;
var recipeOrderMissingButtonDisabledClasses = "" ;
if ( resolvedRecipe . need _fulfilled _with _shopping _list == 1 )
{
recipeOrderMissingButtonDisabledClasses = "disabled" ;
}
var recipeConsumeButtonDisabledClasses = "" ;
if ( resolvedRecipe . need _fulfilled == 0 )
{
recipeConsumeButtonDisabledClasses = "disabled" ;
}
var fulfillmentInfoHtml = _ _t ( 'Enough in stock' ) ;
2022-04-04 20:10:29 +02:00
var fulfillmentIconHtml = '<i class="fa-solid fa-check text-success"></i>' ;
2021-07-15 17:54:48 +02:00
if ( resolvedRecipe . need _fulfilled != 1 )
{
fulfillmentInfoHtml = _ _t ( 'Not enough in stock' ) ;
2022-04-04 20:10:29 +02:00
var fulfillmentIconHtml = '<i class="fa-solid fa-times text-danger"></i>' ;
2021-07-15 17:54:48 +02:00
}
var costsAndCaloriesPerServing = ""
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _STOCK _PRICE _TRACKING )
{
2023-02-05 15:55:45 +01:00
costsAndCaloriesPerServing = '<h5 class="small text-truncate mb-1"><span class="locale-number locale-number-currency">' + resolvedRecipe . costs + '</span> / <span class="locale-number locale-number-generic">' + resolvedRecipe . calories / mealPlanEntry . recipe _servings + '</span> ' + Grocy . EnergyUnit + ' ' + _ _t ( 'per serving' ) + '</h5>' ;
2021-07-15 17:54:48 +02:00
}
else
{
2023-02-05 15:55:45 +01:00
costsAndCaloriesPerServing = '<h5 class="small text-truncate mb-1"><span class="locale-number locale-number-generic">' + resolvedRecipe . calories / mealPlanEntry . recipe _servings + '</span> ' + Grocy . EnergyUnit + ' ' + _ _t ( 'per serving' ) + '</h5>' ;
2021-07-15 17:54:48 +02:00
}
if ( ! Grocy . FeatureFlags . GROCY _FEATURE _FLAG _STOCK )
{
fulfillmentIconHtml = "" ;
fulfillmentInfoHtml = "" ;
}
var shoppingListButtonHtml = "" ;
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _SHOPPINGLIST )
{
2022-04-04 20:10:29 +02:00
shoppingListButtonHtml = '<a class="ml-1 btn btn-outline-primary btn-xs recipe-order-missing-button ' + recipeOrderMissingButtonDisabledClasses + '" href="#" data-toggle="tooltip" title="' + _ _t ( "Put missing products on shopping list" ) + '" data-recipe-id="' + recipe . id . toString ( ) + '" data-mealplan-servings="' + mealPlanEntry . recipe _servings + '" data-recipe-name="' + recipe . name + '" data-recipe-type="' + recipe . type + '"><i class="fa-solid fa-cart-plus"></i></a>' ;
2021-07-15 17:54:48 +02:00
}
2021-07-13 21:24:08 +02:00
2021-07-15 17:54:48 +02:00
element . html ( ' \
2020-01-23 20:59:19 +01:00
< div > \
2021-07-13 19:29:23 +02:00
< h5 class = "text-truncate mb-1 cursor-link display-recipe-button ' + additionalTitleCssClasses + '" data - toggle = "tooltip" title = "' + __t(" Display recipe ") + '" data - recipe - id = "' + recipe.id.toString() + '" data - recipe - name = "' + recipe.name + '" data - mealplan - servings = "' + mealPlanEntry.recipe_servings + '" data - recipe - type = "' + recipe.type + '" > ' + recipe.name + ' < / h 5 > \
< h5 class = "small text-truncate mb-1" > ' + __n(mealPlanEntry.recipe_servings, "%s serving", "%s servings") + ' < / h 5 > \
< h5 class = "small timeago-contextual text-truncate mb-1" > ' + fulfillmentIconHtml + " " + fulfillmentInfoHtml + ' < / h 5 > \
2020-01-23 20:59:19 +01:00
' + costsAndCaloriesPerServing + ' \
2021-08-06 20:18:43 +02:00
< h5 class = "d-print-none" > \
2022-04-04 20:10:29 +02:00
< a class = "ml-1 btn btn-outline-info btn-xs edit-meal-plan-entry-button" href = "#" data - toggle = "tooltip" title = "' + __t(" Edit this item ") + '" > < i class = "fa-solid fa-edit" > < / i > < / a > \
< a class = "btn btn-outline-danger btn-xs remove-recipe-button" href = "#" data - toggle = "tooltip" title = "' + __t(" Delete this item ") + '" > < i class = "fa-solid fa-trash" > < / i > < / a > \
2021-07-13 21:24:08 +02:00
' + shoppingListButtonHtml + ' \
2022-04-04 20:10:29 +02:00
< a class = "btn btn-outline-success btn-xs recipe-consume-button ' + recipeConsumeButtonDisabledClasses + '" href = "#" data - toggle = "tooltip" title = "' + __t(" Consume all ingredients needed by this recipe ") + '" data - recipe - id = "' + internalShadowRecipe.id.toString() + '" data - mealplan - entry - id = "' + mealPlanEntry.id.toString() + '" data - recipe - name = "' + recipe.name + '" data - recipe - type = "' + recipe.type + '" > < i class = "fa-solid fa-utensils" > < / i > < / a > \
2021-07-11 18:32:26 +02:00
' + doneButtonHtml + ' \
2020-01-23 20:59:19 +01:00
< / h 5 > \
< / d i v > ' ) ;
2020-01-21 22:44:04 +01:00
2023-02-06 20:22:10 +01:00
if ( recipe . picture _file _name )
2020-01-21 22:44:04 +01:00
{
2023-05-21 18:01:47 +02:00
element . prepend ( '<div class="mx-auto mb-1"><img src="' + U ( "/api/files/recipepictures/" ) + btoa ( recipe . picture _file _name ) + '?force_serve_as=picture&best_fit_width=400" class="img-fluid rounded-circle" loading="lazy"></div>' )
2020-01-21 22:44:04 +01:00
}
}
2021-07-15 17:54:48 +02:00
else if ( event . type == "product" )
2020-01-25 11:51:00 +01:00
{
2021-07-15 17:54:48 +02:00
var productDetails = JSON . parse ( event . productDetails ) ;
if ( productDetails === null || productDetails === undefined )
{
return false ;
}
2020-08-29 16:41:27 +02:00
2021-07-15 17:54:48 +02:00
if ( productDetails . last _price === null )
{
productDetails . last _price = 0 ;
}
2020-01-25 11:51:00 +01:00
2021-07-15 17:54:48 +02:00
element . attr ( "data-product-details" , event . productDetails ) ;
2020-01-25 19:42:46 +01:00
2021-07-15 17:54:48 +02:00
var productOrderMissingButtonDisabledClasses = "disabled" ;
2023-02-06 20:22:10 +01:00
if ( productDetails . stock _amount _aggregated < mealPlanEntry . product _amount )
2021-07-15 17:54:48 +02:00
{
productOrderMissingButtonDisabledClasses = "" ;
}
2020-01-25 11:51:00 +01:00
2021-07-15 17:54:48 +02:00
var productConsumeButtonDisabledClasses = "disabled" ;
2023-02-06 20:22:10 +01:00
if ( productDetails . stock _amount _aggregated >= mealPlanEntry . product _amount )
2021-07-15 17:54:48 +02:00
{
productConsumeButtonDisabledClasses = "" ;
}
2020-01-25 11:51:00 +01:00
2021-07-15 17:54:48 +02:00
fulfillmentInfoHtml = _ _t ( 'Not enough in stock' ) ;
2022-04-04 20:10:29 +02:00
var fulfillmentIconHtml = '<i class="fa-solid fa-times text-danger"></i>' ;
2023-02-06 20:22:10 +01:00
if ( productDetails . stock _amount _aggregated >= mealPlanEntry . product _amount )
2021-07-15 17:54:48 +02:00
{
var fulfillmentInfoHtml = _ _t ( 'Enough in stock' ) ;
2022-04-04 20:10:29 +02:00
var fulfillmentIconHtml = '<i class="fa-solid fa-check text-success"></i>' ;
2021-07-15 17:54:48 +02:00
}
2020-01-25 11:51:00 +01:00
2021-07-15 17:54:48 +02:00
var costsAndCaloriesPerServing = ""
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _STOCK _PRICE _TRACKING )
{
2023-02-05 15:55:45 +01:00
costsAndCaloriesPerServing = '<h5 class="small text-truncate mb-1"><span class="locale-number locale-number-currency">' + productDetails . last _price * mealPlanEntry . product _amount + '</span> / <span class="locale-number locale-number-generic">' + productDetails . product . calories + '</span> ' + Grocy . EnergyUnit + ' </h5>' ;
2021-07-15 17:54:48 +02:00
}
else
{
2023-02-05 15:55:45 +01:00
costsAndCaloriesPerServing = '<h5 class="small text-truncate mb-1"><span class="locale-number locale-number-generic">' + productDetails . product . calories + '</span> ' + Grocy . EnergyUnit + ' </h5>' ;
2021-07-15 17:54:48 +02:00
}
2020-01-25 11:51:00 +01:00
2021-07-15 17:54:48 +02:00
var shoppingListButtonHtml = "" ;
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _SHOPPINGLIST )
{
2022-04-04 20:10:29 +02:00
shoppingListButtonHtml = '<a class="btn btn-outline-primary btn-xs show-as-dialog-link ' + productOrderMissingButtonDisabledClasses + '" href="' + U ( "/shoppinglistitem/new?embedded&updateexistingproduct&product=" ) + mealPlanEntry . product _id + '&amount=' + mealPlanEntry . product _amount + '" data-toggle="tooltip" title="' + _ _t ( "Add to shopping list" ) + '" data-product-id="' + productDetails . product . id . toString ( ) + '" data-product-name="' + productDetails . product . name + '" data-product-amount="' + mealPlanEntry . product _amount + '"><i class="fa-solid fa-cart-plus"></i></a>' ;
2021-07-15 17:54:48 +02:00
}
2021-07-13 21:24:08 +02:00
2021-07-15 17:54:48 +02:00
element . html ( ' \
2020-01-25 11:51:00 +01:00
< div > \
2023-05-23 17:32:54 +02:00
< h5 class = "text-truncate mb-1 cursor-link productcard-trigger ' + additionalTitleCssClasses + '" data - toggle = "tooltip" title = "' + __t(" Display product ") + '" data - product - id = "' + productDetails.product.id.toString() + '" > ' + productDetails.product.name + ' < / h 5 > \
2022-02-06 21:09:34 +01:00
< h5 class = "small text-truncate mb-1" > < span class = "locale-number locale-number-quantity-amount" > ' + mealPlanEntry.product_amount + "</span> " + __n(mealPlanEntry.product_amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true) + ' < / h 5 > \
2021-07-13 19:29:23 +02:00
< h5 class = "small timeago-contextual text-truncate mb-1" > ' + fulfillmentIconHtml + " " + fulfillmentInfoHtml + ' < / h 5 > \
2020-01-25 11:51:00 +01:00
' + costsAndCaloriesPerServing + ' \
2021-08-06 20:18:43 +02:00
< h5 class = "d-print-none" > \
2022-04-04 20:10:29 +02:00
< a class = "ml-1 btn btn-outline-danger btn-xs remove-product-button" href = "#" data - toggle = "tooltip" title = "' + __t(" Delete this item ") + '" > < i class = "fa-solid fa-trash" > < / i > < / a > \
< a class = "btn btn-outline-info btn-xs edit-meal-plan-entry-button" href = "#" data - toggle = "tooltip" title = "' + __t(" Edit this item ") + '" > < i class = "fa-solid fa-edit" > < / i > < / a > \
2023-02-06 20:22:10 +01:00
< a class = "ml-1 btn btn-outline-success btn-xs product-consume-button ' + productConsumeButtonDisabledClasses + '" href = "#" data - toggle = "tooltip" title = "' + __t(" Consume % 1 $s of % 2 $s ", mealPlanEntry.product_amount.toLocaleString() + ' ' + __n(mealPlanEntry.product_amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true), productDetails.product.name) + '" data - product - id = "' + productDetails.product.id.toString() + '" data - product - name = "' + productDetails.product.name + '" data - product - amount = "' + mealPlanEntry.product_amount + '" data - mealplan - entry - id = "' + mealPlanEntry.id.toString() + '" > < i class = "fa-solid fa-utensils" > < / i > < / a > \
2021-07-13 21:24:08 +02:00
' + shoppingListButtonHtml + ' \
2021-07-11 18:32:26 +02:00
' + doneButtonHtml + ' \
2020-01-25 18:34:03 +01:00
< / h 5 > \
2020-01-25 11:51:00 +01:00
< / d i v > ' ) ;
2023-02-06 20:22:10 +01:00
if ( productDetails . product . picture _file _name )
2021-07-15 17:54:48 +02:00
{
2023-05-21 18:01:47 +02:00
element . prepend ( '<div class="mx-auto mb-1"><img src="' + U ( "/api/files/productpictures/" ) + btoa ( productDetails . product . picture _file _name ) + '?force_serve_as=picture&best_fit_width=400" class="img-fluid rounded-circle" loading="lazy"></div>' )
2021-07-15 17:54:48 +02:00
}
}
else if ( event . type == "note" )
2020-01-25 11:51:00 +01:00
{
2021-07-15 17:54:48 +02:00
element . html ( ' \
< div > \
< h5 class = "text-wrap text-break mb-1 ' + additionalTitleCssClasses + '" > ' + mealPlanEntry.note + ' < / h 5 > \
2021-08-06 20:18:43 +02:00
< h5 class = "d-print-none" > \
2022-04-04 20:10:29 +02:00
< a class = "ml-1 btn btn-outline-danger btn-xs remove-note-button" href = "#" data - toggle = "tooltip" title = "' + __t(" Delete this item ") + '" > < i class = "fa-solid fa-trash" > < / i > < / a > \
< a class = "btn btn-outline-info btn-xs edit-meal-plan-entry-button" href = "#" data - toggle = "tooltip" title = "' + __t(" Edit this item ") + '" > < i class = "fa-solid fa-edit" > < / i > < / a > \
2021-07-15 17:54:48 +02:00
' + doneButtonHtml + ' \
< / h 5 > \
< / d i v > ' ) ;
2020-01-25 11:51:00 +01:00
}
var dayRecipeName = event . start . format ( "YYYY-MM-DD" ) ;
if ( ! $ ( "#day-summary-" + dayRecipeName ) . length ) // This runs for every event/recipe, so maybe multiple times per day, so only add the day summary once
{
var dayRecipe = FindObjectInArrayByPropertyValue ( internalRecipes , "name" , dayRecipeName ) ;
if ( dayRecipe != null )
{
var dayRecipeResolved = FindObjectInArrayByPropertyValue ( recipesResolved , "recipe_id" , dayRecipe . id ) ;
var costsAndCaloriesPerDay = ""
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _STOCK _PRICE _TRACKING )
{
2023-02-05 15:55:45 +01:00
costsAndCaloriesPerDay = '<h5 class="small text-truncate"><span class="locale-number locale-number-currency">' + dayRecipeResolved . costs + '</span> / <span class="locale-number locale-number-generic">' + dayRecipeResolved . calories + '</span> ' + Grocy . EnergyUnit + ' ' + _ _t ( 'per day' ) + '</h5>' ;
2020-01-25 11:51:00 +01:00
}
else
{
2023-02-05 15:55:45 +01:00
costsAndCaloriesPerDay = '<h5 class="small text-truncate"><span class="locale-number locale-number-generic">' + dayRecipeResolved . calories + '</span> ' + Grocy . EnergyUnit + ' ' + _ _t ( 'per day' ) + '</h5>' ;
2020-01-25 11:51:00 +01:00
}
2021-07-15 17:54:48 +02:00
$ ( ".calendar[data-primary-section='true'] .fc-day-header[data-date='" + dayRecipeName + "']" ) . append ( '<h5 id="day-summary-' + dayRecipeName + '" class="small text-truncate border-top pt-1 pb-0">' + costsAndCaloriesPerDay + '</h5>' ) ;
2020-01-25 11:51:00 +01:00
}
}
2021-07-15 17:54:48 +02:00
} ,
"eventAfterAllRender" : function ( view )
2020-01-23 20:59:19 +01:00
{
2021-07-15 17:54:48 +02:00
if ( isPrimarySection )
{
2021-07-16 17:32:08 +02:00
UpdateUriParam ( "start" , view . start . format ( "YYYY-MM-DD" ) ) ;
2019-07-06 14:48:46 +02:00
2022-02-08 18:08:26 +01:00
if ( view . name == "agendaDay" )
{
UpdateUriParam ( "days" , "0" ) ;
}
else
{
RemoveUriParam ( "days" ) ;
}
2021-07-15 17:54:48 +02:00
if ( firstRender )
{
firstRender = false
}
else
{
$ ( ".calendar" ) . addClass ( "d-none" ) ;
window . location . reload ( ) ;
return false ;
}
}
if ( isLastSection )
{
$ ( ".fc-axis span" ) . replaceWith ( function ( )
{
return $ ( "<div />" , { html : $ ( this ) . html ( ) } ) ;
} ) ;
2020-12-21 20:13:49 +01:00
2021-07-15 17:54:48 +02:00
RefreshLocaleNumberDisplay ( ) ;
$ ( '[data-toggle="tooltip"]' ) . tooltip ( ) ;
2021-07-10 22:56:39 +02:00
2021-07-15 17:54:48 +02:00
if ( ! Grocy . FeatureFlags . GROCY _FEATURE _FLAG _STOCK )
{
$ ( ".recipe-order-missing-button" ) . addClass ( "d-none" ) ;
$ ( ".recipe-consume-button" ) . addClass ( "d-none" ) ;
}
}
2020-12-21 20:13:49 +01:00
}
2021-07-15 17:54:48 +02:00
} ) ;
2019-05-06 19:38:47 +02:00
} ) ;
$ ( document ) . on ( "click" , ".add-recipe-button" , function ( e )
{
2020-01-23 20:59:19 +01:00
var day = $ ( this ) . parent ( ) . parent ( ) . data ( "date" ) ;
2019-05-06 19:38:47 +02:00
2022-04-03 19:08:36 +02:00
$ ( "#add-recipe-modal-title" ) . text ( _ _t ( "Add meal plan entry" ) ) ;
2022-04-03 17:03:23 +02:00
$ ( ".datetimepicker-wrapper" ) . detach ( ) . prependTo ( "#add-recipe-form" ) ;
$ ( "input#day" ) . detach ( ) . appendTo ( "#add-recipe-form" ) ;
Grocy . Components . DateTimePicker . Init ( true ) ;
Grocy . Components . DateTimePicker . SetValue ( day ) ;
2019-05-06 19:38:47 +02:00
Grocy . Components . RecipePicker . Clear ( ) ;
2021-07-15 17:54:48 +02:00
$ ( "#section_id_note" ) . val ( - 1 ) ;
2019-05-06 19:38:47 +02:00
$ ( "#add-recipe-modal" ) . modal ( "show" ) ;
Grocy . FrontendHelpers . ValidateForm ( "add-recipe-form" ) ;
2020-02-09 17:15:13 +01:00
Grocy . IsMealPlanEntryEditAction = false ;
2019-05-06 19:38:47 +02:00
} ) ;
2020-01-23 20:59:19 +01:00
$ ( document ) . on ( "click" , ".add-note-button" , function ( e )
{
var day = $ ( this ) . parent ( ) . parent ( ) . parent ( ) . data ( "date" ) ;
2022-04-03 19:08:36 +02:00
$ ( "#add-note-modal-title" ) . text ( _ _t ( "Add meal plan entry" ) ) ;
2022-04-03 17:03:23 +02:00
$ ( ".datetimepicker-wrapper" ) . detach ( ) . prependTo ( "#add-note-form" ) ;
$ ( "input#day" ) . detach ( ) . appendTo ( "#add-note-form" )
Grocy . Components . DateTimePicker . Init ( true ) ;
Grocy . Components . DateTimePicker . SetValue ( day ) ;
2020-01-23 20:59:19 +01:00
$ ( "#note" ) . val ( "" ) ;
2021-07-15 17:54:48 +02:00
$ ( "#section_id_note" ) . val ( - 1 ) ;
2020-01-23 20:59:19 +01:00
$ ( "#add-note-modal" ) . modal ( "show" ) ;
Grocy . FrontendHelpers . ValidateForm ( "add-note-form" ) ;
2020-02-09 17:15:13 +01:00
Grocy . IsMealPlanEntryEditAction = false ;
2020-01-23 20:59:19 +01:00
} ) ;
2020-01-25 11:51:00 +01:00
$ ( document ) . on ( "click" , ".add-product-button" , function ( e )
{
var day = $ ( this ) . parent ( ) . parent ( ) . parent ( ) . data ( "date" ) ;
2022-04-03 19:08:36 +02:00
$ ( "#add-product-modal-title" ) . text ( _ _t ( "Add meal plan entry" ) ) ;
2022-04-03 17:03:23 +02:00
$ ( ".datetimepicker-wrapper" ) . detach ( ) . prependTo ( "#add-product-form" ) ;
$ ( "input#day" ) . detach ( ) . appendTo ( "#add-product-form" )
Grocy . Components . DateTimePicker . Init ( true ) ;
Grocy . Components . DateTimePicker . SetValue ( day ) ;
2020-01-25 11:51:00 +01:00
Grocy . Components . ProductPicker . Clear ( ) ;
2021-07-15 17:54:48 +02:00
$ ( "#section_id_note" ) . val ( - 1 ) ;
2020-01-25 11:51:00 +01:00
$ ( "#add-product-modal" ) . modal ( "show" ) ;
Grocy . FrontendHelpers . ValidateForm ( "add-product-form" ) ;
2020-02-09 17:15:13 +01:00
Grocy . IsMealPlanEntryEditAction = false ;
} ) ;
2020-08-30 12:18:16 +02:00
$ ( document ) . on ( "click" , ".edit-meal-plan-entry-button" , function ( e )
2020-02-09 17:15:13 +01:00
{
var mealPlanEntry = JSON . parse ( $ ( this ) . parents ( ".fc-h-event:first" ) . attr ( "data-meal-plan-entry" ) ) ;
if ( mealPlanEntry . type == "recipe" )
{
2022-04-03 17:03:23 +02:00
$ ( ".datetimepicker-wrapper" ) . detach ( ) . prependTo ( "#add-recipe-form" ) ;
$ ( "input#day" ) . detach ( ) . appendTo ( "#add-recipe-form" )
Grocy . Components . DateTimePicker . Init ( true ) ;
Grocy . Components . DateTimePicker . SetValue ( mealPlanEntry . day ) ;
2022-04-03 19:08:36 +02:00
$ ( "#add-recipe-modal-title" ) . text ( _ _t ( "Edit meal plan entry" ) ) ;
2020-02-09 17:15:13 +01:00
$ ( "#recipe_servings" ) . val ( mealPlanEntry . recipe _servings ) ;
Grocy . Components . RecipePicker . SetId ( mealPlanEntry . recipe _id ) ;
$ ( "#add-recipe-modal" ) . modal ( "show" ) ;
2021-07-15 17:54:48 +02:00
$ ( "#section_id_recipe" ) . val ( mealPlanEntry . section _id ) ;
2020-02-09 17:15:13 +01:00
Grocy . FrontendHelpers . ValidateForm ( "add-recipe-form" ) ;
}
else if ( mealPlanEntry . type == "product" )
{
2022-04-03 17:03:23 +02:00
$ ( ".datetimepicker-wrapper" ) . detach ( ) . prependTo ( "#add-product-form" ) ;
$ ( "input#day" ) . detach ( ) . appendTo ( "#add-product-form" )
Grocy . Components . DateTimePicker . Init ( true ) ;
Grocy . Components . DateTimePicker . SetValue ( mealPlanEntry . day ) ;
2022-04-03 19:08:36 +02:00
$ ( "#add-product-modal-title" ) . text ( _ _t ( "Edit meal plan entry" ) ) ;
2020-02-09 17:15:13 +01:00
Grocy . Components . ProductPicker . SetId ( mealPlanEntry . product _id ) ;
$ ( "#add-product-modal" ) . modal ( "show" ) ;
2021-07-15 17:54:48 +02:00
$ ( "#section_id_product" ) . val ( mealPlanEntry . section _id ) ;
2020-02-09 17:15:13 +01:00
Grocy . FrontendHelpers . ValidateForm ( "add-product-form" ) ;
Grocy . Components . ProductPicker . GetPicker ( ) . trigger ( "change" ) ;
}
else if ( mealPlanEntry . type == "note" )
{
2022-04-03 17:03:23 +02:00
$ ( ".datetimepicker-wrapper" ) . detach ( ) . prependTo ( "#add-note-form" ) ;
$ ( "input#day" ) . detach ( ) . appendTo ( "#add-note-form" ) ;
Grocy . Components . DateTimePicker . Init ( true ) ;
Grocy . Components . DateTimePicker . SetValue ( mealPlanEntry . day ) ;
2022-04-03 19:08:36 +02:00
$ ( "#add-note-modal-title" ) . text ( _ _t ( "Edit meal plan entry" ) ) ;
2020-02-09 17:15:13 +01:00
$ ( "#note" ) . val ( mealPlanEntry . note ) ;
$ ( "#add-note-modal" ) . modal ( "show" ) ;
2021-07-15 17:54:48 +02:00
$ ( "#section_id_note" ) . val ( mealPlanEntry . section _id ) ;
2020-02-09 17:15:13 +01:00
Grocy . FrontendHelpers . ValidateForm ( "add-note-form" ) ;
}
Grocy . IsMealPlanEntryEditAction = true ;
2022-01-23 12:53:21 +01:00
Grocy . MealPlanEntryEditObject = mealPlanEntry ;
2020-01-25 11:51:00 +01:00
} ) ;
2021-07-12 20:44:42 +02:00
$ ( document ) . on ( "click" , ".copy-day-button" , function ( e )
{
var day = $ ( this ) . parent ( ) . parent ( ) . parent ( ) . data ( "date" ) ;
$ ( "#copy-day-modal-title" ) . text ( _ _t ( "Copy all meal plan entries of %s" , day . toString ( ) ) ) ;
2022-04-03 17:03:23 +02:00
Grocy . Components . DateTimePicker . SetValue ( day ) ;
Grocy . Components . DateTimePicker2 . Clear ( ) ;
2021-07-12 20:44:42 +02:00
$ ( "#copy-day-modal" ) . modal ( "show" ) ;
Grocy . FrontendHelpers . ValidateForm ( "copy-day-form" ) ;
Grocy . IsMealPlanEntryEditAction = false ;
} ) ;
2019-05-06 19:38:47 +02:00
$ ( "#add-recipe-modal" ) . on ( "shown.bs.modal" , function ( e )
{
2022-02-11 18:18:17 +01:00
if ( ! Grocy . FeatureFlags . GROCY _FEATURE _FLAG _DISABLE _BROWSER _BARCODE _CAMERA _SCANNING )
{
Grocy . Components . BarcodeScanner . Init ( ) ;
}
2019-05-06 19:38:47 +02:00
Grocy . Components . RecipePicker . GetInputElement ( ) . focus ( ) ;
2023-05-23 20:31:51 +02:00
} ) ;
2019-05-06 19:38:47 +02:00
2020-08-30 12:18:16 +02:00
$ ( "#add-note-modal" ) . on ( "shown.bs.modal" , function ( e )
2020-01-23 20:59:19 +01:00
{
$ ( "#note" ) . focus ( ) ;
2023-05-23 20:31:51 +02:00
} ) ;
2020-01-23 20:59:19 +01:00
2020-08-30 12:18:16 +02:00
$ ( "#add-product-modal" ) . on ( "shown.bs.modal" , function ( e )
2020-01-25 11:51:00 +01:00
{
2022-02-11 18:18:17 +01:00
if ( ! Grocy . FeatureFlags . GROCY _FEATURE _FLAG _DISABLE _BROWSER _BARCODE _CAMERA _SCANNING )
{
Grocy . Components . BarcodeScanner . Init ( ) ;
}
2020-01-25 11:51:00 +01:00
Grocy . Components . ProductPicker . GetInputElement ( ) . focus ( ) ;
2023-05-23 20:31:51 +02:00
} ) ;
2020-01-25 11:51:00 +01:00
2021-07-12 20:44:42 +02:00
$ ( "#copy-day-modal" ) . on ( "shown.bs.modal" , function ( e )
{
2022-04-03 17:03:23 +02:00
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . focus ( ) ;
2023-05-23 20:31:51 +02:00
} ) ;
2021-07-12 20:44:42 +02:00
2020-01-25 11:51:00 +01:00
$ ( document ) . on ( "click" , ".remove-recipe-button, .remove-note-button, .remove-product-button" , function ( e )
2019-05-06 19:38:47 +02:00
{
2019-06-09 09:10:29 +02:00
var mealPlanEntry = JSON . parse ( $ ( this ) . parents ( ".fc-h-event:first" ) . attr ( "data-meal-plan-entry" ) ) ;
2019-05-06 19:38:47 +02:00
2020-08-30 12:18:16 +02:00
Grocy . Api . Delete ( 'objects/meal_plan/' + mealPlanEntry . id . toString ( ) , { } ,
2019-05-06 19:38:47 +02:00
function ( result )
{
2019-07-06 13:55:29 +02:00
window . location . reload ( ) ;
2019-05-06 19:38:47 +02:00
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
} ) ;
2020-01-25 11:51:00 +01:00
$ ( '#save-add-recipe-button' ) . on ( 'click' , function ( e )
2020-01-23 20:59:19 +01:00
{
2020-01-25 11:51:00 +01:00
e . preventDefault ( ) ;
2020-01-23 20:59:19 +01:00
2022-04-03 17:03:23 +02:00
if ( ! Grocy . FrontendHelpers . ValidateForm ( "add-recipe-form" , true ) || $ ( ".combobox-menu-visible" ) . length )
2020-01-25 11:51:00 +01:00
{
return false ;
}
2021-07-15 17:54:48 +02:00
var formData = $ ( '#add-recipe-form' ) . serializeJSON ( ) ;
formData . section _id = formData . section _id _recipe ;
delete formData . section _id _recipe ;
2022-04-03 17:03:23 +02:00
formData . day = Grocy . Components . DateTimePicker . GetValue ( ) ;
2021-07-15 17:54:48 +02:00
2020-02-09 17:15:13 +01:00
if ( Grocy . IsMealPlanEntryEditAction )
{
2022-01-23 12:53:21 +01:00
Grocy . Api . Put ( 'objects/meal_plan/' + Grocy . MealPlanEntryEditObject . id , formData ,
2020-02-09 17:15:13 +01:00
function ( result )
{
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
}
else
{
2021-07-15 17:54:48 +02:00
Grocy . Api . Post ( 'objects/meal_plan' , formData ,
2020-02-09 17:15:13 +01:00
function ( result )
{
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
}
2020-01-23 20:59:19 +01:00
} ) ;
2020-01-25 11:51:00 +01:00
$ ( '#save-add-note-button' ) . on ( 'click' , function ( e )
2019-05-06 19:38:47 +02:00
{
e . preventDefault ( ) ;
2022-04-03 17:03:23 +02:00
if ( ! Grocy . FrontendHelpers . ValidateForm ( "add-note-form" , true ) || $ ( ".combobox-menu-visible" ) . length )
2019-05-06 19:38:47 +02:00
{
return false ;
}
2020-01-25 11:51:00 +01:00
var jsonData = $ ( '#add-note-form' ) . serializeJSON ( ) ;
2022-04-03 17:03:23 +02:00
jsonData . day = Grocy . Components . DateTimePicker . GetValue ( ) ;
2021-07-15 20:11:49 +02:00
jsonData . section _id = jsonData . section _id _note ;
delete jsonData . section _id _note ;
2020-02-09 17:15:13 +01:00
if ( Grocy . IsMealPlanEntryEditAction )
{
2022-01-23 12:53:21 +01:00
Grocy . Api . Put ( 'objects/meal_plan/' + Grocy . MealPlanEntryEditObject . id , jsonData ,
2020-02-09 17:15:13 +01:00
function ( result )
{
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
}
else
{
Grocy . Api . Post ( 'objects/meal_plan' , jsonData ,
function ( result )
{
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
}
2020-08-29 16:41:27 +02:00
2019-05-06 19:38:47 +02:00
} ) ;
2020-01-25 11:51:00 +01:00
$ ( '#save-add-product-button' ) . on ( 'click' , function ( e )
2020-01-23 20:59:19 +01:00
{
e . preventDefault ( ) ;
2022-04-03 17:03:23 +02:00
if ( ! Grocy . FrontendHelpers . ValidateForm ( "add-product-form" , true ) || $ ( ".combobox-menu-visible" ) . length )
2020-01-23 20:59:19 +01:00
{
return false ;
}
2020-01-25 11:51:00 +01:00
var jsonData = $ ( '#add-product-form' ) . serializeJSON ( ) ;
2022-04-03 19:14:54 +02:00
jsonData . day = Grocy . Components . DateTimePicker . GetValue ( ) ;
2020-01-25 11:51:00 +01:00
delete jsonData . display _amount ;
jsonData . product _amount = jsonData . amount ;
delete jsonData . amount ;
2022-04-03 19:14:54 +02:00
jsonData . product _qu _id = $ ( "#qu_id" ) . val ( ) ;
2020-01-25 11:51:00 +01:00
delete jsonData . qu _id ;
2021-07-15 17:54:48 +02:00
jsonData . section _id = jsonData . section _id _product ;
delete jsonData . section _id _product ;
2020-02-09 17:15:13 +01:00
if ( Grocy . IsMealPlanEntryEditAction )
{
2022-01-23 12:53:21 +01:00
Grocy . Api . Put ( 'objects/meal_plan/' + Grocy . MealPlanEntryEditObject . id , jsonData ,
2020-08-30 12:18:16 +02:00
function ( result )
2020-02-09 17:15:13 +01:00
{
window . location . reload ( ) ;
} ,
2020-08-30 12:18:16 +02:00
function ( xhr )
2020-02-09 17:15:13 +01:00
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
}
else
{
Grocy . Api . Post ( 'objects/meal_plan' , jsonData ,
function ( result )
{
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
}
2020-01-23 20:59:19 +01:00
} ) ;
2021-07-12 20:44:42 +02:00
var itemsToCopy = 0 ;
var itemsCopied = 0 ;
$ ( '#save-copy-day-button' ) . on ( 'click' , function ( e )
{
e . preventDefault ( ) ;
2022-03-26 10:34:00 +01:00
if ( ! Grocy . FrontendHelpers . ValidateForm ( "copy-day-form" , true ) )
2021-07-12 20:44:42 +02:00
{
return false ;
}
2022-04-03 17:03:23 +02:00
var dayFrom = Grocy . Components . DateTimePicker . GetValue ( ) ;
var dayTo = Grocy . Components . DateTimePicker2 . GetValue ( ) ;
2021-07-12 20:44:42 +02:00
Grocy . Api . Get ( 'objects/meal_plan?query[]=day=' + dayFrom ,
function ( sourceMealPlanEntries )
{
itemsToCopy = sourceMealPlanEntries . length ;
sourceMealPlanEntries . forEach ( ( item ) =>
{
item . day = dayTo ;
item . done = 0 ;
delete item . id ;
delete item . row _created _timestamp ;
Grocy . Api . Post ( "objects/meal_plan" , item ,
function ( result )
{
itemsCopied ++ ;
if ( itemsCopied == itemsToCopy )
{
window . location . reload ( ) ;
}
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response ) ;
}
) ;
} ) ;
//window.location.reload();
} ,
function ( xhr )
{
console . error ( xhr ) ;
}
) ;
} ) ;
2020-08-30 12:18:16 +02:00
$ ( '#add-recipe-form input' ) . keydown ( function ( event )
2019-05-06 19:38:47 +02:00
{
2022-03-30 18:00:28 +02:00
if ( event . keyCode === 13 ) // Enter
2019-05-06 19:38:47 +02:00
{
event . preventDefault ( ) ;
2022-03-30 18:00:28 +02:00
if ( ! Grocy . FrontendHelpers . ValidateForm ( 'add-recipe-form' ) )
2019-05-06 19:38:47 +02:00
{
return false ;
}
else
{
$ ( "#save-add-recipe-button" ) . click ( ) ;
}
}
} ) ;
2019-05-07 19:48:14 +02:00
2020-08-30 12:18:16 +02:00
$ ( '#add-product-form input' ) . keydown ( function ( event )
2020-02-03 20:04:22 +01:00
{
2022-03-30 18:00:28 +02:00
if ( event . keyCode === 13 ) // Enter
2020-02-03 20:04:22 +01:00
{
event . preventDefault ( ) ;
2022-03-30 18:00:28 +02:00
if ( ! Grocy . FrontendHelpers . ValidateForm ( 'add-product-form' ) )
2020-02-03 20:04:22 +01:00
{
return false ;
}
else
{
$ ( "#save-add-product-button" ) . click ( ) ;
}
}
} ) ;
2020-01-25 11:02:50 -06:00
$ ( document ) . on ( "keydown" , "#servings" , function ( e )
2019-05-07 19:48:14 +02:00
{
2022-03-30 18:00:28 +02:00
if ( e . keyCode === 13 ) // Enter
2019-05-07 19:48:14 +02:00
{
2022-03-26 10:34:00 +01:00
e . preventDefault ( ) ;
2019-05-07 19:48:14 +02:00
2022-03-30 18:00:28 +02:00
if ( ! Grocy . FrontendHelpers . ValidateForm ( 'add-recipe-form' ) )
2019-05-07 19:48:14 +02:00
{
return false ;
}
else
{
$ ( "#save-add-recipe-button" ) . click ( ) ;
}
}
} ) ;
$ ( document ) . on ( 'click' , '.recipe-order-missing-button' , function ( e )
{
2023-05-03 08:32:49 +02:00
$ ( ".tooltip" ) . tooltip ( "hide" ) ;
2020-08-29 16:41:27 +02:00
2020-10-14 22:58:26 +02:00
var objectName = $ ( e . currentTarget ) . attr ( 'data-recipe-name' ) ;
2019-05-07 19:48:14 +02:00
var objectId = $ ( e . currentTarget ) . attr ( 'data-recipe-id' ) ;
var button = $ ( this ) ;
2020-02-09 14:43:31 -06:00
var servings = $ ( e . currentTarget ) . attr ( 'data-mealplan-servings' ) ;
2019-05-07 19:48:14 +02:00
bootbox . confirm ( {
message : _ _t ( 'Are you sure to put all missing ingredients for recipe "%s" on the shopping list?' , objectName ) ,
2019-09-24 10:24:47 +02:00
closeButton : false ,
2019-05-07 19:48:14 +02:00
buttons : {
confirm : {
label : _ _t ( 'Yes' ) ,
className : 'btn-success'
} ,
cancel : {
label : _ _t ( 'No' ) ,
className : 'btn-danger'
}
} ,
callback : function ( result )
{
if ( result === true )
{
Grocy . FrontendHelpers . BeginUiBusy ( ) ;
2020-02-09 21:50:56 +01:00
// Set the recipes desired_servings so that the "recipes resolved"-views resolve correctly based on the meal plan entry servings
2020-08-30 12:18:16 +02:00
Grocy . Api . Put ( 'objects/recipes/' + objectId , { "desired_servings" : servings } ,
2020-02-09 14:43:31 -06:00
function ( result )
{
2020-08-30 12:18:16 +02:00
Grocy . Api . Post ( 'recipes/' + objectId + '/add-not-fulfilled-products-to-shoppinglist' , { } ,
2020-02-09 21:50:56 +01:00
function ( result )
{
if ( button . attr ( "data-recipe-type" ) == "normal" )
{
button . addClass ( "disabled" ) ;
Grocy . FrontendHelpers . EndUiBusy ( ) ;
}
else
{
window . location . reload ( ) ;
}
} ,
function ( xhr )
{
Grocy . FrontendHelpers . EndUiBusy ( ) ;
console . error ( xhr ) ;
}
) ;
2020-02-09 14:43:31 -06:00
} ,
function ( xhr )
{
console . error ( xhr ) ;
}
) ;
2019-05-07 19:48:14 +02:00
}
}
} ) ;
} ) ;
2019-07-06 20:02:40 +02:00
2020-01-25 11:02:50 -06:00
$ ( document ) . on ( 'click' , '.product-consume-button' , function ( e )
{
e . preventDefault ( ) ;
2023-05-03 08:32:49 +02:00
$ ( ".tooltip" ) . tooltip ( "hide" ) ;
2020-01-25 11:02:50 -06:00
Grocy . FrontendHelpers . BeginUiBusy ( ) ;
var productId = $ ( e . currentTarget ) . attr ( 'data-product-id' ) ;
2023-02-06 20:22:10 +01:00
var consumeAmount = Number . parseFloat ( $ ( e . currentTarget ) . attr ( 'data-product-amount' ) ) ;
2021-07-11 18:32:26 +02:00
var mealPlanEntryId = $ ( e . currentTarget ) . attr ( 'data-mealplan-entry-id' ) ;
2020-01-25 11:02:50 -06:00
2020-08-30 12:18:16 +02:00
Grocy . Api . Post ( 'stock/products/' + productId + '/consume' , { 'amount' : consumeAmount , 'spoiled' : false } ,
2020-01-25 11:02:50 -06:00
function ( bookingResponse )
{
Grocy . Api . Get ( 'stock/products/' + productId ,
2020-08-30 12:18:16 +02:00
function ( result )
2020-01-25 11:02:50 -06:00
{
2022-04-04 20:10:29 +02:00
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 , true ) , result . product . name ) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + bookingResponse [ 0 ] . transaction _id + '\')"><i class="fa-solid fa-undo"></i> ' + _ _t ( "Undo" ) + '</a>' ;
2020-01-25 11:02:50 -06:00
2021-07-11 18:32:26 +02:00
Grocy . Api . Put ( 'objects/meal_plan/' + mealPlanEntryId , { "done" : 1 } ,
function ( result )
{
Grocy . FrontendHelpers . EndUiBusy ( ) ;
toastr . success ( toastMessage ) ;
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
2020-01-25 11:02:50 -06:00
} ,
function ( xhr )
{
Grocy . FrontendHelpers . EndUiBusy ( ) ;
console . error ( xhr ) ;
}
) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . EndUiBusy ( ) ;
console . error ( xhr ) ;
}
) ;
} ) ;
2019-07-06 20:02:40 +02:00
$ ( document ) . on ( 'click' , '.recipe-consume-button' , function ( e )
{
2023-05-03 08:32:49 +02:00
$ ( ".tooltip" ) . tooltip ( "hide" ) ;
2019-09-26 13:14:24 +02:00
2020-10-14 22:58:26 +02:00
var objectName = $ ( e . currentTarget ) . attr ( 'data-recipe-name' ) ;
2019-07-06 20:02:40 +02:00
var objectId = $ ( e . currentTarget ) . attr ( 'data-recipe-id' ) ;
2021-07-11 18:32:26 +02:00
var mealPlanEntryId = $ ( e . currentTarget ) . attr ( 'data-mealplan-entry-id' ) ;
2019-09-24 01:13:42 -05:00
2019-07-06 20:02:40 +02:00
bootbox . confirm ( {
2020-12-19 14:03:28 +01:00
message : _ _t ( 'Are you sure to consume all ingredients needed by recipe "%s" (ingredients marked with "only check if any amount is in stock" will be ignored)?' , objectName ) ,
2019-09-24 10:24:47 +02:00
closeButton : false ,
2019-07-06 20:02:40 +02:00
buttons : {
confirm : {
label : _ _t ( 'Yes' ) ,
className : 'btn-success'
} ,
cancel : {
label : _ _t ( 'No' ) ,
className : 'btn-danger'
}
} ,
callback : function ( result )
{
if ( result === true )
{
Grocy . FrontendHelpers . BeginUiBusy ( ) ;
2021-07-11 18:32:26 +02:00
Grocy . Api . Post ( 'recipes/' + objectId + '/consume' , { } ,
2019-07-06 20:02:40 +02:00
function ( result )
{
2021-07-11 18:32:26 +02:00
Grocy . Api . Put ( 'objects/meal_plan/' + mealPlanEntryId , { "done" : 1 } ,
2020-02-09 21:50:56 +01:00
function ( result )
{
Grocy . FrontendHelpers . EndUiBusy ( ) ;
toastr . success ( _ _t ( 'Removed all ingredients of recipe "%s" from stock' , objectName ) ) ;
2020-02-11 19:24:34 +01:00
window . location . reload ( ) ;
2020-02-09 21:50:56 +01:00
} ,
function ( xhr )
{
2021-07-11 18:32:26 +02:00
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
2020-02-09 21:50:56 +01:00
}
) ;
2019-07-06 20:02:40 +02:00
} ,
function ( xhr )
{
2021-07-11 18:32:26 +02:00
toastr . warning ( _ _t ( 'Not all ingredients of recipe "%s" are in stock, nothing removed' , objectName ) ) ;
Grocy . FrontendHelpers . EndUiBusy ( ) ;
2019-07-06 20:02:40 +02:00
console . error ( xhr ) ;
}
) ;
}
}
} ) ;
} ) ;
2019-09-24 01:13:42 -05:00
2021-07-13 19:29:23 +02:00
$ ( document ) . on ( "click" , ".display-recipe-button" , function ( e )
2019-09-24 01:13:42 -05:00
{
2023-05-03 08:32:49 +02:00
$ ( ".tooltip" ) . tooltip ( "hide" ) ;
2019-09-26 13:14:24 +02:00
2019-09-24 01:13:42 -05:00
var objectId = $ ( e . currentTarget ) . attr ( 'data-recipe-id' ) ;
2020-02-09 14:43:31 -06:00
var servings = $ ( e . currentTarget ) . attr ( 'data-mealplan-servings' ) ;
2020-02-09 21:50:56 +01:00
// Set the recipes desired_servings so that the "recipes resolved"-views resolve correctly based on the meal plan entry servings
Grocy . Api . Put ( 'objects/recipes/' + objectId , { "desired_servings" : servings } ,
2020-02-09 14:43:31 -06:00
function ( result )
{
2020-02-09 21:50:56 +01:00
bootbox . dialog ( {
2023-05-21 18:01:47 +02:00
message : '<iframe height="650px" class="embed-responsive" src="' + U ( "/recipes?embedded&recipe=" ) + objectId + '#fullscreen" loading="lazy"></iframe>' ,
2020-02-09 21:50:56 +01:00
size : 'extra-large' ,
backdrop : true ,
closeButton : false ,
buttons : {
cancel : {
label : _ _t ( 'Close' ) ,
className : 'btn-secondary responsive-button' ,
2020-08-30 12:18:16 +02:00
callback : function ( )
2020-02-09 21:50:56 +01:00
{
bootbox . hideAll ( ) ;
}
}
}
} ) ;
2020-02-09 14:43:31 -06:00
} ,
function ( xhr )
{
console . error ( xhr ) ;
}
) ;
2019-09-24 01:13:42 -05:00
} ) ;
2019-09-24 09:21:57 +02:00
2021-07-11 18:32:26 +02:00
$ ( document ) . on ( "click" , ".mealplan-entry-done-button" , function ( e )
{
e . preventDefault ( ) ;
2023-05-03 08:32:49 +02:00
$ ( ".tooltip" ) . tooltip ( "hide" ) ;
2021-07-11 18:32:26 +02:00
var mealPlanEntryId = $ ( e . currentTarget ) . attr ( "data-mealplan-entry-id" ) ;
Grocy . Api . Put ( "objects/meal_plan/" + mealPlanEntryId , { "done" : 1 } ,
function ( result )
{
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
} ) ;
$ ( document ) . on ( "click" , ".mealplan-entry-undone-button" , function ( e )
{
e . preventDefault ( ) ;
2023-05-03 08:32:49 +02:00
$ ( ".tooltip" ) . tooltip ( "hide" ) ;
2021-07-11 18:32:26 +02:00
var mealPlanEntryId = $ ( e . currentTarget ) . attr ( "data-mealplan-entry-id" ) ;
Grocy . Api . Put ( "objects/meal_plan/" + mealPlanEntryId , { "done" : 0 } ,
function ( result )
{
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
} ) ;
2020-12-16 17:26:39 +01:00
$ ( window ) . one ( "resize" , function ( )
2019-09-24 09:21:57 +02:00
{
2021-07-15 17:54:48 +02:00
// Automatically switch the calendar to "agendaDay" view on small screens and to "agendaWeek" otherwise
var windowWidth = $ ( window ) . width ( ) ;
$ ( ".calendar" ) . each ( function ( )
2019-09-24 09:21:57 +02:00
{
2021-07-15 17:54:48 +02:00
if ( windowWidth < 768 )
{
$ ( this ) . fullCalendar ( "changeView" , "agendaDay" ) ;
}
else
{
$ ( this ) . fullCalendar ( "changeView" , "agendaWeek" ) ;
}
} ) ;
2019-09-24 09:21:57 +02:00
} ) ;
2020-01-25 11:51:00 +01:00
Grocy . Components . ProductPicker . GetPicker ( ) . on ( 'change' , function ( e )
{
var productId = $ ( e . target ) . val ( ) ;
if ( productId )
{
Grocy . Api . Get ( 'stock/products/' + productId ,
function ( productDetails )
{
2020-02-03 20:04:22 +01:00
Grocy . Components . ProductAmountPicker . Reload ( productDetails . product . id , productDetails . quantity _unit _stock . id ) ;
2021-07-10 22:56:39 +02:00
Grocy . Components . ProductAmountPicker . SetQuantityUnit ( productDetails . quantity _unit _stock . id ) ;
2020-01-25 11:51:00 +01:00
2022-01-23 12:53:21 +01:00
if ( Grocy . IsMealPlanEntryEditAction )
{
$ ( '#display_amount' ) . val ( Grocy . MealPlanEntryEditObject . product _amount ) ;
}
else
{
$ ( '#display_amount' ) . val ( 1 ) ;
}
2020-11-15 14:15:09 +01:00
RefreshLocaleNumberInput ( ) ;
2020-01-25 11:51:00 +01:00
$ ( '#display_amount' ) . focus ( ) ;
2020-02-03 20:04:22 +01:00
$ ( '#display_amount' ) . select ( ) ;
2020-01-25 11:51:00 +01:00
$ ( ".input-group-productamountpicker" ) . trigger ( "change" ) ;
Grocy . FrontendHelpers . ValidateForm ( 'add-product-form' ) ;
} ,
function ( xhr )
{
console . error ( xhr ) ;
}
) ;
}
} ) ;
2020-01-25 11:02:50 -06:00
function UndoStockTransaction ( transactionId )
{
2020-08-30 12:18:16 +02:00
Grocy . Api . Post ( 'stock/transactions/' + transactionId . toString ( ) + '/undo' , { } ,
function ( result )
2020-01-25 11:02:50 -06:00
{
toastr . success ( _ _t ( "Transaction successfully undone" ) ) ;
} ,
2020-08-30 12:18:16 +02:00
function ( xhr )
2020-01-25 11:02:50 -06:00
{
console . error ( xhr ) ;
}
) ;
} ;
2020-02-03 20:04:22 +01:00
Grocy . Components . RecipePicker . GetPicker ( ) . on ( 'change' , function ( e )
{
var recipeId = $ ( e . target ) . val ( ) ;
if ( recipeId )
{
2020-02-09 13:57:25 -06:00
Grocy . Api . Get ( 'objects/recipes/' + recipeId ,
function ( recipe )
{
$ ( "#recipe_servings" ) . val ( recipe . base _servings ) ;
2020-02-09 21:01:29 +01:00
$ ( "#recipe_servings" ) . focus ( ) ;
$ ( "#recipe_servings" ) . select ( ) ;
2020-02-09 13:57:25 -06:00
} ,
function ( xhr )
{
console . error ( xhr ) ;
}
) ;
2020-02-03 20:04:22 +01:00
}
} ) ;
2021-08-06 20:18:43 +02:00
$ ( "#print-meal-plan-button" ) . on ( "click" , function ( e )
{
window . print ( ) ;
} ) ;