Added the last tab, fermentation to the product editer.

Wed, 02 Jan 2019 17:34:53 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Wed, 02 Jan 2019 17:34:53 +0100
changeset 164
0a5abea575a9
parent 163
4a4cc3497a57
child 165
5970c8377b89

Added the last tab, fermentation to the product editer.

www/includes/db_product.php file | annotate | diff | comparison | revisions
www/includes/formulas.php file | annotate | diff | comparison | revisions
www/js/global.js file | annotate | diff | comparison | revisions
www/js/prod_edit.js file | annotate | diff | comparison | revisions
www/prod_edit.php file | annotate | diff | comparison | revisions
--- a/www/includes/db_product.php	Wed Jan 02 14:49:17 2019 +0100
+++ b/www/includes/db_product.php	Wed Jan 02 17:34:53 2019 +0100
@@ -56,7 +56,7 @@
 	$sql .= "', code='" . mysqli_real_escape_string($connect, $_POST['code']);
 	$sql .= "', birth='" . $_POST['birth'];
 	$sql .= "', stage='" . $_POST['stage'];
-//	$sql .= "', notes='" . mysqli_real_escape_string($connect, $_POST['notes']);
+	$sql .= "', notes='" . mysqli_real_escape_string($connect, $_POST['notes']);
 	($_POST['log_brew'] == 'true') ? $sql .= "', log_brew='1" : $sql .= "', log_brew='0";
 	($_POST['log_fermentation'] == 'true') ? $sql .= "', log_fermentation='1" : $sql .= "', log_fermentation='0";
 	($_POST['inventory_reduced'] == 'true') ? $sql .= "', inventory_reduced='1" : $sql .= "', inventory_reduced='0";
@@ -77,7 +77,7 @@
 	$sql .= "', eq_calc_boil_volume='" . $_POST['eq_calc_boil_volume'];
 	$sql .= "', eq_top_up_kettle='" . $_POST['eq_top_up_kettle'];
 	$sql .= "', eq_hop_utilization='" . $_POST['eq_hop_utilization'];
-//	$sql .= "', eq_notes='" . mysqli_real_escape_string($connect, $_POST['eq_notes']);
+	$sql .= "', eq_notes='" . mysqli_real_escape_string($connect, $_POST['eq_notes']);
 	$sql .= "', eq_lauter_volume='" . $_POST['eq_lauter_volume'];
 	$sql .= "', eq_lauter_height='" . $_POST['eq_lauter_height'];
 	$sql .= "', eq_lauter_deadspace='" . $_POST['eq_lauter_deadspace'];
@@ -86,49 +86,42 @@
 	$sql .= "', eq_mash_volume='" . $_POST['eq_mash_volume'];
 	$sql .= "', eq_mash_max='" . $_POST['eq_mash_max'];
 	$sql .= "', eq_efficiency='" . $_POST['eq_efficiency'];
