mirror of
				https://github.com/grocy/grocy.git
				synced 2025-10-31 18:49:38 +00:00 
			
		
		
		
	Implement that recipe ingredients can have arbitrary quantity units (references #32)
This commit is contained in:
		| @@ -76,8 +76,9 @@ class RecipesController extends BaseController | |||||||
| 		{ | 		{ | ||||||
| 			return $this->AppContainer->view->render($response, 'recipeposform', [ | 			return $this->AppContainer->view->render($response, 'recipeposform', [ | ||||||
| 				'mode' => 'create', | 				'mode' => 'create', | ||||||
| 				'recipe' =>  $this->Database->recipes($args['recipeId']), | 				'recipe' => $this->Database->recipes($args['recipeId']), | ||||||
| 				'products' =>  $this->Database->products()->orderBy('name') | 				'products' => $this->Database->products()->orderBy('name'), | ||||||
|  | 				'quantityUnits' => $this->Database->quantity_units()->orderBy('name') | ||||||
| 			]); | 			]); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| @@ -85,8 +86,9 @@ class RecipesController extends BaseController | |||||||
| 			return $this->AppContainer->view->render($response, 'recipeposform', [ | 			return $this->AppContainer->view->render($response, 'recipeposform', [ | ||||||
| 				'mode' => 'edit', | 				'mode' => 'edit', | ||||||
| 				'recipe' =>  $this->Database->recipes($args['recipeId']), | 				'recipe' =>  $this->Database->recipes($args['recipeId']), | ||||||
| 				'recipePos' =>  $this->Database->recipes_pos($args['recipePosId']), | 				'recipePos' => $this->Database->recipes_pos($args['recipePosId']), | ||||||
| 				'products' =>  $this->Database->products()->orderBy('name') | 				'products' => $this->Database->products()->orderBy('name'), | ||||||
|  | 				'quantityUnits' => $this->Database->quantity_units()->orderBy('name') | ||||||
| 			]); | 			]); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -208,6 +208,8 @@ return array( | |||||||
| 	'Never expires' => 'Läuft nie ab', | 	'Never expires' => 'Läuft nie ab', | ||||||
| 	'This cannot be lower than #1' => 'Dies darf nicht kleiner als #1 sein', | 	'This cannot be lower than #1' => 'Dies darf nicht kleiner als #1 sein', | ||||||
| 	'-1 means that this product never expires' => '-1 bedeuet, dass dieses Produkt niemals abläuft', | 	'-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)', | ||||||
| 	 | 	 | ||||||
| 	//Constants | 	//Constants | ||||||
| 	'manually' => 'Manuell', | 	'manually' => 'Manuell', | ||||||
| @@ -272,5 +274,10 @@ return array( | |||||||
| 	'Italian' => 'Italienisch', | 	'Italian' => 'Italienisch', | ||||||
| 	'Demo in different language' => 'Demo in anderer Sprache', | 	'Demo in different language' => 'Demo in anderer Sprache', | ||||||
| 	'This is the note content of the recipe ingredient' => 'Dies ist der Inhalt der Notiz der Zutat', | 	'This is the note content of the recipe ingredient' => 'Dies ist der Inhalt der Notiz der Zutat', | ||||||
| 	'Demo User' => 'Demo Benutzer' | 	'Demo User' => 'Demo Benutzer', | ||||||
|  | 	'Gram' => 'Gramm', | ||||||
|  |     'Grams' => 'Gramm', | ||||||
|  |     'Flour' => 'Mehl', | ||||||
|  |     'Pancackes' => 'Pfannkuchen', | ||||||
|  |     'Sugar' => 'Zucker' | ||||||
| ); | ); | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								migrations/0034.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								migrations/0034.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | ALTER TABLE recipes_pos | ||||||
|  | ADD qu_id INTEGER; | ||||||
|  |  | ||||||
|  | UPDATE recipes_pos | ||||||
|  | SET qu_id = (SELECT qu_id_stock FROM products where id = product_id); | ||||||
|  |  | ||||||
|  | CREATE TRIGGER recipes_pos_qu_id_default AFTER INSERT ON recipes_pos | ||||||
|  | BEGIN | ||||||
|  | 	UPDATE recipes_pos | ||||||
|  | 	SET qu_id = (SELECT qu_id_stock FROM products where id = product_id) | ||||||
|  | 	WHERE qu_id IS NULL | ||||||
|  | 		AND id = NEW.id; | ||||||
|  | END; | ||||||
|  |  | ||||||
|  | ALTER TABLE recipes_pos | ||||||
|  | ADD only_check_single_unit_in_stock TINYINT NOT NULL DEFAULT 0; | ||||||
|  |  | ||||||
|  | DROP VIEW recipes_fulfillment; | ||||||
|  | CREATE VIEW recipes_fulfillment | ||||||
|  | AS | ||||||
|  | SELECT | ||||||
|  | 	r.id AS recipe_id, | ||||||
|  | 	rp.id AS recipe_pos_id, | ||||||
|  | 	rp.product_id AS product_id, | ||||||
|  | 	rp.amount AS recipe_amount, | ||||||
|  | 	IFNULL(sc.amount, 0) AS stock_amount, | ||||||
|  | 	CASE WHEN IFNULL(sc.amount, 0) >= CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) END THEN 1 ELSE 0 END AS need_fulfilled, | ||||||
|  | 	CASE WHEN IFNULL(sc.amount, 0) - CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) END < 0 THEN ABS(IFNULL(sc.amount, 0) - CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) END) ELSE 0 END AS missing_amount, | ||||||
|  | 	IFNULL(sl.amount, 0) AS amount_on_shopping_list, | ||||||
|  | 	CASE WHEN IFNULL(sc.amount, 0) + IFNULL(sl.amount, 0) >= CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) END THEN 1 ELSE 0 END AS need_fulfilled_with_shopping_list, | ||||||
|  | 	rp.qu_id | ||||||
|  | FROM recipes r | ||||||
|  | JOIN recipes_pos rp | ||||||
|  | 	ON r.id = rp.recipe_id | ||||||
|  | LEFT JOIN ( | ||||||
|  | 	SELECT product_id, SUM(amount + amount_autoadded) AS amount | ||||||
|  | 	FROM shopping_list | ||||||
|  | 	GROUP BY product_id) sl | ||||||
|  | 	ON rp.product_id = sl.product_id | ||||||
|  | LEFT JOIN stock_current sc | ||||||
|  | 	ON rp.product_id = sc.product_id; | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| { | { | ||||||
| 	e.preventDefault(); | 	e.preventDefault(); | ||||||
|  |  | ||||||
| 	var jsonData = $('#recipe-pos-form').serializeJSON(); | 	var jsonData = $('#recipe-pos-form').serializeJSON({ checkboxUncheckedValue: "0" }); | ||||||
| 	jsonData.recipe_id = Grocy.EditObjectParentId; | 	jsonData.recipe_id = Grocy.EditObjectParentId; | ||||||
| 	console.log(jsonData); | 	console.log(jsonData); | ||||||
| 	if (Grocy.EditMode === 'create') | 	if (Grocy.EditMode === 'create') | ||||||
| @@ -44,7 +44,10 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e) | |||||||
| 		Grocy.Api.Get('stock/get-product-details/' + productId, | 		Grocy.Api.Get('stock/get-product-details/' + productId, | ||||||
| 			function (productDetails) | 			function (productDetails) | ||||||
| 			{ | 			{ | ||||||
| 				$('#amount_qu_unit').text(productDetails.quantity_unit_purchase.name); | 				if (!$("#only_check_single_unit_in_stock").is(":checked")) | ||||||
|  | 				{ | ||||||
|  | 					$("#qu_id").val(productDetails.quantity_unit_stock.id); | ||||||
|  | 				} | ||||||
| 				$('#amount').focus(); | 				$('#amount').focus(); | ||||||
| 				Grocy.FrontendHelpers.ValidateForm('recipe-pos-form'); | 				Grocy.FrontendHelpers.ValidateForm('recipe-pos-form'); | ||||||
| 			}, | 			}, | ||||||
| @@ -76,12 +79,12 @@ $('#amount').on('focus', function(e) | |||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|  |  | ||||||
| $('#recipe-pos-form input').keyup(function (event) | $('#recipe-pos-form input').keyup(function(event) | ||||||
| { | { | ||||||
| 	Grocy.FrontendHelpers.ValidateForm('recipe-pos-form'); | 	Grocy.FrontendHelpers.ValidateForm('recipe-pos-form'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| $('#recipe-pos-form input').keydown(function (event) | $('#recipe-pos-form input').keydown(function(event) | ||||||
| { | { | ||||||
| 	if (event.keyCode === 13) //Enter | 	if (event.keyCode === 13) //Enter | ||||||
| 	{ | 	{ | ||||||
| @@ -96,3 +99,16 @@ $('#recipe-pos-form input').keydown(function (event) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | $("#only_check_single_unit_in_stock").on("click", function() | ||||||
|  | { | ||||||
|  | 	if (this.checked) | ||||||
|  | 	{ | ||||||
|  | 		$("#qu_id").removeAttr("disabled"); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		$("#qu_id").attr("disabled", ""); | ||||||
|  | 		Grocy.Components.ProductPicker.GetPicker().trigger("change"); | ||||||
|  | 	} | ||||||
|  | }); | ||||||
|   | |||||||
| @@ -21,14 +21,15 @@ class DemoDataGeneratorService extends BaseService | |||||||
| 				INSERT INTO users (username, password) VALUES ('{$localizationService->Localize('Demo User')} 3', 'x'); | 				INSERT INTO users (username, password) VALUES ('{$localizationService->Localize('Demo User')} 3', 'x'); | ||||||
| 				INSERT INTO users (username, password) VALUES ('{$localizationService->Localize('Demo User')} 4', 'x'); | 				INSERT INTO users (username, password) VALUES ('{$localizationService->Localize('Demo User')} 4', 'x'); | ||||||
|  |  | ||||||
| 				INSERT INTO locations (name) VALUES ('{$localizationService->Localize('Pantry')}'); --2 | 				INSERT INTO locations (name) VALUES ('{$localizationService->Localize('Pantry')}'); --3 | ||||||
| 				INSERT INTO locations (name) VALUES ('{$localizationService->Localize('Candy cupboard')}'); --3 | 				INSERT INTO locations (name) VALUES ('{$localizationService->Localize('Candy cupboard')}'); --4 | ||||||
| 				INSERT INTO locations (name) VALUES ('{$localizationService->Localize('Tinned food cupboard')}'); --4 | 				INSERT INTO locations (name) VALUES ('{$localizationService->Localize('Tinned food cupboard')}'); --5 | ||||||
|  |  | ||||||
| 				INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Glass')}', '{$localizationService->Localize('Glasses')}'); --4 | 				INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Glass')}', '{$localizationService->Localize('Glasses')}'); --4 | ||||||
| 				INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Tin')}', '{$localizationService->Localize('Tins')}'); --5 | 				INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Tin')}', '{$localizationService->Localize('Tins')}'); --5 | ||||||
| 				INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Can')}', '{$localizationService->Localize('Cans')}'); --6 | 				INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Can')}', '{$localizationService->Localize('Cans')}'); --6 | ||||||
| 				INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Bunch')}', '{$localizationService->Localize('Bunches')}'); --7 | 				INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Bunch')}', '{$localizationService->Localize('Bunches')}'); --7 | ||||||
|  | 				INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Gram')}', '{$localizationService->Localize('Grams')}'); --8 | ||||||
|  |  | ||||||
| 				DELETE FROM sqlite_sequence WHERE name = 'products'; --Just to keep IDs in order as mentioned here... | 				DELETE FROM sqlite_sequence WHERE name = 'products'; --Just to keep IDs in order as mentioned here... | ||||||
| 				INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, min_stock_amount) VALUES ('{$localizationService->Localize('Cookies')}', 3, 3, 3, 1, 8); --1 | 				INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, min_stock_amount) VALUES ('{$localizationService->Localize('Cookies')}', 3, 3, 3, 1, 8); --1 | ||||||
| @@ -51,6 +52,8 @@ class DemoDataGeneratorService extends BaseService | |||||||
| 				INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Salami')}', 2, 3, 3, 1); --18 | 				INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Salami')}', 2, 3, 3, 1); --18 | ||||||
| 				INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Toast')}', 4, 5, 5, 1); --19 | 				INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Toast')}', 4, 5, 5, 1); --19 | ||||||
| 				INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Minced meat')}', 2, 3, 3, 1); --20 | 				INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Minced meat')}', 2, 3, 3, 1); --20 | ||||||
|  | 				INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Flour')}', 2, 3, 3, 1); --21 | ||||||
|  | 				INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Sugar')}', 3, 3, 3, 1); --22 | ||||||
|  |  | ||||||
| 				INSERT INTO shopping_list (note, amount) VALUES ('{$localizationService->Localize('Some good snacks')}', 1); | 				INSERT INTO shopping_list (note, amount) VALUES ('{$localizationService->Localize('Some good snacks')}', 1); | ||||||
| 				INSERT INTO shopping_list (product_id, amount) VALUES (20, 1); | 				INSERT INTO shopping_list (product_id, amount) VALUES (20, 1); | ||||||
| @@ -59,6 +62,7 @@ class DemoDataGeneratorService extends BaseService | |||||||
| 				INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Pizza')}', '{$loremIpsum}'); --1 | 				INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Pizza')}', '{$loremIpsum}'); --1 | ||||||
| 				INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Spaghetti bolognese')}', '{$loremIpsum}'); --2 | 				INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Spaghetti bolognese')}', '{$loremIpsum}'); --2 | ||||||
| 				INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Sandwiches')}', '{$loremIpsum}'); --3 | 				INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Sandwiches')}', '{$loremIpsum}'); --3 | ||||||
|  | 				INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Pancackes')}', '{$loremIpsum}'); --4 | ||||||
|  |  | ||||||
| 				INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (1, 16, 1); | 				INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (1, 16, 1); | ||||||
| 				INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (1, 17, 1); | 				INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (1, 17, 1); | ||||||
| @@ -70,6 +74,9 @@ class DemoDataGeneratorService extends BaseService | |||||||
| 				INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (2, 20, 1); | 				INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (2, 20, 1); | ||||||
| 				INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (3, 10, 1); | 				INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (3, 10, 1); | ||||||
| 				INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (3, 11, 1); | 				INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (3, 11, 1); | ||||||
|  | 				INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (4, 5, 4); | ||||||
|  | 				INSERT INTO recipes_pos (recipe_id, product_id, amount, qu_id, only_check_single_unit_in_stock) VALUES (4, 21, 200, 8, 1); | ||||||
|  | 				INSERT INTO recipes_pos (recipe_id, product_id, amount, qu_id, only_check_single_unit_in_stock) VALUES (4, 22, 200, 8, 1); | ||||||
|  |  | ||||||
| 				INSERT INTO habits (name, period_type, period_days) VALUES ('{$localizationService->Localize('Changed towels in the bathroom')}', 'manually', 5); --1 | 				INSERT INTO habits (name, period_type, period_days) VALUES ('{$localizationService->Localize('Changed towels in the bathroom')}', 'manually', 5); --1 | ||||||
| 				INSERT INTO habits (name, period_type, period_days) VALUES ('{$localizationService->Localize('Cleaned the kitchen floor')}', 'dynamic-regular', 7); --2 | 				INSERT INTO habits (name, period_type, period_days) VALUES ('{$localizationService->Localize('Cleaned the kitchen floor')}', 'dynamic-regular', 7); --2 | ||||||
| @@ -151,6 +158,10 @@ class DemoDataGeneratorService extends BaseService | |||||||
| 			$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-30 days')), $this->RandomPrice()); | 			$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-30 days')), $this->RandomPrice()); | ||||||
| 			$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-40 days')), $this->RandomPrice()); | 			$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-40 days')), $this->RandomPrice()); | ||||||
| 			$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-50 days')), $this->RandomPrice()); | 			$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-50 days')), $this->RandomPrice()); | ||||||
|  | 			$stockService->AddProduct(21, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-10 days')), $this->RandomPrice()); | ||||||
|  | 			$stockService->AddProduct(21, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-20 days')), $this->RandomPrice()); | ||||||
|  | 			$stockService->AddProduct(22, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-10 days')), $this->RandomPrice()); | ||||||
|  | 			$stockService->AddProduct(22, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-20 days')), $this->RandomPrice()); | ||||||
| 			$stockService->AddMissingProductsToShoppingList(); | 			$stockService->AddMissingProductsToShoppingList(); | ||||||
|  |  | ||||||
| 			$habitsService = new HabitsService(); | 			$habitsService = new HabitsService(); | ||||||
|   | |||||||
| @@ -76,7 +76,7 @@ | |||||||
| 						{{ FindObjectInArrayByPropertyValue($products, 'id', $recipePosition->product_id)->name }} | 						{{ FindObjectInArrayByPropertyValue($products, 'id', $recipePosition->product_id)->name }} | ||||||
| 					</td> | 					</td> | ||||||
| 					<td> | 					<td> | ||||||
| 						{{ $recipePosition->amount }} {{ Pluralize($recipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $recipePosition->product_id)->qu_id_stock)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $recipePosition->product_id)->qu_id_stock)->name_plural) }} | 						{{ $recipePosition->amount }} {{ Pluralize($recipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $recipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $recipePosition->qu_id)->name_plural) }} | ||||||
| 						<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->missing_amount, FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->amount_on_shopping_list) }} @endif</span> | 						<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->missing_amount, FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->amount_on_shopping_list) }} @endif</span> | ||||||
| 					</td> | 					</td> | ||||||
| 					<td class="fit-content"> | 					<td class="fit-content"> | ||||||
|   | |||||||
| @@ -32,10 +32,34 @@ | |||||||
| 				'prefillByName' => $prefillByName | 				'prefillByName' => $prefillByName | ||||||
| 			)) | 			)) | ||||||
|  |  | ||||||
| 			<div class="form-group"> | 			<div class="form-group row"> | ||||||
| 				<label for="amount">{{ $L('Amount') }}  <span id="amount_qu_unit" class="small text-muted"></span></label> | 				<div class="col"> | ||||||
| 				<input type="number" class="form-control" id="amount" name="amount" value="@if($mode == 'edit'){{ $recipePos->amount }}@else{{1}}@endif" min="0" required> | 					<div class="row"> | ||||||
| 				<div class="invalid-feedback">{{ $L('This cannot be negative') }}</div> | 						<div class="form-group col-4"> | ||||||
|  | 							<label for="amount">{{ $L('Amount') }}</label> | ||||||
|  | 							<input type="number" class="form-control" id="amount" name="amount" value="@if($mode == 'edit'){{ $recipePos->amount }}@else{{1}}@endif" min="0" required> | ||||||
|  | 							<div class="invalid-feedback">{{ $L('This cannot be negative') }}</div> | ||||||
|  | 						</div> | ||||||
|  | 						<div class="form-group col-8"> | ||||||
|  | 							<label for="qu_id">{{ $L('Quantity unit') }}</label> | ||||||
|  | 							<select required @if($mode == 'create' || ($mode == 'edit' && $recipePos->only_check_single_unit_in_stock != 1)) disabled @endif class="form-control" id="qu_id" name="qu_id"> | ||||||
|  | 								@foreach($quantityUnits as $quantityunit) | ||||||
|  | 									<option @if($mode == 'edit' && $quantityunit->id == $recipePos->qu_id) selected @endif value="{{ $quantityunit->id }}">{{ $quantityunit->name }}</option> | ||||||
|  | 								@endforeach | ||||||
|  | 							</select> | ||||||
|  | 							<div class="invalid-feedback">{{ $L('A quantity unit is required') }}</div> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					<div class="row"> | ||||||
|  | 						<div class="col"> | ||||||
|  | 							<div class="form-check"> | ||||||
|  | 								<input type="hidden" name="only_check_single_unit_in_stock" value="0"> | ||||||
|  | 								<input @if($mode == 'edit' && $recipePos->only_check_single_unit_in_stock == 1) checked @endif class="form-check-input" type="checkbox" id="only_check_single_unit_in_stock" name="only_check_single_unit_in_stock" value="1"> | ||||||
|  | 								<label class="form-check-label" for="only_check_single_unit_in_stock">{{ $L('Only check if a single unit is in stock (a different quantity can then be used above)') }}</label> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 				</div> | ||||||
| 			</div> | 			</div> | ||||||
|  |  | ||||||
| 			<div class="form-group"> | 			<div class="form-group"> | ||||||
|   | |||||||
| @@ -71,7 +71,7 @@ | |||||||
| 			<ul class="list-group list-group-flush"> | 			<ul class="list-group list-group-flush"> | ||||||
| 				@foreach($selectedRecipePositions as $selectedRecipePosition) | 				@foreach($selectedRecipePositions as $selectedRecipePosition) | ||||||
| 				<li class="list-group-item"> | 				<li class="list-group-item"> | ||||||
| 					{{ $selectedRecipePosition->amount }} {{ Pluralize($selectedRecipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->qu_id_stock)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->qu_id_stock)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }} | 					{{ $selectedRecipePosition->amount }} {{ Pluralize($selectedRecipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }} | ||||||
| 					<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount, FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list) }} @endif</span> | 					<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount, FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list) }} @endif</span> | ||||||
|  |  | ||||||
| 					@if(!empty($selectedRecipePosition->note)) | 					@if(!empty($selectedRecipePosition->note)) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user