# HG changeset patch # User Michiel Broek # Date 1545689452 -3600 # Node ID 2c9cfe2f086026dd405764eab43de845f54cfecd # Parent 159d7a89fcef7f76179643d8cf9cc937980c4f45 Merged prod_main and prod_recipe database tables into products. Added recipe tabs in the products editor. diff -r 159d7a89fcef -r 2c9cfe2f0860 www/import/from_brouwhulp.php --- a/www/import/from_brouwhulp.php Mon Dec 24 15:52:11 2018 +0100 +++ b/www/import/from_brouwhulp.php Mon Dec 24 23:10:52 2018 +0100 @@ -974,14 +974,10 @@ $len_mash = 0; echo " Start adding brews to the database\n"; - $psql = "TRUNCATE TABLE prod_main;"; - if (! $presult = mysqli_query($db, $psql)) { + $sql = "TRUNCATE TABLE products;"; + if (! $presult = mysqli_query($db, $sql)) { printf("Error: %s\n", mysqli_error($db)); } - $rsql = "TRUNCATE TABLE prod_recipes;"; - if (! $rresult = mysqli_query($db, $rsql)) { - printf("Error: %s\n", mysqli_error($db)); - } date_default_timezone_set('Europe/Amsterdam'); $recipes = simplexml_load_file($brouwhulp . '/brews.xml'); @@ -999,75 +995,70 @@ $stage = "Plan"; // Default value. $uuid = str_replace("\n", "", file_get_contents('/proc/sys/kernel/random/uuid')); - $psql = "INSERT INTO prod_main SET puuid='" . $uuid; // So we can link the records. - $rsql = "INSERT INTO prod_recipes SET uuid='" . $uuid; - - $psql .= "', pname='" . mysqli_real_escape_string($db, $recipe->NAME); - $rsql .= "', name='" . mysqli_real_escape_string($db, $recipe->NAME); + $sql = "INSERT INTO products SET uuid='" . $uuid; + $sql .= "', name='" . mysqli_real_escape_string($db, $recipe->NAME); if ($recipe->NOTES) { - $rsql .= "', notes='" . mysqli_real_escape_string($db, $recipe->NOTES); // Duplicate the notes - $psql .= "', pnotes='" . mysqli_real_escape_string($db, $recipe->NOTES); + $sql .= "', notes='" . mysqli_real_escape_string($db, $recipe->NOTES); } else { - $rsql .= "', notes='"; - $psql .= "', pnotes='"; + $sql .= "', notes='"; } if ($recipe->TYPE) - $rsql .= "', type='" . mysqli_real_escape_string($db, $recipe->TYPE); + $sql .= "', type='" . mysqli_real_escape_string($db, $recipe->TYPE); else - $rsql .= "', type='"; + $sql .= "', type='"; if ($recipe->BATCH_SIZE) $batch_size = floatval($recipe->BATCH_SIZE); - $rsql .= "', batch_size='" . $batch_size; + $sql .= "', batch_size='" . $batch_size; if ($recipe->BOIL_SIZE) $boil_size = floatval($recipe->BOIL_SIZE); - $rsql .= "', boil_size='" . $boil_size; + $sql .= "', boil_size='" . $boil_size; if ($recipe->BOIL_TIME) - $rsql .= "', boil_time='" . floatval($recipe->BOIL_TIME); + $sql .= "', boil_time='" . floatval($recipe->BOIL_TIME); else - $rsql .= "', boil_time='90"; + $sql .= "', boil_time='90"; if ($recipe->EFFICIENCY) $efficiency = floatval($recipe->EFFICIENCY); - $rsql .= "', efficiency='" . $efficiency; + $sql .= "', efficiency='" . $efficiency; /* Don't use $recipe->EST_OG but recalculate it */ /* Don't use $recipe->EST_FG but recalculate it */ /* Don't use $recipe->EST_COLOR but recalculate it */ if ($recipe->COLOR_METHOD) - $rsql .= "', color_method='" . mysqli_real_escape_string($db, $recipe->COLOR_METHOD); + $sql .= "', color_method='" . mysqli_real_escape_string($db, $recipe->COLOR_METHOD); if ($recipe->IBU) - $rsql .= "', est_ibu='" . floatval($recipe->IBU); + $sql .= "', est_ibu='" . floatval($recipe->IBU); if ($recipe->IBU_METHOD) - $rsql .= "', ibu_method='" . mysqli_real_escape_string($db, $recipe->IBU_METHOD); + $sql .= "', ibu_method='" . mysqli_real_escape_string($db, $recipe->IBU_METHOD); if ($recipe->CARBONATION) - $rsql .= "', est_carb='" . floatval($recipe->CARBONATION); + $sql .= "', est_carb='" . floatval($recipe->CARBONATION); if ($recipe->STYLE) { - $rsql .= recipe_style($recipe); + $sql .= recipe_style($recipe); } if ($recipe->CALC_ACID) { - ($recipe->CALC_ACID == "TRUE") ? $rsql .= "', calc_acid='1" : $rsql .= "', calc_acid='0"; + ($recipe->CALC_ACID == "TRUE") ? $sql .= "', calc_acid='1" : $sql .= "', calc_acid='0"; } if ($recipe->TARGET_PH) { - $rsql .= "', mash_ph='" . floatval($recipe->TARGET_PH); + $sql .= "', mash_ph='" . floatval($recipe->TARGET_PH); } if ($recipe->SPARGE_ACID_TYPE && ($recipe->SPARGE_ACID_TYPE == "Lactic")) { - $rsql .= "', sparge_acid_type='Melkzuur"; + $sql .= "', sparge_acid_type='Melkzuur"; } else if ($recipe->SPARGE_ACID_TYPE && ($recipe->SPARGE_ACID_TYPE == "Hydrochloric")) { - $rsql .= "', sparge_acid_type='Zoutzuur"; + $sql .= "', sparge_acid_type='Zoutzuur"; } else if ($recipe->SPARGE_ACID_TYPE && ($recipe->SPARGE_ACID_TYPE == "Phosphoric")) { - $rsql .= "', sparge_acid_type='Fosforzuur"; + $sql .= "', sparge_acid_type='Fosforzuur"; } else if ($recipe->SPARGE_ACID_TYPE && ($recipe->SPARGE_ACID_TYPE == "Sulfuric")) { - $rsql .= "', sparge_acid_type='Zwavelzuur"; + $sql .= "', sparge_acid_type='Zwavelzuur"; } if ($recipe->ACID_SPARGE_PERC) { - $rsql .= "', sparge_acid_perc='" . floatval($recipe->ACID_SPARGE_PERC); + $sql .= "', sparge_acid_perc='" . floatval($recipe->ACID_SPARGE_PERC); } if ($recipe->LACTIC_SPARGE) { - $rsql .= "', sparge_acid_amount='" . floatval($recipe->LACTIC_SPARGE); + $sql .= "', sparge_acid_amount='" . floatval($recipe->LACTIC_SPARGE); } if ($recipe->VOLUME_HLT) { - $rsql .= "', sparge_volume='" . floatval($recipe->VOLUME_HLT); + $sql .= "', sparge_volume='" . floatval($recipe->VOLUME_HLT); } /* @@ -1075,7 +1066,7 @@ */ if ($recipe->FERMENTABLES) { $fermentables = recipe_fermentables($recipe); - $rsql .= "', json_fermentables='" . $fermentables; + $sql .= "', json_fermentables='" . $fermentables; if (strlen($fermentables) > $len_fermentables) $len_fermentables = strlen($fermentables); } @@ -1085,7 +1076,7 @@ */ if ($recipe->HOPS) { $hops = recipe_hops($recipe); - $rsql .= "', json_hops='" . $hops; + $sql .= "', json_hops='" . $hops; if (strlen($hops) > $len_hops) $len_hops = strlen($hops); } @@ -1095,7 +1086,7 @@ */ if ($recipe->MISCS) { $miscs = recipe_miscs($recipe); - $rsql .= "', json_miscs='" . $miscs; + $sql .= "', json_miscs='" . $miscs; if (strlen($miscs) > $len_miscs) $len_miscs = strlen($miscs); } @@ -1105,7 +1096,7 @@ */ if ($recipe->YEASTS) { $yeasts = recipe_yeasts($recipe); - $rsql .= "', json_yeasts='" . $yeasts; + $sql .= "', json_yeasts='" . $yeasts; if (strlen($yeasts) > $len_yeasts) $len_yeasts = strlen($yeasts); } @@ -1114,21 +1105,21 @@ * Get the waters */ if ($recipe->WATERS) { - $rsql .= recipe_waters($recipe, $db); + $sql .= recipe_waters($recipe, $db); } /* * Put the mash in a json array */ if ($recipe->MASH) { - $rsql .= "',sparge_temp='" . floatval($recipe->MASH->SPARGE_TEMP); - $rsql .= "',sparge_ph='" . floatval($recipe->MASH->PH); + $sql .= "',sparge_temp='" . floatval($recipe->MASH->SPARGE_TEMP); + $sql .= "',sparge_ph='" . floatval($recipe->MASH->PH); if ($recipe->MASH->NAME) - $rsql .= "',mash_name='" . mysqli_real_escape_string($db, $recipe->MASH->NAME); + $sql .= "',mash_name='" . mysqli_real_escape_string($db, $recipe->MASH->NAME); if ($recipe->MASH->MASH_STEPS) { $steps = recipe_mash_steps($recipe); - $rsql .= "', json_mashs='" . $steps; + $sql .= "', json_mashs='" . $steps; if (strlen($steps) > $len_mash) $len_mash = strlen($steps); } @@ -1139,41 +1130,41 @@ * OG, FG, color, IBU */ $og = estimate_sg($f_sugars, $batch_size); - $rsql .= "', est_og='" . floatval($og); + $sql .= "', est_og='" . floatval($og); $fg = estimate_fg($pSugar, $pCara, 0, 0, 0, $svg, $og); - $rsql .= "', est_fg='" . floatval($fg); + $sql .= "', est_fg='" . floatval($fg); $abv = abvol($og, $fg); - $rsql .= "', est_abv='" . floatval($abv); + $sql .= "', est_abv='" . floatval($abv); $color = kw_to_ebc(mysqli_real_escape_string($db, $recipe->COLOR_METHOD), $colorw); - $rsql .= "', est_color='" . floatval($color); - $psql .= "', code='" . mysqli_real_escape_string($db, $recipe->NR_RECIPE); + $sql .= "', est_color='" . floatval($color); + $sql .= "', code='" . mysqli_real_escape_string($db, $recipe->NR_RECIPE); /* * Update external logfiles */ - $sql = "UPDATE log_brews SET product_uuid='".$uuid."', product_name='".mysqli_real_escape_string($db, $recipe->NAME); - $sql .= "' WHERE product_code='".mysqli_real_escape_string($db, $recipe->NR_RECIPE)."';"; - if (! $result = mysqli_query($db, $sql)) { + $lsql = "UPDATE log_brews SET product_uuid='".$uuid."', product_name='".mysqli_real_escape_string($db, $recipe->NAME); + $lsql .= "' WHERE product_code='".mysqli_real_escape_string($db, $recipe->NR_RECIPE)."';"; + if (! $result = mysqli_query($db, $lsql)) { printf("Error: %s\n", mysqli_error($db)); } $count = mysqli_affected_rows($db); if ($count > 0) { - $psql .= "', log_brew='1"; + $sql .= "', log_brew='1"; } - $sql = "UPDATE log_fermentation SET product_uuid='".$uuid."', product_name='".mysqli_real_escape_string($db, $recipe->NAME); - $sql .= "' WHERE product_code='".mysqli_real_escape_string($db, $recipe->NR_RECIPE)."';"; - if (! $result = mysqli_query($db, $sql)) { + $lsql = "UPDATE log_fermentation SET product_uuid='".$uuid."', product_name='".mysqli_real_escape_string($db, $recipe->NAME); + $lsql .= "' WHERE product_code='".mysqli_real_escape_string($db, $recipe->NR_RECIPE)."';"; + if (! $result = mysqli_query($db, $lsql)) { printf("Error: %s\n", mysqli_error($db)); } $count = mysqli_affected_rows($db); if ($count > 0) { - $psql .= "', log_fermentation='1"; + $sql .= "', log_fermentation='1"; } else { // See if there really are no records - $sql = "SELECT product_code FROM log_fermentation WHERE product_code='".$recipe->NR_RECIPE."';"; + $lsql = "SELECT product_code FROM log_fermentation WHERE product_code='".$recipe->NR_RECIPE."';"; $count = mysqli_affected_rows($db); if ($count > 0) { - $psql .= "', log_fermentation='1"; + $sql .= "', log_fermentation='1"; } } @@ -1199,47 +1190,47 @@ printf("Error: %s\n", mysqli_error($db)); } } - $psql .= "', log_fermentation='1"; + $sql .= "', log_fermentation='1"; } if ($recipe->EQUIPMENT) { - $psql .= "', eq_name='" . mysqli_real_escape_string($db, $recipe->EQUIPMENT->NAME); - $psql .= "', eq_notes='" . mysqli_real_escape_string($db, $recipe->EQUIPMENT->NOTES); - $psql .= "', eq_boil_size='" . floatval($recipe->EQUIPMENT->BOIL_SIZE); - $psql .= "', eq_batch_size='" . floatval($recipe->EQUIPMENT->BATCH_SIZE); - $psql .= "', eq_tun_volume='" . floatval($recipe->EQUIPMENT->TUN_VOLUME); - $psql .= "', eq_tun_weight='" . floatval($recipe->EQUIPMENT->TUN_WEIGHT); - $psql .= "', eq_tun_specific_heat='" . floatval($recipe->EQUIPMENT->TUN_SPECIFIC_HEAT); - $psql .= "', eq_tun_material='" . mysqli_real_escape_string($db, $recipe->EQUIPMENT->TUN_MATERIAL); - $psql .= "', eq_tun_height='" . floatval($recipe->EQUIPMENT->TUN_HEIGHT); + $sql .= "', eq_name='" . mysqli_real_escape_string($db, $recipe->EQUIPMENT->NAME); + $sql .= "', eq_notes='" . mysqli_real_escape_string($db, $recipe->EQUIPMENT->NOTES); + $sql .= "', eq_boil_size='" . floatval($recipe->EQUIPMENT->BOIL_SIZE); + $sql .= "', eq_batch_size='" . floatval($recipe->EQUIPMENT->BATCH_SIZE); + $sql .= "', eq_tun_volume='" . floatval($recipe->EQUIPMENT->TUN_VOLUME); + $sql .= "', eq_tun_weight='" . floatval($recipe->EQUIPMENT->TUN_WEIGHT); + $sql .= "', eq_tun_specific_heat='" . floatval($recipe->EQUIPMENT->TUN_SPECIFIC_HEAT); + $sql .= "', eq_tun_material='" . mysqli_real_escape_string($db, $recipe->EQUIPMENT->TUN_MATERIAL); + $sql .= "', eq_tun_height='" . floatval($recipe->EQUIPMENT->TUN_HEIGHT); if ($recipe->EQUIPMENT->TOP_UP_WATER) - $psql .= "', eq_top_up_water='" . floatval($recipe->EQUIPMENT->TOP_UP_WATER); - $psql .= "', eq_trub_chiller_loss='" . floatval($recipe->EQUIPMENT->TRUB_CHILLER_LOSS); + $sql .= "', eq_top_up_water='" . floatval($recipe->EQUIPMENT->TOP_UP_WATER); + $sql .= "', eq_trub_chiller_loss='" . floatval($recipe->EQUIPMENT->TRUB_CHILLER_LOSS); /* * Brouwhulp uses a percentage for the evaporation rate. This is wrong * but was made so because the beerxml standard requires this. What we * do is calculate the actual evaporation and store that. * This is what we use. Brouwhulp calculates this on the fly. */ - $psql .= "', eq_evap_rate='" . (floatval($recipe->EQUIPMENT->EVAP_RATE) * floatval($recipe->EQUIPMENT->BOIL_SIZE)) / 100; - $psql .= "', eq_boil_time='" . floatval($recipe->EQUIPMENT->BOIL_TIME); - ($recipe->EQUIPMENT->CALC_BOIL_VOLUME == 'TRUE') ? $psql .= "', eq_calc_boil_volume='1" : $psql .= "', eq_calc_boil_volume='0"; + $sql .= "', eq_evap_rate='" . (floatval($recipe->EQUIPMENT->EVAP_RATE) * floatval($recipe->EQUIPMENT->BOIL_SIZE)) / 100; + $sql .= "', eq_boil_time='" . floatval($recipe->EQUIPMENT->BOIL_TIME); + ($recipe->EQUIPMENT->CALC_BOIL_VOLUME == 'TRUE') ? $sql .= "', eq_calc_boil_volume='1" : $sql .= "', eq_calc_boil_volume='0"; if ($recipe->EQUIPMENT->TOP_UP_KETTLE) - $psql .= "', eq_top_up_kettle='" . floatval($recipe->EQUIPMENT->TOP_UP_KETTLE); - $psql .= "', eq_hop_utilization='" . floatval($recipe->EQUIPMENT->HOP_UTILIZATION); - $psql .= "', eq_lauter_volume='" . floatval($recipe->EQUIPMENT->LAUTER_VOLUME); - $psql .= "', eq_lauter_height='" . floatval($recipe->EQUIPMENT->LAUTER_HEIGHT); - $psql .= "', eq_lauter_deadspace='" . floatval($recipe->EQUIPMENT->LAUTER_DEADSPACE); - $psql .= "', eq_kettle_volume='" . floatval($recipe->EQUIPMENT->KETTLE_VOLUME); - $psql .= "', eq_kettle_height='" . floatval($recipe->EQUIPMENT->KETTLE_HEIGHT); - $psql .= "', eq_mash_volume='" . floatval($recipe->EQUIPMENT->MASH_VOLUME); - $psql .= "', eq_mash_max='" . round((floatval($recipe->EQUIPMENT->MASH_VOLUME) / 3) * 10) / 10; // Not in beerxml/brouwhulp. For RIMS systems. - $psql .= "', eq_efficiency='" . floatval($recipe->EQUIPMENT->EFFICIENCY); + $sql .= "', eq_top_up_kettle='" . floatval($recipe->EQUIPMENT->TOP_UP_KETTLE); + $sql .= "', eq_hop_utilization='" . floatval($recipe->EQUIPMENT->HOP_UTILIZATION); + $sql .= "', eq_lauter_volume='" . floatval($recipe->EQUIPMENT->LAUTER_VOLUME); + $sql .= "', eq_lauter_height='" . floatval($recipe->EQUIPMENT->LAUTER_HEIGHT); + $sql .= "', eq_lauter_deadspace='" . floatval($recipe->EQUIPMENT->LAUTER_DEADSPACE); + $sql .= "', eq_kettle_volume='" . floatval($recipe->EQUIPMENT->KETTLE_VOLUME); + $sql .= "', eq_kettle_height='" . floatval($recipe->EQUIPMENT->KETTLE_HEIGHT); + $sql .= "', eq_mash_volume='" . floatval($recipe->EQUIPMENT->MASH_VOLUME); + $sql .= "', eq_mash_max='" . round((floatval($recipe->EQUIPMENT->MASH_VOLUME) / 3) * 10) / 10; // Not in beerxml/brouwhulp. For RIMS systems. + $sql .= "', eq_efficiency='" . floatval($recipe->EQUIPMENT->EFFICIENCY); } if (($recipe->DATE) && (! $recipe->TIME_STARTED) && (! $recipe->TIME_ENDED)) { /* We have a plan date but haven't brewed yet, use current date */ - $psql .= "', birth='" . date("Y-m-d"); + $sql .= "', birth='" . date("Y-m-d"); $stageno= 1; $stage = "Wait"; } @@ -1249,74 +1240,74 @@ $stageno = 3; $stage = "Primary"; // Need to think about during a brew... $brewdate = substr($recipe->DATE, 6, 4).substr($recipe->DATE,2,4).substr($recipe->DATE,0,2); - $psql .= "', birth='" . $brewdate; + $sql .= "', birth='" . $brewdate; $date_start = $brewdate.' '.$recipe->TIME_STARTED; $date_end = $brewdate.' '.$recipe->TIME_ENDED; - $psql .= "', brew_date_start='" . $date_start; + $sql .= "', brew_date_start='" . $date_start; if ($recipe->PH_ADJUSTED) - $psql .= "', brew_mash_ph='" . floatval($recipe->PH_ADJUSTED); + $sql .= "', brew_mash_ph='" . floatval($recipe->PH_ADJUSTED); if (floatval($recipe->SG_END_MASH) != 1.0) - $psql .= "', brew_mash_sg='" . floatval($recipe->SG_END_MASH); + $sql .= "', brew_mash_sg='" . floatval($recipe->SG_END_MASH); if ($recipe->MASH->SPARGE_TEMP) - $psql .= "', brew_sparge_temperature='" . floatval($recipe->MASH->SPARGE_TEMP); + $sql .= "', brew_sparge_temperature='" . floatval($recipe->MASH->SPARGE_TEMP); if ($recipe->MASH->PH) - $psql .= "', brew_sparge_ph='" . floatval($recipe->MASH->PH); + $sql .= "', brew_sparge_ph='" . floatval($recipe->MASH->PH); if ($recipe->VOLUME_HLT) - $psql .= "', brew_sparge_volume='" . floatval($recipe->VOLUME_HLT); + $sql .= "', brew_sparge_volume='" . floatval($recipe->VOLUME_HLT); if ($recipe->VOLUME_BEFORE_BOIL) - $psql .= "', brew_preboil_volume='" . floatval($recipe->VOLUME_BEFORE_BOIL); + $sql .= "', brew_preboil_volume='" . floatval($recipe->VOLUME_BEFORE_BOIL); if (floatval($recipe->OG_BEFORE_BOIL) != 1.0) - $psql .= "', brew_preboil_sg='" . floatval($recipe->OG_BEFORE_BOIL); + $sql .= "', brew_preboil_sg='" . floatval($recipe->OG_BEFORE_BOIL); if ($recipe->PH_BEFORE_BOIL) - $psql .= "', brew_preboil_ph='" . floatval($recipe->PH_BEFORE_BOIL); + $sql .= "', brew_preboil_ph='" . floatval($recipe->PH_BEFORE_BOIL); if ($recipe->VOLUME_AFTER_BOIL) - $psql .= "', brew_aboil_volume='" . floatval($recipe->VOLUME_AFTER_BOIL); - $psql .= "', brew_aboil_sg='" . floatval($recipe->OG); + $sql .= "', brew_aboil_volume='" . floatval($recipe->VOLUME_AFTER_BOIL); + $sql .= "', brew_aboil_sg='" . floatval($recipe->OG); if ($recipe->PH_AFTER_BOIL) - $psql .= "', brew_aboil_ph='" . floatval($recipe->PH_AFTER_BOIL); + $sql .= "', brew_aboil_ph='" . floatval($recipe->PH_AFTER_BOIL); if ($recipe->ACTUAL_EFFICIENCY) - $psql .= "', brew_aboil_efficiency='" . floatval($recipe->ACTUAL_EFFICIENCY); - $psql .= "', brew_whirlpool2='" . floatval($recipe->WHIRLPOOL_TIME); - $psql .= "', brew_cooling_method='" . mysqli_real_escape_string($db, $recipe->COOLING_METHOD); - $psql .= "', brew_cooling_time='" . floatval($recipe->COOLING_TIME); - $psql .= "', brew_cooling_to='" . floatval($recipe->COOLING_TO); + $sql .= "', brew_aboil_efficiency='" . floatval($recipe->ACTUAL_EFFICIENCY); + $sql .= "', brew_whirlpool2='" . floatval($recipe->WHIRLPOOL_TIME); + $sql .= "', brew_cooling_method='" . mysqli_real_escape_string($db, $recipe->COOLING_METHOD); + $sql .= "', brew_cooling_time='" . floatval($recipe->COOLING_TIME); + $sql .= "', brew_cooling_to='" . floatval($recipe->COOLING_TO); if ($recipe->VOLUME_FERMENTER) - $psql .= "', brew_fermenter_volume='" . floatval($recipe->VOLUME_FERMENTER); + $sql .= "', brew_fermenter_volume='" . floatval($recipe->VOLUME_FERMENTER); if ($recipe->EQUIPMENT->TOP_UP_WATER_BREWDAY) - $psql .= "', brew_fermenter_extrawater='" . floatval($recipe->EQUIPMENT->TOP_UP_WATER_BREWDAY); - $psql .= "', brew_fermenter_sg='" . floatval($recipe->OG_FERMENTER); - $psql .= "', brew_fermenter_ibu='" . floatval($recipe->IBU); - $psql .= "', brew_aeration_type='" . mysqli_real_escape_string($db, $recipe->AERATION_TYPE); + $sql .= "', brew_fermenter_extrawater='" . floatval($recipe->EQUIPMENT->TOP_UP_WATER_BREWDAY); + $sql .= "', brew_fermenter_sg='" . floatval($recipe->OG_FERMENTER); + $sql .= "', brew_fermenter_ibu='" . floatval($recipe->IBU); + $sql .= "', brew_aeration_type='" . mysqli_real_escape_string($db, $recipe->AERATION_TYPE); if ($recipe->AERATION_TYPE != "None") { - $psql .= "', brew_aeration_speed='" . floatval($recipe->AERATION_SPEED); - $psql .= "', brew_aeration_time='" . floatval($recipe->AERATION_TIME); + $sql .= "', brew_aeration_speed='" . floatval($recipe->AERATION_SPEED); + $sql .= "', brew_aeration_time='" . floatval($recipe->AERATION_TIME); } - $psql .= "', brew_date_end='" . $date_end; + $sql .= "', brew_date_end='" . $date_end; } if ($recipe->PRIMARY_AGE && ($stageno >= 3)) { /* PRIMARY_TEMP is the average of START_TEMP_PRIMARY MAX_TEMP_PRIMARY END_TEMP_PRIMARY */ $pdate = new DateTime($brewdate); $pdate->modify("+".floatval($recipe->PRIMARY_AGE)." days"); - $psql .= "', primary_start_temp='" . floatval($recipe->START_TEMP_PRIMARY); - $psql .= "', primary_max_temp='" . floatval($recipe->MAX_TEMP_PRIMARY); - $psql .= "', primary_end_temp='" . floatval($recipe->END_TEMP_PRIMARY); - $psql .= "', primary_end_sg='" . floatval($recipe->SG_END_PRIMARY); - $psql .= "', primary_end_date='" . $pdate->format("Y-m-d"); + $sql .= "', primary_start_temp='" . floatval($recipe->START_TEMP_PRIMARY); + $sql .= "', primary_max_temp='" . floatval($recipe->MAX_TEMP_PRIMARY); + $sql .= "', primary_end_temp='" . floatval($recipe->END_TEMP_PRIMARY); + $sql .= "', primary_end_sg='" . floatval($recipe->SG_END_PRIMARY); + $sql .= "', primary_end_date='" . $pdate->format("Y-m-d"); $stageno = 4; $stage = "Secondary"; if ($recipe->SECONDARY_AGE && ($stageno >= 4)) { $sdate = new DateTime($brewdate); $sdate->modify("+".floatval($recipe->SECONDARY_AGE)." days"); - $psql .= "', secondary_temp='" . floatval($recipe->SECONDARY_TEMP); - $psql .= "', secondary_end_date='" . $sdate->format("Y-m-d"); + $sql .= "', secondary_temp='" . floatval($recipe->SECONDARY_TEMP); + $sql .= "', secondary_end_date='" . $sdate->format("Y-m-d"); $stageno = 5; $stage = "Tertiary"; if ($recipe->TERTIARY_TEMP && ($stageno >= 5)) { - $psql .= "', tertiary_temp='" . floatval($recipe->TERTIARY_TEMP); + $sql .= "', tertiary_temp='" . floatval($recipe->TERTIARY_TEMP); } } } @@ -1324,7 +1315,7 @@ if ($recipe->DATE_BOTTLING && ($recipe->AMOUNT_BOTTLING || $recipe->AMOUNT_KEGGED) && ($recipe->AMOUNT_PRIMING || $recipe->AMOUNT_PRIMING_KEGS) && ($stageno >= 5)) { $bdate = substr($recipe->DATE_BOTTLING, 6, 4).substr($recipe->DATE_BOTTLING,2,4).substr($recipe->DATE_BOTTLING,0,2); - $psql .= "', package_date='" . $bdate; + $sql .= "', package_date='" . $bdate; $stage = "Package"; $stageno = 6; $dStart = new DateTime($bdate); @@ -1346,61 +1337,54 @@ } if ($recipe->AMOUNT_BOTTLING && $recipe->AMOUNT_PRIMING) { - $psql .= "', bottle_amount='" . floatval($recipe->AMOUNT_BOTTLING); - $psql .= "', bottle_carbonation='" . floatval($recipe->CARBONATION); - $psql .= "', bottle_priming_sugar='" . mysqli_real_escape_string($db, $recipe->PRIMING_SUGAR_BOTTLES); - $psql .= "', bottle_priming_amount='" . floatval($recipe->AMOUNT_PRIMING); - $psql .= "', bottle_carbonation_temp='" . floatval($recipe->CARBONATION_TEMP); + $sql .= "', bottle_amount='" . floatval($recipe->AMOUNT_BOTTLING); + $sql .= "', bottle_carbonation='" . floatval($recipe->CARBONATION); + $sql .= "', bottle_priming_sugar='" . mysqli_real_escape_string($db, $recipe->PRIMING_SUGAR_BOTTLES); + $sql .= "', bottle_priming_amount='" . floatval($recipe->AMOUNT_PRIMING); + $sql .= "', bottle_carbonation_temp='" . floatval($recipe->CARBONATION_TEMP); } if ($recipe->AMOUNT_KEGGED && $recipe->AMOUNT_PRIMING_KEGS) { - $psql .= "', keg_amount='" . floatval($recipe->AMOUNT_KEGGED); - $psql .= "', keg_carbonation='" . floatval($recipe->CARBONATION); // Lijkt wel hetzelfde als bottles - $psql .= "', keg_priming_sugar='" . mysqli_real_escape_string($db, $recipe->PRIMING_SUGAR_KEGS); - $psql .= "', keg_priming_amount='" . floatval($recipe->AMOUNT_PRIMING_KEGS); - $psql .= "', keg_carbonation_temp='" . floatval($recipe->KEG_CARB_TEMP); - ($recipe->FORCED_CARB_KEGS == 'TRUE') ? $psql .= "', keg_forced_carb='1" : $psql .= "', keg_forced_carb='0"; - $psql .= "', keg_pressure='" . floatval($recipe->KEG_PRESSURE); - $psql .= "', keg_priming_factor='" . floatval($recipe->KEG_PRIMING_FACTOR); + $sql .= "', keg_amount='" . floatval($recipe->AMOUNT_KEGGED); + $sql .= "', keg_carbonation='" . floatval($recipe->CARBONATION); // Lijkt wel hetzelfde als bottles + $sql .= "', keg_priming_sugar='" . mysqli_real_escape_string($db, $recipe->PRIMING_SUGAR_KEGS); + $sql .= "', keg_priming_amount='" . floatval($recipe->AMOUNT_PRIMING_KEGS); + $sql .= "', keg_carbonation_temp='" . floatval($recipe->KEG_CARB_TEMP); + ($recipe->FORCED_CARB_KEGS == 'TRUE') ? $sql .= "', keg_forced_carb='1" : $sql .= "', keg_forced_carb='0"; + $sql .= "', keg_pressure='" . floatval($recipe->KEG_PRESSURE); + $sql .= "', keg_priming_factor='" . floatval($recipe->KEG_PRIMING_FACTOR); } } if ($recipe->TASTE_NOTES && $recipe->TASTING_RATE && $recipe->TASTE_DATE && ($stageno >= 9)) { $stage = "Ready"; // Ready if tasted. $stageno = 10; - $psql .= "', taste_notes='" . mysqli_real_escape_string($db, $recipe->TASTE_NOTES); - $psql .= "', taste_rate='" . floatval($recipe->TASTING_RATE); + $sql .= "', taste_notes='" . mysqli_real_escape_string($db, $recipe->TASTE_NOTES); + $sql .= "', taste_rate='" . floatval($recipe->TASTING_RATE); $tdate = substr($recipe->TASTE_DATE, 6, 4).substr($recipe->TASTE_DATE,2,4).substr($recipe->TASTE_DATE,0,2); - $psql .= "', taste_date='" . $tdate; - $psql .= "', taste_color='" . mysqli_real_escape_string($db, $recipe->TASTE_COLOR); - $psql .= "', taste_transparency='" . mysqli_real_escape_string($db, $recipe->TASTE_TRANSPARENCY); - $psql .= "', taste_head='" . mysqli_real_escape_string($db, $recipe->TASTE_HEAD); - $psql .= "', taste_aroma='" . mysqli_real_escape_string($db, $recipe->TASTE_AROMA); - $psql .= "', taste_taste='" . mysqli_real_escape_string($db, $recipe->TASTE_TASTE); - $psql .= "', taste_mouthfeel='" . mysqli_real_escape_string($db, $recipe->TASTE_MOUTHFEEL); - $psql .= "', taste_aftertaste='" . mysqli_real_escape_string($db, $recipe->TASTE_AFTERTASTE); + $sql .= "', taste_date='" . $tdate; + $sql .= "', taste_color='" . mysqli_real_escape_string($db, $recipe->TASTE_COLOR); + $sql .= "', taste_transparency='" . mysqli_real_escape_string($db, $recipe->TASTE_TRANSPARENCY); + $sql .= "', taste_head='" . mysqli_real_escape_string($db, $recipe->TASTE_HEAD); + $sql .= "', taste_aroma='" . mysqli_real_escape_string($db, $recipe->TASTE_AROMA); + $sql .= "', taste_taste='" . mysqli_real_escape_string($db, $recipe->TASTE_TASTE); + $sql .= "', taste_mouthfeel='" . mysqli_real_escape_string($db, $recipe->TASTE_MOUTHFEEL); + $sql .= "', taste_aftertaste='" . mysqli_real_escape_string($db, $recipe->TASTE_AFTERTASTE); } - ($recipe->INVENTORY_REDUCED == 'TRUE') ? $psql .= "', inventory_reduced='1" : $psql .= "', inventory_reduced='0"; + ($recipe->INVENTORY_REDUCED == 'TRUE') ? $sql .= "', inventory_reduced='1" : $sql .= "', inventory_reduced='0"; if (($recipe->LOCKED == 'TRUE') && ($stage == 'Ready')) { - $psql .= "', plocked='1"; - $rsql .= "', locked='1"; + $sql .= "', locked='1"; $stage = "Closed"; $stageno = 11; } else { - $psql .= "', plocked='0"; - $rsql .= "', locked='0"; + $sql .= "', locked='0"; } - $psql .= "', stage='" . $stage; + $sql .= "', stage='" . $stage; // echo ' '.$brewdate.' '.$recipe->NR_RECIPE.' '.$stage . PHP_EOL; - $rsql .= "';"; - if (! $rresult = mysqli_query($db, $rsql)) { - printf("Error: %s\n", mysqli_error($db)); - } - - $psql .= "';"; - if (! $presult = mysqli_query($db, $psql)) { + $sql .= "';"; + if (! $rresult = mysqli_query($db, $sql)) { printf("Error: %s\n", mysqli_error($db)); } } diff -r 159d7a89fcef -r 2c9cfe2f0860 www/includes/db_product.php --- a/www/includes/db_product.php Mon Dec 24 15:52:11 2018 +0100 +++ b/www/includes/db_product.php Mon Dec 24 23:10:52 2018 +0100 @@ -12,25 +12,55 @@ $escapers = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c"); $replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b"); - +$rescapers = array("'"); +$rreplacements = array("\\'"); +$disallowed = array('visibleindex','uniqueid','boundindex','uid','h_weight','m_weight'); if (isset($_POST['insert']) || isset($_POST['update'])) { if (isset($_POST['insert'])) { - $sql = "INSERT INTO `prod_main` SET "; + $sql = "INSERT INTO `products` SET "; } if (isset($_POST['update'])) { - $sql = "UPDATE `prod_main` SET "; + $sql = "UPDATE `products` SET "; } + + $stage = $_POST['stage']; + if ($stage == 'Plan') + $stageno = 0; + else if ($stage == 'Wait') + $stageno = 1; + else if ($stage == 'Brew') + $stageno = 2; + else if ($stage == 'Primary') + $stageno = 3; + else if ($stage == 'Secondary') + $stageno = 4; + else if ($stage == 'Tertiary') + $stageno = 5; + else if ($stage == 'Package') + $stageno = 6; + else if ($stage == 'Carbonation') + $stageno = 7; + else if ($stage == 'Mature') + $stageno = 8; + else if ($stage == 'Taste') + $stageno = 9; + else if ($stage == 'Ready') + $stageno = 10; + else if ($stage == 'Closed') + $stageno = 11; + // Basic settings - $sql .= "puuid='" . $_POST['puuid']; - $sql .= "', pname='" . mysqli_real_escape_string($connect, $_POST['pname']); + $sql .= "uuid='" . $_POST['uuid']; + $sql .= "', name='" . mysqli_real_escape_string($connect, $_POST['name']); + $sql .= "', code='" . mysqli_real_escape_string($connect, $_POST['code']); $sql .= "', birth='" . $_POST['birth']; $sql .= "', stage='" . $_POST['stage']; - $sql .= "', pnotes='" . mysqli_real_escape_string($connect, $_POST['pnotes']); + $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"; - ($_POST['plocked'] == 'true') ? $sql .= "', plocked='1" : $sql .= "', plocked='0"; + ($_POST['locked'] == 'true') ? $sql .= "', locked='1" : $sql .= "', locked='0"; // Equipment $sql .= "', eq_name='" . mysqli_real_escape_string($connect, $_POST['eq_name']); $sql .= "', eq_boil_size='" . $_POST['eq_boil_size']; @@ -57,6 +87,7 @@ $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 @@ -86,14 +117,26 @@ // brew_fermenter_ibu // brew_date_end // brew_log_available + } + + if ($stageno >= 3) { // primary_start_temp // primary_max_temp // primary_end_temp // primary_end_sg - // primary_end_date + // primary_end_date + } + + if ($stageno >= 4) { // secondary_temp - // secondary_end_date - // tertiary_temp + // secondary_end_date + } + + if ($stageno >= 5) { + // tertiary_temp + } + + if ($stageno >= 6) { // package_date // bottle_amount // bottle_carbonation @@ -107,7 +150,10 @@ // keg_carbonation_temp // keg_forced_carb // keg_pressure - // keg_priming_factor + // keg_priming_factor + } + + if ($stageno >= 9) { // taste_notes // taste_rate // taste_date @@ -117,8 +163,133 @@ // taste_aroma // taste_taste // taste_mouthfeel - // taste_aftertaste + // taste_aftertaste + } + + /* + * Recipe part + */ +// $sql .= "', st_name='" . mysqli_real_escape_string($connect, $_POST['st_name']); +// $sql .= "', st_letter='" . mysqli_real_escape_string($connect, $_POST['st_letter']); +// $sql .= "', st_guide='" . mysqli_real_escape_string($connect, $_POST['st_guide']); +// $sql .= "', st_type='" . mysqli_real_escape_string($connect, $_POST['st_type']); +// $sql .= "', st_category='" . mysqli_real_escape_string($connect, $_POST['st_category']); +// $sql .= "', st_category_number='" . $_POST['st_category_number']; + $sql .= "', st_og_min='" . $_POST['st_og_min']; + $sql .= "', st_og_max='" . $_POST['st_og_max']; + $sql .= "', st_fg_min='" . $_POST['st_fg_min']; + $sql .= "', st_fg_max='" . $_POST['st_fg_max']; + $sql .= "', st_ibu_min='" . $_POST['st_ibu_min']; + $sql .= "', st_ibu_max='" . $_POST['st_ibu_max']; + $sql .= "', st_color_min='" . $_POST['st_color_min']; + $sql .= "', st_color_max='" . $_POST['st_color_max']; + $sql .= "', st_carb_min='" . $_POST['st_carb_min']; + $sql .= "', st_carb_max='" . $_POST['st_carb_max']; + $sql .= "', st_abv_min='" . $_POST['st_abv_min']; + $sql .= "', st_abv_max='" . $_POST['st_abv_max']; + $sql .= "', type='" . $_POST['type']; + $sql .= "', batch_size='" . $_POST['batch_size']; + $sql .= "', boil_size='" . $_POST['boil_size']; + $sql .= "', boil_time='" . $_POST['boil_time']; + $sql .= "', efficiency='" . $_POST['efficiency']; + $sql .= "', est_og='" . $_POST['est_og']; + $sql .= "', est_fg='" . $_POST['est_fg']; + $sql .= "', est_abv='" . $_POST['est_abv']; + $sql .= "', est_carb='" . $_POST['est_carb']; + $sql .= "', est_color='" . $_POST['est_color']; + $sql .= "', color_method='" . $_POST['color_method']; + $sql .= "', est_ibu='" . $_POST['est_ibu']; + $sql .= "', ibu_method='" . $_POST['ibu_method']; + $sql .= "', sparge_temp='" . $_POST['sparge_temp']; + $sql .= "', sparge_ph='" . $_POST['sparge_ph']; + $sql .= "', sparge_volume='" . $_POST['sparge_volume']; +// $sql .= "', sparge_acid_type='" . $_POST['sparge_acid_type']; +// $sql .= "', sparge_acid_perc='" . $_POST['sparge_acid_perc']; +// $sql .= "', sparge_acid_amount='" . $_POST['sparge_acid_amount']; + $sql .= "', mash_ph='" . $_POST['mash_ph']; + $sql .= "', mash_name='" . $_POST['mash_name']; + $sql .= "', calc_acid='" . $_POST['calc_acid']; + if (isset($_POST['w1_name'])) { + $sql .= "', w1_name='" . mysqli_real_escape_string($connect, $_POST['w1_name']); + $sql .= "', w1_amount='" . $_POST['w1_amount']; + $sql .= "', w1_calcium='" . $_POST['w1_calcium']; + $sql .= "', w1_sulfate='" . $_POST['w1_sulfate']; + $sql .= "', w1_chloride='" . $_POST['w1_chloride']; + $sql .= "', w1_sodium='" . $_POST['w1_sodium']; + $sql .= "', w1_magnesium='" . $_POST['w1_magnesium']; + $sql .= "', w1_total_alkalinity='" . $_POST['w1_total_alkalinity']; + $sql .= "', w1_ph='" . $_POST['w1_ph']; + $sql .= "', w1_cost='" . $_POST['w1_cost']; + } + if (isset($_POST['w2_name'])) { + $sql .= "', w2_name='" . mysqli_real_escape_string($connect, $_POST['w2_name']); + $sql .= "', w2_amount='" . $_POST['w2_amount']; + $sql .= "', w2_calcium='" . $_POST['w2_calcium']; + $sql .= "', w2_sulfate='" . $_POST['w2_sulfate']; + $sql .= "', w2_chloride='" . $_POST['w2_chloride']; + $sql .= "', w2_sodium='" . $_POST['w2_sodium']; + $sql .= "', w2_magnesium='" . $_POST['w2_magnesium']; + $sql .= "', w2_total_alkalinity='" . $_POST['w2_total_alkalinity']; + $sql .= "', w2_ph='" . $_POST['w2_ph']; + $sql .= "', w2_cost='" . $_POST['w2_cost']; + } syslog(LOG_NOTICE, $sql); + + if (isset($_POST['fermentables'])) { + $array = $_POST['fermentables']; + foreach($array as $key => $item){ + foreach ($disallowed as $disallowed_key) { + unset($array[$key]["$disallowed_key"]); + } + } + syslog(LOG_NOTICE, "json_fermentables=: ".str_replace($rescapers,$rreplacements,json_encode($array))); + $sql .= "', json_fermentables='" . str_replace($rescapers,$rreplacements,json_encode($array)); + } + + if (isset($_POST['hops'])) { + $array = $_POST['hops']; + foreach($array as $key => $item){ + foreach ($disallowed as $disallowed_key) { + unset($array[$key]["$disallowed_key"]); + } + } + syslog(LOG_NOTICE, "json_hops: ".str_replace($rescapers,$rreplacements,json_encode($array))); + $sql .= "', json_hops='" . str_replace($rescapers,$rreplacements,json_encode($array)); + } + + if (isset($_POST['miscs'])) { + $array = $_POST['miscs']; + foreach($array as $key => $item){ + foreach ($disallowed as $disallowed_key) { + unset($array[$key]["$disallowed_key"]); + } + } + syslog(LOG_NOTICE, "json_miscs: ".str_replace($rescapers,$rreplacements,json_encode($array))); + $sql .= "', json_miscs='" . str_replace($rescapers,$rreplacements,json_encode($array)); + } + + if (isset($_POST['yeasts'])) { + $array = $_POST['yeasts']; + foreach($array as $key => $item){ + foreach ($disallowed as $disallowed_key) { + unset($array[$key]["$disallowed_key"]); + } + } + syslog(LOG_NOTICE, "json_yeasts: ". str_replace($rescapers,$rreplacements,json_encode($array))); + $sql .= "', json_yeasts='" . str_replace($rescapers,$rreplacements,json_encode($array)); + } + + if (isset($_POST['mashs'])) { + $array = $_POST['mashs']; + foreach($array as $key => $item){ + foreach ($disallowed as $disallowed_key) { + unset($array[$key]["$disallowed_key"]); + } + } + syslog(LOG_NOTICE, "json_mashs: ".str_replace($rescapers,$rreplacements,json_encode($array))); + $sql .= "', json_mashs='" . str_replace($rescapers,$rreplacements,json_encode($array)); + } + if (isset($_POST['insert'])) { $sql .= "';"; } @@ -144,17 +315,9 @@ } else if (isset($_POST['delete'])) { /* - * DELETE command, first delete the recipe and then the product. + * DELETE command. */ - $sql = "DELETE FROM `prod_recipes` WHERE uuid='".$_POST['uuid']."';"; - $result = mysqli_query($connect, $sql); - if (! $result) { - syslog(LOG_NOTICE, "db_product: ".$sql." result: ".mysqli_error($connect)); - } else { - syslog(LOG_NOTICE, "db_product: deleted recipe uuid ".$_POST['uuid']); - } - - $sql = "DELETE FROM `prod_main` WHERE puuid='".$_POST['uuid']."';"; + $sql = "DELETE FROM `products` WHERE uuid='".$_POST['uuid']."';"; $result = mysqli_query($connect, $sql); if (! $result) { syslog(LOG_NOTICE, "db_product: ".$sql." result: ".mysqli_error($connect)); @@ -168,12 +331,12 @@ * SELECT, produce a list of products that are not yet Closed. */ if (isset($_GET['select']) && ($_GET['select'] == "inprod")) { - $query = "SELECT record,pname,code,birth,stage FROM prod_main WHERE stage != 'Closed' ORDER BY birth,code;"; + $query = "SELECT record,name,code,birth,stage FROM products WHERE stage != 'Closed' ORDER BY birth,code;"; $result = mysqli_query($connect, $query) or die("SQL Error 1: " . mysqli_error($connect)); while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) { $brews[] = array( 'record' => $row['record'], - 'pname' => $row['pname'], + 'name' => $row['name'], 'code' => $row['code'], 'birth' => $row['birth'], 'stage' => $row['stage'] @@ -187,10 +350,9 @@ * Default, select all or a given record. */ if (isset($_GET['record'])) { - $query = "SELECT * FROM prod_main LEFT JOIN prod_recipes ON puuid = uuid WHERE prod_main.record='"; - $query .= $_GET['record'] . "';"; + $query = "SELECT * FROM products WHERE record='" . $_GET['record'] . "';"; } else { - $query = "SELECT * FROM prod_main LEFT JOIN prod_recipes ON puuid = uuid ORDER BY birth,code;"; + $query = "SELECT * FROM products ORDER BY birth,code;"; } $result = mysqli_query($connect, $query) or die("SQL Error 1: " . mysqli_error($connect)); $brews = '['; @@ -201,16 +363,16 @@ $brews .= ','; $comma = TRUE; $brew = '{"record":' . $row['record']; - $brew .= ',"puuid":"' . str_replace($escapers, $replacements, $row['puuid']); - $brew .= '","pname":"' . str_replace($escapers, $replacements, $row['pname']); + $brew .= ',"uuid":"' . str_replace($escapers, $replacements, $row['uuid']); + $brew .= '","name":"' . str_replace($escapers, $replacements, $row['name']); $brew .= '","code":"' . str_replace($escapers, $replacements, $row['code']); $brew .= '","birth":"' . str_replace($escapers, $replacements, $row['birth']); $brew .= '","stage":"' . str_replace($escapers, $replacements, $row['stage']); - $brew .= '","pnotes":"' . str_replace($escapers, $replacements, $row['pnotes']); + $brew .= '","notes":"' . str_replace($escapers, $replacements, $row['notes']); $brew .= '","log_brew":' . $row['log_brew']; $brew .= ',"log_fermentation":' . $row['log_fermentation']; $brew .= ',"inventory_reduced":' . $row['inventory_reduced']; - $brew .= ',"plocked":' . $row['plocked']; + $brew .= ',"locked":' . $row['locked']; $brew .= ',"eq_name":"' . str_replace($escapers, $replacements, $row['eq_name']); $brew .= '","eq_notes":"' . str_replace($escapers, $replacements, $row['eq_notes']); $brew .= '","eq_boil_size":' . floatval($row['eq_boil_size']); @@ -316,8 +478,7 @@ $brew .= ',"st_carb_max":' . floatval($row['st_carb_max']); $brew .= ',"st_abv_min":' . floatval($row['st_abv_min']); $brew .= ',"st_abv_max":' . floatval($row['st_abv_max']); - $brew .= ',"notes":"' . str_replace($escapers, $replacements, $row['notes']); - $brew .= '","type":"' . $row['type']; + $brew .= ',"type":"' . $row['type']; $brew .= '","batch_size":' . floatval($row['batch_size']); $brew .= ',"boil_size":' . floatval($row['boil_size']); $brew .= ',"boil_time":' . floatval($row['boil_time']); @@ -365,6 +526,7 @@ $brew .= ',"yeasts":' . $row['json_yeasts']; $brew .= ',"mashs":' . $row['json_mashs']; $brew .= '}'; +// syslog(LOG_NOTICE, $brew); $brews .= $brew; } $brews .= ']'; diff -r 159d7a89fcef -r 2c9cfe2f0860 www/js/prod_edit.js --- a/www/js/prod_edit.js Mon Dec 24 15:52:11 2018 +0100 +++ b/www/js/prod_edit.js Mon Dec 24 23:10:52 2018 +0100 @@ -53,11 +53,42 @@ var sugarsf = 0; // Sugars after boil var psugar = 0; // Percentage real sugars var pcara = 0; // Percentage cara/crystal malts + var svg = 77; // Default attenuation + var mashkg = 0; // Malt in mash weight + var hop_flavour = 0; + var hop_aroma = 0; + var mash_infuse = 0; + var last_base = ''; + var last_acid = ''; + + var MMCa = 40.048; + var MMMg = 24.305; + var MMNa = 22.98976928; + var MMCl = 35.453; + var MMSO4 = 96.0626; + var MMCO3 = 60.01684; + var MMHCO3 = 61.01684; + var MMCaSO4 = 172.171; + var MMCaCl2 = 147.015; + var MMCaCO3 = 100.087; + var MMMgSO4 = 246.475; + var MMNaHCO3 = 84.007; + var MMNa2CO3 = 105.996; + var MMNaCl = 58.443; + var MMCaOH2 = 74.06268; + var old_efficiency; var old_batch_size; var old_boil_time; console.log("record:" + my_record + " return:" + my_return + " theme:" + theme); + $("#jqxLoader").jqxLoader({ + width: 250, + height: 150, + isModal: true, + text: "Laden product ...", + theme: theme + }); function calcFermentables() { console.log("calcFermentables()"); @@ -65,29 +96,43 @@ sugarsm = 0; psugar = 0; pcara = 0; + mashkg = 0; var colorw = 0; // Colors working + var my_100 = false; - for (var i = 0; i < dataRecord.fermentables.length; i++) { - var row = dataRecord.fermentables[i]; + var rows = $('#fermentableGrid').jqxGrid('getrows'); + for (var i = 0; i < rows.length; i++) { + var row = rows[i]; + if (row.f_adjust_to_total_100) + my_100 = true; if (row.f_type == "Sugar") psugar += row.f_percentage; - if (row.f_type == "Crystal") + if (row.f_graintype == "Crystal") pcara += row.f_percentage; var d = row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100); if (row.f_added == "Mash") { d = parseFloat(dataRecord.efficiency) / 100 * d; sugarsm += d; + mashkg += row.f_amount; } sugarsf += d; colorw += row.f_amount * ebc_to_srm(row.f_color) / parseFloat(dataRecord.batch_size) * 8.34436; } - console.log("sugarsm: " + sugarsm + " sugarsf: " + sugarsf + " batch: " + dataRecord.batch_size); - console.log("est_og: " + estimate_sg(sugarsf, parseFloat(dataRecord.batch_size))); + to_100 = my_100; + var est_og = estimate_sg(sugarsf, parseFloat(dataRecord.batch_size)); + $('#est_og').val(est_og); + $('#est_og2').val(est_og); preboil_sg = estimate_sg(sugarsm, parseFloat(dataRecord.boil_size)); - console.log("preboil_sg: " + preboil_sg); - console.log("est_color: " + kw_to_ebc(dataRecord.color_method, colorw)); - $("#est_og").val(estimate_sg(sugarsf, parseFloat(dataRecord.batch_size))); - $('#est_color').val(kw_to_ebc(dataRecord.color_method, colorw)); + var color = kw_to_ebc(dataRecord.color_method, colorw); + $('#est_color').val(color); + $('#est_color2').val(color); + var scolor = ebc_to_color(color); + document.getElementById("bcolor").style.background= scolor; + document.getElementById("bcolor2").style.background= scolor; + pmalts = mashkg / dataRecord.eq_mash_max * 100; + $("#perc_malts").jqxProgressBar('val', pmalts); + $("#perc_sugars").jqxProgressBar('val', psugar); + $("#perc_cara").jqxProgressBar('val', pcara); }; function calcFermentablesFromOG(OG) { @@ -100,7 +145,7 @@ for (j = 1; j < 15; j++) { // Maybe needed if there is equipment, not here. vol = 0; sug2 = 0; - efficiency = parseFloat($("#efficiency").jqxNumberInput('decimal')); + efficiency = parseFloat(dataRecord.efficiency); var rows = $('#fermentableGrid').jqxGrid('getrows'); for (i = 0; i < rows.length; i++) { row = rows[i]; @@ -150,15 +195,64 @@ //CalcWaterBalance; }; + function hopFlavourContribution(bt, vol, use, amount) { + var result; + + if ((use == "First Wort") || (use == "First wort")) { + result = 0.15; // assume 15% flavourcontribution for fwh + } else if (bt > 50) { + result = 0.10; // assume 10% flavourcontribution as a minimum + } else { + result = 15.25 / (6 * Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * Math.pow((bt - 21) /6, 2)); + if (result < 0.10) + result = 0.10; // assume 10% flavourcontribution as a minimum + } + result = (result * amount * 1000) / vol; + // console.log("hopFlavourContribution("+bt+","+vol+","+use+","+amount+"): "+result); + return result; + } + + function hopAromaContribution(bt, vol, use, amount) { + var result = 0; + + if (bt > 20) { + result = 0; + } else if (bt > 7.5) { + result = 10.03 / (4 * Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * Math.pow((bt - 7.5) /4, 2)); + } else if (use == "Boil") { + result = 1; + } else if (use == "Aroma") { + result = 1.2; + } else if (use == "Whirlpool") { + result = 1.2; + } else if ((use == "Dry Hop") || (use == "Dry hop")) { + result = 1.33; + } + result = (result * amount * 1000) / vol; + // console.log("hopAromaContribution("+bt+","+vol+","+use+","+amount+"): "+result); + return result; + } + function calcIBUs() { var total_ibus = 0; - for (var i = 0; i < dataRecord.hops.length; i++) { - var row = dataRecord.hops[i]; + hop_aroma = hop_flavour = 0; + var rows = $('#hopGrid').jqxGrid('getrows'); + for (var i = 0; i < rows.length; i++) { + var row = rows[i]; total_ibus += toIBU(row.h_useat, row.h_form, preboil_sg, parseFloat(dataRecord.batch_size), parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method); + hop_flavour += hopFlavourContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), + row.h_useat, parseFloat(row.h_amount)); + hop_aroma += hopAromaContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), + row.h_useat, parseFloat(row.h_amount)); } - console.log("calcIBUs(): " + total_ibus); + total_ibus = Math.round(total_ibus); + console.log("calcIBUs(): " + total_ibus + " flavour: " + hop_flavour + " aroma: " + hop_aroma); + dataRecord.est_ibu = total_ibus; $('#est_ibu').val(total_ibus); + $('#est_ibu2').val(total_ibus); + $("#hop_flavour").jqxProgressBar('val', hop_flavour * 10); + $("#hop_aroma").jqxProgressBar('val', hop_aroma * 10); }; function calcSGendMash() { @@ -166,17 +260,18 @@ var mvol = 0; // Mash volume var s = 0; var gs = 0; // Grain absorbtion - for (var i = 0; i < dataRecord.mashs.length; i++) { - var row = dataRecord.mashs[i]; + var rows = $('#mashGrid').jqxGrid('getrows'); + for (var i = 0; i < rows.length; i++) { + var row = rows[i]; // console.log("step " + i + " " + row.step_name + " " + row.step_type); if (row.step_type == 'Infusion') mvol += parseFloat(row.step_infuse_amount); } if (mvol > 0) { // console.log("mash volume: " + mvol); - for (var i = 0; i < dataRecord.fermentables.length; i++) { - var row = dataRecord.fermentables[i]; - + var rows = $('#fermentableGrid').jqxGrid('getrows'); + for (var i = 0; i < rows.length; i++) { + var row = rows[i]; if (row.f_added == "Mash") { var d = row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100); mvol += row.f_amount * row.f_moisture / 100; @@ -204,6 +299,14 @@ $("#brew_mash_efficiency").val(0); }; + function calcInit () { + console.log("calc.init()"); + + calcSGendMash(); + calcMashEfficiency(); + + }; + // Equipemnt dropdown list var equipmentUrl = "includes/db_inventory_equipments.php"; var equipmentSource = { @@ -284,11 +387,11 @@ var dataRecord = {}; var url = "includes/db_product.php"; // tooltips - $("#pname").jqxTooltip({ content: 'De naam voor dit product.' }); + $("#name").jqxTooltip({ content: 'De naam voor dit product.' }); $("#code").jqxTooltip({ content: 'Product code nummer.' }); $("#birth").jqxTooltip({ content: 'De ontwerp datum van dit product.' }); $("#stage").jqxTooltip({ content: 'De productie fase van dit product.' }); - $("#pnotes").jqxTooltip({ content: 'De uitgebreide opmerkingen over dit product.' }); + $("#notes").jqxTooltip({ content: 'De uitgebreide opmerkingen over dit product.' }); $("#eq_name").jqxTooltip({ content: 'De naam van deze brouw apparatuur.' }); $("#eq_notes").jqxTooltip({ content: 'Opmerkingen over deze apparatuur.' }); $("#eq_tun_volume").jqxTooltip({ content: 'Maisch ketel volume.' }); @@ -305,6 +408,48 @@ $("#eq_hop_utilization").jqxTooltip({ content: '100% voor kleine installaties, hoger voor grote brouwerijen.' }); $("#eq_batch_size").jqxTooltip({ content: 'Berekende batch grootte in liters aan het eind van de kook.' }); $("#eq_trub_chiller_loss").jqxTooltip({ content: 'Standaard verlies bij het overbrengen naar het gistvat.' }); + $("#type").jqxTooltip({ content: 'Het brouw type van dit recept.' }); + $("#batch_size").jqxTooltip({ content: 'Het volume van het gekoelde wort na het koken.' }); + $("#boil_time").jqxTooltip({ content: 'De kooktijd in minuten.' }); + $("#boil_size").jqxTooltip({ content: 'Het volume van het wort voor het koken.' }); + $("#efficiency").jqxTooltip({ content: 'Het rendement van maischen en koken.' }); + $("#est_og").jqxTooltip({ content: 'Het begin SG wat je wilt bereiken. De moutstort wordt automatisch herberekend.' }); + $("#est_og2").jqxTooltip({ content: 'Het begin SG wat je wilt bereiken. De moutstort wordt automatisch herberekend.' }); + $("#est_fg").jqxTooltip({ content: 'Het eind SG. Dit wordt automatisch berekend.' }); + $("#est_color").jqxTooltip({ content: 'De kleur in EBC. Dit wordt automatisch berekend.' }); + $("#est_color2").jqxTooltip({ content: 'De kleur in EBC. Dit wordt automatisch berekend.' }); + $("#est_ibu").jqxTooltip({ content: 'De bitterheid in IBU. Dit wordt automatisch berekend.' }); + $("#est_ibu2").jqxTooltip({ content: 'De bitterheid in IBU. Dit wordt automatisch berekend.' }); + $("#est_abv").jqxTooltip({ content: 'Alcohol volume %. Dit wordt automatisch berekend.' }); + $("#est_carb").jqxTooltip({ content: 'Koolzuur volume. Dit wordt automatisch berekend.' }); +// $("#st_name").jqxTooltip({ content: 'De bierstijl naam voor dit recept.'}); +// $("#st_letter").jqxTooltip({ content: 'De bierstijl letter voor dit recept.'}); +// $("#st_guide").jqxTooltip({ content: 'De bierstijl gids voor dit recept.'}); +// $("#st_category").jqxTooltip({ content: 'De Amerikaanse bierstijl categorie.'}); +// $("#st_category_number").jqxTooltip({ content: 'De Amerikaanse bierstijl categorie sub nummer.'}); +// $("#st_type").jqxTooltip({ content: 'Het bierstijl type.'}); + $("#st_og_min").jqxTooltip({ content: 'Het minimum begin SG voor deze bierstijl.'}); + $("#st_og_max").jqxTooltip({ content: 'Het maximum begin SG voor deze bierstijl.'}); + $("#st_fg_min").jqxTooltip({ content: 'Het minimum eind SG voor deze bierstijl.'}); + $("#st_fg_max").jqxTooltip({ content: 'Het maximum eind SG voor deze bierstijl.'}); + $("#st_color_min").jqxTooltip({ content: 'De minimum kleur voor deze bierstijl.'}); + $("#st_color_max").jqxTooltip({ content: 'De maximum kleur voor deze bierstijl.'}); + $("#st_ibu_min").jqxTooltip({ content: 'De minimum bitterheid voor deze bierstijl.'}); + $("#st_ibu_max").jqxTooltip({ content: 'De maximum bitterheid voor deze bierstijl.'}); + $("#st_abv_min").jqxTooltip({ content: 'Het minimum alcohol volume % voor deze bierstijl.'}); + $("#st_abv_max").jqxTooltip({ content: 'Het maximum alcohol volume % voor deze bierstijl.'}); + $("#st_carb_min").jqxTooltip({ content: 'Het minimum koolzuur volume voor deze bierstijl.'}); + $("#st_carb_max").jqxTooltip({ content: 'Het maximum koolzuur volume voor deze bierstijl.'}); + $("#wa_cacl2").jqxTooltip({ content: 'Voor het maken van een ander waterprofiel. Voegt calcium en chloride toe. Voor het verbeteren van zoetere bieren.'}); + $("#wa_caso4").jqxTooltip({ content: 'Gips. Voor het maken van een ander waterprofiel. Voegt calcium en sulfaat toe. Voor het verbeteren van bittere bieren.'}); + $("#wa_mgso4").jqxTooltip({ content: 'Epsom zout. Voor het maken van een ander waterprofiel. Voegt magnesium en sulfaat toe. Gebruik spaarzaam!'}); + $("#wa_nacl").jqxTooltip({ content: 'Keukenzout. Voor het maken van een ander waterprofiel. Voegt natrium en chloride toe. Voor het accentueren van zoetheid. Bij hoge dosering wordt het bier ziltig.'}); + $("#w2_amount").jqxTooltip({ content: 'De verdeling van het hoofd en meng water. Het totale maisch water volume blijft gelijk.'}); + $("#wb_calcium").jqxTooltip({ content: 'De ideale hoeveelheid Calcium is tussen 40 en 150.'}); + $("#wb_magnesium").jqxTooltip({ content: 'De ideale hoeveelheid Magnesium is lager dan 30.'}); + $("#wb_sodium").jqxTooltip({ content: 'De ideale hoeveelheid Natrium is lager dan 150.'}); + $("#wb_chloride").jqxTooltip({ content: 'De ideale hoeveelheid Chloride is lager dan 100.'}); + $("#wb_sulfate").jqxTooltip({ content: 'De ideale hoeveelheid Sulfaat is lager dan 350.'}); // Prepare the data var source = { @@ -313,16 +458,16 @@ datafields: [ // From prod_main { name: 'record', type: 'number' }, - { name: 'puuid', type: 'string' }, - { name: 'pname', type: 'string' }, + { name: 'uuid', type: 'string' }, + { name: 'name', type: 'string' }, { name: 'code', type: 'string' }, { name: 'birth', type: 'string' }, { name: 'stage', type: 'string' }, - { name: 'pnotes', type: 'string' }, + { name: 'notes', type: 'string' }, { name: 'log_brew', type: 'bool' }, { name: 'log_fermentation', type: 'bool' }, { name: 'inventory_reduced', type: 'bool' }, - { name: 'plocked', type: 'bool' }, + { name: 'locked', type: 'bool' }, { name: 'eq_name', type: 'string' }, { name: 'eq_boil_size', type: 'float' }, { name: 'eq_batch_size', type: 'float' }, @@ -408,9 +553,6 @@ { name: 'taste_taste', type: 'string' }, { name: 'taste_mouthfeel', type: 'string' }, { name: 'taste_aftertaste', type: 'string' }, - // From prod_recipes - { name: 'uuid', type: 'string' }, - { name: 'locked', type: 'bool' }, { name: 'st_name', type: 'string' }, { name: 'st_letter', type: 'string' }, { name: 'st_guide', type: 'string' }, @@ -429,8 +571,6 @@ { name: 'st_carb_max', type: 'float' }, { name: 'st_abv_min', type: 'float' }, { name: 'st_abv_max', type: 'float' }, - { name: 'name', type: 'string' }, - { name: 'notes', type: 'string' }, { name: 'type', type: 'string' }, { name: 'batch_size', type: 'float' }, { name: 'boil_size', type: 'float' }, @@ -444,14 +584,39 @@ { name: 'est_ibu', type: 'float' }, { name: 'ibu_method', type: 'string' }, { name: 'est_carb', type: 'float' }, - { name: 'mash_sparge_temp', type: 'float' }, + { name: 'sparge_temp', type: 'float' }, + { name: 'sparge_ph', type: 'float' }, + { name: 'sparge_volume', type: 'float' }, + { name: 'sparge_acid_type', type: 'string' }, + { name: 'sparge_acid_perc', type: 'float' }, + { name: 'sparge_acid_amount', type: 'float' }, { name: 'mash_ph', type: 'float' }, { name: 'mash_name', type: 'string' }, + { name: 'calc_acid', type: 'bool' }, + { name: 'w1_name', type: 'string' }, + { name: 'w1_amount', type: 'float' }, + { name: 'w1_calcium', type: 'float' }, + { name: 'w1_sulfate', type: 'float' }, + { name: 'w1_chloride', type: 'float' }, + { name: 'w1_sodium', type: 'float' }, + { name: 'w1_magnesium', type: 'float' }, + { name: 'w1_total_alkalinity', type: 'float' }, + { name: 'w1_ph', type: 'float' }, + { name: 'w1_cost', type: 'float' }, + { name: 'w2_name', type: 'string' }, + { name: 'w2_amount', type: 'float' }, + { name: 'w2_calcium', type: 'float' }, + { name: 'w2_sulfate', type: 'float' }, + { name: 'w2_chloride', type: 'float' }, + { name: 'w2_sodium', type: 'float' }, + { name: 'w2_magnesium', type: 'float' }, + { name: 'w2_total_alkalinity', type: 'float' }, + { name: 'w2_ph', type: 'float' }, + { name: 'w2_cost', type: 'float' }, { name: 'fermentables', type: 'array' }, { name: 'hops', type: 'string' }, { name: 'miscs', type: 'string' }, { name: 'yeasts', type: 'string' }, - { name: 'waters', type: 'array' }, { name: 'mashs', type: 'string' } ], id: 'record', @@ -463,15 +628,15 @@ var records = dataAdapter.records; dataRecord = records[0]; // Hidden record uuid - $("#pname").val(dataRecord.pname); + $("#name").val(dataRecord.name); $("#code").val(dataRecord.code); $("#birth").val(dataRecord.birth); $("#stage").val(dataRecord.stage); - $("#pnotes").val(dataRecord.pnotes); + $("#notes").val(dataRecord.notes); $("#log_brew").val(dataRecord.log_brew); $("#log_fermentation").val(dataRecord.log_fermentation); $("#inventory_reduced").val(dataRecord.inventory_reduced); - $("#plocked").val(dataRecord.plocked); + $("#locked").val(dataRecord.locked); $("#eq_name").val(dataRecord.eq_name); $("#eq_notes").val(dataRecord.eq_notes); $("#eq_boil_size").val(dataRecord.eq_boil_size); @@ -533,31 +698,78 @@ $("#brew_date_end").val(dataRecord.brew_date_end); // Recipe - // locked - // st_ style settings. - // name - // notes - // type + $("#st_name").val(dataRecord.st_name); + $("#st_letter").val(dataRecord.st_letter); + $("#st_guide").val(dataRecord.st_guide); + $("#st_category").val(dataRecord.st_category); + $("#st_category_number").val(dataRecord.st_category_number); + $("#st_type").val(dataRecord.st_type); + $("#st_og_min").val(dataRecord.st_og_min); + $("#st_og_max").val(dataRecord.st_og_max); + $("#st_fg_min").val(dataRecord.st_fg_min); + $("#st_fg_max").val(dataRecord.st_fg_max); + $("#st_abv_min").val(dataRecord.st_abv_min); + $("#st_abv_max").val(dataRecord.st_abv_max); + $("#st_color_min").val(dataRecord.st_color_min); + $("#st_color_max").val(dataRecord.st_color_max); + $("#st_ibu_min").val(dataRecord.st_ibu_min); + $("#st_ibu_max").val(dataRecord.st_ibu_max); + $("#st_carb_min").val(dataRecord.st_carb_min); + $("#st_carb_max").val(dataRecord.st_carb_max); + $("#type").val(dataRecord.type); + $("#batch_size").val(dataRecord.batch_size); old_batch_size = dataRecord.batch_size; - // boil_size + $("#boil_size").val(dataRecord.boil_size); + $("#boil_time").val(dataRecord.boil_time); old_boil_time = dataRecord.boil_time; + $("#efficiency").val(dataRecord.efficiency); old_efficiency = dataRecord.efficiency; - // est_og - // est_fg - // est_abv - // est_color - // color_method - // est_ibu - // ibu_method - // mash_sparge_temp - // mash_ph - // mash_name - // fermentables - // hops - // miscs - // yeasts - // waters - // mashs + $("#est_og").val(dataRecord.est_og); + $("#est_og2").val(dataRecord.est_og); + $("#est_fg").val(dataRecord.est_fg); + $("#est_color").val(dataRecord.est_color); + $("#est_color2").val(dataRecord.est_color); + $("#est_abv").val(dataRecord.est_abv); + $("#color_method").val(dataRecord.color_method); + $("#est_ibu").val(dataRecord.est_ibu); + $("#est_ibu2").val(dataRecord.est_ibu); + $("#ibu_method").val(dataRecord.ibu_method); + $("#est_carb").val(dataRecord.est_carb); + $("#mash_name").val(dataRecord.mash_name); + $("#mash_ph").val(dataRecord.mash_ph); + $("#tgt_mash_ph").val(dataRecord.mash_ph); + $("#sparge_temp").val(dataRecord.sparge_temp); + $("#sparge_ph").val(dataRecord.sparge_ph); + $("#sparge_volume").val(dataRecord.sparge_volume); + $("#sparge_acid_type").val(dataRecord.sparge_acid_type); + $("#sparge_acid_perc").val(dataRecord.sparge_acid_perc); + $("#sparge_acid_amount").val(dataRecord.sparge_acid_amount); + $("#calc_acid").val(dataRecord.calc_acid); + $("#w1_name").val(dataRecord.w1_name); + $("#w1_amount").val(dataRecord.w1_amount); + $("#w1_calcium").val(dataRecord.w1_calcium); + $("#w1_sulfate").val(dataRecord.w1_sulfate); + $("#w1_chloride").val(dataRecord.w1_chloride); + $("#w1_sodium").val(dataRecord.w1_sodium); + $("#w1_magnesium").val(dataRecord.w1_magnesium); + $("#w1_total_alkalinity").val(dataRecord.w1_total_alkalinity); + $("#w1_ph").val(dataRecord.w1_ph); + $("#w1_cost").val(dataRecord.w1_cost); + $("#w2_name").val(dataRecord.w2_name); + $("#w2_amount").val(dataRecord.w2_amount); + $("#w2_calcium").val(dataRecord.w2_calcium); + $("#w2_sulfate").val(dataRecord.w2_sulfate); + $("#w2_chloride").val(dataRecord.w2_chloride); + $("#w2_sodium").val(dataRecord.w2_sodium); + $("#w2_magnesium").val(dataRecord.w2_magnesium); + $("#w2_total_alkalinity").val(dataRecord.w2_total_alkalinity); + $("#w2_ph").val(dataRecord.w2_ph); + $("#w2_cost").val(dataRecord.w2_cost); + editFermentable(dataRecord); + editHop(dataRecord); + editMisc(dataRecord); + editYeast(dataRecord); + editMash(dataRecord); switch (dataRecord.stage) { case 'Plan': brewstage = 0; break; @@ -585,39 +797,1113 @@ $("#birth").jqxDateTimeInput({ disabled: true }); } if (brewstage < 3) { - $("#brew_log").jqxButton({ disabled: true }); - $("#ferment_log").jqxButton({ disabled: true }); + // $("#brew_log").jqxButton({ disabled: true }); + // $("#ferment_log").jqxButton({ disabled: true }); } else { - if (! dataRecord.log_brew) - $("#brew_log").jqxButton({ disabled: true }); - if (! dataRecord.log_fermentation) - $("#ferment_log").jqxButton({ disabled: true }); + // if (! dataRecord.log_brew) + // $("#brew_log").jqxButton({ disabled: true }); + // if (! dataRecord.log_fermentation) + // $("#ferment_log").jqxButton({ disabled: true }); } if (brewstage < 6) $("#inventory_reduced").jqxCheckBox({ disabled : true }); else if ($('#inventory_reduced').jqxCheckBox('checked')) $("#inventory_reduced").jqxCheckBox({ disabled : true }); - calcFermentables(); - calcIBUs(); - calcSGendMash(); - calcMashEfficiency(); + $('#jqxTabs').jqxTabs('select', 2); }, loadError: function (jqXHR, status, error) { - } + }, + beforeLoadComplete: function (records) { + $('#jqxLoader').jqxLoader('open'); + } }); dataAdapter.dataBind(); + // Inline fermentables editor + var editFermentable = function (data) { + var fermentableSource = { + localdata: data.fermentables, + datatype: "local", + datafields: [ + { name: 'f_name', type: 'string' }, + { name: 'f_origin', type: 'string' }, + { name: 'f_supplier', type: 'string' }, + { name: 'f_amount', type: 'float' }, + { name: 'f_cost', type: 'float' }, + { name: 'f_type', type: 'string' }, + { name: 'f_yield', type: 'float' }, + { name: 'f_color', type: 'float' }, + { name: 'f_coarse_fine_diff', type: 'float' }, + { name: 'f_moisture', type: 'float' }, + { name: 'f_diastatic_power', type: 'float' }, + { name: 'f_protein', type: 'float' }, + { name: 'f_max_in_batch', type: 'float' }, + { name: 'f_graintype', type: 'string' }, + { name: 'f_added', type: 'string' }, + { name: 'f_dissolved_protein', type: 'float' }, + { name: 'f_recommend_mash', type: 'bool' }, + { name: 'f_add_after_boil', type: 'bool' }, + { name: 'f_adjust_to_total_100', type: 'bool' }, + { name: 'f_percentage', type: 'float' }, + { name: 'f_di_ph', type: 'float' } + ], + addrow: function (rowid, rowdata, position, commit) { + commit(true); + }, + deleterow: function (rowid, commit) { + commit(true); + } + }; + var fermentableAdapter = new $.jqx.dataAdapter(fermentableSource); + $("#fermentableGrid").jqxGrid({ + width: 1150, + height: 400, + source: fermentableAdapter, + theme: theme, + selectionmode: 'singlerow', + editmode: 'selectedcell', + editable: true, + localization: getLocalization(), + showtoolbar: true, + rendertoolbar: function (toolbar) { + var me = this; + var container = $("
"); + toolbar.append(container); + container.append('
'); + container.append('
In voorraad:
'); + container.append('
'); + container.append(''); + // add fermentable from dropdownlist. + $("#faddrowbutton").jqxDropDownList({ + placeHolder: "Kies mout:", + theme: theme, + source: fermentablelist, + displayMember: "name", + width: 150, + height: 27, + dropDownWidth: 500, + dropDownHeight: 500, + renderer: function (index, label, value) { + var datarecord = fermentablelist.records[index]; + return datarecord.supplier+ " / " + datarecord.name + " (" + datarecord.color + " EBC)"; + } + }); + $("#faddrowbutton").on('select', function (event) { + if (event.args) { + var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + var index = event.args.index; + var datarecord = fermentablelist.records[index]; + var row = {}; + row["f_name"] = datarecord.name; + row["f_origin"] = datarecord.origin; + row["f_supplier"] = datarecord.supplier; + row["f_amount"] = 0; + row["f_cost"] = datarecord.cost; + row["f_type"] = datarecord.type; + row["f_yield"] = datarecord.yield; + row["f_color"] = datarecord.color; + row["f_coarse_fine_diff"] = datarecord.coarse_fine_diff; + row["f_moisture"] = datarecord.moisture; + row["f_diastatic_power"] = datarecord.diastatic_power; + row["f_protein"] = datarecord.protein; + row["f_max_in_batch"] = datarecord.max_in_batch; + row["f_graintype"] = datarecord.graintype; + if (datarecord.add_after_boil) { + row["f_added"] = "Primary"; + } else if ((datarecord.type == "Sugar") || (datarecord.type == "Adjunct")) { + row["f_added"] = "Boil"; + } else { + row["f_added"] = "Mash"; + } + row["f_dissolved_protein"] = 0; + row["f_recommend_mash"] = datarecord.recommend_mash; + row["f_add_after_boil"] = datarecord.add_after_boil; + if (rowscount == 0) { + // The first fermentable + row["f_adjust_to_total_100"] = 1; + row["f_percentage"] = 100; + } else { + row["f_adjust_to_total_100"] = 0; + row["f_percentage"] = 0; + } + row["f_di_ph"] = datarecord.di_ph; + var commit = $("#fermentableGrid").jqxGrid('addrow', null, row); + } + }); + + $("#finstockbutton").jqxCheckBox({ theme: theme, height: 27 }); + $("#finstockbutton").on('change', function (event) { + fermentableinstock = event.args.checked; + fermentablelist.dataBind(); + }); + + // delete selected fermentable. + $("#fdeleterowbutton").jqxButton({ theme: theme, height: 27, width: 150 }); + $("#fdeleterowbutton").on('click', function () { + var selectedrowindex = $("#fermentableGrid").jqxGrid('getselectedrowindex'); + var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + if (selectedrowindex >= 0 && selectedrowindex < rowscount) { + var id = $("#fermentableGrid").jqxGrid('getrowid', selectedrowindex); + var percent = $('#fermentableGrid').jqxGrid('getcellvalue', id, "f_percentage"); + var amount = $('#fermentableGrid').jqxGrid('getcellvalue', id, "f_amount"); + var commit = $("#fermentableGrid").jqxGrid('deleterow', id); + } + rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + if (rowscount > 1) { + if (to_100) { + for (var i = 0; i < rowscount; i++) { + var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + if (rowdata.f_adjust_to_total_100) { + rowdata.f_percentage += percent; + rowdata.f_amount += amount; + } + } + } else { + var tw = 0; + for (i = 0; i < rowscount; i++) { + var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + tw += rowdata.f_amount; + }; + for (i = 0; i < rowscount; i++) { + var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + var percentage = Math.round(rowdata.f_amount / tw * 1000) / 10.0; + $("#fermentableGrid").jqxGrid('setcellvalue', i, "f_percentage", percentage); + }; + } + } else { + $("#fermentableGrid").jqxGrid('setcellvalue', 0, "f_percentage", 100); + } + calcFermentables(); + calcSVG(); + calcABV(); + calcIBUs(); + }); + }, + ready: function() { + calcFermentables(); + $('#jqxTabs').jqxTabs('next'); + }, + columns: [ + { text: 'Vergistbaar ingrediënt', editable: false, datafield: 'f_name', + cellsrenderer: function (row, columnfield, value, defaulthtml, columnproperties) { + var rowData = $("#fermentableGrid").jqxGrid('getrowdata', row); + return "" +rowData.f_supplier+" / "+rowData.f_name+" ("+rowData.f_color+" EBC)"; + } + }, + { text: 'Type', editable: false, align: 'center', cellsalign: 'center', width: 100, datafield: 'f_type' }, + { text: 'Moment', width: 110, align: 'center', cellsalign: 'center', datafield: 'f_added', columntype: 'dropdownlist', + createeditor: function (row, column, editor) { + var srcAdded = [ "Mash", "Boil", "Fermentation", "Lagering", "Bottle" ]; + editor.jqxDropDownList({ autoDropDownHeight: true, source: srcAdded }); + } + }, + { text: 'Opbrengst', editable: false, datafield: 'f_yield', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'p1' }, + { text: 'Gewicht Kg', datafield: 'f_amount', width: 120, align: 'right', cellsalign: 'right', cellsformat: 'f3', + columntype: 'numberinput', + validation: function (cell, value) { + // Maximum weight is the batch_size, just a simple check. + var maxmout = parseFloat($("#batch_size").jqxNumberInput('decimal')); + if (value < 0 || value > maxmout) { + return { result: false, message: "Gewicht moet 0-"+maxmout+" zijn" }; + } + return true; + }, + initeditor: function (row, cellvalue, editor) { + editor.jqxNumberInput({ inputMode: 'simple', min: 0, decimalDigits: 3, spinButtons: false }); + }, + cellvaluechanging: function (row, column, columntype, oldvalue, newvalue) { + if (to_100) { + return oldvalue; // When using percentages, don't allow edited results. + } + } + }, + { text: 'Percentage', datafield: 'f_percentage', width: 110, align: 'right', cellsalign: 'right', cellsformat: 'p1', + columntype: 'numberinput', + validation: function (cell, value) { + if (value < 0 || value > 100) { + return { result: false, message: "Percentage moet 0-100 zijn" }; + } + return true; + }, + initeditor: function (row, cellvalue, editor) { + editor.jqxNumberInput({ decimalDigits: 1, min: 0, max: 100, spinButtons: false }); + }, + cellvaluechanging: function (row, column, columntype, oldvalue, newvalue) { + oldvalue = Math.round(oldvalue * 10) / 10.0; + var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + if ((oldvalue != newvalue) && (rowscount > 1)) { + var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', row); + if (rowdata.f_adjust_to_total_100) { + return oldvalue; + } + var diff = newvalue - oldvalue; + var tw = 0; // total weight + for (i = 0; i < rowscount; i++) { + var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + tw += rowdata.f_amount; + } + if (to_100) { + // Adjust this row and the 100% row. + var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', row); + rowdata.f_amount += tw * diff / 100; + for (i = 0; i < rowscount; i++) { + var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + if (rowdata.f_adjust_to_total_100) { + rowdata.f_percentage -= diff; + rowdata.f_amount -= tw * diff / 100; + } + } + } else { + // Adjust all the rows. + var nw = tw * diff / 100; + for (i = 0; i < rowscount; i++) { + var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + if (i == row) { + rowdata.f_amount += nw; + } else { + rowdata.f_amount -= nw / (rowscount - 1); + rowdata.f_percentage = Math.round((rowdata.f_amount / tw) * 1000) / 10.0; + } + } + } + } + } + }, + { text: '100%', align: 'center', datafield: 'f_adjust_to_total_100', columntype: 'checkbox', width: 80, + cellvaluechanging: function (row, column, columntype, oldvalue, newvalue) { + if (to_100) { + var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + for (i = 0; i < rowscount; i++) { + if (i != row) { + var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + rowdata.f_adjust_to_total_100 = false; + } + } + } + } + } + ] + }); + $("#fermentableGrid").on('cellendedit', function (event) { + var args = event.args; + console.log("Event Type: cellendedit, Column: " + args.datafield + ", Row: " + (args.rowindex) + ", Value: " + args.value); + // Make sure the grid itself is updated. + $("#fermentableGrid").jqxGrid('setcellvalue', args.rowindex, args.datafield, args.value); + if ((args.datafield == 'f_amount') && (! to_100)) { + // If one of the amounts is changed, recalculate the percentages. + console.log("adjust percentages"); + var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + if (rowscount > 1) { + var tw = 0; + for (i = 0; i < rowscount; i++) { + var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + tw += rowdata.f_amount; + }; + for (i = 0; i < rowscount; i++) { + var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + var percentage = Math.round(rowdata.f_amount / tw * 1000) / 10.0; + $("#fermentableGrid").jqxGrid('setcellvalue', i, "f_percentage", percentage); + }; + } else { + $("#fermentableGrid").jqxGrid('setcellvalue', 0, "f_percentage", 100); + } + }; + $('#fermentableGrid').jqxGrid('sortby', 'f_amount', 'desc'); // TODO: not reliable + calcFermentables(); + calcSVG(); + calcABV(); + calcIBUs(); // Depends on gravity, so recalculate. + }); + }; + + // Inline hops editor + var editHop = function (data) { + var hopSource = { + localdata: data.hops, + datatype: "local", + cache: false, + datafields: [ + { name: 'h_name', type: 'string' }, + { name: 'h_origin', type: 'string' }, + { name: 'h_amount', type: 'float' }, + { name: 'h_cost', type: 'float' }, + { name: 'h_type', type: 'string' }, + { name: 'h_form', type: 'string' }, + { name: 'h_useat', type: 'string' }, + { name: 'h_time', type: 'float' }, + { name: 'h_alpha', type: 'float' }, + { name: 'h_beta', type: 'float' }, + { name: 'h_hsi', type: 'float' }, + { name: 'h_humulene', type: 'float' }, + { name: 'h_carophyllene', type: 'float' }, + { name: 'h_cohumulone', type: 'float' }, + { name: 'h_myrcene', type: 'float' }, + { name: 'h_total_oil', type: 'float' }, + { name: 'h_weight', type: 'float' } + ], + addrow: function (rowid, rowdata, position, commit) { + commit(true); + }, + deleterow: function (rowid, commit) { + commit(true); + } + }; + var hopAdapter = new $.jqx.dataAdapter(hopSource, { + beforeLoadComplete: function (records) { + var data = new Array(); + for (var i = 0; i < records.length; i++) { + var row = records[i]; + row.h_weight = row.h_amount * 1000; + data.push(row); + } + return data; + }, + loadError: function(jqXHR, status, error) { + $('#err').text(status + ' ' + error); + }, + }); + $("#hopGrid").jqxGrid({ + width: 1050, + height: 400, + source: hopAdapter, + theme: theme, + selectionmode: 'singlerow', + editmode: 'selectedcell', + editable: true, + localization: getLocalization(), + showtoolbar: true, + rendertoolbar: function (toolbar) { + var me = this; + var container = $("
"); + toolbar.append(container); + container.append('
'); + container.append('
In voorraad:
'); + container.append('
'); + container.append(''); + // add hop from dropdownlist. + $("#haddrowbutton").jqxDropDownList({ + placeHolder: "Kies hop:", + theme: theme, + source: hoplist, + displayMember: "name", + width: 150, + height: 27, + dropDownWidth: 500, + dropDownHeight: 500, + renderer: function (index, label, value) { + var datarecord = hoplist.records[index]; + return datarecord.origin+ " / " + datarecord.name + " (" + datarecord.alpha + "% α)"; + } + }); + $("#haddrowbutton").on('select', function (event) { + if (event.args) { + var index = event.args.index; + var datarecord = hoplist.records[index]; + var row = {}; + row["h_name"] = datarecord.name; + row["h_origin"] = datarecord.origin; + row["h_amount"] = 0; + row["h_cost"] = datarecord.cost; + row["h_type"] = datarecord.type; + row["h_form"] = datarecord.form; + row["h_useat"] = datarecord.useat; + row["h_time"] = 0; + row["h_alpha"] = datarecord.alpha; + row["h_beta"] = datarecord.beta; + row["h_hsi"] = datarecord.hsi; + row["h_humulene"] = datarecord.humulene; + row["h_carophyllene"] = datarecord.carophyllene; + row["h_cohumulone"] = datarecord.cohumulone; + row["h_myrcene"] = datarecord.myrcene; + row["h_total_oil"] = datarecord.total_oil; + row["h_weight"] = 0; + var commit = $("#hopGrid").jqxGrid('addrow', null, row); + } + }); + + $("#hinstockbutton").jqxCheckBox({ theme: theme, height: 27 }); + $("#hinstockbutton").on('change', function (event) { + hopinstock = event.args.checked; + hoplist.dataBind(); + }); + + // delete selected hop. + $("#hdeleterowbutton").jqxButton({ theme: theme, height: 27, width: 150 }); + $("#hdeleterowbutton").on('click', function () { + var selectedrowindex = $("#hopGrid").jqxGrid('getselectedrowindex'); + var rowscount = $("#hopGrid").jqxGrid('getdatainformation').rowscount; + if (selectedrowindex >= 0 && selectedrowindex < rowscount) { + var id = $("#hopGrid").jqxGrid('getrowid', selectedrowindex); + var commit = $("#hopGrid").jqxGrid('deleterow', id); + } + }); + }, + ready: function() { + $('#jqxTabs').jqxTabs('next'); + }, + columns: [ + { text: 'Hop', editable: false, datafield: 'h_name', + cellsrenderer: function (row, columnfield, value, defaulthtml, columnproperties) { + var rowData = $("#hopGrid").jqxGrid('getrowdata', row); + return "" +rowData.h_origin+" / "+rowData.h_name+""; + }, + }, + { text: 'Type', editable: false, width: 90, align: 'center', cellsalign: 'center', datafield: 'h_type' }, + { text: 'Vorm', editable: false, width: 90, align: 'center', cellsalign: 'center', datafield: 'h_form' }, + { text: 'Alpha', editable: false, datafield: 'h_alpha', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'p1' }, + { text: 'Amount', hidden: true, datafield: 'h_amount' }, + { text: 'Gewicht gr', datafield: 'h_weight', width: 120, align: 'right', cellsalign: 'right', cellsformat: 'f1', + columntype: 'numberinput', + cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { + return "
" + dataAdapter.formatNumber(value, "f1") + " gr
"; + }, + initeditor: function (row, cellvalue, editor, celltext, pressedChar) { + editor.jqxNumberInput({ + inputMode: 'simple', decimalDigits: 1, min: 0, max: parseFloat(dataRecord.batch_size * 200), + spinButtons: false + }); + }, + validation: function (cell, value) { + var maxhops = parseFloat(dataRecord.batch_size) * 200; + if (value < 0 || value > maxhops ) { + return { result: false, message: "Gewicht moet tussen 0 en "+maxhops+" gram zijn" }; + } + return true; + } + }, + { text: 'Gebruik', width: 110, align: 'center', cellsalign: 'center', datafield: 'h_useat', columntype: 'dropdownlist', + createeditor: function (row, column, editor) { + var srcUse = [ "Boil", "Dry Hop", "Mash", "First Wort", "Aroma" ]; + editor.jqxDropDownList({ autoDropDownHeight: true, source: srcUse }); + }, + cellvaluechanging: function (row, column, columntype, oldvalue, newvalue) { + if ((newvalue == "Mash") || (newvalue == "First Wort")) { + $("#hopGrid").jqxGrid('setcellvalue', row, "h_time", parseFloat(dataRecord.boil_time)); + } else if (newvalue == "Aroma") { + $("#hopGrid").jqxGrid('setcellvalue', row, "h_time", 0); + } + } + }, + { text: 'Tijd', datafield: 'h_time', width: 70, align: 'right', cellsalign: 'right', cellsformat: 'f0', + columntype: 'numberinput', + cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { + if ((rowdata.h_useat == "Boil") || (rowdata.h_useat == "Dry Hop") || (rowdata.h_useat == "Dry hop")) + return "
"+dataAdapter.formatNumber(value, "f0")+"
"; + else + return "
"; + }, + initeditor: function (row, cellvalue, editor, celltext, pressedChar) { + editor.jqxNumberInput({ decimalDigits: 0, digits: 3, min: 0, max: parseFloat(dataRecord.boil_time) }); + }, + cellvaluechanging: function (row, column, columntype, oldvalue, newvalue) { + var use = $("#hopGrid").jqxGrid('getcellvalue', row, "h_useat"); + if ((use == "Mash") || (use == "First Wort") || (use == "First wort") || (use == "Aroma")) + return oldvalue; + }, + validation: function (cell, value) { + var high = parseFloat(dataRecord.boil_time); + if (value < 0 || value > high ) { + return { result: false, message: "De tijd moet 0-"+high+" zijn" }; + } + return true; + } + }, + { text: 'IBU', editable: false, datafield: 'ibu', width: 80, align: 'right', + cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { + var ibu = toIBU(rowdata.h_useat, + rowdata.h_form, + preboil_sg, + parseFloat($("#batch_size").jqxNumberInput('decimal')), + parseFloat(rowdata.h_amount), + parseFloat(rowdata.h_time), + parseFloat(rowdata.h_alpha), + $("#ibu_method").val() + ); + calcIBUs(); + return "
" + dataAdapter.formatNumber(ibu, "f1") + "
"; + } + } + ] + }); + $("#hopGrid").on('cellendedit', function (event) { + var args = event.args; + console.log("Event Type: cellendedit, Column: " + args.datafield + ", Row: " + (args.rowindex) + ", Value: " + args.value); + $("#hopGrid").jqxGrid('setcellvalue', args.rowindex, args.datafield, args.value); + if (args.datafield == 'h_weight') + $("#hopGrid").jqxGrid('setcellvalue', args.rowindex, 'h_amount', args.value / 1000); + //$('#hopGrid').jqxGrid('sortby', 'f_amount', 'desc'); + }); + }; + + // Inline miscs editor + var editMisc = function (data) { + var miscSource = { + localdata: data.miscs, + datatype: "local", + cache: false, + datafields: [ + { name: 'm_name', type: 'string' }, + { name: 'm_amount', type: 'float' }, + { name: 'm_cost', type: 'float' }, + { name: 'm_type', type: 'string' }, + { name: 'm_use_use', type: 'string' }, + { name: 'm_time', type: 'float' }, + { name: 'm_amount_is_weight', type: 'bool' }, + { name: 'm_weight', type: 'float' } + ], + addrow: function (rowid, rowdata, position, commit) { + commit(true); + }, + deleterow: function (rowid, commit) { + commit(true); + } + }; + var miscAdapter = new $.jqx.dataAdapter(miscSource, { + beforeLoadComplete: function (records) { + var data = new Array(); + for (var i = 0; i < records.length; i++) { + var row = records[i]; + row.m_weight = row.m_amount * 1000; + data.push(row); + // Initial set water agent values. + switch (row.m_name) { + case 'CaCl2': $("#wa_cacl2").val(row.m_weight); + break; + case 'CaSO4': $("#wa_caso4").val(row.m_weight); + break; + case 'MgSO4': $("#wa_mgso4").val(row.m_weight); + break; + case 'NaCl': $("#wa_nacl").val(row.m_weight); + break; + case 'Melkzuur': $("#wa_acid_name").val('Melkzuur'); + $("#wa_acid").val(row.m_weight); + $("#wa_acid_perc").val(80); + last_acid = 'Melkzuur'; + break; + case 'Zoutzuur': $("#wa_acid_name").val('Zoutzuur'); + $("#wa_acid").val(row.m_weight); + $("#wa_acid_perc").val(80); + last_acid = 'Zoutzuur'; + break; + case 'Fosforzuur': $("#wa_acid_name").val('Fosforzuur'); + $("#wa_acid").val(row.m_weight); + $("#wa_acid_perc").val(80); + last_acid = 'Fosforzuur'; + break; + case 'Zwavelzuur': $("#wa_acid_name").val('Zwavelzuur'); + $("#wa_acid").val(row.m_weight); + $("#wa_acid_perc").val(80); + last_acid = 'Zwavelzuur'; + break; + case 'NaHCO3': $("#wa_base_name").val('NaHCO3'); + $("#wa_base").val(row.m_weight); + last_base = 'NaHCO3'; + break; + case 'Na2CO3': $("#wa_base_name").val('Na2CO3'); + $("#wa_base").val(row.m_weight); + last_base = 'Na2CO3'; + break; + case 'CaCO3': $("#wa_base_name").val('CaCO3'); + $("#wa_base").val(row.m_weight); + last_base = 'CaCO3'; + break; + case 'Ca(OH)2': $("#wa_base_name").val('Ca(OH)2'); + $("#wa_base").val(row.m_weight); + last_base = 'Ca(OH)2'; + break; + } + } + return data; + }, + loadError: function(jqXHR, status, error) { + $('#err').text(status + ' ' + error); + }, + }); + $("#miscGrid").jqxGrid({ + width: 960, + height: 400, + source: miscAdapter, + theme: theme, + selectionmode: 'singlerow', + editmode: 'selectedcell', + editable: true, + localization: getLocalization(), + showtoolbar: true, + rendertoolbar: function (toolbar) { + var me = this; + var container = $("
"); + toolbar.append(container); + container.append('
'); + container.append('
In voorraad:
'); + container.append('
'); + container.append(''); + // add misc from dropdownlist. + $("#maddrowbutton").jqxDropDownList({ + placeHolder: "Kies ingredient:", + theme: theme, + source: misclist, + displayMember: "name", + width: 150, + height: 27, + dropDownWidth: 500, + dropDownHeight: 500 + }); + $("#maddrowbutton").on('select', function (event) { + if (event.args) { + var index = event.args.index; + var datarecord = misclist.records[index]; + var row = {}; + row["m_name"] = datarecord.name; + row["m_amount"] = 0; + row["m_cost"] = datarecord.cost; + row["m_type"] = datarecord.type; + row["m_use_use"] = datarecord.use_use; + row["m_time"] = 0; + row["m_weight"] = 0; + row["m_amount_is_weight"] = datarecord.amount_is_weight; + var commit = $("#miscGrid").jqxGrid('addrow', null, row); + } + }); + $("#minstockbutton").jqxCheckBox({ theme: theme, height: 27 }); + $("#minstockbutton").on('change', function (event) { + miscinstock = event.args.checked; + misclist.dataBind(); + }); + // delete selected misc. + $("#mdeleterowbutton").jqxButton({ theme: theme, height: 27, width: 150 }); + $("#mdeleterowbutton").on('click', function () { + var selectedrowindex = $("#miscGrid").jqxGrid('getselectedrowindex'); + var rowscount = $("#miscGrid").jqxGrid('getdatainformation').rowscount; + var type = $("#miscGrid").jqxGrid('getcellvalue', selectedrowindex, "m_type"); + if (selectedrowindex >= 0 && selectedrowindex < rowscount && type != "Water agent") { + var id = $("#miscGrid").jqxGrid('getrowid', selectedrowindex); + var commit = $("#miscGrid").jqxGrid('deleterow', id); + } + }); + }, + ready: function() { + $('#jqxTabs').jqxTabs('next'); + }, + columns: [ + { text: 'Ingredient', editable: false, datafield: 'm_name' }, + { text: 'Type', editable: false, width: 120, align: 'center', cellsalign: 'center', datafield: 'm_type' }, + { text: 'Gebruik', width: 110, align: 'center', cellsalign: 'center', datafield: 'm_use_use', columntype: 'dropdownlist', + createeditor: function (row, column, editor) { + var srcUseUse = [ "Mash", "Boil", "Primary", "Secondary", "Bottling" ]; + editor.jqxDropDownList({ autoDropDownHeight: true, source: srcUseUse }); + }, + cellvaluechanging: function (row, column, columntype, oldvalue, newvalue) { + var type = $("#miscGrid").jqxGrid('getcellvalue', row, "m_type"); + if (type == "Water agent") + return oldvalue; + } + }, + { datafield: 'm_amount_is_weight', hidden: true }, // We need to declare this column + { datafield: 'm_amount', hidden: true }, // We need to declare this column + { text: 'Hoeveelheid', datafield: 'm_weight', width: 120, align: 'right', cellsalign: 'right', cellsformat: 'f2', + columntype: 'numberinput', + cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { + var vstr = rowdata.m_amount_is_weight ? "gr":"ml"; + return "
"+dataAdapter.formatNumber(value,"f2")+" "+vstr+"
"; + }, + validation: function (cell, value) { + var high = parseFloat(dataRecord.boil_size) * 1000; + if (value < 0 || value > high) { + return { result: false, message: "Hoeveelheid moet tussen 0 en "+high+" zijn" }; + } + return true; + }, + initeditor: function (row, cellvalue, editor) { + editor.jqxNumberInput({ + inputMode: 'simple', min: 0, max: parseFloat(dataRecord.boil_size) * 1000, + decimalDigits: 2, spinButtons: false + }); + }, + cellvaluechanging: function (row, column, columntype, oldvalue, newvalue) { + var type = $("#miscGrid").jqxGrid('getcellvalue', row, "m_type"); + if (type == "Water agent") + return oldvalue; + } + }, + { text: 'Tijd', datafield: 'm_time', width: 70, align: 'right', cellsalign: 'right', cellsformat: 'f0', + columntype: 'numberinput', + cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { + if (rowdata.m_use_use == 'Boil') { + return "
"+dataAdapter.formatNumber(value, "f0")+" m
"; + } else if (rowdata.m_use_use == 'Secondary') { + return "
"+dataAdapter.formatNumber(value, "f0")+" d
"; + } else { + var tijd = 0; + return "
"; + } + }, + initeditor: function (row, cellvalue, editor, celltext, pressedChar) { + editor.jqxNumberInput({ decimalDigits: 0, digits: 3, min: 0, max: parseFloat(dataRecord.boil_time) }); + }, + cellvaluechanging: function (row, column, columntype, oldvalue, newvalue) { + var use = $("#miscGrid").jqxGrid('getcellvalue', row, "m_use_use"); + if ((use != "Boil") && (use != "Secondary")) + return oldvalue; + }, + validation: function (cell, value) { + var high = parseFloat(dataRecord.boil_time); + if (value < 0 || value > high ) { + return { result: false, message: "De tijd moet 0-"+high+" zijn" }; + } + return true; + } + } + ] + }); + $("#miscGrid").on('cellendedit', function (event) { + var args = event.args; + console.log("Event Type: cellendedit, Column: " + args.datafield + ", Row: " + (args.rowindex) + ", Value: " + args.value); + $("#miscGrid").jqxGrid('setcellvalue', args.rowindex, args.datafield, args.value); + if (args.datafield == 'm_weight') { + $("#miscGrid").jqxGrid('setcellvalue', args.rowindex, 'm_amount', parseFloat(args.value) / 1000); + } + }); + }; + + // Inline yeasts editor + var editYeast = function (data) { + var yeastSource = { + localdata: data.yeasts, + datatype: "local", + cache: false, + datafields: [ + { name: 'y_name', type: 'string' }, + { name: 'y_laboratory', type: 'string' }, + { name: 'y_product_id', type: 'string' }, + { name: 'y_amount', type: 'float' }, + { name: 'y_cost', type: 'float' }, + { name: 'y_type', type: 'string' }, + { name: 'y_form', type: 'string' }, + { name: 'y_time', type: 'float' }, + { name: 'y_min_temperature', type: 'float' }, + { name: 'y_max_temperature', type: 'float' }, + { name: 'y_attenuation', type: 'float' }, + { name: 'y_amount_is_weight', type: 'bool' }, + { name: 'y_use', type: 'string' }, + { name: 'y_weight', type: 'float' } + ], + addrow: function (rowid, rowdata, position, commit) { + commit(true); + }, + deleterow: function (rowid, commit) { + commit(true); + } + }; + var yeastAdapter = new $.jqx.dataAdapter(yeastSource, { + beforeLoadComplete: function (records) { + var data = new Array(); + for (var i = 0; i < records.length; i++) { + var row = records[i]; + if (row.y_form == 'Liquid') + row.y_weight = Math.round(row.y_amount * 17); + else + row.y_weight = row.y_amount * 1000; + data.push(row); + } + return data; + }, + loadError: function(jqXHR, status, error) { + $('#err').text(status + ' ' + error); + }, + }); + $("#yeastGrid").jqxGrid({ + width: 1050, + height: 300, + source: yeastAdapter, + theme: theme, + selectionmode: 'singlerow', + editmode: 'selectedcell', + editable: true, + localization: getLocalization(), + showtoolbar: true, + rendertoolbar: function (toolbar) { + var me = this; + var container = $("
"); + toolbar.append(container); + container.append('
'); + container.append('
In voorraad:
'); + container.append('
'); + container.append(''); + // add yeast from dropdownlist. + $("#yaddrowbutton").jqxDropDownList({ + placeHolder: "Kies gist:", + theme: theme, + source: yeastlist, + displayMember: "name", + width: 150, + height: 27, + dropDownWidth: 500, + dropDownHeight: 500, + renderer: function (index, label, value) { + var datarecord = yeastlist.records[index]; + return datarecord.laboratory+" "+datarecord.product_id+" "+datarecord.name; + } + }); + $("#yaddrowbutton").on('select', function (event) { + if (event.args) { + var index = event.args.index; + var datarecord = yeastlist.records[index]; + var row = {}; + row["y_name"] = datarecord.name; + row["y_laboratory"] = datarecord.laboratory; + row["y_product_id"] = datarecord.product_id; + row["y_type"] = datarecord.type; + row["y_form"] = datarecord.form; + row["y_amount"] = 0; + row["y_cost"] = datarecord.cost; + row["y_use"] = "Primary"; + row["y_time"] = 0; + if (datarecord.form == "Dry") { + row["y_amount_is_weight"] = 1; + } else { + row["y_amount_is_weight"] = 0; + } + row["y_min_temperature"] = datarecord.min_temperature; + row["y_max_temperature"] = datarecord.max_temperature; + row["y_attenuation"] = datarecord.attenuation; + row["y_weight"] = 0; + var commit = $("#yeastGrid").jqxGrid('addrow', null, row); + } + }); + $("#yinstockbutton").jqxCheckBox({ theme: theme, height: 27 }); + $("#yinstockbutton").on('change', function (event) { + yeastinstock = event.args.checked; + yeastlist.dataBind(); + }); + // delete selected yeast. + $("#ydeleterowbutton").jqxButton({ theme: theme, height: 27, width: 150 }); + $("#ydeleterowbutton").on('click', function () { + var selectedrowindex = $("#yeastGrid").jqxGrid('getselectedrowindex'); + var rowscount = $("#yeastGrid").jqxGrid('getdatainformation').rowscount; + if (selectedrowindex >= 0 && selectedrowindex < rowscount) { + var id = $("#yeastGrid").jqxGrid('getrowid', selectedrowindex); + var commit = $("#yeastGrid").jqxGrid('deleterow', id); + } + }); + }, + ready: function() { +// calcSVG(); + $('#jqxTabs').jqxTabs('next'); + }, + columns: [ + { text: 'Gist', editable: false, datafield: 'y_name' }, + { text: 'Laboratorium', editable: false, width: 150, datafield: 'y_laboratory' }, + { text: 'Code', editable: false, width: 90, datafield: 'y_product_id' }, + { text: 'Soort', editable: false, width: 80, align: 'center', cellsalign: 'center', datafield: 'y_form' }, + { text: 'Min.', editable: false, width: 70, align: 'right', cellsalign: 'right', datafield: 'y_min_temperature' }, + { text: 'Max.', editable: false, width: 70, align: 'right', cellsalign: 'right', datafield: 'y_max_temperature' }, + { text: 'Attn.', editable: false, width: 70, align: 'right', cellsalign: 'right', datafield: 'y_attenuation', cellsformat: 'f1' }, + { text: 'Voor', width: 100, align: 'center', cellsalign: 'center', datafield: 'y_use', columntype: 'dropdownlist', + createeditor: function (row, column, editor) { + var srcYUse = [ "Primary", "Secondary", "Bottle" ]; + editor.jqxDropDownList({ autoDropDownHeight: true, source: srcYUse }); + } + }, + { datafield: 'y_amount', width: 90 }, + { text: 'Hoeveel', datafield: 'y_weight', width: 110, align: 'right', cellsalign: 'right', + cellsformat: 'f1', columntype: 'numberinput', + cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { + if (rowdata.y_form == 'Liquid') { + return "
"+dataAdapter.formatNumber(value, "f0")+" pk
"; + } else if (rowdata.y_form == 'Dry') { + return "
"+dataAdapter.formatNumber(value, "f1")+" gr
"; + } else { + return "
"+dataAdapter.formatNumber(value, "f0")+" ml
"; + } + }, + initeditor: function (row, cellvalue, editor, celltext, pressedChar) { + var form = $("#yeastGrid").jqxGrid('getcellvalue', args.rowindex, 'y_form'); + if (form == 'Dry') { + editor.jqxNumberInput({ decimalDigits: 1, min: 0, spinButtons: false }); + } else { + editor.jqxNumberInput({ decimalDigits: 0, min: 0, spinButtons: false }); + } + }, + validation: function (cell, value) { + if (value < 0 || value > 100000000000 ) { + return { result: false, message: "Hoeveelheid moet 0-~ zijn" }; + } + return true; + } + } + ] + }); + $("#yeastGrid").on('cellendedit', function (event) { + var args = event.args; + console.log("Event Type: cellendedit, Column: " + args.datafield + ", Row: " + (args.rowindex) + ", Value: " + args.value); + $("#yeastGrid").jqxGrid('setcellvalue', args.rowindex, args.datafield, args.value); + if (args.datafield == 'y_weight') { + var form = $("#yeastGrid").jqxGrid('getcellvalue', args.rowindex, 'y_form'); + if (form == 'Liquid') + $("#yeastGrid").jqxGrid('setcellvalue', args.rowindex, 'y_amount', parseFloat(args.value * 0.0588)); + else + $("#yeastGrid").jqxGrid('setcellvalue', args.rowindex, 'y_amount', parseFloat(args.value / 1000)); + } + }); + }; + + // inline mash editor + var editMash = function (data) { + var generaterow = function () { + var row = {}; + row["step_name"] = "Stap 1"; + row["step_type"] = "Infusion"; + row["step_infuse_amount"] = 15; + row["step_temp"] = 62.0; + row['step_time'] = 20.0; + row['ramp_time'] = 1.0; + row['end_temp'] = 62.0; + return row; + } + var mashSource = { + localdata: data.mashs, + datatype: "local", + cache: false, + datafields: [ + { name: 'step_name', type: 'string' }, + { name: 'step_type', type: 'string' }, + { name: 'step_infuse_amount', type: 'float' }, + { name: 'step_temp', type: 'float' }, + { name: 'step_time', type: 'float' }, + { name: 'ramp_time', type: 'float' }, + { name: 'end_temp', type: 'float' } + ], + addrow: function (rowid, rowdata, position, commit) { + commit(true); + }, + deleterow: function (rowid, commit) { + commit(true); + } + }; + var mashAdapter = new $.jqx.dataAdapter(mashSource, { + beforeLoadComplete: function (records) { + mash_infuse = 0; + var data = new Array(); + for (var i = 0; i < records.length; i++) { + var row = records[i]; + if (row.step_type == 'Infusion') + mash_infuse += parseFloat(row.step_infuse_amount); + } + }, + }); + $("#mashGrid").jqxGrid({ + width: 960, + height: 400, + source: mashAdapter, + theme: theme, + selectionmode: 'singlerow', + editmode: 'selectedcell', + editable: true, + localization: getLocalization(), + showtoolbar: true, + rendertoolbar: function (toolbar) { + var me = this; + var container = $("
"); + toolbar.append(container); + container.append(''); + container.append(''); + $("#saddrowbutton").jqxButton({ theme: theme, height: 27, width: 150 }); + $("#saddrowbutton").on('click', function () { + var datarow = generaterow(); + var commit = $("#mashGrid").jqxGrid('addrow', null, datarow); + }); + // delete selected yeast. + $("#sdeleterowbutton").jqxButton({ theme: theme, height: 27, width: 150 }); + $("#sdeleterowbutton").on('click', function () { + var selectedrowindex = $("#mashGrid").jqxGrid('getselectedrowindex'); + var rowscount = $("#mashGrid").jqxGrid('getdatainformation').rowscount; + if (selectedrowindex >= 0 && selectedrowindex < rowscount) { + var id = $("#mashGrid").jqxGrid('getrowid', selectedrowindex); + var commit = $("#mashGrid").jqxGrid('deleterow', id); + } + }); + }, + ready: function() { + var fg = estimate_fg(psugar, pcara, 0, 0, 0, svg, parseFloat(parseFloat($("#est_og").jqxNumberInput('decimal')))); + dataRecord.est_fg = fg; + $('#est_fg').val(fg); + calcInit(); + $('#jqxLoader').jqxLoader('close'); + $('#jqxTabs').jqxTabs('first'); + }, + columns: [ + { text: 'Stap naam', datafield: 'step_name' }, + { text: 'Stap type', datafield: 'step_type', width: 110, columntype: 'dropdownlist', + createeditor: function (row, cellvalue, editor, celltext, cellwidth, cellheight) { + var dataSource = [ "Infusion", "Temperature", "Decoction" ]; + editor.jqxDropDownList({ source: dataSource, dropDownHeight: 105 }); + } + }, + { text: 'Temperatuur', datafield: 'step_temp', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1', + validation: function (cell, value) { + if (value < 35 || value > 80) { + return { result: false, message: "De temperatuur moet tussen 35 en 80 zijn." }; + } + return true; + } + }, + { text: 'Eind', datafield: 'end_temp', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1', + validation: function (cell, value) { + if (value < 35 || value > 80) { + return { result: false, message: "De temperatuur moet tussen 35 en 80 zijn." }; + } + return true; + } + }, + { text: 'Tijd', datafield: 'step_time', width: 70, align: 'right', cellsalign: 'right', + validation: function (cell, value) { + if (value < 1 || value > 360) { + return { result: false, message: "De tijd moet tussen 1 en 360 zijn." }; + } + return true; + } + }, + { text: 'Stap', datafield: 'ramp_time', width: 70, align: 'right', cellsalign: 'right', + validation: function (cell, value) { + if (value < 1 || value > 60) { + return { result: false, message: "De tijd moet tussen 1 en 60 zijn." }; + } + return true; + } + }, + { text: 'Infuse', datafield: 'step_infuse_amount', width: 70, align: 'right', cellsalign: 'right', + validation: function (cell, value) { + if (value < 0 || value > 60) { + return { result: false, message: "De waarde moet tussen 0 en 60 zijn." }; + } + return true; + } + } + ] + }); + $("#mashGrid").on('cellendedit', function (event) { + $('#mashGrid').jqxGrid('sortby', 'step_temp', 'asc'); + }); + }; + // initialize the input fields. + var srcType = [ "All Grain", "Partial Mash", "Extract" ]; + var srcColor = [ "Morey", "Mosher", "Daniels" ]; + var srcIBU = [ "Tinseth", "Rager", "Daniels" ]; // Only these are supported at this time. + var srcBase = [ "NaHCO3", "Na2CO3", "CaCO3", "Ca(OH)2" ]; + var srcAcid = [ "Melkzuur", "Zoutzuur", "Fosforzuur", "Zwavelzuur" ]; var srcMaterial= [ "RVS", "Aluminium", "Kunststof", "Koper" ]; var srcAeration= [ 'None', 'Air', 'Oxygen' ]; var srcCooling= [ '-', 'Emersion chiller', 'Counterflow chiller', 'Au bain marie', 'Natural' ]; // '-', 'Dompelkoeler', 'Tegenstroomkoeler', 'Au bain marie', 'Laten afkoelen' - $("#pname").jqxInput({ theme: theme, width: 640, height: 23 }); + $("#name").jqxInput({ theme: theme, width: 640, height: 23 }); $("#code").jqxInput({ theme: theme, width: 100, height: 23 }); $("#birth").jqxDateTimeInput({ theme: theme, width: 150, height: 23, formatString: 'yyyy-MM-dd' }); $("#stage").jqxInput({ theme: theme, width: 100, height: 23 }); - $("#pnotes").jqxInput({ theme: theme, width: 960, height: 200 }); + $("#notes").jqxInput({ theme: theme, width: 960, height: 200 }); $("#log_brew").jqxCheckBox({ theme: theme, width: 120, height: 23, disabled : true }); $("#log_fermentation").jqxCheckBox({ theme: theme, width: 120, height: 23, disabled : true }); $("#inventory_reduced").jqxCheckBox({ theme: theme, width: 120, height: 23 }); @@ -627,14 +1913,14 @@ // Call the script with the uuid. $("#inventory_reduced").jqxCheckBox({ disabled : true }); }); - $("#plocked").jqxCheckBox({ theme: theme, width: 120, height: 23, disabled : true }); - $('#plocked').on('checked', function (event) { + $("#locked").jqxCheckBox({ theme: theme, width: 120, height: 23, disabled : true }); + $('#locked').on('checked', function (event) { if (brewstage >= 10) { $("#stage").val('Closed'); brewstage = 11; } }); - $('#plocked').on('unchecked', function (event) { + $('#locked').on('unchecked', function (event) { if (brewstage >= 10) { $("#stage").val('Ready'); brewstage = 10; @@ -695,12 +1981,201 @@ // Packaging // Tasting - // Recipe + $("#batch_size").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 4, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: 'L', symbolPosition: 'right' }); + $("#boil_size").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 2, readOnly: true, symbol: 'L', symbolPosition: 'right' }); + $("#boil_time").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 4, max: 360, decimalDigits: 0, spinButtons: true }); + $("#efficiency").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 40, max: 100, decimalDigits: 0, spinButtons: true, symbol: '%', symbolPosition: 'right' }); $("#est_og").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 70, height: 23, decimalDigits: 3 }); - $("#est_ibu").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 70, height: 23, decimalDigits: 0 }); - $("#est_color").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 70, height: 23, decimalDigits: 0 }); + $("#est_og2").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 3, readOnly: true }); + $("#st_og_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); + $("#st_og_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); + + $("#est_fg").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 3, readOnly: true }); + $("#st_fg_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); + $("#st_fg_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); + + $("#est_abv").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); + $("#st_abv_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); + $("#st_abv_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); + + $("#est_color").jqxNumberInput({ inputMode: 'simple', theme: theme, symbol: ' EBC', symbolPosition: 'right', width: 100, height: 23, decimalDigits: 0, readOnly: true }); + $("#est_color2").jqxNumberInput({ inputMode: 'simple', theme: theme, symbol: ' EBC', symbolPosition: 'right', width: 100, height: 23, decimalDigits: 0, readOnly: true }); + $("#st_color_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); + $("#st_color_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); + $("#color_method").jqxDropDownList({ theme: theme, source: srcColor, width: 125, height: 23, dropDownHeight: 95 }); + + $("#est_ibu").jqxNumberInput({ inputMode: 'simple', theme: theme, symbol: ' IBU', symbolPosition: 'right', width: 100, height: 23, decimalDigits: 0, readOnly: true }); + $("#est_ibu2").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); + $("#st_ibu_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); + $("#st_ibu_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); + $("#ibu_method").jqxDropDownList({ theme: theme, source: srcIBU, width: 125, height: 23, dropDownHeight: 95, dropDownVerticalAlignment: 'top' }); + + $("#est_carb").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); + $("#st_carb_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); + $("#st_carb_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); + + $("#mash_name").jqxInput({ theme: theme, width: 320, height: 23 }); + $("#mash_ph").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 4, max: 8, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1 }); + $("#tgt_mash_ph").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 1, readOnly: true }); + $("#sparge_temp").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 70, max: 98, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.5 }); + $("#est_mash_sg").jqxNumberInput({ inputMode: 'simple', readOnly: true, theme: theme, width: 70, height: 23, decimalDigits: 3 }); + // Several gauges + $("#hop_flavour").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true }); + $("#hop_aroma").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true }); + $("#perc_malts").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true }); + $("#perc_sugars").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true }); + $("#perc_cara").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true }); + + // Water treatment + $("#w1_name").jqxDropDownList({ + placeHolder: "Kies hoofd water:", + theme: theme, + source: waterlist, + displayMember: "name", + width: 250, + height: 27, + dropDownWidth: 400, + dropDownHeight: 400 + }); + $("#w1_name").on('select', function (event) { + if (event.args) { + var index = event.args.index; + var datarecord = waterlist.records[index]; + dataRecord.w1_name = datarecord.name; + $("#w1_calcium").val(datarecord.calcium); + dataRecord.w1_calcium = datarecord.calcium; + $("#w1_sulfate").val(datarecord.sulfate); + dataRecord.w1_sulfate = datarecord.sulfate; + $("#w1_chloride").val(datarecord.chloride); + dataRecord.w1_chloride = datarecord.chloride; + $("#w1_sodium").val(datarecord.sodium); + dataRecord.w1_sodium = datarecord.sodium; + $("#w1_magnesium").val(datarecord.magnesium); + dataRecord.w1_magnesium = datarecord.magnesium; + $("#w1_total_alkalinity").val(datarecord.total_alkalinity); + dataRecord.w1_total_alkalinity = datarecord.total_alkalinity; + $("#w1_ph").val(datarecord.ph); + dataRecord.w1_ph = datarecord.ph; + $("#w1_cost").val(datarecord.cost); + dataRecord.w1_cost = datarecord.cost; + calcWater(); + } + }); + $("#w1_amount").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w1_calcium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w1_magnesium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w1_sodium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w1_total_alkalinity").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w1_chloride").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w1_sulfate").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w1_ph").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + + $("#w2_name").jqxDropDownList({ + placeHolder: "Kies meng water:", + theme: theme, + source: waterlist, + displayMember: "name", + width: 250, + height: 27, + dropDownWidth: 400, + dropDownHeight: 400 + }); + $("#w2_name").on('select', function (event) { + if (event.args) { + var index = event.args.index; + var datarecord = waterlist.records[index]; + dataRecord.w2_name = datarecord.name; + $("#w2_calcium").val(datarecord.calcium); + dataRecord.w2_calcium = datarecord.calcium; + $("#w2_sulfate").val(datarecord.sulfate); + dataRecord.w2_sulfate = datarecord.sulfate; + $("#w2_chloride").val(datarecord.chloride); + dataRecord.w2_chloride = datarecord.chloride; + $("#w2_sodium").val(datarecord.sodium); + dataRecord.w2_sodium = datarecord.sodium; + $("#w2_magnesium").val(datarecord.magnesium); + dataRecord.w2_magnesium = datarecord.magnesium; + $("#w2_total_alkalinity").val(datarecord.total_alkalinity); + dataRecord.w2_total_alkalinity = datarecord.total_alkalinity; + $("#w2_ph").val(datarecord.ph); + dataRecord.w2_ph = datarecord.ph; + $("#w2_cost").val(datarecord.cost); + dataRecord.w2_cost = datarecord.cost; + $("#w2_amount").jqxNumberInput({ max: 100000, readOnly: false }); // Set high max to enable the spinbuttons. + calcWater(); + } + }); + $("#w2_amount").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 94, height: 23, min: 0, max: 0, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.5, readOnly: true }); + $("#w2_calcium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w2_magnesium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w2_sodium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w2_total_alkalinity").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w2_chloride").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w2_sulfate").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#w2_ph").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + + $("#wg_amount").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wg_calcium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wg_magnesium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wg_sodium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wg_total_alkalinity").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wg_chloride").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wg_sulfate").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wg_ph").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wb_calcium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wb_magnesium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wb_sodium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wb_total_alkalinity").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wb_chloride").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wb_sulfate").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wb_ph").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + + $("#pr_name").jqxDropDownList({ + placeHolder: "Kies doel profiel:", + theme: theme, + source: waterprofiles, + displayMember: "name", + width: 250, + height: 27, + dropDownWidth: 400, + dropDownHeight: 300 + }); + $("#pr_name").on('select', function (event) { + if (event.args) { + var index = event.args.index; + var datarecord = waterprofiles.records[index]; + $("#pr_calcium").val(datarecord.calcium); + $("#pr_sulfate").val(datarecord.sulfate); + $("#pr_chloride").val(datarecord.chloride); + $("#pr_sodium").val(datarecord.sodium); + $("#pr_magnesium").val(datarecord.magnesium); + $("#pr_total_alkalinity").val(datarecord.total_alkalinity); + } + }); + $("#pr_calcium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#pr_magnesium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#pr_sodium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#pr_total_alkalinity").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#pr_chloride").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#pr_sulfate").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); + $("#wa_cacl2").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); + $("#wa_caso4").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); + $("#wa_mgso4").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); + $("#wa_nacl").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); + + $("#calc_acid").jqxCheckBox({ theme: theme, width: 120, height: 23 }); + $("#wa_base_name").jqxDropDownList({ theme: theme, source: srcBase, width: 125, height: 23, dropDownHeight: 128 }); + $("#wa_base").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 2, spinButtons: true, spinButtonsStep: 0.05, symbol: ' gr', symbolPosition: 'right' }); + $("#wa_acid_name").jqxDropDownList({ theme: theme, source: srcAcid, width: 125, height: 23, dropDownHeight: 128 }) + $("#wa_acid").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 2, spinButtons: true, spinButtonsStep: 0.05, symbol: ' ml', symbolPosition: 'right' }); + $("#wa_acid_perc").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 80, height: 23, min: 0, max: 100, decimalDigits: 0, spinButtons: true, symbol: '%', symbolPosition: 'right' }); + + $("#sparge_volume").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1 }); + $("#sparge_ph").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1 }); + $("#sparge_acid_amount").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 5, readOnly: true }); + $('#jqxTabs').jqxTabs({ theme: theme, width: 1280, @@ -709,18 +2184,13 @@ position: 'top' }); - // Buttons sidebar - $("#rec_edit").jqxButton({ template: "primary", width: '140px', theme: theme }); - $("#brew_log").jqxButton({ template: "primary", width: '140px', theme: theme }); - $("#ferment_log").jqxButton({ template: "primary", width: '140px', theme: theme }); - // Buttons below $("#Delete").jqxButton({ template: "danger", width: '80px', theme: theme }); $("#Delete").click(function () { // Open a popup to confirm this action. $('#eventWindow').jqxWindow('open'); $("#delOk").click(function () { - var data = "delete=true&" + $.param({ uuid: dataRecord.puuid }); + var data = "delete=true&" + $.param({ uuid: dataRecord.uuid }); $.ajax({ dataType: 'json', url: url, @@ -744,20 +2214,24 @@ $("#Save").jqxButton({ template: "success", width: '90px', theme: theme }); $("#Save").click(function () { - console.log(dataRecord.puuid); - + console.log(dataRecord.uuid); + var fermentablerow = $('#fermentableGrid').jqxGrid('getrows'); + var hoprow = $('#hopGrid').jqxGrid('getrows'); + var miscrow = $('#miscGrid').jqxGrid('getrows'); + var yeastrow = $('#yeastGrid').jqxGrid('getrows'); + var mashrow = $('#mashGrid').jqxGrid('getrows'); var row = { record: my_record, - puuid: dataRecord.puuid, - pname: $("#pname").val(), + uuid: dataRecord.uuid, + name: $("#name").val(), code: $("#code").val(), birth: $("#birth").val(), stage: $("#stage").val(), - pnotes: $("#pnotes").val(), + notes: $("#notes").val(), log_brew: $("#log_brew").val(), log_fermentation: $("#log_fermentation").val(), inventory_reduced: $("#inventory_reduced").val(), - plocked: $("#plocked").val(), + locked: $("#locked").val(), eq_name: $("#eq_name").val(), eq_boil_size: parseFloat($("#eq_boil_size").jqxNumberInput('decimal')), eq_batch_size: parseFloat($("#eq_batch_size").jqxNumberInput('decimal')), @@ -781,7 +2255,72 @@ eq_kettle_height: dataRecord.eq_kettle_height, 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')) + eq_efficiency: parseFloat($("#eq_efficiency").jqxNumberInput('decimal')), + // st_name: $('#st_name').val(), + // st_letter: $('#st_letter').val(), + // st_guide: $('#st_guide').val(), + // st_type: $('#st_type').val(), + // st_category: $('#st_category').val(), + // st_category_number: parseFloat($("#st_category_number").jqxNumberInput('decimal')), + st_og_min: parseFloat($("#st_og_min").jqxNumberInput('decimal')), + st_og_max: parseFloat($("#st_og_max").jqxNumberInput('decimal')), + st_fg_min: parseFloat($("#st_fg_min").jqxNumberInput('decimal')), + st_fg_max: parseFloat($("#st_fg_max").jqxNumberInput('decimal')), + st_ibu_min: parseFloat($("#st_ibu_min").jqxNumberInput('decimal')), + st_ibu_max: parseFloat($("#st_ibu_max").jqxNumberInput('decimal')), + st_color_min: parseFloat($("#st_color_min").jqxNumberInput('decimal')), + st_color_max: parseFloat($("#st_color_max").jqxNumberInput('decimal')), + st_carb_min: parseFloat($("#st_carb_min").jqxNumberInput('decimal')), + st_carb_max: parseFloat($("#st_carb_max").jqxNumberInput('decimal')), + st_abv_min: parseFloat($("#st_abv_min").jqxNumberInput('decimal')), + st_abv_max: parseFloat($("#st_abv_max").jqxNumberInput('decimal')), + type: $("#type").val(), + batch_size: parseFloat($("#batch_size").jqxNumberInput('decimal')), + boil_size: parseFloat($("#boil_size").jqxNumberInput('decimal')), + boil_time: parseFloat($("#boil_time").jqxNumberInput('decimal')), + efficiency: parseFloat($("#efficiency").jqxNumberInput('decimal')), + est_og: parseFloat($("#est_og").jqxNumberInput('decimal')), + est_fg: parseFloat($("#est_fg").jqxNumberInput('decimal')), + est_abv: parseFloat($("#est_abv").jqxNumberInput('decimal')), + est_color: parseFloat($("#est_color").jqxNumberInput('decimal')), + color_method: $("#color_method").val(), + est_ibu: parseFloat($("#est_ibu").jqxNumberInput('decimal')), + ibu_method: $("#ibu_method").val(), + est_carb: parseFloat($("#est_carb").jqxNumberInput('decimal')), + mash_name: $("#mash_name").val(), + mash_ph: parseFloat($("#mash_ph").jqxNumberInput('decimal')), + sparge_temp: parseFloat($("#sparge_temp").jqxNumberInput('decimal')), + sparge_ph: parseFloat($("#sparge_ph").jqxNumberInput('decimal')), + sparge_volume: parseFloat($("#sparge_volume").jqxNumberInput('decimal')), + // sparge_acid_type: $("#sparge_acid_type").val(), + // sparge_acid_perc: parseFloat($("#sparge_acid_perc").jqxNumberInput('decimal')), + // sparge_acid_amount: parseFloat($("#sparge_acid_amount").jqxNumberInput('decimal')), + calc_acid: $("#calc_acid").val(), + w1_name: $("#w1_name").val(), + w1_amount: parseFloat($("#w1_amount").jqxNumberInput('decimal')), + w1_calcium: parseFloat($("#w1_calcium").jqxNumberInput('decimal')), + w1_sulfate: parseFloat($("#w1_sulfate").jqxNumberInput('decimal')), + w1_chloride: parseFloat($("#w1_chloride").jqxNumberInput('decimal')), + w1_sodium: parseFloat($("#w1_sodium").jqxNumberInput('decimal')), + w1_magnesium: parseFloat($("#w1_magnesium").jqxNumberInput('decimal')), + w1_total_alkalinity: parseFloat($("#w1_total_alkalinity").jqxNumberInput('decimal')), + w1_ph: parseFloat($("#w1_ph").jqxNumberInput('decimal')), + w1_cost: dataRecord.w1_cost, + w2_name: $("#w2_name").val(), + w2_amount: parseFloat($("#w2_amount").jqxNumberInput('decimal')), + w2_calcium: parseFloat($("#w2_calcium").jqxNumberInput('decimal')), + w2_sulfate: parseFloat($("#w2_sulfate").jqxNumberInput('decimal')), + w2_chloride: parseFloat($("#w2_chloride").jqxNumberInput('decimal')), + w2_sodium: parseFloat($("#w2_sodium").jqxNumberInput('decimal')), + w2_magnesium: parseFloat($("#w2_magnesium").jqxNumberInput('decimal')), + w2_total_alkalinity: parseFloat($("#w2_total_alkalinity").jqxNumberInput('decimal')), + w2_ph: parseFloat($("#w2_ph").jqxNumberInput('decimal')), + w2_cost: dataRecord.w2_cost, + fermentables: fermentablerow, + hops: hoprow, + miscs: miscrow, + yeasts: yeastrow, + mashs: mashrow }; var data = "update=true&" + $.param(row); $.ajax({ diff -r 159d7a89fcef -r 2c9cfe2f0860 www/js/prod_inprod.js --- a/www/js/prod_inprod.js Mon Dec 24 15:52:11 2018 +0100 +++ b/www/js/prod_inprod.js Mon Dec 24 23:10:52 2018 +0100 @@ -27,7 +27,7 @@ cache: false, datafields: [ { name: 'record', type: 'number' }, - { name: 'pname', type: 'string' }, + { name: 'name', type: 'string' }, { name: 'code', type: 'string' }, { name: 'birth', type: 'string' }, { name: 'stage', type: 'string' }, @@ -61,7 +61,7 @@ columns: [ { text: 'Datum', datafield: 'birth', width: 120 }, { text: 'Code', datafield: 'code', width: 120 }, - { text: 'Naam', datafield: 'pname' }, + { text: 'Naam', datafield: 'name' }, { text: 'Fase', datafield: 'stage', width: 130 }, { text: 'Wijzig', datafield: 'Edit', width: 120, align: 'center', columntype: 'button', cellsrenderer: function () { return "Wijzig"; diff -r 159d7a89fcef -r 2c9cfe2f0860 www/prod_edit.php --- a/www/prod_edit.php Mon Dec 24 15:52:11 2018 +0100 +++ b/www/prod_edit.php Mon Dec 24 23:10:52 2018 +0100 @@ -5,54 +5,88 @@
-
+
- - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Brouw naam:
Brouw code:Start planning:
Brouw fase:
Brouw log:
Vergisting log:
Ingredienten afgeboekt:
Afgesloten:
Opmerkingen:
-
- - - - -
-
Brouw naam:
Brouw code:Start planning:
Brouw fase:
Brouw log:
Vergisting log:
Ingredienten afgeboekt:
Afgesloten:
Opmerkingen:
Brouw type:
Brouwzaal rendement:
Brouw volume:
Kooktijd minuten:
Kook volume:
Start SG:
Eind SG:
Alcohol vol%:
Kleur:
Kleur methode:
Koolzuur vol:
Bitterheid:
Bitterheid methode:
@@ -65,7 +99,7 @@
-
+
@@ -137,6 +171,231 @@ +
+
+
+ + + + + + + + + + + + + + + + + + + + +
Kleur:
Percentage moutstort:
Begin SG:
Percentage suiker:
Percentage cara:
+
+
+ +
+
+ + + + + + + + + + + + + +
Bitterheid IBU:
Smaak bijdrage:
Aroma bijdrage:
Hoppen:
+
+
+ +
+
+ + + + + +
Diversen:
Graat
+
+
+ +
+
+ + + + + +
Gisten:
Graat
+
+
+ +
+
+ + + + + + + + + + + + + +
Maischchema:Maish pH:
Spoelwater temp:
Stappen:
Graat
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bitterheidsindex:
Richtgetal Cl/SO4:
Doel maisch pH:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Water overzicht
Water profielVolumeCaMgNaCaCO3ClSO4pH
Gemengd water:
Behandeld water:
Resultaat:
+
+
Calciumchloride (CaCl2):
Automatisch pH aanpassen:
Spoelwater volume:
Gips (CaSO4):
Ontzuren met:
Spoelwater bron:
Epsom zout (MgSO4):
Aanzuren met:
Spoelwater pH:
Keukenzout (NaCl):
Aanzuren met:
Aanzuren hoeveelheid:
+
+
+
@@ -254,7 +513,22 @@
-
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+