-
-	if ($stageno >= 2) {
-	// brew_date_start
-	// brew_mash_ph
-	// brew_mash_sg
-	// brew_sparge_temperature
-	// brew_sparge_volume
-	// brew_sparge_ph
-	// brew_preboil_volume
-	// brew_preboil_sg
-	// brew_preboil_ph
-	// brew_aboil_volume
-	// brew_aboil_sg
-	// brew_aboil_ph
-	// brew_aboil_efficiency
-	// brew_cooling_method
-	// brew_cooling_time
-	// brew_cooling_to
-	// brew_whirlpool9
-	// brew_whirlpool7
-	// brew_whirlpool6
-	// brew_whirlpool2
-	// brew_fermenter_volume
-	// brew_fermenter_extrawater
-	// brew_aeration_time
-	// brew_aeration_speed
-	// brew_aeration_type
-	// brew_fermenter_sg
-	// brew_fermenter_ibu
-	// brew_date_end
-	// brew_log_available
-	}
+	$sql .= "', brew_date_start='" . $_POST['brew_date_start'];
+	$sql .= "', brew_mash_ph='" . $_POST['brew_mash_ph'];
+	$sql .= "', brew_mash_sg='" . $_POST['brew_mash_sg'];
+	$sql .= "', brew_sparge_temperature='" . $_POST['brew_sparge_temperature'];
+	$sql .= "', brew_sparge_volume='" . $_POST['brew_sparge_volume'];
+	$sql .= "', brew_sparge_ph='" . $_POST['brew_sparge_ph'];
+	$sql .= "', brew_preboil_volume='" . $_POST['brew_preboil_volume'];
+	$sql .= "', brew_preboil_sg='" . $_POST['brew_preboil_sg'];
+	$sql .= "', brew_preboil_ph='" . $_POST['brew_preboil_ph'];
+	$sql .= "', brew_aboil_volume='" . $_POST['brew_aboil_volume'];
+	$sql .= "', brew_aboil_sg='" . $_POST['brew_aboil_sg'];
+	$sql .= "', brew_aboil_ph='" . $_POST['brew_aboil_ph'];
+	$sql .= "', brew_aboil_efficiency='" . $_POST['brew_aboil_efficiency'];
+	$sql .= "', brew_cooling_method='" . $_POST['brew_cooling_method'];
+	$sql .= "', brew_cooling_time='" . $_POST['brew_cooling_time'];
+	$sql .= "', brew_cooling_to='" . $_POST['brew_cooling_to'];
+	$sql .= "', brew_whirlpool9='" . $_POST['brew_whirlpool9'];
+	$sql .= "', brew_whirlpool7='" . $_POST['brew_whirlpool7'];
+	$sql .= "', brew_whirlpool6='" . $_POST['brew_whirlpool6'];
+	$sql .= "', brew_whirlpool2='" . $_POST['brew_whirlpool2'];
+	$sql .= "', brew_aeration_time='" . $_POST['brew_aeration_time'];
+	$sql .= "', brew_aeration_speed='" . $_POST['brew_aeration_speed'];
+	$sql .= "', brew_aeration_type='" . $_POST['brew_aeration_type'];
+	$sql .= "', brew_fermenter_volume='" . $_POST['brew_fermenter_volume'];
+	$sql .= "', brew_fermenter_extrawater='" . $_POST['brew_fermenter_extrawater'];
+	$sql .= "', brew_fermenter_sg='" . $_POST['brew_fermenter_sg'];
+	$sql .= "', brew_fermenter_ibu='" . $_POST['brew_fermenter_ibu'];
+	$sql .= "', brew_date_end='" . $_POST['brew_date_end'];
+	($_POST['brew_log_available'] == 'true') ? $sql .= "', brew_log_available='1" : $sql .= "', brew_log_available='0";
 	$sql .= "', og='" . $_POST['og'];
 	$sql .= "', fg='" . $_POST['fg'];
-
-	if ($stageno >= 3) {
-	// primary_start_temp
-	// primary_max_temp
-	// primary_end_temp
-	// primary_end_sg
-		// primary_end_date
-	}
-
+	$sql .= "', primary_start_temp='" . $_POST['primary_start_temp'];
+	$sql .= "', primary_max_temp='" . $_POST['primary_max_temp'];
+	$sql .= "', primary_end_temp='" . $_POST['primary_end_temp'];
+	$sql .= "', primary_end_sg='" . $_POST['primary_end_sg'];
+	$sql .= "', primary_end_date='" . $_POST['primary_end_date'];
 	$sql .= "', secondary_temp='" . $_POST['secondary_temp'];
 	$sql .= "', secondary_end_date='" . $_POST['secondary_end_date'];
 	$sql .= "', tertiary_temp='" . $_POST['tertiary_temp'];
@@ -233,7 +226,7 @@
 				unset($array[$key]["$disallowed_key"]);
 			}
 		}
-		syslog(LOG_NOTICE, "json_fermentables=: ".str_replace($rescapers,$rreplacements,json_encode($array)));
+//		syslog(LOG_NOTICE, "json_fermentables=: ".str_replace($rescapers,$rreplacements,json_encode($array)));
 		$sql .= "', json_fermentables='" . str_replace($rescapers,$rreplacements,json_encode($array));
 	}
 
@@ -244,7 +237,7 @@
 				unset($array[$key]["$disallowed_key"]);
 			}
 		}
-		syslog(LOG_NOTICE, "json_hops: ".str_replace($rescapers,$rreplacements,json_encode($array)));
+//		syslog(LOG_NOTICE, "json_hops: ".str_replace($rescapers,$rreplacements,json_encode($array)));
 		$sql .= "', json_hops='" . str_replace($rescapers,$rreplacements,json_encode($array));
 	}
 
@@ -255,7 +248,7 @@
 				unset($array[$key]["$disallowed_key"]);
 			}
 		}
-		syslog(LOG_NOTICE, "json_miscs: ".str_replace($rescapers,$rreplacements,json_encode($array)));
+//		syslog(LOG_NOTICE, "json_miscs: ".str_replace($rescapers,$rreplacements,json_encode($array)));
 		$sql .= "', json_miscs='" . str_replace($rescapers,$rreplacements,json_encode($array));
 	}
 
@@ -266,7 +259,7 @@
 				unset($array[$key]["$disallowed_key"]);
 			}
 		}
-		syslog(LOG_NOTICE, "json_yeasts: ". str_replace($rescapers,$rreplacements,json_encode($array)));
+//		syslog(LOG_NOTICE, "json_yeasts: ". str_replace($rescapers,$rreplacements,json_encode($array)));
 		$sql .= "', json_yeasts='" . str_replace($rescapers,$rreplacements,json_encode($array));
 	}
 
@@ -277,7 +270,7 @@
 				unset($array[$key]["$disallowed_key"]);
 			}
 		}
-		syslog(LOG_NOTICE, "json_mashs: ".str_replace($rescapers,$rreplacements,json_encode($array)));
+//		syslog(LOG_NOTICE, "json_mashs: ".str_replace($rescapers,$rreplacements,json_encode($array)));
 		$sql .= "', json_mashs='" . str_replace($rescapers,$rreplacements,json_encode($array));
 	}
 
--- a/www/includes/formulas.php	Wed Jan 02 14:49:17 2019 +0100
+++ b/www/includes/formulas.php	Wed Jan 02 17:34:53 2019 +0100
@@ -270,40 +270,6 @@
 
 Brouwhulp data.pas
 
-Function THop.FlavourContribution : double; //in % * concentration in g/l
-var bt, vol : double;
-begin
-  bt:= FTime.Value;
-  vol:= 0;
-  if FRecipe <> NIL then vol:= FRecipe.BatchSize.Value;
-  if FUse = huFirstWort then Result:= 0.15 * FAmount.Value * 1000 //assume 15% flavourcontribution for fwh
-  else if bt > 50 then Result:= 0.10 * FAmount.Value * 1000 //assume 10% flavourcontribution as a minimum
-  else
-  begin
-    Result:= 15.25 / (6 * sqrt(2 * PI)) * Exp(-0.5*Power((bt-21)/6, 2))
-             * FAmount.Value * 1000;
-    if result < 0.10 * FAmount.Value * 1000 then
-      Result:= 0.10 * FAmount.Value * 1000 //assume 10% flavourcontribution as a minimum
-  end;
-  if vol > 0 then Result:= Result / vol;
-end;
-
-Function THop.AromaContribution : double; //in % * concentration in g/l
-var bt, vol : double;
-begin
-  bt:= FTime.Value;
-  vol:= 0;
-  if FRecipe <> NIL then vol:= FRecipe.BatchSize.Value;
-  if bt > 20 then Result:= 0
-  else if bt > 7.5 then
-    Result:= 10.03 / (4 * sqrt(2 * PI)) * Exp(-0.5*Power((bt-7.5)/4, 2))
-             * FAmount.Value * 1000
-  else if FUse = huBoil then Result:= FAmount.Value * 1000
-  else if FUse = huAroma then Result:= 1.2 * FAmount.Value * 1000
-  else if FUse = huWhirlpool then Result:= 1.2 * FAmount.Value * 1000
-  else if FUse = huDryHop then Result:= 1.33 * FAmount.Value * 1000;
-    if vol > 0 then Result:= Result / vol;
-end;
 
 
 Procedure TFermentable.SetpHParameters(force : boolean);
@@ -439,139 +405,12 @@
 end;
 
 
-Procedure TWater.AddMinerals(Ca, Mg, Na, HCO3, Cl, SO4 : double);
-begin
-  FCalcium.Add(Ca);
-  FMagnesium.Add(Mg);
-  FSodium.Add(Na);
-  FBicarbonate.Add(HCO3);
-  FChloride.Add(Cl);
-  FSulfate.Add(SO4);
-end;
-
 function TWater.GetResidualAlkalinity: double;
 begin
   //Result in mg/l as CaCO3
   Result:= FTotalAlkalinity.Value - (FCalcium.Value / 1.4 + FMagnesium.Value / 1.7);
 end;
 
-const
-  Ka1 = 0.0000004445;
-  Ka2 = 0.0000000000468;
-
-Function PartCO3(pH : double) : double;
-var H : double;
-begin
-  H:= Power(10, -pH);
-  Result:= 100 * Ka1 * Ka2 / (H*H + H * Ka1 + Ka1 * Ka2);
-end;
-
-Function PartHCO3(pH : double) : double;
-var H : double;
-begin
-  H:= Power(10, -pH);
-  Result:= 100 * Ka1 * H / (H*H + H * Ka1 + Ka1 * Ka2);
-end;
-
-Function PartH2CO3(pH : double) : double;
-var H : double;
-begin
-  H:= Power(10, -pH);
-  Result:= 100 * H * H / (H*H + H * Ka1 + Ka1 * Ka2);
-end;
-
-Function Charge(pH : double) : double;
-begin
-  Result:= (-2 * PartCO3(pH) - PartHCO3(pH));
-end;
-
-//Z alkalinity is the amount of acid (in mEq/l) needed to bring water to the target pH (Z pH)
-Function TWater.ZAlkalinity(pHZ : double) : double;  //in mEq/l
-var CT, DeltaCNaught, DeltaCZ, C43, Cw, Cz : double;
-begin
-  C43:= Charge(4.3);
-  Cw:= Charge(FpH.Value);
-  Cz:= Charge(pHz);
-  DeltaCNaught:= -C43+Cw;
-  CT:= GetAlkalinity / 50 / DeltaCNaught;
-  DeltaCZ:= -Cz+Cw;
-  Result:= CT * DeltaCZ;
-end;
-
-//Z Residual alkalinity is the amount of acid (in mEq/l) needed to bring the water in the mash to the target pH (Z pH)
-Function TWater.ZRA(pHZ : double) : double; //in mEq/l
-var Calc, Magn, Z : double;
-begin
-  Calc:= FCalcium.Value / (MMCa / 2);
-  Magn:= FMagnesium.Value / (MMMg / 2);
-  Z:= ZAlkalinity(pHZ);
-  Result:= Z - (Calc / 3.5 + Magn / 7);
-end;
-
-Function TWater.ProtonDeficit(pHZ : double) : double;
-var i : integer;
-    F : TFermentable;
-    x : double;
-begin
-  Result:= ZRA(pHZ) * FAmount.Value;
-  //proton deficit for the added malts
-  for i:= 0 to FRecipe.NumFermentables - 1 do
-  begin
-    F:= FRecipe.Fermentable[i];
-    if (F.AddedType = atMash) and (F.GrainType <> gtNone) then
-    begin
-      x:= F.AcidRequired(pHZ) * F.Amount.Value;
-      Result:= Result + x;
-    end;
-  end;
-end;
-
-Function TWater.MashpH : double;
-var n : integer;
-    pd : double;
-    pH, deltapH, deltapd : double;
-begin
-  Result:= 0;
-  n:= 0;
-  pH:= 5.4;
-  deltapH:= 0.001;
-  deltapd:= 0.1;
-  pd:= ProtonDeficit(pH);
-  while ((pd < -deltapd) or (pd > deltapd)) and (n < 1000) do
-  begin
-    inc(n);
-    if pd < -deltapd then ph:= ph - deltapH
-    else if pd > deltapd then pH:= pH + deltapH;
-    pd:= ProtonDeficit(pH);
-  end;
-  Result:= pH;
-end;
-
-Function TWater.MashpH2(PrDef : double) : double;
-var n : integer;
-    pd : double;
-    pH, deltapH, deltapd : double;
-begin
-  Result:= 0;
-  n:= 0;
-  pH:= 5.4;
-  deltapH:= 0.001;
-  deltapd:= 0.1;
-  pd:= ProtonDeficit(pH);
-  while ((pd < PrDef-deltapd) or (pd > PrDef + deltapd)) and (n < 1000) do
-  begin
-    inc(n);
-    if pd < PrDef-deltapd then ph:= ph - deltapH
-    else if pd > PrDef+deltapd then pH:= pH + deltapH;
-    pd:= ProtonDeficit(pH);
-  end;
-  Result:= pH;
-end;
-
-function TWater.GetAlkalinity: double;
-begin
-  Result := FBicarbonate.Value / 1.22; //mEq/l
-end;
 
 function TWater.GetHardness: double;
 begin
@@ -593,79 +432,6 @@
 end;
 
 
-function TBeerStyle.GetBUGUMin: double;
-var
-  B, G: double;
-begin
-  Result:= 0;
-  if ((FOGMax.Value + FOGMin.Value) > 0) and ((FIBUMax.Value + FIBUMin.Value) > 0) then
-  begin
-    G := (FOGMax.Value - FOGMin.Value) / ((FOGMax.Value + FOGMin.Value) / 2);
-    B := (FIBUMax.Value - FIBUMin.Value) / ((FIBUMax.Value + FIBUMin.Value) / 2);
-    if G > B then
-      Result := ((FIBUMin.Value + FIBUMax.Value) / 2) / (1000 * (FOGMax.Value - 1))
-    else
-      Result := FIBUMin.Value / (1000 * (((FOGMax.Value + FOGMin.Value) / 2) - 1));
-  end;
-end;
-
-function TBeerStyle.GetBUGUMax: double;
-var
-  B, G: double;
-begin
-  Result:= 0;
-  if ((FOGMax.Value + FOGMin.Value) > 0) and ((FIBUMax.Value + FIBUMin.Value) > 0)
-  and (FOGMin.Value > 1) then
-  begin
-    G := (FOGMax.Value - FOGMin.Value) / ((FOGMax.Value + FOGMin.Value) / 2);
-    B := (FIBUMax.Value - FIBUMin.Value) / ((FIBUMax.Value + FIBUMin.Value) / 2);
-    if G > B then
-      Result := ((FIBUMin.Value + FIBUMax.Value) / 2) / (1000 * (FOGMin.Value - 1))
-    else
-      Result := FIBUMax.Value / (1000 * (((FOGMax.Value + FOGMin.Value) / 2) - 1));
-  end;
-end;
-
-
-        // Get concentration of ions in diluted brewwater (1) and target water (2) in mmol/l
-        Ca1 := W.Calcium.Value / MMCa;
-        Ca2 := W2.Calcium.Value / MMCa;
-        Mg1 := W.Magnesium.Value / MMMg;
-        Mg2 := W2.Magnesium.Value / MMMg;
-        Na1 := W.Sodium.Value / MMNa;
-        Na2 := W2.Sodium.Value / MMNa;
-
-        CO31 := W.Bicarbonate.Value / MMHCO3;
-        CO32 := W2.Bicarbonate.Value / MMHCO3;
-        SO41 := W.Sulfate.Value / MMSO4;
-        SO42 := W2.Sulfate.Value / MMSO4;
-        Cl1 := W.Sulfate.Value / MMSO4;
-        Cl2 := W2.Sulfate.Value / MMSO4;
-
-
-procedure TRecipe.CalcWaterBalance;
-var
-  i: integer;
-  F: TFermentable;
-begin
-  FAbsorbedByGrain := 0;
-  for i := Low(FFermentables) to High(FFermentables) do
-  begin
-    F := TFermentable(FFermentables[i]);
-    if (F.FermentableType = ftGrain) or (F.FermentableType = ftAdjunct) then
-      FAbsorbedByGrain := FAbsorbedByGrain + F.Amount.Value;
-  end;
-  FAbsorbedByGrain := FAbsorbedByGrain * Settings.GrainAbsorption.Value;
-
-  if FEquipment.CalcBoilVolume.Value then
-    {FBoilSize.Value := FBatchSize.Value / (1 - (FEquipment.EvapRate.Value / 100) *
-      (FBoilTime.Value / 60));}
-    FBoilSize.Value:= FBatchSize.Value + FEquipment.BoilSize.Value
-                              * FEquipment.EvapRate.Value / 100 *
-                              (FBoilTime.Value / 60);
-end;
-
-
 
 
 
--- a/www/js/global.js	Wed Jan 02 14:49:17 2019 +0100
+++ b/www/js/global.js	Wed Jan 02 17:34:53 2019 +0100
@@ -608,12 +608,3 @@
 }
 
 
-/*
- * Steinie:
- *
- *
- * HCO3 = CaCo3 x 1,22
- * CaCO3) = HCO3- x 50 / 61
- * 1°F = 10mg/L CaCo3
- */
-
--- a/www/js/prod_edit.js	Wed Jan 02 14:49:17 2019 +0100
+++ b/www/js/prod_edit.js	Wed Jan 02 17:34:53 2019 +0100
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2018
+ * Copyright (C) 2018-2019
  *
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -985,6 +985,22 @@
 		$("#sparge_acid_amount").val(Acid);
 	}
 
+	function calcFermentation() {
+		if (dataRecord.brew_fermenter_sg < 1.020)
+			return;
+		if ((dataRecord.primary_end_sg > 0.990) && (dataRecord.primary_end_sg < dataRecord.brew_fermenter_sg)) {
+			var primary_svg = 100 * (dataRecord.brew_fermenter_sg - dataRecord.primary_end_sg) / (dataRecord.brew_fermenter_sg - 1);
+			console.log("primary svg: "+primary_svg);
+			$("#primary_svg").val(primary_svg);
+			if ((dataRecord.fg > 0.990) && (dataRecord.fg < dataRecord.brew_fermenter_sg)) {
+				var final_svg = 100 * (dataRecord.brew_fermenter_sg - dataRecord.fg) / (dataRecord.brew_fermenter_sg - 1);
+				$("#final_svg").val(final_svg);
+				var ABV = abvol(dataRecord.brew_fermenter_sg, dataRecord.fg);
+				$("#final_abv").val(ABV);
+			}
+		}
+	}
+
 	function CarbCO2toS(CO2, T, SFactor) {
 		// Calcuation of disolved CO2 in the beer.
 		// Brewersfriend uses: 3.0378 - (0.050062 * temp) + (0.00026555 * temp^2)
@@ -1210,6 +1226,7 @@
 			calcSparge();
 		});
 
+		calcFermentation();
 		calcCarbonation();
 		$('#bottle_amount').on('change', function (event) {
 			dataRecord.bottle_amount = parseFloat(event.args.value);
@@ -1617,6 +1634,7 @@
 			// Header Naar gistvat
 			$("#brew_fermenter_volume").val(dataRecord.brew_fermenter_volume);
 			$("#brew_fermenter_sg").val(dataRecord.brew_fermenter_sg);
+			$("#brew_fermenter_sg2").val(dataRecord.brew_fermenter_sg);
 			$("#brew_fermenter_ibu").val(dataRecord.brew_fermenter_ibu);
 
 			$("#brew_aboil_ph").val(dataRecord.brew_aboil_ph);
@@ -1635,6 +1653,14 @@
 			$("#brew_date_end").val(dataRecord.brew_date_end);
 			$("#og").val(dataRecord.og);
 			$("#fg").val(dataRecord.fg);
+			$("#primary_start_temp").val(dataRecord.primary_start_temp);
+			$("#primary_max_temp").val(dataRecord.primary_max_temp);
+			$("#primary_end_temp").val(dataRecord.primary_end_temp);
+			$("#primary_end_sg").val(dataRecord.primary_end_sg);
+			$("#primary_end_date").val(dataRecord.primary_end_date);
+			$("#secondary_temp").val(dataRecord.secondary_temp);
+			$("#secondary_end_date").val(dataRecord.secondary_end_date);
+			$("#tertiary_temp").val(dataRecord.tertiary_temp);
 			$("#package_date").val(dataRecord.package_date);
 			$("#bottle_amount").val(dataRecord.bottle_amount);
 			$("#bottle_carbonation").val(dataRecord.bottle_carbonation);
@@ -1689,6 +1715,7 @@
 			$("#est_og2").val(dataRecord.est_og);
 			$("#est_og3").val(dataRecord.est_og);
 			$("#est_fg").val(dataRecord.est_fg);
+			$("#est_fg2").val(dataRecord.est_fg);
 			$("#est_color").val(dataRecord.est_color);
 			$("#est_color2").val(dataRecord.est_color);
 			$("#est_abv").val(dataRecord.est_abv);
@@ -2807,6 +2834,7 @@
                                 var fg = estimate_fg(psugar, pcara, 0, 0, 0, svg, parseFloat(parseFloat($("#est_og").jqxNumberInput('decimal'))));
                                 dataRecord.est_fg = fg;
                                 $('#est_fg').val(fg);
+				$('#est_fg2').val(fg);
                                 calcInit();
                                 $('#jqxLoader').jqxLoader('close');
                                 $('#jqxTabs').jqxTabs('first');
@@ -2943,6 +2971,7 @@
 	$("#st_og_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true });
 	$("#est_fg").jqxTooltip({ content: 'Het eind SG. Dit wordt automatisch berekend.' });
 	$("#est_fg").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 3, readOnly: true });
+	$("#est_fg2").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 70, height: 23, decimalDigits: 3, readOnly: true });
 	$("#st_fg_min").jqxTooltip({ content: 'Het minimum eind SG voor deze bierstijl.'});
 	$("#st_fg_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true });
 	$("#st_fg_max").jqxTooltip({ content: 'Het maximum eind SG voor deze bierstijl.'});
@@ -3243,7 +3272,39 @@
 
 	// Tab 10, Fermentation
 	// Note, fermentation temps changes must do calcCarbonation()
+	$("#brew_fermenter_sg2").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 70, height: 23, decimalDigits: 3 });
+	$("#primary_start_temp").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 90, height: 23, min: 0, max: 40, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.5 });
+	$("#primary_max_temp").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 90, height: 23, min: 0, max: 40, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.5 });
+	$("#primary_end_temp").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 90, height: 23, min: 0, max: 40, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.5 });
+	$("#primary_end_sg").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 90, height: 23, min: 0.990, max: 1.2, decimalDigits: 3, spinButtons: true, spinButtonsStep: 0.001 });
+	$("#primary_svg").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 70, height: 23, decimalDigits: 1 });
+	$("#primary_end_date").jqxTooltip({ content: 'De eind datum van de hoofdvergisting en eventueel overhevelen.' });
+	$("#primary_end_date").jqxDateTimeInput({
+		theme: theme,
+		width: 150,
+		height: 23,
+		allowNullDate: true,
+		todayString: 'Vandaag',
+		clearString: 'Wissen',
+		showFooter: true,
+		formatString: 'yyyy-MM-dd'
+	});
+	$("#secondary_temp").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 90, height: 23, min: 0, max: 40, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.5 });
+	$("#secondary_end_date").jqxTooltip({ content: 'De eind datum van de navergisting en het begin van het lageren.' });
+	$("#secondary_end_date").jqxDateTimeInput({
+		theme: theme,
+		width: 150,
+		height: 23,
+		allowNullDate: true,
+		todayString: 'Vandaag',
+		clearString: 'Wissen',
+		showFooter: true,
+		formatString: 'yyyy-MM-dd'
+	});
+	$("#tertiary_temp").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 90, height: 23, min: 0, max: 40, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.5 });
 	$("#fg").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 90, height: 23, min: 0, decimalDigits: 3, spinButtons: true, spinButtonsStep: 0.001 });
+	$("#final_abv").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 70, height: 23, decimalDigits: 1 });
+	$("#final_svg").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 70, height: 23, decimalDigits: 1 });
 
 	// Tab 11, Packaging
 	$("#package_date").jqxTooltip({ content: 'De verpakkings datum van dit bier.' });
@@ -3400,9 +3461,45 @@
 			eq_mash_volume: parseFloat($("#eq_mash_volume").jqxNumberInput('decimal')),
 			eq_mash_max: parseFloat($("#eq_mash_max").jqxNumberInput('decimal')),
 			eq_efficiency: parseFloat($("#eq_efficiency").jqxNumberInput('decimal')),
-
+			brew_date_start: $("#brew_date_start").val(),
+			brew_mash_ph: parseFloat($("#brew_mash_ph").jqxNumberInput('decimal')),
+			brew_mash_sg: parseFloat($("#brew_mash_sg").jqxNumberInput('decimal')),
+			brew_sparge_temperature: parseFloat($("#brew_sparge_temperature").jqxNumberInput('decimal')),
+			brew_sparge_volume: parseFloat($("#brew_sparge_volume").jqxNumberInput('decimal')),
+			brew_sparge_ph: parseFloat($("#brew_sparge_ph").jqxNumberInput('decimal')),
+			brew_preboil_volume: parseFloat($("#brew_preboil_volume").jqxNumberInput('decimal')),
+			brew_preboil_sg: parseFloat($("#brew_preboil_sg").jqxNumberInput('decimal')),
+			brew_preboil_ph: parseFloat($("#brew_preboil_ph").jqxNumberInput('decimal')),
+			brew_aboil_volume: parseFloat($("#brew_aboil_volume").jqxNumberInput('decimal')),
+			brew_aboil_sg: parseFloat($("#brew_aboil_sg").jqxNumberInput('decimal')),
+			brew_aboil_ph: parseFloat($("#brew_aboil_ph").jqxNumberInput('decimal')),
+			brew_aboil_efficiency: parseFloat($("#brew_aboil_efficiency").jqxNumberInput('decimal')),
+			brew_cooling_method: $("#brew_cooling_method").val(),
+			brew_cooling_time: parseFloat($("#brew_cooling_time").jqxNumberInput('decimal')),
+			brew_cooling_to: parseFloat($("#brew_cooling_to").jqxNumberInput('decimal')),
+			brew_whirlpool9: parseFloat($("#brew_whirlpool9").jqxNumberInput('decimal')),
+			brew_whirlpool7: parseFloat($("#brew_whirlpool7").jqxNumberInput('decimal')),
+			brew_whirlpool6: parseFloat($("#brew_whirlpool6").jqxNumberInput('decimal')),
+			brew_whirlpool2: parseFloat($("#brew_whirlpool2").jqxNumberInput('decimal')),
+			brew_fermenter_volume: parseFloat($("#brew_fermenter_volume").jqxNumberInput('decimal')),
+			brew_fermenter_extrawater: parseFloat($("#brew_fermenter_extrawater").jqxNumberInput('decimal')),
+			brew_aeration_time: parseFloat($("#brew_aeration_time").jqxNumberInput('decimal')),
+			brew_aeration_speed: parseFloat($("#brew_aeration_speed").jqxNumberInput('decimal')),
+			brew_aeration_type: $("#brew_aeration_type").val(),
+			brew_fermenter_sg: parseFloat($("#brew_fermenter_sg").jqxNumberInput('decimal')),
+			brew_fermenter_ibu: parseFloat($("#brew_fermenter_ibu").jqxNumberInput('decimal')),
+			brew_date_end: $("#brew_date_end").val(),
+			brew_log_available: $("#brew_log_available").val(),
 			og: dataRecord.og,
 			fg: parseFloat($("#fg").jqxNumberInput('decimal')),
+			primary_start_temp: parseFloat($("#primary_start_temp").jqxNumberInput('decimal')),
+			primary_max_temp: parseFloat($("#primary_max_temp").jqxNumberInput('decimal')),
+			primary_end_temp: parseFloat($("#primary_end_temp").jqxNumberInput('decimal')),
+			primary_end_sg: parseFloat($("#primary_end_sg").jqxNumberInput('decimal')),
+			primary_end_date: $("#primary_end_date").val(),
+			secondary_temp: parseFloat($("#secondary_temp").jqxNumberInput('decimal')),
+			secondary_end_date: $("#secondary_end_date").val(),
+			tertiary_temp: parseFloat($("#tertiary_temp").jqxNumberInput('decimal')),
 			package_date: $("#package_date").val(),
 			bottle_amount: parseFloat($("#bottle_amount").jqxNumberInput('decimal')),
 			bottle_carbonation: parseFloat($("#bottle_carbonation").jqxNumberInput('decimal')),
--- a/www/prod_edit.php	Wed Jan 02 14:49:17 2019 +0100
+++ b/www/prod_edit.php	Wed Jan 02 17:34:53 2019 +0100
@@ -550,8 +550,72 @@
      <div style="overflow: hidden;">
       <table style="width: 100%;">
        <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">FG:</td>
-        <td align="left" style="vertical-align: top;"><div id="fg"></div></td>
+        <th style="text-align: center;" colspan="4">Hoofdvergisting</th>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">OG begin vergisting:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="brew_fermenter_sg2"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Start temperatuur hoofdvergisting &deg;C:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_start_temp"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Maximum temperatuur hoofdvergisting &deg;C:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_max_temp"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind temperatuur hoofdvergisting &deg;C:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_end_temp"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind SG hoofdvergisting:</td>
+	<td align="left" style="vertical-align: top;"><div id="primary_end_sg"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad:</td>
+        <td align="left" style="vertical-align: top;"><div id="primary_svg"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind hoofdvergisting/overhevelen:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_end_date"></div></td>
+       </tr>
+       <tr>
+        <td colspan="4"><hr></td>
+       </tr>
+       <tr>
+        <th style="text-align: center;" colspan="4">Nagisting</th>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Temperatuur nagisting &deg;C:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="secondary_temp"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind nagisting/start lageren:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="secondary_end_date"></div></td>
+       </tr>
+       <tr>
+        <td colspan="4"><hr></td>
+       </tr>
+       <tr>
+        <th style="text-align: center;" colspan="4">Lageren</th>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Temperatuur lageren &deg;C:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="tertiary_temp"></div></td>
+       </tr>
+       <tr>
+        <th style="text-align: center;" colspan="4">&nbsp;</th>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind SG:</td>
+	<td align="left" style="vertical-align: top;"><div id="fg"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Voorspeld:</td>
+        <td align="left" style="vertical-align: top;"><div id="est_fg2"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Alcohol percentage voor hergisting:</td>
+        <td align="left" style="vertical-align: top;"><div id="final_abv"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad:</td>
+        <td align="left" style="vertical-align: top;"><div id="final_svg"></div></td>
        </tr>
       </table>
      </div>

mercurial