diff -r 371f2da785d9 -r 3d532097860d www/js/prod_edit.js --- a/www/js/prod_edit.js Fri Sep 06 14:11:56 2019 +0200 +++ b/www/js/prod_edit.js Fri Sep 06 22:59:59 2019 +0200 @@ -46,2876 +46,63 @@ $(document).ready(function () { - var to_100 = false; // Fermentables adjust to 100% - var preboil_sg = 0; - var aboil_sg = 0; - var est_mash_sg = 0; - 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 pitchrate = 0.75; // Yeast pitch rate default - var initcells = 0; // Initial yeast cell count - - var ok_fermentables = 1; // Fermentables are in stock - var ok_hops = 1; // Hops are in stock - var ok_miscs = 1; // Miscs are in stock - var ok_yeasts = 1; // Yeasts are in stock - var ok_waters = 1; // Waters are in stock - - 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 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 fermentableRow = 0; - var fermentableData = {}; - var fermentableInit = 1; - var hopRow = 0; - var hopData = {}; - var miscRow = 0; - var miscData = {}; - var yeastRow = 0; - var yeastData = {}; - var mashRow = 0; - var mashData = {}; - - /* - * Remove the top menu so that we MUST use the buttons to leave the editor. - */ - $('#jqxMenu').jqxMenu('destroy'); - - console.log("record:" + my_record + " return:" + my_return + " theme:" + theme); - $("#jqxLoader").jqxLoader({width:250,height:150,isModal:true,text:"Laden product ...",theme:theme}); - - function calcSupplies() { - if (dataRecord.inventory_reduced > 6) { - $("#ok_pmpt").hide(); - return; - } - if (ok_fermentables && ok_hops && ok_miscs && ok_yeasts && ok_waters) - $("#ok_supplies").html(""); - else - $("#ok_supplies").html(""); - } - - function calcPercentages() { - - console.log("calcPercentages()"); - var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; - if (rowscount > 1) { - var tw = 0; - for (i = 0; i < rowscount; i++) { - var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); - if (rowdata.f_added < 4) - tw += Math.round(rowdata.f_amount * 1000) / 1000; - }; - tw = Math.round(tw * 1000) / 1000; - - for (i = 0; i < rowscount; i++) { - var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); - if (rowdata.f_added < 4) { - var percentage = Math.round(rowdata.f_amount / tw * 1000) / 10.0; - $("#fermentableGrid").jqxGrid('setcellvalue', i, "f_percentage", percentage); - } else { - $("#fermentableGrid").jqxGrid('setcellvalue', i, "f_percentage", 0); - } - }; - } else { - $("#fermentableGrid").jqxGrid('setcellvalue', 0, "f_percentage", 100); - } - } - - /* - * All calculations that depend on changes in the fermentables, - * volumes and equipments. - */ - function calcFermentables() { - - var sugarsf = 0; // fermentable sugars mash + boil - var sugarsm = 0; // fermentable sugars in mash - psugar = 0; - pcara = 0; - mashkg = 0; - ok_fermentables = 1; // All is in stock. - ok_yeasts = 1; - var vol = 0; // Volume sugars after boil - var addedS = 0; // Added sugars after boil - var addedmass = 0; // Added mass after boil - var mvol = 0; // mash volume - var colort = 0; // Colors srm * vol totals - var colorh = 0; // Colors ebc * vol * kt - var colorn = 0; // Colors ebc * pt * pct - var my_100 = false; - var mashtime = 0; // Total mash time - var mashtemp = 0; // Average mash temperature - var bv = 0.925; // Bierverlies rendement - var sr = 0.95; // Mash en spoel rendement - var lintner = 0; // Total recipe lintner - - if ((rows = $('#mashGrid').jqxGrid('getrows'))){ - for(var i=0;i5) - mashtime-=5;//Correct last ramp > 75 - mashtemp=Round(mashtemp/mashtime,2); - } - - if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) { - return; // grid not yet loaded. - } - - var s = 0; - 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 == 1 && row.f_added < 4) // Sugar - psugar += row.f_percentage; - if (row.f_graintype == 2 && row.f_added < 4) // Crystal - pcara += row.f_percentage; - var d = row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100); - if (row.f_added == 0) { // Mash - if (mvol > 0) { // Only if mash already known. - mvol += row.f_amount * row.f_moisture / 100; - s += d; - } - d = parseFloat(dataRecord.efficiency) / 100 * d; - sugarsm += d; - mashkg += parseFloat(row.f_amount); - } - if (row.f_added == 0 || row.f_added == 1) // Mash or Boil - sugarsf += d; - if (row.f_added == 2 || row.f_added == 3) { // Fermentation or lagering - var x = (row.f_yield / 100) * (1 - row.f_moisture / 100); - addedS += row.f_amount * x; - addedmass += row.f_amount; - vol += (x * sugardensity + (1 - x) * 1) * row.f_amount; - } - if (row.f_added < 4) { - colort += row.f_amount * ebc_to_srm(row.f_color); - colorh += row.f_amount * row.f_color * get_kt(row.f_color); - colorn += (row.f_percentage / 100) * row.f_color; // For 8.6 Pt wort. - } - if (fermentableInit) { - if (row.f_added == 4) { - $("#bottle_priming_total").val(row.f_amount * 1000); // Prevent clearing - $("#bottle_priming_sugar").jqxDropDownList('selectItem', row.f_name); - } - if (row.f_added == 5) { - $("#keg_priming_total").val(row.f_amount * 1000); - $("#keg_priming_sugar").jqxDropDownList('selectItem', row.f_name); - } - } - // Check supplies. - if ((((dataRecord.inventory_reduced <= 2) && (row.f_added <= 1)) || // Mash or boil - ((dataRecord.inventory_reduced <= 3) && (row.f_added == 2)) || // Primary - ((dataRecord.inventory_reduced <= 5) && (row.f_added == 3)) || // Secondary or Tertiary - ((dataRecord.inventory_reduced <= 6) && (row.f_added == 4)) || // Bottle - ((dataRecord.inventory_reduced <= 6) && (row.f_added == 5))) && row.f_inventory < row.f_amount) { - ok_fermentables = 0; - } - if (row.f_added == 0 && (row.f_type == 0 || row.f_type == 4) && row.f_color < 50) { // Mash and Grain/Adjunct and Color < 50 - lintner += row.f_diastatic_power * row.f_amount; - } - } - fermentableInit = 0; - $("#ferm_lintner").val(Math.round(parseFloat(lintner / mashkg))); - $("#mash_kg").val(mashkg); - console.log("calcFermentables() supplies:"+ok_fermentables+" moutsuiker:"+sugarsm+"/"+sugarsf); - to_100 = my_100; - if (to_100) { - $("#wf_amount").jqxNumberInput({ width: 90, readOnly: true, spinButtons: false }); - } else { - $("#wf_amount").jqxNumberInput({ width: 110, readOnly: false, spinButtons: true }); - } - - if (mvol > 0) { - var v = s / sugardensity + mvol; - s = 1000 * s / (v * 10); //deg. Plato - est_mash_sg = Math.round(plato_to_sg(s) * 10000) / 10000; - $('#est_mash_sg').val(est_mash_sg); - } - - // Estimate total recipe OG. - dataRecord.est_og = estimate_sg(sugarsf + addedS, parseFloat(dataRecord.batch_size)); - $('#est_og').val(dataRecord.est_og); - $('#est_og2').val(dataRecord.est_og); - var org = dataRecord.est_og; - - // Estimate SG in kettle after boil - aboil_sg = estimate_sg(sugarsf, parseFloat(dataRecord.batch_size)); - $('#est_og3').val(aboil_sg); - - // Estimate SG in kettle before boil - preboil_sg = estimate_sg(sugarsm, parseFloat(dataRecord.boil_size)); - $('#est_pre_sg').val(preboil_sg); - - // Recalculate volumes. - var aboil_volume = parseFloat(dataRecord.batch_size); - if (dataRecord.brew_aboil_volume > 0) - aboil_volume = dataRecord.brew_aboil_volume / 1.04; // volume @ 20 degrees - if (dataRecord.brew_fermenter_tcloss == 0) { - dataRecord.brew_fermenter_tcloss = dataRecord.eq_trub_chiller_loss; - $("#brew_fermenter_tcloss").val(dataRecord.brew_fermenter_tcloss); - } - dataRecord.brew_fermenter_volume = aboil_volume - dataRecord.brew_fermenter_tcloss + dataRecord.brew_fermenter_extrawater; - $("#brew_fermenter_volume").val(dataRecord.brew_fermenter_volume); - // Estimated needed sparge water corrected for the temperature. - var spoelw = (dataRecord.boil_size - mash_infuse + (mashkg * my_grain_absorbtion) + dataRecord.eq_lauter_deadspace) * 1.03; - $("#brew_sparge_est").val(spoelw); - - // Calculate SG in fermenter - var ogx = dataRecord.brew_aboil_sg; - if (ogx < 1.002) - ogx = aboil_sg; - var top = dataRecord.brew_fermenter_extrawater; - - if (dataRecord.brew_fermenter_volume > 0) { - var sug = sg_to_plato(ogx) * dataRecord.brew_fermenter_volume * ogx / 100; //kg of sugar in - sug += addedS; //kg - - if ((dataRecord.brew_fermenter_volume * ogx + addedmass) > 0) { - var pt = 100 * sug / (dataRecord.brew_fermenter_volume * ogx + addedmass + top); - dataRecord.brew_fermenter_sg = Round(plato_to_sg(pt),4); - $("#brew_fermenter_sg").val(dataRecord.brew_fermenter_sg); - // color - if (dataRecord.color_method == 4) { - dataRecord.brew_fermenter_color = Math.round(((pt / 8.6) * colorn) + (dataRecord.boil_time / 60)); - } else if (dataRecord.color_method == 3) { - dataRecord.brew_fermenter_color = Math.round((4.46 * bv * sr) / (aboil_volume + top) * colorh); - } else { - var cw = colort / (aboil_volume + top) * 8.34436; - dataRecord.brew_fermenter_color = kw_to_ebc(dataRecord.color_method, cw); - } - $("#brew_fermenter_color").val(dataRecord.brew_fermenter_color); - var scolor = ebc_to_color(dataRecord.brew_fermenter_color); - $("#bcolorf").show(); - document.getElementById("bcolorf").style.background= scolor; - } - } else { - // Negative volume - dataRecord.brew_fermenter_sg = dataRecord.brew_fermenter_color = 0; - $("#brew_fermenter_sg").val(0); - $("#brew_fermenter_color").val(0); - $("#bcolorf").hide(); - } - - // Color of the wort - if (dataRecord.color_method == 4) { - var color = Math.round(((sg_to_plato(dataRecord.est_og) / 8.6) * colorn) + (dataRecord.boil_time / 60)); - } else if (dataRecord.color_method == 3) { // Hans Halberstadt - var color = Math.round((4.46 * bv * sr) / parseFloat(dataRecord.batch_size) * colorh); - } else { - var cw = colort / parseFloat(dataRecord.batch_size) * 8.34436; - var color = kw_to_ebc(dataRecord.color_method, cw); - } - dataRecord.est_color = color; - $('#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; - - // Progress bars - pmalts = mashkg / dataRecord.eq_mash_max * 100; - $("#perc_malts").jqxProgressBar('val', pmalts); - $("#perc_sugars").jqxProgressBar('val', psugar); - $("#perc_cara").jqxProgressBar('val', pcara); - calcStage(); - - // Calculate estimated svg. - svg = 0; // default. - initcells = 0; - var rows = $('#yeastGrid').jqxGrid('getrows'); - for (var i = 0; i < rows.length; i++) { - var row = rows[i]; - if (row.y_use == 0) { // Primary - if (parseFloat(row.y_attenuation) > svg) - svg = parseFloat(row.y_attenuation); // Take the highest if multiple yeasts. - if (row.y_form == 0) - initcells += (parseFloat(row.y_cells) / 1000000000) * parseFloat(row.y_amount) * (dataRecord.starter_viability / 100); - else - initcells += (parseFloat(row.y_cells) / 1000000) * parseFloat(row.y_amount); - } - // TODO: brett in secondary ?? - if ((((dataRecord.inventory_reduced <= 3) && (row.y_use == 0)) || // Primary - ((dataRecord.inventory_reduced <= 4) && (row.y_use == 1)) || // Secondary - ((dataRecord.inventory_reduced <= 5) && (row.y_use == 2)) || // Tertiary - ((dataRecord.inventory_reduced <= 6) && (row.y_use == 3))) && // Bottle - (row.y_inventory < row.y_amount)) { - ok_yeasts = 0; - } - } - calcSupplies(); - if (svg == 0) - svg = 77; - - if ((mashkg > 0) && (mash_infuse > 0) && (mashtime > 0) && (mashtemp > 0)) { - dataRecord.est_fg = estimate_fg(psugar, pcara, mash_infuse / mashkg, mashtime, mashtemp, svg, dataRecord.est_og); - } else { - dataRecord.est_fg = estimate_fg(psugar, pcara, 0, 0, 0, svg, dataRecord.est_og); - } - $('#est_fg').val(dataRecord.est_fg); - $('#est_fg2').val(dataRecord.est_fg); - $('#est_fg3').val(dataRecord.est_fg); - var fig = dataRecord.est_fg; - - dataRecord.est_abv = abvol(dataRecord.est_og, dataRecord.est_fg); - $("#est_abv").val(dataRecord.est_abv); - $("#est_abv2").val(dataRecord.est_abv); - - // Calculate the final svg if available use the real value. - if ((dataRecord.stage >= 6) && (dataRecord.fg > 0.990) && (dataRecord.fg < dataRecord.brew_fermenter_sg)) { - svg = 100 * (dataRecord.brew_fermenter_sg - dataRecord.fg) / (dataRecord.brew_fermenter_sg - 1); - org = dataRecord.brew_fermenter_sg; - fig = dataRecord.fg; - } - - $("#yeast_cells").val(initcells); - $("#need_cells").val(getNeededYeastCells()); - - // Calculate the calories in kcal/l (from brouwhulp) - var alc = 1881.22 * fig * (org - fig) / (1.775 - org); - var sug = 3550 * fig * (0.1808 * org + 0.8192 * fig - 1.0004); - $("#kcal").val(Math.round((alc + sug) / (12 * 0.0295735296))); - }; - - function calcMash() { - - if (!(rows = $('#mashGrid').jqxGrid('getrows'))) - return; - if (mashkg == 0) - return; - - var infused = 0; - for (var i = 0; i < rows.length; i++) { - var row = $("#mashGrid").jqxGrid('getrowdata', i); - if (row.step_type == 0) // Infusion - infused += row.step_infuse_amount; - $("#mashGrid").jqxGrid('setcellvalue', i, "step_thickness", infused / mashkg); - } - } - - /* - * Change OG of recipe but keep the water volumes. - */ - function calcFermentablesFromOG(OG) { - - console.log("calcFermentablesFromOG("+OG+")"); - var efficiency = parseFloat($("#efficiency").jqxNumberInput('decimal')); - var sug = sg_to_plato(OG) * parseFloat($("#batch_size").jqxNumberInput('decimal')) * OG / 100; //total amount of sugars in kg - var tot = 0; - var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; - - for (var i = 0; i < rowscount; i++) { - var row = $("#fermentableGrid").jqxGrid('getrowdata', i); - if (row.f_added < 4) { - var d = row.f_percentage / 100 * (row.f_yield / 100) * (1 - row.f_moisture / 100); - if (row.f_added == 0) // Mash - d = efficiency / 100 * d; - tot += d; - } - } - var totmass = 0; - if (tot) - totmass = Math.round((sug / tot) * 1000) / 1000; - - if (totmass) { - for (i = 0; i < rowscount; i++) { - var row = $("#fermentableGrid").jqxGrid('getrowdata', i); - if (row.f_added < 4) { - var amount = Math.round(row.f_percentage * 10 * totmass) / 1000; - $("#fermentableGrid").jqxGrid('setcellvalue', i, "f_amount", amount); - } - } - } - }; - - function getNeededYeastCells() { - - var sg = dataRecord.brew_fermenter_sg; - if (sg <= 1.0001 && dataRecord.fg > 1.000) - sg = dataRecord.fg; - else if (sg <= 1.0001) - sg = dataRecord.est_og; - var plato = sg_to_plato(sg); - - var volume = dataRecord.brew_fermenter_volume; - if (volume <= 0) - volume = dataRecord.batch_size - dataRecord.eq_trub_chiller_loss; - - var result = pitchrate * volume * plato; - return result; - } - - function hopFlavourContribution(bt, vol, use, amount) { - var result; - - if (use == 1) { // 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 - } - return (result * amount * 1000) / vol; - } - - function hopAromaContribution(bt, vol, use, amount) { - var result = 0; - - if (use == 5) { // Dry hop - result = 1.33; - } else 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 == 2) { // Boil - result = 1; - } else if (use == 3) { // Aroma - result = 1.2; - } else if (use == 4) { // Whirlpool - result = 1.2; - } - return (result * amount * 1000) / vol; - } - - function calcIBUs() { - var total_ibus = 0; - var ferm_ibus = 0; - var rows = {}; - hop_aroma = hop_flavour = 0; - if (!(rows = $('#hopGrid').jqxGrid('getrows'))) { - return; - } - ok_hops = 1; - 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); - ferm_ibus += toIBU(row.h_useat, row.h_form, preboil_sg, - parseFloat(dataRecord.brew_fermenter_volume) + parseFloat(dataRecord.brew_fermenter_tcloss), - 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)); - if ((((dataRecord.inventory_reduced <= 2) && (row.h_useat <= 4)) || // Mash, FW, Boil, Aroma, Whirlpool - ((dataRecord.inventory_reduced <= 6) && (row.h_useat == 5))) && // Dry-hop - (row.h_inventory < row.h_amount)) - ok_hops = 0; - } - total_ibus = Math.round(total_ibus * 10) / 10; - ferm_ibus = Math.round(ferm_ibus * 10) / 10; - hop_flavour = Math.round(hop_flavour * 1000 / 5) / 10; - hop_aroma = Math.round(hop_aroma * 1000 / 6) / 10; - if (hop_flavour > 100) - hop_flavour = 100; - if (hop_aroma > 100) - hop_aroma = 100; - console.log("calcIBUs(): " + total_ibus + " flavour: " + hop_flavour + " aroma: " + hop_aroma+" fermenter:"+ferm_ibus+" supplies:"+ok_hops); - dataRecord.est_ibu = total_ibus; - $('#est_ibu').val(total_ibus); - $('#est_ibu2').val(total_ibus); - $("#hop_flavour").jqxProgressBar('val', hop_flavour); - $("#hop_aroma").jqxProgressBar('val', hop_aroma); - $("#brew_fermenter_ibu").val(ferm_ibus); - calcStage(); - calcSupplies(); - }; - - /* - * http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/ - * - * stype: 0=stirred, 1=shaken, 2=simple - * totcells: initial cells - * egrams: gram extract - */ - function getGrowthRate(stype, totcells, egrams){ - - /* Cells per grams extract (B/g) */ - var cpe = totcells / egrams; - - if (cpe > 3.5) - return 0; // no growth - if (stype == 2) - return 0.4; // simple starter - if (stype == 1) - return 0.62; // shaken starter - if (cpe <= 1.4) // stirred starter - return 1.4; - return 2.33 - (.67 * cpe ); - }; - - function calcStep(svol, stype, start) { - - var gperpoint = 2.72715; //number of grams of extract per point of starter gravity per liter - var prate = start/svol * 1000; - var irate = Math.round(prate * 10) / 10; - var egrams = (dataRecord.starter_sg - 1) * svol * gperpoint; - var grate = getGrowthRate(stype, start, egrams); - var ncells = Math.round(egrams * grate * 10) / 10; - var totcells = parseFloat(ncells) + start; - console.log("svol:"+svol+" start:"+start+" irate:"+irate+" egrams:"+egrams+" grate:"+grate+" ncells:"+ncells); - return { - svol: svol, - irate: irate, - prate: Math.round(prate * 10)/10, - ncells: ncells, - totcells: totcells, - growf: Math.round(ncells/start*100)/100 - }; - } - - /* - * Calculate all starter steps. - * stype: final starter type: 0 = stirred, 1 = shaked, 2 = simple. - * start: initial cells in billions - * needed: needed cells in billions - * - * result: all values updated. - */ - function calcSteps(stype, start, needed) { - - var uvols = [ 20, 40, 60, 80, 100, 150, 200, 250, 375, 500, 625, 750, 875, 1000, 1250, 1500, 2000, 2500, 3000, 4000, 5000 ]; - var mvols = uvols.length; - var svol = 0; - var lasti = 0; - var result = {}; - - /* - * If no values are set, auto calculate the starter. - */ - if ((parseFloat($("#prop1_volume").jqxNumberInput('decimal')) + parseFloat($("#prop2_volume").jqxNumberInput('decimal')) + - parseFloat($("#prop3_volume").jqxNumberInput('decimal')) + parseFloat($("#prop4_volume").jqxNumberInput('decimal'))) == 0) { - // clear by default - for (var i = 1; i < 5; i++) { - $("#prop"+i+"_type").hide(); - $("#r"+i+"_pmpt").show(); - $("#prop"+i+"_type").val(stype); - $("#prop"+i+"_volume").hide(); - $("#prop"+i+"_volume").val(0); - $("#prop"+i+"_irate").hide(); - $("#prop"+i+"_ncells").hide(); - $("#prop"+i+"_tcells").hide(); - $("#prop"+i+"_growf").hide(); - } - if (start > needed) { - return; // no starter needed - } - $("#prop1_type").show(); - $("#r1_pmpt").hide(); - $("#prop1_volume").show(); - $("#prop1_irate").show(); - $("#prop1_ncells").show(); - $("#prop1_tcells").show(); - $("#prop1_growf").show(); - for (var i = lasti; i <= mvols; i++) { - lasti = i; - svol = uvols[lasti]; - result = calcStep(svol, stype, start); - if (result.irate < 25) { - // inocculation rate too low, backup one step and break out. - lasti = i - 1; - svol = uvols[lasti]; - result = calcStep(svol, stype, start); - break; - } - if (result.totcells > needed || i == mvols) { // hit the target or loops done - break; - } - } - $("#prop1_volume").val(result.svol / 1000); // to liters - $("#prop1_irate").val(result.prate); - $("#prop1_ncells").val(result.ncells); - $("#prop1_tcells").val(result.totcells); - $("#prop1_growf").val(result.growf); - if (result.totcells > needed) - return; // hit the target - - // second stage - $("#r2_pmpt").hide(); - $("#prop2_type").val(stype); - $("#prop2_type").show(); - $("#prop2_volume").show(); - $("#prop2_irate").show(); - $("#prop2_ncells").show(); - $("#prop2_tcells").show(); - $("#prop2_growf").show(); - for (var i = lasti; i <= mvols; i++) { - lasti = i; - svol = uvols[lasti]; - result = calcStep(svol, stype, $("#prop1_tcells").val()); - if (result.irate < 25) { - lasti = i - 1; - svol = uvols[lasti]; - result = calcStep(svol, stype, $("#prop1_tcells").val()); - break; - } - if (result.totcells > needed || i == mvols) { // hit the target or loops done - break; - } - } - $("#prop2_volume").val(result.svol / 1000); // to liters - $("#prop2_irate").val(result.prate); - $("#prop2_ncells").val(result.ncells); - $("#prop2_tcells").val(result.totcells); - $("#prop2_growf").val(result.growf); - if (result.totcells > needed) - return; // hit the target - - // third stage - $("#r3_pmpt").hide(); - $("#prop3_type").val(stype); - $("#prop3_type").show(); - $("#prop3_volume").show(); - $("#prop3_irate").show(); - $("#prop3_ncells").show(); - $("#prop3_tcells").show(); - $("#prop3_growf").show(); - for (var i = lasti; i <= mvols; i++) { - lasti = i; - svol = uvols[lasti]; - result = calcStep(svol, stype, $("#prop2_tcells").val()); - if (result.irate < 25) { - lasti = i - 1; - svol = uvols[lasti]; - result = calcStep(svol, stype, $("#prop2_tcells").val()); - break; - } - if (result.totcells > needed || i == mvols) { // hit the target or loops done - break; - } - } - $("#prop3_volume").val(result.svol / 1000); // to liters - $("#prop3_irate").val(result.prate); - $("#prop3_ncells").val(result.ncells); - $("#prop3_tcells").val(result.totcells); - $("#prop3_growf").val(result.growf); - if (result.totcells > needed) - return; // hit the target - - // fourth stage - $("#r4_pmpt").hide(); - $("#prop4_type").val(stype); - $("#prop4_type").show(); - $("#prop4_volume").show(); - $("#prop4_irate").show(); - $("#prop4_ncells").show(); - $("#prop4_tcells").show(); - $("#prop4_growf").show(); - for (var i = lasti; i <= mvols; i++) { - lasti = i; - svol = uvols[lasti]; - result = calcStep(svol, stype, $("#prop3_tcells").val()); - if (result.totcells > needed || i == mvols) { // hit the target or loops done - $("#prop4_volume").val(result.svol / 1000); // to liters - $("#prop4_irate").val(result.prate); - $("#prop4_ncells").val(result.ncells); - $("#prop4_tcells").val(result.totcells); - $("#prop4_growf").val(result.growf); - return; - } - } - } else { - // recalculate - if (dataRecord.prop1_volume > 0) { - $("#r1_pmpt").hide(); - $("#prop1_type").show(); - $("#prop1_volume").show(); - $("#prop1_irate").show(); - $("#prop1_ncells").show(); - $("#prop1_tcells").show(); - $("#prop1_growf").show(); - result = calcStep($("#prop1_volume").val() * 1000, dataRecord.prop1_type, start); - $("#prop1_irate").val(result.prate); - $("#prop1_ncells").val(result.ncells); - $("#prop1_tcells").val(result.totcells); - $("#prop1_growf").val(result.growf); - } - if (dataRecord.prop2_volume > 0) { - $("#r2_pmpt").hide(); - $("#prop2_type").show(); - $("#prop2_volume").show(); - $("#prop2_irate").show(); - $("#prop2_ncells").show(); - $("#prop2_tcells").show(); - $("#prop2_growf").show(); - result = calcStep($("#prop2_volume").val() * 1000, dataRecord.prop2_type, $("#prop1_tcells").val()); - $("#prop2_irate").val(result.prate); - $("#prop2_ncells").val(result.ncells); - $("#prop2_tcells").val(result.totcells); - $("#prop2_growf").val(result.growf); - } - if (dataRecord.prop3_volume > 0) { - $("#r3_pmpt").hide(); - $("#prop3_type").show(); - $("#prop3_volume").show(); - $("#prop3_irate").show(); - $("#prop3_ncells").show(); - $("#prop3_tcells").show(); - $("#prop3_growf").show(); - result = calcStep($("#prop3_volume").val() * 1000, dataRecord.prop3_type, $("#prop2_tcells").val()); - $("#prop3_irate").val(result.prate); - $("#prop3_ncells").val(result.ncells); - $("#prop3_tcells").val(result.totcells); - $("#prop3_growf").val(result.growf); - } - if (dataRecord.prop4_volume > 0) { - $("#r4_pmpt").hide(); - $("#prop4_type").show(); - $("#prop4_volume").show(); - $("#prop4_irate").show(); - $("#prop4_ncells").show(); - $("#prop4_tcells").show(); - $("#prop4_growf").show(); - result = calcStep($("#prop4_volume").val() * 1000, dataRecord.prop4_type, $("#prop3_tcells").val()); - $("#prop4_irate").val(result.prate); - $("#prop4_ncells").val(result.ncells); - $("#prop4_tcells").val(result.totcells); - $("#prop4_growf").val(result.growf); - } - - } - } - - function calcYeast() { - - // Calculate needed cells. - var sg = dataRecord.brew_fermenter_sg; - if (sg <= 1.0001 && dataRecord.fg > 1.000) - sg = dataRecord.fg; - else if (sg <= 1.0001) - sg = dataRecord.est_og; - var plato = sg_to_plato(sg); - - var volume = dataRecord.brew_fermenter_volume; - if (volume > 0) { - if (dataRecord.brew_fermenter_extrawater > 0) - volume += dataRecord.brew_fermenter_extrawater; - } else { - volume = dataRecord.batch_size - dataRecord.eq_trub_chiller_loss; - } - - // Also in calcFermentables() - $("#yeast_cells").val(initcells); - - if (!(rows = $('#yeastGrid').jqxGrid('getrows'))) { - return; // grid not yet loaded. - } - var rowscount = $("#yeastGrid").jqxGrid('getdatainformation').rowscount; - if (rowscount == 0) - return; // no yeast in recipe - - for (var i = 0; i < rowscount; i++) { - var row = $("#yeastGrid").jqxGrid('getrowdata', i); - if (row.y_use == 0) { // primary - // pitchrate see https://www.brewersfriend.com/yeast-pitch-rate-and-starter-calculator/ - // and http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/ - pitchrate = 0.75; - if (dataRecord.est_og > 1.060) - pitchrate = 1.0; -// if (dataRecord.est_og > 1.076) -// pitchrate = 1.25; // Wyeast labs. http://www.wyeastlab.com/hb_pitchrates.cfm - if (row.y_type == 0) // lager yeast - pitchrate *= 2; - - if (row.y_form == 1) { // dry yeast - } else { // possible starter needed - } - } - } - var needed = pitchrate * volume * plato; - console.log("calcYeast() pitchrate:"+pitchrate+" start:"+initcells+" needed:"+needed+" volume:"+volume); - $("#need_cells").val(needed); - var use_cells = initcells; - - if (dataRecord.starter_enable) { - calcSteps(dataRecord.starter_type, initcells, needed); - - for (var i = 1; i < 5; i++) { - $("#r"+i+"_irate").html(""); - $("#r"+i+"_growf").html(""); - $("#r"+i+"_tcells").html(""); - if (parseFloat($("#prop"+i+"_volume").val()) > 0) { - if ((parseFloat($("#prop"+i+"_irate").val()) < 25) || (parseFloat($("#prop"+i+"_irate").val()) > 100)) { - $("#r"+i+"_irate").html(""); - } else { - $("#r"+i+"_irate").html(""); - } - if (parseFloat($("#prop"+i+"_growf").val()) < 1) - $("#r"+i+"_growf").html(""); - if (($("#prop"+i+"_type").val() > 0) && (parseFloat($("#prop"+i+"_growf").val()) > 3)) - $("#r"+i+"_growf").html(""); - if (parseFloat($("#prop"+i+"_tcells").val()) > needed) - $("#r"+i+"_tcells").html(""); - use_cells = parseFloat($("#prop"+i+"_tcells").val()); - } else { - $("#r"+i+"_irate").html(""); - } - } - } - $("#plato_cells").val(parseFloat(use_cells / (volume * plato) )); - }; - - function adjustHops(factor) { - - console.log("adjustHops("+factor+")"); - - var rowscount = $("#hopGrid").jqxGrid('getdatainformation').rowscount; - if (rowscount == 0) - return; - - for (var i = 0; i < rowscount; i++) { - var row = $("#hopGrid").jqxGrid('getrowdata', i); - var amount = row.h_amount * factor; - $("#hopGrid").jqxGrid('setcellvalue', i, "h_amount", amount); - } - }; - - function calcMiscs() { - - ok_miscs = 1; - var rowscount = $("#miscGrid").jqxGrid('getdatainformation').rowscount; - - if (rowscount == 0) - return; - - for (var i = 0; i < rowscount; i++) { - var row = $("#miscGrid").jqxGrid('getrowdata', i); - if ((((dataRecord.inventory_reduced <= 2) && (row.m_use_use <= 2)) || // Starter, Mash, Boil - ((dataRecord.inventory_reduced <= 3) && (row.m_use_use == 3)) || // Primary - ((dataRecord.inventory_reduced <= 5) && (row.m_use_use == 4)) || // Secondary, Teriary - ((dataRecord.inventory_reduced <= 6) && (row.m_use_use == 5))) && // Bottle - (row.m_inventory < row.m_amount)) { - ok_miscs = 0; - } - } - calcSupplies(); - }; - - function adjustMiscs(factor) { - - console.log("adjustMiscs("+factor+")"); - - var rowscount = $("#miscGrid").jqxGrid('getdatainformation').rowscount; - if (rowscount == 0) - return; - - for (var i = 0; i < rowscount; i++) { - var row = $("#miscGrid").jqxGrid('getrowdata', i); - var amount = row.m_amount * factor; - $("#miscGrid").jqxGrid('setcellvalue', i, "m_amount", amount); - switch (row.m_name) { - case 'CaCl2': $("#wa_cacl2").val(row.m_amount * 1000); - break; - case 'CaSO4': $("#wa_caso4").val(row.m_amount * 1000); - break; - case 'MgSO4': $("#wa_mgso4").val(row.m_amount * 1000); - break; - case 'NaCl': $("#wa_nacl").val(row.m_amount * 1000); - break; - case 'Melkzuur': - case 'Zoutzuur': - case 'Fosforzuur': - case 'Zwavelzuur': $("#wa_acid").val(row.m_amount * 1000); - break; - case 'NaHCO3': - case 'Na2CO3': - case 'CaCO3': - case 'Ca(OH)2': $("#wa_base").val(row.m_amount * 1000); - break; - } - } - }; - - function adjustYeasts(factor) { - - console.log("adjustYeasts("+factor+")"); - - var rowscount = $("#yeastGrid").jqxGrid('getdatainformation').rowscount; - if (rowscount == 0) - return; - - for (var i = 0; i < rowscount; i++) { - var row = $("#yeastGrid").jqxGrid('getrowdata', i); - if (row.y_form == 1) { // Only adjust dry yeast - var amount = row.y_amount * factor; - $("#yeastGrid").jqxGrid('setcellvalue', i, "y_amount", amount); - } - } - - calcYeast(); - }; - - function adjustWaters(factor) { - - console.log("adjustWaters("+factor+")"); - - var rowscount = $("#mashGrid").jqxGrid('getdatainformation').rowscount; - if (rowscount == 0) - return; - - mash_infuse = 0; - for (var i = 0; i < rowscount; i++) { - var row = $("#mashGrid").jqxGrid('getrowdata', i); - if (row.step_type == 0) { // Infusion - var amount = Math.round(row.step_infuse_amount * factor * 10) / 10; - $("#mashGrid").jqxGrid('setcellvalue', i, "step_infuse_amount", amount); - mash_infuse += amount; - } - } - if (dataRecord.w2_amount == 0) { - dataRecord.w1_amount = mash_infuse; - $("#w1_amount").val(mash_infuse); - } else { - dataRecord.w1_amount = (dataRecord.w1_amount / (dataRecord.w1_amount + dataRecord.w2_amount)) * mash_infuse; - dataRecord.w2_amount = (dataRecord.w2_amount / (dataRecord.w1_amount + dataRecord.w2_amount)) * mash_infuse; - $("#w1_amount").val(dataRecord.w1_amount); - $("#w2_amount").val(dataRecord.w2_amount); - } - $('#wg_amount').val(mash_infuse); - }; - - - - function calcMashEfficiency() { - if (parseFloat($("#brew_mash_sg").jqxNumberInput('decimal')) < 1.002) - return; - var c = sg_to_plato(est_mash_sg); - var m = sg_to_plato(parseFloat($("#brew_mash_sg").jqxNumberInput('decimal'))); - if (c > 0.5) - $("#brew_mash_efficiency").val(100 * m / c); - else - $("#brew_mash_efficiency").val(0); - }; - - function calcEfficiencyBeforeBoil() { - var m = 0; - var rows = {}; - if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) { - return; // grid not yet loaded. - } - for (var i = 0; i < rows.length; i++) { - var row = rows[i]; - if (row.f_added == 0) { // Mash - m += row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100); - } - } - var tot = sg_to_plato(dataRecord.brew_preboil_sg) * (dataRecord.brew_preboil_volume / 1.04) * dataRecord.brew_preboil_sg * 10 / 1000; - var result = 0; - if (m > 0) - result = Math.round((tot / m * 100) * 10) / 10; - if (result < 0) - result = 0; - $("#brew_preboil_efficiency").val(result); - } - - function calcEfficiencyAfterBoil() { - var m = 0; // Sugars added at mash - var b = 0; // Sugars added at boil - var rows = {}; - if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) { - return; // grid not yet loaded. - } - for (var i = 0; i < rows.length; i++) { - var row = rows[i]; - if (row.f_added == 0) { // Mash - m += row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100); - } else if (row.f_added == 1) { // Boil - b += row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100); - } - } - var tot = sg_to_plato(dataRecord.brew_aboil_sg) * (dataRecord.brew_aboil_volume / 1.04) * dataRecord.brew_aboil_sg * 10 / 1000; - tot -= b; // total sugars in wort minus added sugars. - var result = 0; - if (m > 0) - result = Math.round((tot / m * 100) * 10) / 10; - if (result < 0) - result = 0; - dataRecord.brew_aboil_efficiency = result; - $("#brew_aboil_efficiency").val(result); - - } - - function GetBUGU() { - var gu = (dataRecord.est_og - 1) * 1000; - if (gu > 0) - return dataRecord.est_ibu / gu; - else - return 0.5; - } - - function GetOptClSO4ratio() { - var BUGU = GetBUGU(); - return (-1.2 * BUGU + 1.4); - } - - function setWaterAgent(name, amount) { - var rows = $('#miscGrid').jqxGrid('getrows'); - if (amount == 0) { - for (var i = 0; i < rows.length; i++) { - var row = rows[i]; - if (row.m_name == name) { - var id = $("#miscGrid").jqxGrid('getrowid', i); - $("#miscGrid").jqxGrid('deleterow', id); - } - } - } else { - var found = false; - for (var i = 0; i < rows.length; i++) { - var row = rows[i]; - if (row.m_name == name) { - found = true; - $("#miscGrid").jqxGrid('setcellvalue', i, 'm_amount', amount / 1000); - break; - } - } - if (! found) { - var miscs = new $.jqx.dataAdapter(miscInvSource, { - loadComplete: function () { - var records = miscs.records; - for (var i = 0; i < records.length; i++) { - var record = records[i]; - if (record.name == name) { - var row = {}; - row["m_name"] = record.name; - row["m_amount"] = amount / 1000; - row["m_cost"] = record.cost; - row["m_type"] = record.type; - row["m_use_use"] = record.use_use; - row["m_time"] = 0; - row["m_amount_is_weight"] = record.amount_is_weight; - row["m_inventory"] = record.inventory; - row["m_avail"] = 1; - $("#miscGrid").jqxGrid('addrow', null, row); - } - } - } - }); - miscs.dataBind(); - return; - } - } - } - - function setRangeIndicator(ion, rangeCode) { - if ((rangeCode == "laag") || (rangeCode == "hoog")) - $("#wr_"+ion).html(""+rangeCode + ""); - else - $("#wr_"+ion).html(""); - } - - function mix(v1, v2, c1, c2) { - if ((v1 + v2) > 0) { - return ((v1 * c1) + (v2 * c2)) / (v1 + v2); - } - return 0; - } - - // mg/l as CaCO3 - function ResidualAlkalinity(total_alkalinity, calcium, magnesium) { - return total_alkalinity - (calcium / 1.4 + magnesium / 1.7); - } - - var Ka1 = 0.0000004445; - var Ka2 = 0.0000000000468; - - function PartCO3(pH) { - var H = Math.pow(10, -pH); - return 100 * Ka1 * Ka2 / (H*H + H * Ka1 + Ka1 * Ka2); - } - - function PartHCO3(pH) { - var H = Math.pow(10, -pH); - return 100 * Ka1 * H / (H*H + H * Ka1 + Ka1 * Ka2); - } - - function Charge(pH) { - return (-2 * PartCO3(pH) - PartHCO3(pH)); - } - - //Z alkalinity is the amount of acid (in mEq/l) needed to bring water to the target pH (Z pH) - function ZAlkalinity(pHZ) { - var C43 = Charge(4.3); - var Cw = Charge(parseFloat($("#wg_ph").jqxNumberInput('decimal'))); - var Cz = Charge(pHZ); - var DeltaCNaught = -C43+Cw; - var CT = parseFloat($("#wg_total_alkalinity").jqxNumberInput('decimal')) / 50 / DeltaCNaught; - var DeltaCZ = -Cz+Cw; - return CT * DeltaCZ; - } - - //Z Residual alkalinity is the amount of acid (in mEq/l) needed to bring the water in the mash to the target pH (Z pH) - function ZRA(pHZ) { - - var Calc = parseFloat($("#wg_calcium").jqxNumberInput('decimal')) / (MMCa / 2); - var Magn = parseFloat($("#wg_magnesium").jqxNumberInput('decimal')) / (MMMg / 2); - var Z = ZAlkalinity(pHZ); - return Z - (Calc / 3.5 + Magn / 7); - } - - function ProtonDeficit(pHZ) { - - var Result = ZRA(pHZ) * parseFloat($("#wg_amount").jqxNumberInput('decimal')); - // proton deficit for the grist - var rows = $('#fermentableGrid').jqxGrid('getrows'); - for (var i = 0; i < rows.length; i++) { - var row = rows[i]; - if (row.f_added == 0 && row.f_graintype != 6) { // Added == Mash && graintype != No Malt - // Check if acid is required - var C1 = 0; - if ((row.f_di_ph != 5.7) && ((row.f_acid_to_ph_57 < - 0.1) || (row.f_acid_to_ph_57 > 0.1))) { - C1 = row.f_acid_to_ph_57 / (row.f_di_ph - 5.7); - } else { - // If the acid_to_ph_5.7 is unknown from the maltster, guess the required acid. - var ebc = row.f_color; - switch (row.f_graintype) { - case 0: // Base, Special, Kilned - case 3: - case 5: C1 = 0.014 * ebc - 34.192; - break; - case 2: C1 = -0.0597 * ebc - 32.457; // Crystal - break; - case 1: C1 = 0.0107 * ebc - 54.768; // Roast - break; - case 4: C1 = -149; // Sour malt - break; - } - } - x = C1 * (pHZ - row.f_di_ph); // AcidRequired(ZpH) - Result += x * row.f_amount; - } - } - return Result; - } - - function MashpH() { - var n = 0; - var pH = 5.4; - var deltapH = 0.001; - var deltapd = 0.1; - var pd = ProtonDeficit(pH); - while (((pd < -deltapd) || (pd > deltapd)) && (n < 2000)) { - n++; - if (pd < -deltapd) - pH -= deltapH; - else if (pd > deltapd) - pH += deltapH; - pd = ProtonDeficit(pH); - } - console.log("MashpH() n: "+n+" pH: "+pH); - return pH; - } - - function GetAcidSpecs(AT) { - switch(AT) { - case 0: return { // Melkzuur - pK1: 3.86, - pK2: 20, - pK3: 20, - MolWt: 90.08, - AcidSG: 1214, // 1214 1209 - AcidPrc: 0.88 // 0.88 0.80 - }; - case 1: return { // Zoutzuur - pK1: -7, - pK2: 20, - pK3: 20, - MolWt: 36.46, - AcidSG: 1142, - AcidPrc: 0.28 - }; - case 2: return { // Fosforzuur - pK1: 2.12, - pK2: 7.20, - pK3: 12.44, - MolWt: 98.00, - AcidSG: 1170, - AcidPrc: 0.25 - }; - case 3: return { // Zwavelzuur - pK1: -1, - pK2: 1.92, - pK3: 20, - MolWt: 98.07, - AcidSG: 1700, - AcidPrc: 0.93 - }; - } - } - - - function calcWater() { - - console.log("calcWater()"); - var liters = 0; - var calcium = 0; - var magnesium = 0; - var sodium = 0; - var total_alkalinity = 0; - var bicarbonate = 0; - var chloride = 0; - var sulfate = 0; - var ph = 0; - var RA = 0; - var frac = 0; - var TpH = 0; - var protonDeficit = 0; - - if (dataRecord.w1_name == "") { - return; - } - - // If there is a dillute water source, mix the waters. - if (dataRecord.w2_name != "") { - liters = dataRecord.w1_amount + dataRecord.w2_amount; - calcium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_calcium, dataRecord.w2_calcium); - magnesium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_magnesium, dataRecord.w2_magnesium); - sodium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sodium, dataRecord.w2_sodium); - chloride = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_chloride, dataRecord.w2_chloride); - sulfate = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sulfate, dataRecord.w2_sulfate); - total_alkalinity = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_total_alkalinity, dataRecord.w2_total_alkalinity); - ph = -Math.log10(((Math.pow(10, -dataRecord.w1_ph) * dataRecord.w1_amount) + (Math.pow(10, -dataRecord.w2_ph) * dataRecord.w2_amount)) / liters); - } else { - liters = dataRecord.w1_amount; - calcium = dataRecord.w1_calcium; - magnesium = dataRecord.w1_magnesium; - sodium = dataRecord.w1_sodium; - chloride = dataRecord.w1_chloride; - sulfate = dataRecord.w1_sulfate; - total_alkalinity = dataRecord.w1_total_alkalinity; - ph = dataRecord.w1_ph; - } - $('#wg_amount').val(liters); - var wg_calcium = calcium; - $('#wg_calcium').val(Math.round(calcium * 10) / 10); - //var wg_magnesium = magnesium; - $('#wg_magnesium').val(Math.round(magnesium * 10) / 10); - var wg_sodium = sodium; - $('#wg_sodium').val(Math.round(sodium * 10) / 10); - var wg_total_alkalinity = total_alkalinity; - $('#wg_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10); - var wg_chloride = chloride; - $('#wg_chloride').val(Math.round(chloride * 10) / 10); - var wg_sulfate = sulfate; - $('#wg_sulfate').val(Math.round(sulfate * 10) / 10); - // Note: brouwhulp has the malts included here in the result. - //var wg_ph = ph; - $('#wg_ph').val(Math.round(ph * 10) / 10); - $('#wb_ph').val(Math.round(MashpH() * 10) / 10); - $('#est_mash_ph').val(Math.round(MashpH() * 10) / 10); - bicarbonate = total_alkalinity * 1.22; - var wg_bicarbonate = bicarbonate; - - // Noot: de volgende berekeningen geven bijna gelijke resultaten in Brun'water. - // Calculate Ca - RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + - parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4; - calcium += 1000 * RA / liters; - - // Calculate Mg - RA = parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMMg / MMMgSO4; - magnesium += 1000 * RA / liters; - - // Calculate Na - RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + - parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; - sodium += 1000 * RA / liters; - - // Calculate SO4 - RA = parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + - parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMSO4 / MMMgSO4; - sulfate += 1000 * RA / liters; - - // Calculate Cl - RA = 2 * parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCl / MMCaCl2 + - parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMCl / MMNaCl; - chloride += 1000 * RA / liters; - // Einde noot. - - if ($("#wa_acid_name").val() < 0 || $("#wa_acid_name").val() > 3) { - $("#wa_acid_name").val(0); - dataRecord.wa_acid_name = 0; - } - if (last_acid == '') - last_acid = AcidTypeData[$("#wa_acid_name").val()].nl; - - if ($("#wa_base_name").val() < 0 || $("#wa_base_name").val() > 3) { - $("#wa_base_name").val(0); - dataRecord.wa_base_name = 0; - } - if (last_base == '') - last_base = BaseTypeData[$("#wa_base_name").val()].nl; - - var AT = dataRecord.wa_acid_name; - var BT = dataRecord.wa_base_name; - - var result = GetAcidSpecs(AT); - var pK1 = result.pK1; - var pK2 = result.pK2; - var pK3 = result.pK3; - var MolWt = result.MolWt; - var AcidSG = result.AcidSG; - var AcidPrc = result.AcidPrc; - - if (dataRecord.calc_acid) { - TpH = parseFloat(dataRecord.mash_ph); - protonDeficit = ProtonDeficit(TpH); - console.log("calc_acid tgt: "+TpH+" protonDeficit: "+protonDeficit); - if (protonDeficit > 0) { // Add acid - $("#wa_base").val(0); - setWaterAgent(last_base, 0); - frac = CalcFrac(TpH, pK1, pK2, pK3); - Acid = protonDeficit / frac; - Acid *= MolWt; // mg - Acidmg = Acid; - Acid = Acid / AcidSG; // ml - - if (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) == 0) - $("#wa_acid_perc").val(AcidPrc); - Acid = Acid * AcidPrc / (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) / 100); // ml - console.log("Final ml: "+Acid); - $("#wa_acid").val(Math.round(Acid * 100) / 100); - setWaterAgent(AcidTypeData[AT].nl, Math.round(Acid * 100) / 100); - - bicarbonate = bicarbonate - protonDeficit * frac / liters; - total_alkalinity = bicarbonate * 50 / 61; - } else if (protonDeficit < 0) { //Add base - $("#wa_acid").val(0); - setWaterAgent(last_acid, 0); - var r1d = Math.pow(10, (TpH - 6.38)); - var r2d = Math.pow(10, (TpH - 10.38)); - var f1d = 1 / (1 + r1d + r1d * r2d); - var f2d = f1d * r1d; - var f3d = f2d * r2d; - switch (BT) { - case 0: RA = -protonDeficit / (f1d - f3d); // Sodiumbicarbonate, mmol totaal - RA = RA * MMNaHCO3/1000; //gram - $("#wa_base").val(Math.round(RA * 100) / 100); - setWaterAgent('NaHCO3', Math.round(RA * 100) / 100); - if (liters > 0) { - // Na - RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + - parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; - RA = 1000 * RA / liters; - sodium = wg_sodium + RA; - // HCO3 - RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3; - RA = 1000 * RA / liters; - bicarbonate = wg_bicarbonate + RA; - total_alkalinity = bicarbonate * 50 / 61; - RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); - } - break; - case 1: RA = -protonDeficit / (2 * f1d + f2d); // Sodiumcarbonate, mmol totaal - RA = RA * MMNa2CO3/1000; //gram - $("#wa_base").val(Math.round(RA * 100) / 100); - setWaterAgent('Na2CO3', Math.round(RA * 100) / 100); - if (liters > 0) { - RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + - parseFloat($("#wa_base").jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3; - RA = 1000 * RA / liters; - sodium = wg_sodium + RA; - // HCO3 - RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3; - RA = 1000 * RA / liters; - bicarbonate = wg_bicarbonate + RA; - total_alkalinity = bicarbonate * 50 / 61; - RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); - } - break; - case 2: RA = -protonDeficit * (f1d - f3d); // Calciumcarbonate, mmol totaal - RA = RA * MMCaCO3/1000; //gram - //but only 1/3 is effective, so add 3 times as much - RA = 3 * RA; - $("#wa_base").val(Math.round(RA * 100) / 100); - setWaterAgent('CaCO3', Math.round(RA * 100) / 100); - if (liters > 0) { - //Bicarbonate - RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3; - RA = 1000 * RA / liters; - bicarbonate = wg_bicarbonate + RA; - total_alkalinity = bicarbonate * 50 / 61; - //Ca precipitates out as Ca10(PO4)6(OH)2 - RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + - parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + - parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaCO3; - RA = 1000 * RA / liters; - calcium = wg_calcium + RA; - RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); - } - break; - case 3: RA = -protonDeficit / 19.3; // Calciumhydroxide - $("#wa_base").val(Math.round(RA * 100) / 100); - setWaterAgent('Ca(OH)2', Math.round(RA * 100) / 100); - if (liters > 0) { - // Bicarbonate - RA = -protonDeficit / liters; - total_alkalinity = wg_total_alkalinity + RA; - bicarbonate = total_alkalinity * 61 / 50; - // Calcium - RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + - parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + - parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaOH2; - RA = 1000 * RA / liters; - calcium = wg_calcium + RA; - RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); - } - break; - } - } - ph = TpH; - $('#wb_ph').val(Math.round(ph * 10) / 10); - $('#est_mash_ph').val(Math.round(ph * 10) / 10); - } else { // Manual - console.log("calc_acid no"); - // First add base salts - if (parseFloat($("#wa_base").jqxNumberInput('decimal')) > 0) { - if (liters > 0) { - switch (BT) { - case 0: // Sodiumbicarbonate, Na - RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + - parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; - RA = 1000 * RA / liters; - sodium = wg_sodium + RA; - // HCO3 - RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3; - RA = 1000 * RA / liters; - bicarbonate = wg_bicarbonate + RA; - total_alkalinity = bicarbonate * 50 / 61; - RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); - break; - case 1: // Sodiumcarbonate - RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + - parseFloat($("#wa_base").jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3; - RA = 1000 * RA / liters; - sodium = wg_sodium + RA; - // HCO3 - RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3; - RA = 1000 * RA / liters; - bicarbonate = wg_bicarbonate + RA; - total_alkalinity = bicarbonate * 50 / 61; - RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); - break; - case 2: // Calciumcarbonate: Bicarbonate - RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3; - RA = 1000 * RA / liters; - bicarbonate = wg_bicarbonate + RA; - total_alkalinity = bicarbonate * 50 / 61; - RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); - // Ca - RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + - parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + - parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaCO3; - RA = 1000 * RA / liters; - calcium = wg_calcium + RA; - break; - } - } - } - - TpH = parseFloat(dataRecord.mash_ph); - pHa = MashpH(); // This one is in demi water, should be in adjusted water??? - // Then calculate the new pH with added acids - if (parseFloat($("#wa_acid").jqxNumberInput('decimal')) > 0) { - console.log("TpH: "+TpH+" water: "+pHa); - Acid = parseFloat($("#wa_acid").jqxNumberInput('decimal')); - if (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) == 0) - $("#wa_acid_perc").val(AcidPrc); - Acid = Acid / AcidPrc * (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) / 100); // ml - Acid *= AcidSG; // ml - Acid /= MolWt; // mg - Acidmg = Acid; - - //find the pH where the protondeficit = protondeficit by the acid - frac = CalcFrac(pHa, pK1, pK2, pK3); - protonDeficit = Acid * frac; - - var deltapH = 0.001; - var deltapd = 0.1; - var pd = ProtonDeficit(pHa); - var n = 0; - while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 2000)) { - n++; - if (pd < (protonDeficit-deltapd)) - pHa -= deltapH; - else if (pd > (protonDeficit+deltapd)) - pHa += deltapH; - frac = CalcFrac(pHa, pK1, pK2, pK3); - protonDeficit = Acid * frac; - pd = ProtonDeficit(pHa); - } - console.log("n: "+n+" pd: "+pd+" protonDeficit: "+protonDeficit+" frac: "+frac+" pHa: "+pHa); - RA = wg_bicarbonate - protonDeficit * frac / liters; - bicarbonate = RA; - total_alkalinity = RA * 50 / 61; - ph = pHa; - $('#wb_ph').val(Math.round(ph * 10) / 10); - $('#est_mash_ph').val(Math.round(ph * 10) / 10); - } - } - - if ((AT == 3) && (liters > 0)) { // Sulfuctic / Zwavelzuur - RA = parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + - parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 + - Acidmg / 1000 * MMSO4 / (MMSO4 + 2); - RA = 1000 * RA / liters; - sulfate = wg_sulfate + RA; // Not add to sulfate?? - } else if ((AT == 1) && (liters > 0)) { // Hydrochloric, Zoutzuur - RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCl / MMCaCl2 + - parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMCl / MMNaCl + - Acidmg / 1000 * MMCl / (MMCl + 1); - RA = 1000 * RA / liters; - chloride = wg_chloride + RA; - } - - // 2:1 Sulfate to Chroride IPA's, Pale Ales. - // 1:1 Sulfate to Chloride Balanced - // 1:2 Sulfate to Chloride Malty - // Note, values below are the other way, cl to so4! - // So: 0.5 is IPA's, Pale Ales. - // 1 Balanced - // 2 Malty. - $('#tgt_bu').val(Math.round(GetBUGU() * 100) / 100); - // From brouwhulp. - if (GetBUGU() < 0.32) - $('#wr_bu').html("Zeer moutig en zoet"); - else if (GetBUGU() < 0.43) - $('#wr_bu').html("Moutig, zoet"); - else if (GetBUGU() < 0.52) - $('#wr_bu').html("Evenwichtig"); - else if (GetBUGU() < 0.63) - $('#wr_bu').html("Licht hoppig, bitter"); - else - $('#wr_bu').html("Extra hoppig, zeer bitter"); - $('#tgt_cl_so4').val(Math.round(GetOptClSO4ratio() * 10) / 10); - if (sulfate > 0) - RA = chloride / sulfate; - else - RA = 10; - $('#got_cl_so4').val(Math.round(RA * 10) / 10); - var piCLSO4_low = 0.8 * GetOptClSO4ratio(); - var piCLSO4_high = 1.2 * GetOptClSO4ratio(); - var Res = 'normaal'; - if (RA < piCLSO4_low) - Res = 'laag'; - else if (RA > piCLSO4_high) - Res = 'hoog'; - setRangeIndicator('cl_so4', Res); - - $('#wb_calcium').val(Math.round(calcium * 10) / 10); - $('#wb_magnesium').val(Math.round(magnesium * 10) / 10); - $('#wb_sodium').val(Math.round(sodium * 10) / 10); - $('#wb_sulfate').val(Math.round(sulfate * 10) / 10); - $('#wb_chloride').val(Math.round(chloride * 10) / 10); - $('#wb_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10); - - if (calcium < 40) { - setRangeIndicator("calcium", "laag"); - } else if (calcium > 150) { - setRangeIndicator("calcium", "hoog"); - } else { - setRangeIndicator("calcium", "normaal"); - } - if (magnesium >= 0 && magnesium <= 30) { - setRangeIndicator("magnesium", "normaal"); - } else { - setRangeIndicator("magnesium", "hoog"); - } - if (sodium <= 150) { - setRangeIndicator("sodium", "normaal"); - } else { - setRangeIndicator("sodium", "hoog"); - } - // Both chloride and sulfate should be above 50 according to - // John Palmer. So the Cl/SO4 ratio calculation will work. - if (chloride <= 50) { - setRangeIndicator("chloride", "laag"); - } else if (chloride <= 100) { - setRangeIndicator("chloride", "normaal"); - } else { - setRangeIndicator("chloride", "hoog"); - } - if (sulfate <= 50) { - setRangeIndicator("sulfate", "laag"); - } else if (sulfate <= 350) { - setRangeIndicator("sulfate", "normaal"); - } else { - setRangeIndicator("sulfate", "hoog"); - } - if (ph < 5.2) { - setRangeIndicator("ph", "laag"); - } else if (ph > 5.6) { - setRangeIndicator("ph", "hoog"); - } else { - setRangeIndicator("ph", "normaal"); - } - calcSparge(); - calcMiscs(); - calcSupplies(); - } - - function calcSparge() { - - // Code from BrewBuddy/Brouwhulp, who got it from http://www.brewery.org/brewery/library/Acidi0,00fWaterAJD0497.html - var TargetpH = dataRecord.sparge_ph; - var Source_pH = dataRecord.w1_ph; - var Source_alkalinity = dataRecord.w1_total_alkalinity; - // Select watersource or fallback to the first source. - if (dataRecord.sparge_source == 1) { // Source 2 - if (dataRecord.w2_ph > 0.0) { - Source_pH = dataRecord.w2_ph; - Source_alkalinity = dataRecord.w2_total_alkalinity; - } else { - dataRecord.sparge_source = 0; // Source 1 - $("#sparge_source").val(0); - } - } else if (dataRecord.sparge_source == 2) { // Mixed - if (dataRecord.w2_ph > 0.0) { - Source_pH = parseFloat($("#wg_ph").jqxNumberInput('decimal')); - Source_alkalinity = parseFloat($("#wg_total_alkalinity").jqxNumberInput('decimal')); - } else { - dataRecord.sparge_source = 0; - $("#sparge_source").val(0); - } - } - - // Step 1: Compute the mole fractions of carbonic (f1o), bicarbonate (f2o) and carbonate(f3o) at the water pH - var r1 = Math.pow(10, Source_pH - 6.38); - var r2 = Math.pow(10, Source_pH - 10.373); - var d = 1 + r1 + r1*r2; - var f1 = 1/d; - //var f2 = r1/d; - var f3 = r1 * r2 / d; - - //Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity) - var r143 = Math.pow(10, 4.3 - 6.38); - var r243 = Math.pow(10, 4.3 - 10.373); - var d43 = 1 + r143 + r143*r243; - var f143 = 1/d43; - //var f243 = r143 / d43; - var f343 = r143 * r243 / d43; - - //Step 3. Convert the water alkalinity to milliequivalents/L - var alkalinity = Source_alkalinity / 50; - - //Step 4. Solve - var Ct = (alkalinity - 1000 * (Math.pow(10, -4.3) - Math.pow(10, -Source_pH))) / ((f143-f1)+(f3-f343)); - - //Step 5. Compute mole fractions at desired pH - var r1g = Math.pow(10, TargetpH - 6.38); - var r2g = Math.pow(10, TargetpH - 10.373); - var dg = 1 + r1g + r1g*r2g; - var f1g = 1/dg; - //var f2g = r1g / dg; - var f3g = r1g * r2g / dg; - - //Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L) - var Acid = Ct * ((f1g-f1)+(f3-f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH); //mEq/l - Acid += 0.01; // Add acid that would be required for distilled water. - if (dataRecord.sparge_acid_type < 0 || dataRecord.sparge_acid_type > 3) { - dataRecord.sparge_acid_type = 0; - $("#sparge_acid_type").val(0); - } - - //Step 8. Get the acid data. - var AT = dataRecord.sparge_acid_type; - var result = GetAcidSpecs(AT); - var pK1 = result.pK1; - var pK2 = result.pK2; - var pK3 = result.pK3; - var MolWt = result.MolWt; - var AcidSG = result.AcidSG; - var AcidPrc = result.AcidPrc; - var fract = CalcFrac(TargetpH, pK1, pK2, pK3); - - //Step 9. Now divide the mEq required by the "fraction". This is the required number of moles of acid. - Acid /= fract; - - //Step 10. Multiply by molecular weight of the acid - Acid *= MolWt; //mg - - Acid = Acid / AcidSG; //ml ; 88% lactic solution - var f1 = dataRecord.sparge_acid_perc; - if (f1 <= 0.1) - f1 = AcidPrc; - Acid = Acid * AcidPrc / (f1 / 100); - - Acid *= dataRecord.sparge_volume; //ml lactic acid total - Acid = Math.round(Acid * 100) / 100; - dataRecord.sparge_acid_amount = Acid / 1000; - $("#sparge_acid_amount").val(Acid); - } - - function calcFermentation(){ - - if (dataRecord.brew_fermenter_sg<1.020) - return; - -// var obrix = sg_to_brix(dataRecord.brew_fermenter_sg); - if ((dataRecord.primary_end_sg>0.990)&&(dataRecord.primary_end_sg0.990)&&(dataRecord.secondary_end_sg0.990)&&(dataRecord.fg 1.005 && dataRecord.est_color > 3 && dataRecord.est_ibu > 3) - newstage = 1; - if (newstage == 1 && parseFloat($("#brew_date_start").val()) > 2000) - newstage = 2; // Brewday - if (newstage == 2 && ($("#brew_date_start").val() == '')) - newstage = 1; // No brewday - if (newstage == 2 && parseFloat($("#brew_date_end").val()) > 2000) - newstage = 3; // Primary - if (newstage == 3 && parseFloat($("#primary_end_date").val()) > 2000) - newstage = 4; // Secondary - if (newstage == 4 && parseFloat($("#secondary_end_date").val()) > 2000) - newstage = 5; // Tertiary - if (newstage == 5 && parseFloat($("#package_date").val()) > 2000) - newstage = 6; // Package - if (newstage >= 6 && newstage < 9) { - var d = new Date(); - var date2 = $("#package_date").val(); - date2 = date2.split('-'); - // Now we convert the array to a Date object - date1 = new Date(d.getFullYear(), d.getMonth(), d.getDate()); - date2 = new Date(date2[0], date2[1]-1, date2[2]); - // We use the getTime() method and get the unixtime - date1_unixtime = parseInt(date1.getTime() / 1000); - date2_unixtime = parseInt(date2.getTime() / 1000); - // This is the calculated difference in seconds - var timeDifference = date1_unixtime - date2_unixtime; - var timeDifferenceInDays = timeDifference / 60 / 60 / 24; - if (timeDifferenceInDays > 0) { // At least one day - if (timeDifferenceInDays >= 42) // 6 weeks - newstage = 9; // Ready to taste - else if (timeDifferenceInDays >= 14) // 14 days - newstage = 8; // Mature - else - newstage = 7; // Carbonation - } - } - if (newstage == 9 && parseFloat($("#taste_date").val()) > 2000) - newstage = 10; // Ready - - if (newstage != dataRecord.stage) { - console.log("calcStage() old: "+dataRecord.stage+" new: "+newstage); - dataRecord.stage = newstage; - } - - /* - * Set stage and enable or disable parts of the screens. - */ - $("#stage").val(StageData[dataRecord.stage].nl); - if (dataRecord.stage >= 10) { - $("#locked").jqxCheckBox({ disabled:false }); - } - - /* - * When the brew is in progress or done, block equipment select and delete. - */ - if (dataRecord.stage > 1) { - $("#equipmentSelect").jqxDropDownList({ disabled: true }); - $("#Delete").jqxButton({ disabled: true }); - } - - if (dataRecord.stage < 1) // Planning, no ingredients - $('#jqxTabs').jqxTabs('disableAt', 8); // Brewday tab - else - $('#jqxTabs').jqxTabs('enableAt', 8); - - if (dataRecord.stage < 3) { // Primary - $('#jqxTabs').jqxTabs('disableAt', 9); // Fermentation tab - } else { - $('#jqxTabs').jqxTabs('enableAt', 9); - $("#name").jqxInput({ disabled: true }); - $("#code").jqxInput({ disabled: true }); - $("#batch_size").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#boil_size").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#boil_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#efficiency").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#est_og").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#type").jqxDropDownList({ disabled: true }); - $("#styleSelect").jqxDropDownList({ disabled: true }); - $("#color_method").jqxDropDownList({ disabled: true }); - $("#ibu_method").jqxDropDownList({ disabled: true }); - $("#mash_select").jqxDropDownList({ disabled: true }); - $("#w1_name").jqxDropDownList({ disabled: true }); - $("#w2_name").jqxDropDownList({ disabled: true }); - $("#w2_amount").jqxNumberInput({ readOnly: true }); - $("#pr_name").jqxDropDownList({ disabled: true }); - $("#wa_cacl2").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#wa_caso4").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#wa_mgso4").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#wa_nacl").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#mash_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#calc_acid").jqxCheckBox({ disabled: true }); - $("#wa_base_name").jqxDropDownList({ disabled: true }); - $("#wa_base").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#wa_acid_name").jqxDropDownList({ disabled: true }); - $("#wa_acid").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#wa_acid_perc").jqxNumberInput({ spinButtons: false, readOnly: true, width: 70 }); - $("#sparge_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#sparge_volume").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#sparge_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#sparge_source").jqxDropDownList({ disabled: true }); - $("#sparge_acid_type").jqxDropDownList({ disabled: true }); - $("#sparge_acid_perc").jqxNumberInput({ spinButtons: false, readOnly: true, width: false }); - $("#starter_enable").jqxCheckBox({ disabled: true }); - $("#starter_type").jqxDropDownList({ disabled: true }); - $("#starter_try").jqxButton({ disabled: true }); - $("#starter_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#starter_viability").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - } - if (dataRecord.stage > 3) { // Primary fermentation done - $("#brew_date_start").jqxDateTimeInput({ disabled: true }); - $("#brew_date_end").jqxDateTimeInput({ disabled: true }); - $("#brew_mash_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_preboil_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_aboil_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_mash_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_preboil_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_aboil_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_preboil_volume").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_aboil_volume").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_whirlpool9").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_cooling_to").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_whirlpool7").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_cooling_method").jqxDropDownList({ disabled: true }); - $("#brew_whirlpool6").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_cooling_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_sparge_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_whirlpool2").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_aeration_type").jqxDropDownList({ disabled: true }); - $("#brew_fermenter_tcloss").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_aeration_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_fermenter_extrawater").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#brew_aeration_speed").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - } - if (dataRecord.stage == 5) // Lagering, allow packaging - $("#package_date").jqxDateTimeInput({ disabled: false }); - else - $("#package_date").jqxDateTimeInput({ disabled: true }); - if (dataRecord.stage >= 5) { // At least secondary - $("#primary_start_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#primary_max_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#primary_end_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#primary_end_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#primary_end_brix").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#primary_end_date").jqxDateTimeInput({ disabled: true }); - } - if (dataRecord.stage >= 6) { // Packaged - $("#secondary_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#secondary_end_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#secondary_end_date").jqxDateTimeInput({ disabled: true }); - $("#tertiary_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#fg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#final_brix").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#package_date").jqxDateTimeInput({ disabled: true }); - $("#package_volume").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#package_infuse_amount").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#package_infuse_abv").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#package_infuse_notes").jqxInput({ disabled: true }); - $("#package_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#bottle_amount").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#bottle_priming_water").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#keg_priming_water").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#keg_amount").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#bottle_carbonation").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#keg_carbonation").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#bottle_priming_sugar").jqxDropDownList({ disabled: true }); - $("#keg_priming_sugar").jqxDropDownList({ disabled: true }); - $("#keg_forced_carb").jqxCheckBox({ disabled : true }); - $("#bottle_carbonation_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#keg_carbonation_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - } - if (dataRecord.stage < 8) { // Taste when at least Mature. - $('#jqxTabs').jqxTabs('disableAt', 11); // Tasting tab - } else { - $('#jqxTabs').jqxTabs('enableAt', 11); - } - - if (dataRecord.stage == 11) { // Locked - $("#taste_date").jqxDateTimeInput({ disabled: true }); - $("#taste_rate").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#taste_color").jqxInput({ disabled: true }); - $("#taste_transparency").jqxInput({ disabled: true }); - $("#taste_head").jqxInput({ disabled: true }); - $("#taste_aroma").jqxInput({ disabled: true }); - $("#taste_taste").jqxInput({ disabled: true }); - $("#taste_aftertaste").jqxInput({ disabled: true }); - $("#taste_mouthfeel").jqxInput({ disabled: true }); - $("#taste_notes").jqxInput({ disabled: true }); - $("#notes").jqxInput({ disabled: true }); - } else { - $("#notes").jqxInput({ disabled: false }); - } - } - - function showStarter() { - - if (dataRecord.starter_enable) { - $("#propagator").show(); - $("#starter_type").jqxDropDownList( {disabled: false }); - $("#starter_try").jqxButton({ disabled: false }); - $("#starter_sg").jqxNumberInput({ spinButtons: true, readOnly: false, width: 110 }); - $("#starter_viability").jqxNumberInput({ spinButtons: true, readOnly: false, width: 110 }); - } else { - $("#propagator").hide(); - $("#starter_type").jqxDropDownList( {disabled: true }); - $("#starter_try").jqxButton({ disabled: true }); - $("#starter_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - $("#starter_viability").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); - } - } - - function calcInit () { - console.log("calcInit()"); - - calcMashEfficiency(); - calcEfficiencyBeforeBoil(); - calcEfficiencyAfterBoil(); - - $("#starter_enable").on('checked', function (event) { - dataRecord.starter_enable = 1; - showStarter(); - calcYeast(); - }); - $("#starter_enable").on('unchecked', function (event) { - dataRecord.starter_enable = 0; - showStarter(); - calcYeast(); - }); - $("#starter_try").click(function () { - $("#prop1_volume").val(0); - $("#prop2_volume").val(0); - $("#prop3_volume").val(0); - $("#prop4_volume").val(0); - calcYeast(); - }); - $('#starter_type').on('change', function (event) { - if (event.args) { - var index = event.args.index; - dataRecord.starter_type = index; - calcYeast(); - } - }); - $('#starter_sg').on('change', function (event) { - if (event.args) { - dataRecord.starter_sg = event.args.value; - calcYeast(); - } - }); - $('#starter_viability').on('change', function (event) { - if (event.args) { - dataRecord.starter_viability = event.args.value; - calcFermentables(); - calcYeast(); - } - }); - $('#prop1_type').on('change', function (event) { - if (event.args) { - var index = event.args.index; - dataRecord.prop1_type = index; - calcYeast(); - } - }); - $('#prop1_volume').on('change', function (event) { - if (event.args) { - dataRecord.prop1_volume = event.args.value; - calcYeast(); - } - }); - $('#prop2_type').on('change', function (event) { - if (event.args) { - var index = event.args.index; - dataRecord.prop2_type = index; - calcYeast(); - } - }); - $('#prop2_volume').on('change', function (event) { - if (event.args) { - dataRecord.prop2_volume = event.args.value; - calcYeast(); - } - }); - $('#prop3_type').on('change', function (event) { - if (event.args) { - var index = event.args.index; - dataRecord.prop3_type = index; - calcYeast(); - } - }); - $('#prop3_volume').on('change', function (event) { - if (event.args) { - dataRecord.prop3_volume = event.args.value; - calcYeast(); - } - }); - $('#prop4_type').on('change', function (event) { - if (event.args) { - var index = event.args.index; - dataRecord.prop4_type = index; - calcYeast(); - } - }); - $('#prop4_volume').on('change', function (event) { - if (event.args) { - dataRecord.prop4_volume = event.args.value; - calcYeast(); - } - }); - - $("#calc_acid").on('checked', function (event) { - dataRecord.calc_acid = 1; - calcWater(); - }); - $("#calc_acid").on('unchecked', function (event) { - dataRecord.calc_acid = 0; - calcWater(); - }); - $("#w1_name").jqxDropDownList('selectItem', dataRecord.w1_name); - $("#w2_name").jqxDropDownList('selectItem', dataRecord.w2_name); - // Fix tap water if zero using mash infuse amount. - if (parseFloat($("#w1_amount").jqxNumberInput('decimal')) == 0 && mash_infuse > 0) { - $("#w1_amount").val(mash_infuse); - dataRecord.w1_amount = mash_infuse; - $("#wg_amount").val(mash_infuse); - $("#w2_amount").val(0); - dataRecord.w2_amount = 0; - } - calcWater(); - $("#w2_amount").on('change', function (event) { - var newval = parseFloat(event.args.value); - - if (newval > mash_infuse) { - $("#w2_amount").val(dataRecord.w2_amount); - return; - } - dataRecord.w1_amount = parseFloat($("#wg_amount").jqxNumberInput('decimal')) - newval; - $("#w1_amount").val(dataRecord.w1_amount); - dataRecord.w2_amount = newval; - console.log("new: "+event.args.value+" w1: "+dataRecord.w1_amount+" w2: "+dataRecord.w2_amount); - calcWater(); - }); - $('#wa_cacl2').on('change', function (event) { - if (event.args) { - setWaterAgent('CaCl2', 0); // This can prevent double entries. - setWaterAgent('CaCl2', event.args.value); - calcWater(); - } - }); - $('#wa_caso4').on('change', function (event) { - if (event.args) { - setWaterAgent('CaSO4', 0); - setWaterAgent('CaSO4', event.args.value); - calcWater(); - } - }); - $('#wa_mgso4').on('change', function (event) { - if (event.args) { - setWaterAgent('MgSO4', 0); - setWaterAgent('MgSO4', event.args.value); - calcWater(); - } - }); - $('#wa_nacl').on('change', function (event) { - if (event.args) { - setWaterAgent('NaCl', 0); - setWaterAgent('NaCl', event.args.value); - calcWater(); - } - }); - $('#wa_base_name').on('change', function (event) { - if (event.args) { - var index = event.args.index; - console.log("wa_base_name "+index); - setWaterAgent(last_base, 0); - last_base = BaseTypeData[index].nl; - setWaterAgent(last_base, parseFloat($("#wa_base").jqxNumberInput('decimal'))); - dataRecord.wa_base_name = index; - calcWater(); - } - }); - $('#wa_base').on('change', function (event) { - var name = BaseTypeData[$("#wa_base_name").val()].nl; - setWaterAgent(name, parseFloat(event.args.value)); - calcWater(); - }); - $('#wa_acid_name').on('change', function (event) { - if (event.args) { - var index = event.args.index; - console.log("wa_acid_name "+index); - setWaterAgent(last_acid, 0); - last_acid = AcidTypeData[index].nl; - setWaterAgent(last_acid, parseFloat($("#wa_acid").jqxNumberInput('decimal'))); - dataRecord.wa_acid_name = index; - calcWater(); - } - }); - $('#wa_acid').on('change', function (event) { - var name = AcidTypeData[$("#wa_acid_name").val()].nl; - setWaterAgent(name, parseFloat(event.args.value)); - calcWater(); - }); - $('#wa_acid_perc').on('change', function (event) { calcWater(); }); - - $('#color_method').on('change', function (event) { - dataRecord.color_method = event.args.index; - calcFermentables(); - }); - $('#ibu_method').on('change', function (event) { - dataRecord.ibu_method = event.args.index; - calcFermentables(); - calcIBUs(); - }); - - $('#batch_size').on('change', function (event) { - console.log("batch_size change:"+event.args.value+" old:"+dataRecord.batch_size); - $("#est_a_vol").val(event.args.value * 1.04); - var new_boil = parseFloat(event.args.value) + dataRecord.boil_size - dataRecord.batch_size; - var factor = parseFloat(event.args.value) / dataRecord.batch_size; - dataRecord.boil_size = new_boil; - $("#boil_size").val(Math.round(new_boil * 100) / 100); - $("#est_pre_vol").val(Math.round(new_boil * 1.04 * 100) / 100); - dataRecord.sparge_volume *= factor; - $("#sparge_volume").val(dataRecord.sparge_volume); - $("#brew_sparge_volume").val(dataRecord.sparge_volume); - dataRecord.batch_size = parseFloat(event.args.value); - calcFermentablesFromOG(parseFloat($("#est_og").jqxNumberInput('decimal'))); // Keep the OG - adjustWaters(factor); - calcFermentables(); - adjustHops(factor); - adjustMiscs(factor); - adjustYeasts(factor); - calcIBUs(); - calcWater(); - calcSparge(); - calcMash(); - }); - $('#boil_time').on('change', function (event) { - console.log("boil_time change:"+parseFloat(event.args.value)+" old:"+dataRecord.boil_time); - var old_evap = parseFloat(dataRecord.boil_size) - parseFloat(dataRecord.batch_size); - var new_evap = old_evap * (parseFloat(event.args.value) / dataRecord.boil_time); - var new_boil = parseFloat(dataRecord.batch_size) + new_evap; - //var factor = new_boil / dataRecord.boil_size; - dataRecord.boil_time = parseFloat(event.args.value); - dataRecord.boil_size = new_boil; - $("#est_pre_vol").val(Math.round(new_boil * 1.04 * 100) / 100); - $("#boil_size").val(Math.round(new_boil * 100) / 100); - calcFermentables(); - calcIBUs(); - calcYeast(); - }); - $('#efficiency').on('change', function (event) { - var estog = parseFloat($("#est_og").jqxNumberInput('decimal')); - dataRecord.efficiency = parseFloat(event.args.value); - console.log("efficiency change:"+dataRecord.efficiency+" est_og:"+estog); - calcFermentablesFromOG(estog); // Keep the OG - calcFermentables(); - calcIBUs(); - calcYeast(); - }); - $('#est_og').on('change', function (event) { - dataRecord.est_og = parseFloat(event.args.value); - console.log("est_og change:"+dataRecord.est_og); - $('#est_og2').val(dataRecord.est_og); - calcFermentablesFromOG(dataRecord.est_og); // Adjust fermentables amounts - calcFermentables(); // Update the recipe details - calcIBUs(); // and the IBU's. - calcMash(); - calcYeast(); - }); - $('#mash_ph').on('change', function (event) { - dataRecord.mash_ph = parseFloat(event.args.value); - calcWater(); - }); - - $('#sparge_ph').on('change', function (event) { - dataRecord.sparge_ph = parseFloat(event.args.value); - calcSparge(); - }); - $('#sparge_volume').on('change', function (event) { - dataRecord.sparge_volume = parseFloat(event.args.value); - $('#brew_sparge_volume').val(dataRecord.sparge_volume); - calcSparge(); - }); - $("#sparge_temp").on('change', function (event) { - dataRecord.sparge_temp = parseFloat(event.args.value); - $('#brew_sparge_temperature').val(dataRecord.sparge_temp); - }); - $('#sparge_source').on('change', function (event) { - if (event.args) { - var index = event.args.index; - dataRecord.sparge_source= index; - calcSparge(); - } - }); - $('#sparge_acid_type').on('change', function (event) { - if (event.args) { - var index = event.args.index; - dataRecord.sparge_acid_type = index; - console.log("new sparge_acid_type: "+dataRecord.sparge_acid_type); - calcSparge(); - } - }); - $('#sparge_acid_perc').on('change', function (event) { - dataRecord.sparge_acid_perc = parseFloat(event.args.value); - calcSparge(); - }); - - calcFermentation(); - calcCarbonation(); - $('#package_volume').on('change', function (event) { - var told = dataRecord.package_volume + dataRecord.package_infuse_amount; - dataRecord.package_volume = parseFloat(event.args.value); - if (dataRecord.package_volume > dataRecord.brew_fermenter_volume) { - dataRecord.package_volume = dataRecord.brew_fermenter_volume; - $('#package_volume').val(dataRecord.package_volume); - } - var tnew = dataRecord.package_volume + dataRecord.package_infuse_amount; - var diff = tnew - told; - if (told > 0) { - dataRecord.bottle_amount += (dataRecord.bottle_amount / told) * diff; - dataRecord.keg_amount += (dataRecord.keg_amount / told) * diff; - } else { - dataRecord.bottle_amount = tnew; - dataRecord.keg_amount = 0; - } - console.log("diff:"+diff+" old:"+told+" bottle:"+dataRecord.bottle_amount+" keg:"+dataRecord.keg_amount); - $('#bottle_amount').val(parseFloat(dataRecord.bottle_amount * 1000) / 1000); - $('#keg_amount').val(parseFloat(dataRecord.keg_amount * 1000) / 1000); - calcCarbonation(); - }); - $('#package_infuse_amount').on('change', function (event) { - var told = dataRecord.package_volume + dataRecord.package_infuse_amount; - dataRecord.package_infuse_amount = parseFloat(event.args.value); - var tnew = dataRecord.package_volume + dataRecord.package_infuse_amount; - var diff = tnew - told; - if (told > 0) { - dataRecord.bottle_amount += (dataRecord.bottle_amount / told) * diff; - dataRecord.keg_amount += (dataRecord.keg_amount / told) * diff; - } else { - dataRecord.bottle_amount = tnew; - dataRecord.keg_amount = 0; - } - console.log("diff:"+diff+" old:"+told+" bottle:"+dataRecord.bottle_amount+" keg:"+dataRecord.keg_amount); - $('#bottle_amount').val(parseFloat(dataRecord.bottle_amount * 1000) / 1000); - $('#keg_amount').val(parseFloat(dataRecord.keg_amount * 1000) / 1000); - calcCarbonation(); - }); - $('#package_infuse_abv').on('change', function (event) { - dataRecord.package_infuse_abv = parseFloat(event.args.value); - calcCarbonation(); - }); - $('#bottle_amount').on('change', function (event) { - var vnew = parseFloat(event.args.value); - var vtot = dataRecord.package_volume + dataRecord.package_infuse_amount; - if (vnew > vtot) - vnew = vtot; - diff = dataRecord.bottle_amount - vnew; - dataRecord.bottle_amount = Math.round((dataRecord.bottle_amount - diff) * 1000) / 1000; - dataRecord.keg_amount = Math.round((dataRecord.keg_amount + diff) * 1000) / 1000; - $('#bottle_amount').val(parseFloat(dataRecord.bottle_amount)); - $('#keg_amount').val(parseFloat(dataRecord.keg_amount)); - calcCarbonation(); - }); - $("#bottle_priming_water").on('change', function (event) { - dataRecord.bottle_priming_water = parseFloat(event.args.value); - calcCarbonation(); - }); - $('#keg_amount').on('change', function (event) { - var vnew = parseFloat(event.args.value); - var vtot = dataRecord.package_volume + dataRecord.package_infuse_amount; - if (vnew > vtot) - vnew = vtot; - diff = dataRecord.keg_amount - vnew; - dataRecord.bottle_amount = Math.round((dataRecord.bottle_amount + diff) * 1000) / 1000; - dataRecord.keg_amount = Math.round((dataRecord.keg_amount - diff) * 1000) / 1000; - $('#bottle_amount').val(parseFloat(dataRecord.bottle_amount)); - $('#keg_amount').val(parseFloat(dataRecord.keg_amount)); - calcCarbonation(); - }); - $("#keg_priming_water").on('change', function (event) { - dataRecord.keg_priming_water = parseFloat(event.args.value); - calcCarbonation(); - }); - $('#bottle_carbonation').on('change', function (event) { - dataRecord.bottle_carbonation = parseFloat(event.args.value); - calcCarbonation(); - }); - $('#bottle_carbonation_temp').on('change', function (event) { - dataRecord.bottle_carbonation_temp = parseFloat(event.args.value); - calcCarbonation(); - }); - $('#keg_carbonation').on('change', function (event) { - dataRecord.keg_carbonation = parseFloat(event.args.value); - calcCarbonation(); - }); - $("#keg_forced_carb").on('checked', function (event) { - dataRecord.keg_forced_carb = 1; - calcCarbonation(); - }); - $("#keg_forced_carb").on('unchecked', function (event) { - dataRecord.keg_forced_carb = 0; - calcCarbonation(); - }); - $('#keg_carbonation_temp').on('change', function (event) { - dataRecord.keg_carbonation_temp = parseFloat(event.args.value); - calcCarbonation(); - }); - - $("#brew_fermenter_extrawater").on('change',function (event){ - dataRecord.brew_fermenter_extrawater=parseFloat(event.args.value);calcFermentables();calcIBUs();calcYeast(); - }); - $("#brew_fermenter_tcloss").on('change',function (event){ - dataRecord.brew_fermenter_tcloss=parseFloat(event.args.value);calcFermentables();calcIBUs();calcYeast(); - }); - $("#primary_end_sg").on('change',function (event){dataRecord.primary_end_sg=parseFloat(event.args.value);calcFermentation();}); - $("#primary_end_brix").on('change', function (event) { - if(dataRecord.brew_fermenter_sg>=1.020){ - OBrix=sg_to_brix(dataRecord.brew_fermenter_sg); - FBrix=parseFloat(event.args.value); -var FG=Round(1.0031-0.002318474*OBrix-0.000007775*(OBrix*OBrix)-0.000000034*Math.pow(OBrix,3)+0.00574*(FBrix)+0.00003344*(FBrix*FBrix)+0.000000086*Math.pow(FBrix,3),4); - //console.log("OBrix:"+OBrix+" FBrix:"+FBrix+" FG:"+FG); - if(FBrix>0.05){$("#primary_end_sg").val(FG);dataRecord.primary_end_sg=FG;} - calcFermentation(); - } - }); - $("#secondary_end_sg").on('change',function (event){dataRecord.secondary_end_sg=parseFloat(event.args.value);calcFermentation();}); - $("#secondary_end_brix").on('change', function (event) { - if(dataRecord.brew_fermenter_sg>=1.020){ - OBrix=sg_to_brix(dataRecord.brew_fermenter_sg); - FBrix=parseFloat(event.args.value); -var FG=Round(1.0031-0.002318474*OBrix-0.000007775*(OBrix*OBrix)-0.000000034*Math.pow(OBrix,3)+0.00574*(FBrix)+0.00003344*(FBrix*FBrix)+0.000000086*Math.pow(FBrix,3),4); - //console.log("OBrix:"+OBrix+" FBrix:"+FBrix+" FG:"+FG); - if(FBrix>0.05){$("#secondary_end_sg").val(FG);dataRecord.secondary_end_sg=FG;} - calcFermentation(); - } - }); - $("#final_brix").on('change',function (event){ - if(dataRecord.brew_fermenter_sg>=1.020){ - OBrix=sg_to_brix(dataRecord.brew_fermenter_sg); - FBrix=parseFloat(event.args.value); -var FG=Round(1.0031-0.002318474*OBrix-0.000007775*(OBrix*OBrix)-0.000000034*Math.pow(OBrix,3)+0.00574*(FBrix)+0.00003344*(FBrix*FBrix)+0.000000086*Math.pow(FBrix,3),4); -// Ook brouwhulp SGFerm() maar is niet in gebruik. -//var FG=((1.001843-0.002318474*OBrix-0.000007775*(OBrix*OBrix)-0.000000034*Math.pow(OBrix,3)+0.00574*(FBrix)+0.00003344*(FBrix*FBrix)+0.000000086*Math.pow(FBrix,3))+(1.313454)*0.001); - //console.log("OBrix:"+OBrix+" FBrix:"+FBrix+" FG:"+FG); - if(FBrix>0.05){$("#fg").val(FG);dataRecord.fg=FG;} - calcFermentation(); - } - }); - $("#fg").on('change',function (event){dataRecord.fg=parseFloat(event.args.value);calcFermentation();}); - $("#BLog").jqxButton({disabled:(dataRecord.log_brew)?false:true}); - $("#FLog").jqxButton({disabled:(dataRecord.log_fermentation)?false:true}); - }; - - $("#styleSelect").jqxDropDownList({ - placeHolder: "Kies bierstijl:", - theme: theme, - source: styleslist, - displayMember: "name", - width: 180, - height: 23, - dropDownVerticalAlignment: 'top', - dropDownWidth: 500, - dropDownHeight: 380, - renderer: function (index, label, value) { - var datarecord = styleslist.records[index]; - return datarecord.style_guide + " " + datarecord.style_letter+ " " + datarecord.name; - } - }); - $("#styleSelect").on('select', function (event) { - if (event.args) { - var index = event.args.index; - var datarecord = styleslist.records[index]; - $("#st_name").val(datarecord.name); - $("#st_category").val(datarecord.category); - $("#st_category_number").val(datarecord.category_number); - $("#st_letter").val(datarecord.style_letter); - $("#st_guide").val(datarecord.style_guide); - $("#st_type").val(StyleTypeData[datarecord.type].nl); - $("#st_og_min").val(datarecord.og_min); - $("#st_og_max").val(datarecord.og_max); - $("#st_fg_min").val(datarecord.fg_min); - $("#st_fg_max").val(datarecord.fg_max); - $("#st_ibu_min").val(datarecord.ibu_min); - $("#st_ibu_max").val(datarecord.ibu_max); - $("#st_color_min").val(datarecord.color_min); - $("#st_color_max").val(datarecord.color_max); - $("#st_carb_min").val(datarecord.carb_min); - $("#st_carb_min2").val(datarecord.carb_min); - $("#st_carb_max").val(datarecord.carb_max); - $("#st_carb_max2").val(datarecord.carb_max); - $("#st_abv_min").val(datarecord.abv_min); - $("#st_abv_max").val(datarecord.abv_max); - } - }); - - // Equipemnt dropdown list - $("#equipmentSelect").jqxDropDownList({ - placeHolder: "Kies apparatuur:", - theme: theme, - source: equipmentlist, - displayMember: "name", - width: 170, - height: 23, - dropDownWidth: 300, - renderer: function (index, label, value) { - var datarecord = equipmentlist.records[index]; - return datarecord.batch_size + " liter " + datarecord.name; - } - }); - $("#equipmentSelect").on('select', function (event) { - if (event.args) { - var index = event.args.index; - var datarecord = equipmentlist.records[index]; - var factor = datarecord.batch_size / dataRecord.batch_size; - $("#eq_name").val(datarecord.name); - $("#eq_boil_size").val(datarecord.boil_size); - dataRecord.boil_size = datarecord.boil_size; - $("#boil_size").val(datarecord.boil_size); - $("#eq_batch_size").val(datarecord.batch_size); - dataRecord.batch_size = datarecord.batch_size; - $("#batch_size").val(datarecord.batch_size); - $("#est_a_vol").val(datarecord.batch_size * 1.04); - $("#eq_tun_volume").val(datarecord.tun_volume); - dataRecord.eq_tun_weight = datarecord.tun_weight; - dataRecord.eq_tun_specific_heat = datarecord.tun_specific_heat; - dataRecord.eq_tun_material = datarecord.tun_material; - dataRecord.eq_tun_height = datarecord.tun_height / 100.0; - $("#eq_top_up_water").val(datarecord.top_up_water); - dataRecord.eq_trub_chiller_loss = datarecord.trub_chiller_loss; - $("#eq_trub_chiller_loss").val(datarecord.trub_chiller_loss); - $("#eq_evap_rate").val(datarecord.evap_rate); - $("#eq_boil_time").val(datarecord.boil_time); - dataRecord.eq_calc_boil_volume = datarecord.calc_boil_volume; - $("#eq_top_up_kettle").val(datarecord.top_up_kettle); - $("#eq_hop_utilization").val(datarecord.hop_utilization); - $("#eq_notes").val(datarecord.notes); - $("#eq_lauter_volume").val(datarecord.lauter_volume); - dataRecord.eq_lauter_height = datarecord.lauter_height / 100.0; - $("#eq_lauter_deadspace").val(datarecord.lauter_deadspace); - $("#eq_kettle_volume").val(datarecord.kettle_volume); - dataRecord.eq_kettle_height = datarecord.kettle_height / 100.0; - $("#eq_mash_volume").val(datarecord.mash_volume); - $("#eq_mash_max").val(datarecord.mash_max); - dataRecord.eq_mash_max = datarecord.mash_max; - $("#mash_max").val(datarecord.mash_max); - $("#eq_efficiency").val(datarecord.efficiency); - dataRecord.efficiency = datarecord.efficiency; - $("#efficiency").val(datarecord.efficiency); - - dataRecord.sparge_volume = Math.round(datarecord.boil_size * 5) / 10; - $("#sparge_volume").val(dataRecord.sparge_volume); - $("#brew_sparge_volume").val(dataRecord.sparge_volume); - $("#est_pre_vol").val(datarecord.boil_size * 1.04); - calcFermentablesFromOG(parseFloat($("#est_og").jqxNumberInput('decimal'))); // Keep the OG - adjustWaters(factor); - calcFermentables(); - adjustHops(factor); - adjustMiscs(factor); - adjustYeasts(factor); - calcIBUs(); - calcWater(); - calcSparge(); - } - }); - - function saveRecord() { - console.log("saveRecord()"); - 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, - uuid: dataRecord.uuid, - name: $("#name").val(), - code: $("#code").val(), - birth: $("#birth").val(), - stage: dataRecord.stage, - notes: $("#notes").val(), - log_brew: dataRecord.log_brew, - log_fermentation: dataRecord.log_fermentation, - inventory_reduced: dataRecord.inventory_reduced, - locked: dataRecord.locked, - eq_name: $("#eq_name").val(), - eq_boil_size: parseFloat($("#eq_boil_size").jqxNumberInput('decimal')), - eq_batch_size: parseFloat($("#eq_batch_size").jqxNumberInput('decimal')), - eq_tun_volume: parseFloat($("#eq_tun_volume").jqxNumberInput('decimal')), - eq_tun_weight: dataRecord.eq_tun_weight, - eq_tun_specific_heat: dataRecord.eq_tun_specific_heat, - eq_tun_material: dataRecord.eq_tun_material, - eq_tun_height: dataRecord.eq_tun_height, - eq_top_up_water: parseFloat($("#eq_top_up_water").jqxNumberInput('decimal')), - eq_trub_chiller_loss: parseFloat($("#eq_trub_chiller_loss").jqxNumberInput('decimal')), - eq_evap_rate: parseFloat($("#eq_evap_rate").jqxNumberInput('decimal')), - eq_boil_time: parseFloat($("#eq_boil_time").jqxNumberInput('decimal')), - eq_calc_boil_volume: dataRecord.eq_calc_boil_volume, - eq_top_up_kettle: parseFloat($("#eq_top_up_kettle").jqxNumberInput('decimal')), - eq_hop_utilization: parseFloat($("#eq_hop_utilization").jqxNumberInput('decimal')), - eq_notes: $("#eq_notes").val(), - eq_lauter_volume: parseFloat($("#eq_lauter_volume").jqxNumberInput('decimal')), - eq_lauter_height: dataRecord.eq_lauter_height, - eq_lauter_deadspace: parseFloat($("#eq_lauter_deadspace").jqxNumberInput('decimal')), - eq_kettle_volume: parseFloat($("#eq_kettle_volume").jqxNumberInput('decimal')), - 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')), - brew_date_start: $("#brew_date_start").val(), - brew_mash_ph: parseFloat($("#brew_mash_ph").jqxNumberInput('decimal')), - brew_mash_sg: parseFloat($("#brew_mash_sg").jqxNumberInput('decimal')), - brew_mash_efficiency: parseFloat($("#brew_mash_efficiency").jqxNumberInput('decimal')), - brew_sparge_est: parseFloat($("#brew_sparge_est").jqxNumberInput('decimal')), - brew_sparge_ph: parseFloat($("#brew_sparge_ph").jqxNumberInput('decimal')), - brew_preboil_volume: parseFloat($("#brew_preboil_volume").jqxNumberInput('decimal')), - brew_preboil_sg: parseFloat($("#brew_preboil_sg").jqxNumberInput('decimal')), - brew_preboil_ph: parseFloat($("#brew_preboil_ph").jqxNumberInput('decimal')), - brew_preboil_efficiency: parseFloat($("#brew_preboil_efficiency").jqxNumberInput('decimal')), - brew_aboil_volume: parseFloat($("#brew_aboil_volume").jqxNumberInput('decimal')), - brew_aboil_sg: parseFloat($("#brew_aboil_sg").jqxNumberInput('decimal')), - brew_aboil_ph: parseFloat($("#brew_aboil_ph").jqxNumberInput('decimal')), - brew_aboil_efficiency: parseFloat($("#brew_aboil_efficiency").jqxNumberInput('decimal')), - brew_cooling_method: $("#brew_cooling_method").val(), - brew_cooling_time: parseFloat($("#brew_cooling_time").jqxNumberInput('decimal')), - brew_cooling_to: parseFloat($("#brew_cooling_to").jqxNumberInput('decimal')), - brew_whirlpool9: parseFloat($("#brew_whirlpool9").jqxNumberInput('decimal')), - brew_whirlpool7: parseFloat($("#brew_whirlpool7").jqxNumberInput('decimal')), - brew_whirlpool6: parseFloat($("#brew_whirlpool6").jqxNumberInput('decimal')), - brew_whirlpool2: parseFloat($("#brew_whirlpool2").jqxNumberInput('decimal')), - brew_fermenter_volume: parseFloat($("#brew_fermenter_volume").jqxNumberInput('decimal')), - brew_fermenter_extrawater: parseFloat($("#brew_fermenter_extrawater").jqxNumberInput('decimal')), - brew_fermenter_tcloss: parseFloat($("#brew_fermenter_tcloss").jqxNumberInput('decimal')), - brew_aeration_time: parseFloat($("#brew_aeration_time").jqxNumberInput('decimal')), - brew_aeration_speed: parseFloat($("#brew_aeration_speed").jqxNumberInput('decimal')), - brew_aeration_type: $("#brew_aeration_type").val(), - brew_fermenter_sg: parseFloat($("#brew_fermenter_sg").jqxNumberInput('decimal')), - brew_fermenter_ibu: parseFloat($("#brew_fermenter_ibu").jqxNumberInput('decimal')), - brew_fermenter_color: parseFloat($("#brew_fermenter_color").jqxNumberInput('decimal')), - brew_date_end: $("#brew_date_end").val(), - og: dataRecord.og, - fg: parseFloat($("#fg").jqxNumberInput('decimal')), - primary_start_temp: parseFloat($("#primary_start_temp").jqxNumberInput('decimal')), - primary_max_temp: parseFloat($("#primary_max_temp").jqxNumberInput('decimal')), - primary_end_temp: parseFloat($("#primary_end_temp").jqxNumberInput('decimal')), - primary_end_sg: parseFloat($("#primary_end_sg").jqxNumberInput('decimal')), - primary_end_date: $("#primary_end_date").val(), - secondary_temp: parseFloat($("#secondary_temp").jqxNumberInput('decimal')), - secondary_end_sg: parseFloat($("#secondary_end_sg").jqxNumberInput('decimal')), - secondary_end_date: $("#secondary_end_date").val(), - tertiary_temp: parseFloat($("#tertiary_temp").jqxNumberInput('decimal')), - package_date: $("#package_date").val(), - package_volume: parseFloat($("#package_volume").jqxNumberInput('decimal')), - package_infuse_amount: parseFloat($("#package_infuse_amount").jqxNumberInput('decimal')), - package_infuse_abv: parseFloat($("#package_infuse_abv").jqxNumberInput('decimal')), - package_infuse_notes: $("#package_infuse_notes").val(), - package_abv: parseFloat($("#package_abv").jqxNumberInput('decimal')), - package_ph: parseFloat($("#package_ph").jqxNumberInput('decimal')), - bottle_amount: parseFloat($("#bottle_amount").jqxNumberInput('decimal')), - bottle_carbonation: parseFloat($("#bottle_carbonation").jqxNumberInput('decimal')), - bottle_priming_water: parseFloat($("#bottle_priming_water").jqxNumberInput('decimal')), - bottle_priming_amount: parseFloat($("#bottle_priming_amount").jqxNumberInput('decimal')), - bottle_carbonation_temp: parseFloat($("#bottle_carbonation_temp").jqxNumberInput('decimal')), - keg_amount: parseFloat($("#keg_amount").jqxNumberInput('decimal')), - keg_carbonation: parseFloat($("#keg_carbonation").jqxNumberInput('decimal')), - keg_priming_water: parseFloat($("#keg_priming_water").jqxNumberInput('decimal')), - keg_priming_amount: parseFloat($("#keg_priming_amount").jqxNumberInput('decimal')), - keg_carbonation_temp: parseFloat($("#keg_carbonation_temp").jqxNumberInput('decimal')), - keg_forced_carb: dataRecord.keg_forced_carb, - keg_pressure: parseFloat($("#keg_pressure").jqxNumberInput('decimal')), - taste_notes: $("#taste_notes").val(), - taste_rate: parseFloat($("#taste_rate").jqxNumberInput('decimal')), - taste_date: $("#taste_date").val(), - taste_color: $("#taste_color").val(), - taste_transparency: $("#taste_transparency").val(), - taste_head: $("#taste_head").val(), - taste_aroma: $("#taste_aroma").val(), - taste_taste: $("#taste_taste").val(), - taste_mouthfeel: $("#taste_mouthfeel").val(), - taste_aftertaste: $("#taste_aftertaste").val(), - st_name: $('#st_name').val(), - st_letter: $('#st_letter').val(), - st_guide: $('#st_guide').val(), - st_type: dataRecord.st_type, - 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_source: $("#sparge_source").val(), - sparge_acid_type: $("#sparge_acid_type").val(), - sparge_acid_perc: parseFloat($("#sparge_acid_perc").jqxNumberInput('decimal')), - sparge_acid_amount: dataRecord.sparge_acid_amount, - calc_acid: dataRecord.calc_acid, - 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, - wg_amount: parseFloat($("#wg_amount").jqxNumberInput('decimal')), - wg_calcium: parseFloat($("#wg_calcium").jqxNumberInput('decimal')), - wg_sulfate: parseFloat($("#wg_sulfate").jqxNumberInput('decimal')), - wg_chloride: parseFloat($("#wg_chloride").jqxNumberInput('decimal')), - wg_sodium: parseFloat($("#wg_sodium").jqxNumberInput('decimal')), - wg_magnesium: parseFloat($("#wg_magnesium").jqxNumberInput('decimal')), - wg_total_alkalinity: parseFloat($("#wg_total_alkalinity").jqxNumberInput('decimal')), - wg_ph: parseFloat($("#wg_ph").jqxNumberInput('decimal')), - wb_calcium: parseFloat($("#wb_calcium").jqxNumberInput('decimal')), - wb_sulfate: parseFloat($("#wb_sulfate").jqxNumberInput('decimal')), - wb_chloride: parseFloat($("#wb_chloride").jqxNumberInput('decimal')), - wb_sodium: parseFloat($("#wb_sodium").jqxNumberInput('decimal')), - wb_magnesium: parseFloat($("#wb_magnesium").jqxNumberInput('decimal')), - wb_total_alkalinity: parseFloat($("#wb_total_alkalinity").jqxNumberInput('decimal')), - wb_ph: parseFloat($("#wb_ph").jqxNumberInput('decimal')), - wa_acid_name: $("#wa_acid_name").val(), - wa_acid_perc: parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')), - wa_base_name: $("#wa_base_name").val(), - starter_enable: dataRecord.starter_enable, - starter_type: $("#starter_type").val(), - starter_sg: parseFloat($("#starter_sg").jqxNumberInput('decimal')), - starter_viability: parseFloat($("#starter_viability").jqxNumberInput('decimal')), - prop1_type: $("#prop1_type").val(), - prop1_volume: parseFloat($("#prop1_volume").jqxNumberInput('decimal')), - prop2_type: $("#prop2_type").val(), - prop2_volume: parseFloat($("#prop2_volume").jqxNumberInput('decimal')), - prop3_type: $("#prop3_type").val(), - prop3_volume: parseFloat($("#prop3_volume").jqxNumberInput('decimal')), - prop4_type: $("#prop4_type").val(), - prop4_volume: parseFloat($("#prop4_volume").jqxNumberInput('decimal')), - fermentables: fermentablerow, - hops: hoprow, - miscs: miscrow, - yeasts: yeastrow, - mashs: mashrow - }; - var data = "update=true&" + $.param(row); - $.ajax({ - dataType: 'json', - url: url, - cache: false, - data: data, - async: false, - type: "POST", - success: function (data, status, xhr) { - console.log("saveRecord() success"); - }, - error: function(jqXHR, textStatus, errorThrown) { - console.log("saveRecord() error"); - } - }); - }; - - var dataRecord = {}; - var url = "includes/db_product.php"; + var i, + to_100 = false, // Fermentables adjust to 100% + preboil_sg = 0, + aboil_sg = 0, + est_mash_sg = 0, + psugar = 0, // Percentage real sugars + pcara = 0, // Percentage cara/crystal malts + svg = 77, // Default attenuation + mashkg = 0, // Malt in mash weight + pitchrate = 0.75, // Yeast pitch rate default + initcells = 0, // Initial yeast cell count + + ok_fermentables = 1, // Fermentables are in stock + ok_hops = 1, // Hops are in stock + ok_miscs = 1, // Miscs are in stock + ok_yeasts = 1, // Yeasts are in stock + ok_waters = 1, // Waters are in stock + + hop_flavour = 0, + hop_aroma = 0, + mash_infuse = 0, + last_base = '', + last_acid = '', + + MMCa = 40.048, + MMMg = 24.305, + MMNa = 22.98976928, + MMCl = 35.453, + MMSO4 = 96.0626, + MMHCO3 = 61.01684, + MMCaSO4 = 172.171, + MMCaCl2 = 147.015, + MMCaCO3 = 100.087, + MMMgSO4 = 246.475, + MMNaHCO3 = 84.007, + MMNa2CO3 = 105.996, + MMNaCl = 58.443, + MMCaOH2 = 74.06268, + + fermentableRow = 0, + fermentableData = {}, + fermentableInit = 1, + hopRow = 0, + hopData = {}, + miscRow = 0, + miscData = {}, + yeastRow = 0, + yeastData = {}, + mashRow = 0, + mashData = {}, + Ka1 = 0.0000004445, + Ka2 = 0.0000000000468, + dataRecord = {}, + url = "includes/db_product.php", // Prepare the data - var source = { + source = { datatype: "json", cache: false, datafields: [ @@ -3125,9 +312,9 @@ ], id: 'record', url: url + '?record=' + my_record - }; + }, // Load data and select one record. - var dataAdapter = new $.jqx.dataAdapter(source, { + dataAdapter = new $.jqx.dataAdapter(source, { loadComplete: function () { var records = dataAdapter.records; dataRecord = records[0]; @@ -3354,11 +541,10 @@ beforeLoadComplete: function (records) { $('#jqxLoader').jqxLoader('open'); } - }); - dataAdapter.dataBind(); + }), // Inline fermentables editor - var editFermentable = function (data) { + editFermentable = function (data) { var fermentableSource = { localdata: data.fermentables, datatype: "local", @@ -3402,8 +588,9 @@ //console.log("fermentable updaterow "+rowid); commit(true); } - }; - var fermentableAdapter = new $.jqx.dataAdapter(fermentableSource); + }, + fermentableAdapter = new $.jqx.dataAdapter(fermentableSource); + $("#fermentableGrid").jqxGrid({ width: 1240, height: 470, @@ -3437,10 +624,9 @@ }); $("#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 = {}; + var index, datarecord, row = {}, rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + index = event.args.index; + datarecord = fermentablelist.records[index]; row["f_name"] = datarecord.name; row["f_origin"] = datarecord.origin; row["f_supplier"] = datarecord.supplier; @@ -3489,19 +675,20 @@ // delete selected fermentable. $("#fdeleterowbutton").jqxButton({ template: "danger", theme: theme, height: 27, width: 150, disabled: (dataRecord.stage > 3) }); $("#fdeleterowbutton").on('click', function () { - var selectedrowindex = $("#fermentableGrid").jqxGrid('getselectedrowindex'); - var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + var rowscount, id, percent, amount, i, rowdata, + selectedrowindex = $("#fermentableGrid").jqxGrid('getselectedrowindex'); + 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"); + id = $("#fermentableGrid").jqxGrid('getrowid', selectedrowindex); + percent = $('#fermentableGrid').jqxGrid('getcellvalue', id, "f_percentage"); + amount = $('#fermentableGrid').jqxGrid('getcellvalue', id, "f_amount"); $("#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); + for (i = 0; i < rowscount; i++) { + rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_adjust_to_total_100) { rowdata.f_percentage += percent; rowdata.f_amount += amount; @@ -3599,10 +786,10 @@ } ] }); - }; + }, // Inline hops editor - var editHop = function (data) { + editHop = function (data) { var hopSource = { localdata: data.hops, datatype: "local", @@ -3640,8 +827,9 @@ console.log("hop updaterow "+rowid); commit(true); } - }; - var hopAdapter = new $.jqx.dataAdapter(hopSource); + }, + hopAdapter = new $.jqx.dataAdapter(hopSource); + $("#hopGrid").jqxGrid({ width: 1240, height: 560, @@ -3676,9 +864,8 @@ }); $("#haddrowbutton").on('select', function (event) { if (event.args) { - var index = event.args.index; - var datarecord = hoplist.records[index]; - var row = {}; + var datarecord, row = {}, index = event.args.index; + datarecord = hoplist.records[index]; row["h_name"] = datarecord.name; row["h_origin"] = datarecord.origin; row["h_amount"] = 0; @@ -3710,10 +897,10 @@ // delete selected hop. $("#hdeleterowbutton").jqxButton({ template: "danger", theme: theme, height: 27, width: 150, disabled: (dataRecord.stage > 3) }); $("#hdeleterowbutton").on('click', function () { - var selectedrowindex = $("#hopGrid").jqxGrid('getselectedrowindex'); - var rowscount = $("#hopGrid").jqxGrid('getdatainformation').rowscount; + var rowscount, id, selectedrowindex = $("#hopGrid").jqxGrid('getselectedrowindex'); + rowscount = $("#hopGrid").jqxGrid('getdatainformation').rowscount; if (selectedrowindex >= 0 && selectedrowindex < rowscount) { - var id = $("#hopGrid").jqxGrid('getrowid', selectedrowindex); + id = $("#hopGrid").jqxGrid('getrowid', selectedrowindex); $("#hopGrid").jqxGrid('deleterow', id); } calcIBUs(); @@ -3775,10 +962,10 @@ cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { if (((dataRecord.inventory_reduced <= 2) && (rowdata.h_useat <= 4)) || // Mash, FW, Boil, Aroma, Whirlpool ((dataRecord.inventory_reduced <= 6) && (rowdata.h_useat == 5))) { // Dry hop - var color = '#ffffff'; + var amount, color = '#ffffff'; if (value < rowdata.h_amount) color = '#ff4040'; - var amount = dataAdapter.formatNumber(value, "f1") + ' kg'; + amount = dataAdapter.formatNumber(value, "f1") + ' kg'; if (value < 1) amount = dataAdapter.formatNumber(value * 1000, "f1") + ' gr'; return ''+amount+''; @@ -3816,10 +1003,10 @@ } ] }); - }; + }, // Inline miscs editor - var editMisc = function (data) { + editMisc = function (data) { var miscSource = { localdata: data.miscs, datatype: "local", @@ -3848,12 +1035,12 @@ console.log("misc updaterow "+rowid); commit(true); } - }; - var miscAdapter = new $.jqx.dataAdapter(miscSource, { + }, + miscAdapter = new $.jqx.dataAdapter(miscSource, { beforeLoadComplete: function (records) { - var data = new Array(); - for (var i = 0; i < records.length; i++) { - var row = records[i]; + var row, i, data = new Array(); + for (i = 0; i < records.length; i++) { + row = records[i]; data.push(row); // Initial set water agent values. switch (row.m_name) { @@ -3938,9 +1125,8 @@ }); $("#maddrowbutton").on('select', function (event) { if (event.args) { - var index = event.args.index; - var datarecord = misclist.records[index]; - var row = {}; + var datarecord, row = {}, index = event.args.index; + datarecord = misclist.records[index]; row["m_name"] = datarecord.name; row["m_amount"] = 0; row["m_cost"] = datarecord.cost; @@ -3960,11 +1146,11 @@ // delete selected misc. $("#mdeleterowbutton").jqxButton({ template: "danger", theme: theme, height: 27, width: 150, disabled: (dataRecord.stage > 3) }); $("#mdeleterowbutton").on('click', function () { - var selectedrowindex = $("#miscGrid").jqxGrid('getselectedrowindex'); - var rowscount = $("#miscGrid").jqxGrid('getdatainformation').rowscount; - var type = $("#miscGrid").jqxGrid('getcellvalue', selectedrowindex, "m_type"); + var rowscount, type, id, selectedrowindex = $("#miscGrid").jqxGrid('getselectedrowindex'); + rowscount = $("#miscGrid").jqxGrid('getdatainformation').rowscount; + type = $("#miscGrid").jqxGrid('getcellvalue', selectedrowindex, "m_type"); if (selectedrowindex >= 0 && selectedrowindex < rowscount && type != 4) { // Water agent - var id = $("#miscGrid").jqxGrid('getrowid', selectedrowindex); + id = $("#miscGrid").jqxGrid('getrowid', selectedrowindex); $("#miscGrid").jqxGrid('deleterow', id); } }); @@ -4004,15 +1190,16 @@ }, { text: 'Voorraad', datafield: 'm_inventory', width: 110, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { + var vstr, color, amount; if (((dataRecord.inventory_reduced <= 2) && (rowdata.m_use_use <= 2)) || // Starter, Mash, Boil ((dataRecord.inventory_reduced <= 3) && (rowdata.m_use_use == 3)) || // Primary ((dataRecord.inventory_reduced <= 5) && (rowdata.m_use_use == 4)) || // Secondary, Teriary ((dataRecord.inventory_reduced <= 6) && (rowdata.m_use_use == 5))) { // Bottle - var vstr = rowdata.m_amount_is_weight ? "gr":"ml"; - var color = '#ffffff'; + vstr = rowdata.m_amount_is_weight ? "gr":"ml"; + color = '#ffffff'; if (value < rowdata.m_amount) color = '#ff4040'; - var amount = dataAdapter.formatNumber(value * 1000,"f2")+" "+vstr; + amount = dataAdapter.formatNumber(value * 1000,"f2")+" "+vstr; return ''+amount+''; } else { return ''; @@ -4048,10 +1235,10 @@ } ] }); - }; + }, // Inline yeasts editor - var editYeast = function (data) { + editYeast = function (data) { var yeastSource = { localdata: data.yeasts, datatype: "local", @@ -4087,8 +1274,9 @@ console.log("yeast updaterow "+rowid); commit(true); } - }; - var yeastAdapter = new $.jqx.dataAdapter(yeastSource); + }, + yeastAdapter = new $.jqx.dataAdapter(yeastSource); + $("#yeastGrid").jqxGrid({ width: 1240, height: 350, @@ -4122,9 +1310,8 @@ }); $("#yaddrowbutton").on('select', function (event) { if (event.args) { - var index = event.args.index; - var datarecord = yeastlist.records[index]; - var row = {}; + var datarecord, row = {}, index = event.args.index; + datarecord = yeastlist.records[index]; row["y_name"] = datarecord.name; row["y_laboratory"] = datarecord.laboratory; row["y_product_id"] = datarecord.product_id; @@ -4153,10 +1340,10 @@ // delete selected yeast. $("#ydeleterowbutton").jqxButton({ template: "danger", theme: theme, height: 27, width: 150, disabled: (dataRecord.stage > 3) }); $("#ydeleterowbutton").on('click', function () { - var selectedrowindex = $("#yeastGrid").jqxGrid('getselectedrowindex'); - var rowscount = $("#yeastGrid").jqxGrid('getdatainformation').rowscount; + var id, rowscount, selectedrowindex = $("#yeastGrid").jqxGrid('getselectedrowindex'); + rowscount = $("#yeastGrid").jqxGrid('getdatainformation').rowscount; if (selectedrowindex >= 0 && selectedrowindex < rowscount) { - var id = $("#yeastGrid").jqxGrid('getrowid', selectedrowindex); + id = $("#yeastGrid").jqxGrid('getrowid', selectedrowindex); $("#yeastGrid").jqxGrid('deleterow', id); calcYeast(); } @@ -4181,8 +1368,7 @@ { text: 'Max. °C', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_max_temperature' }, { text: 'Tol. %', width: 60, align: 'right', cellsalign: 'right', datafield: 'y_tolerance', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { - var color = '#ffffff'; - var amount = ""; + var amount = "", color = '#ffffff'; if (value > 0) { amount = dataAdapter.formatNumber(value, "f1"); if (dataRecord.est_abv > value) @@ -4209,14 +1395,15 @@ }, { text: 'Voorraad', datafield: 'y_inventory', width: 90, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { + var color, amount; if (((dataRecord.inventory_reduced <= 3) && (rowdata.y_use == 0)) || // Primary ((dataRecord.inventory_reduced <= 4) && (rowdata.y_use == 1)) || // Secondary ((dataRecord.inventory_reduced <= 5) && (rowdata.y_use == 2)) || // Tertiary ((dataRecord.inventory_reduced <= 6) && (rowdata.y_use == 3))) { // Bottle - var color = '#ffffff'; + color = '#ffffff'; if (value < rowdata.y_amount) color = '#ff4040'; - var amount = dataAdapter.formatNumber(value*1000, "f0")+" ml"; + amount = dataAdapter.formatNumber(value*1000, "f0")+" ml"; if (rowdata.y_form == 0) // Liquid amount = dataAdapter.formatNumber(value, "f0")+" pk"; else if (rowdata.y_form == 1) // Dry @@ -4259,10 +1446,9 @@ } ] }); - }; - + }, // inline mash editor - var editMash = function (data) { + editMash = function (data) { var mashSource = { localdata: data.mashs, datatype: "local", @@ -4284,13 +1470,13 @@ deleterow: function (rowid, commit) { commit(true); } - }; - var mashAdapter = new $.jqx.dataAdapter(mashSource, { + }, + 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]; + var i, row, data = new Array(); + for (i = 0; i < records.length; i++) { + row = records[i]; if (row.step_type == 0) // Infusion mash_infuse += parseFloat(row.step_infuse_amount); row.step_thickness = 0; // Init this field. @@ -4312,8 +1498,7 @@ container.append(''); $("#saddrowbutton").jqxButton({ template: "primary", theme: theme, height: 27, width: 150, disabled: (dataRecord.stage > 3) }); $("#saddrowbutton").on('click', function () { - var rowscount = $("#mashGrid").jqxGrid('getdatainformation').rowscount; - var row = {}; + var row = {}, rowscount = $("#mashGrid").jqxGrid('getdatainformation').rowscount; row["step_name"] = "Stap " + (rowscount + 1); if (rowscount > 0) { row["step_type"] = 1; @@ -4331,10 +1516,10 @@ // delete selected step. $("#sdeleterowbutton").jqxButton({ template: "danger", theme: theme, height: 27, width: 150, disabled: (dataRecord.stage > 3) }); $("#sdeleterowbutton").on('click', function () { - var selectedrowindex = $("#mashGrid").jqxGrid('getselectedrowindex'); - var rowscount = $("#mashGrid").jqxGrid('getdatainformation').rowscount; + var rowscount, id, selectedrowindex = $("#mashGrid").jqxGrid('getselectedrowindex'); + rowscount = $("#mashGrid").jqxGrid('getdatainformation').rowscount; if (selectedrowindex >= 0 && selectedrowindex < rowscount) { - var id = $("#mashGrid").jqxGrid('getrowid', selectedrowindex); + id = $("#mashGrid").jqxGrid('getrowid', selectedrowindex); $("#mashGrid").jqxGrid('deleterow', id); } }); @@ -4389,6 +1574,2810 @@ }); }; + /* + * Remove the top menu so that we MUST use the buttons to leave the editor. + */ + $('#jqxMenu').jqxMenu('destroy'); + console.log("record:" + my_record + " return:" + my_return + " theme:" + theme); + $("#jqxLoader").jqxLoader({width:250,height:150,isModal:true,text:"Laden product ...",theme:theme}); + dataAdapter.dataBind(); + + /* + * Generic functions + */ + function calcSupplies() { + if (dataRecord.inventory_reduced > 6) { + $("#ok_pmpt").hide(); + return; + } + if (ok_fermentables && ok_hops && ok_miscs && ok_yeasts && ok_waters) + $("#ok_supplies").html(""); + else + $("#ok_supplies").html(""); + } + + function calcPercentages() { + + console.log("calcPercentages()"); + var tw = 0, rowdata, percentage, rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + if (rowscount > 1) { + for (i = 0; i < rowscount; i++) { + rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + if (rowdata.f_added < 4) + tw += Round(rowdata.f_amount, 3); + }; + tw = Round(tw, 3); + + for (i = 0; i < rowscount; i++) { + rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + if (rowdata.f_added < 4) { + percentage = Round(rowdata.f_amount / tw * 100, 1); + $("#fermentableGrid").jqxGrid('setcellvalue', i, "f_percentage", percentage); + } else { + $("#fermentableGrid").jqxGrid('setcellvalue', i, "f_percentage", 0); + } + }; + } else { + $("#fermentableGrid").jqxGrid('setcellvalue', 0, "f_percentage", 100); + } + } + + /* + * All calculations that depend on changes in the fermentables, + * volumes and equipments. + */ + function calcFermentables() { + + var sugarsf = 0, // fermentable sugars mash + boil + sugarsm = 0, // fermentable sugars in mash + vol = 0, // Volume sugars after boil + addedS = 0, // Added sugars after boil + addedmass = 0, // Added mass after boil + mvol = 0, // mash volume + colort = 0, // Colors srm * vol totals + colorh = 0, // Colors ebc * vol * kt + colorn = 0, // Colors ebc * pt * pct + my_100 = false, + mashtime = 0, // Total mash time + mashtemp = 0, // Average mash temperature + bv = 0.925, // Bierverlies rendement + sr = 0.95, // Mash en spoel rendement + lintner = 0, // Total recipe lintner + i, row, rows, org, timem, aboil_volume, spoelw, ogx, topw, s = 0, d, v, x, + sug, alc, pt, cw, color, scolor, fig; + + /* Init global variables */ + psugar = 0; + pcara = 0; + mashkg = 0; + ok_fermentables = 1; // All is in stock. + ok_yeasts = 1; + + if ((rows = $('#mashGrid').jqxGrid('getrows'))){ + for (i = 0; i 5) + mashtime-=5;//Correct last ramp > 75 + mashtemp=Round(mashtemp/mashtime,2); + } + + if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) { + return; // grid not yet loaded. + } + + for (i = 0; i < rows.length; i++) { + row = rows[i]; + if (row.f_adjust_to_total_100) + my_100 = true; + if (row.f_type == 1 && row.f_added < 4) // Sugar + psugar += row.f_percentage; + if (row.f_graintype == 2 && row.f_added < 4) // Crystal + pcara += row.f_percentage; + d = row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100); + if (row.f_added == 0) { // Mash + if (mvol > 0) { // Only if mash already known. + mvol += row.f_amount * row.f_moisture / 100; + s += d; + } + d = parseFloat(dataRecord.efficiency) / 100 * d; + sugarsm += d; + mashkg += parseFloat(row.f_amount); + } + if (row.f_added == 0 || row.f_added == 1) // Mash or Boil + sugarsf += d; + if (row.f_added == 2 || row.f_added == 3) { // Fermentation or lagering + x = (row.f_yield / 100) * (1 - row.f_moisture / 100); + addedS += row.f_amount * x; + addedmass += row.f_amount; + vol += (x * sugardensity + (1 - x) * 1) * row.f_amount; + } + if (row.f_added < 4) { + colort += row.f_amount * ebc_to_srm(row.f_color); + colorh += row.f_amount * row.f_color * get_kt(row.f_color); + colorn += (row.f_percentage / 100) * row.f_color; // For 8.6 Pt wort. + } + if (fermentableInit) { + if (row.f_added == 4) { + $("#bottle_priming_total").val(row.f_amount * 1000); // Prevent clearing + $("#bottle_priming_sugar").jqxDropDownList('selectItem', row.f_name); + } + if (row.f_added == 5) { + $("#keg_priming_total").val(row.f_amount * 1000); + $("#keg_priming_sugar").jqxDropDownList('selectItem', row.f_name); + } + } + // Check supplies. + if ((((dataRecord.inventory_reduced <= 2) && (row.f_added <= 1)) || // Mash or boil + ((dataRecord.inventory_reduced <= 3) && (row.f_added == 2)) || // Primary + ((dataRecord.inventory_reduced <= 5) && (row.f_added == 3)) || // Secondary or Tertiary + ((dataRecord.inventory_reduced <= 6) && (row.f_added == 4)) || // Bottle + ((dataRecord.inventory_reduced <= 6) && (row.f_added == 5))) && row.f_inventory < row.f_amount) { + ok_fermentables = 0; + } + if (row.f_added == 0 && (row.f_type == 0 || row.f_type == 4) && row.f_color < 50) { // Mash and Grain/Adjunct and Color < 50 + lintner += row.f_diastatic_power * row.f_amount; + } + } + fermentableInit = 0; + $("#ferm_lintner").val(Math.round(parseFloat(lintner / mashkg))); + $("#mash_kg").val(mashkg); + console.log("calcFermentables() supplies:"+ok_fermentables+" moutsuiker:"+sugarsm+"/"+sugarsf); + to_100 = my_100; + if (to_100) { + $("#wf_amount").jqxNumberInput({ width: 90, readOnly: true, spinButtons: false }); + } else { + $("#wf_amount").jqxNumberInput({ width: 110, readOnly: false, spinButtons: true }); + } + + if (mvol > 0) { + v = s / sugardensity + mvol; + s = 1000 * s / (v * 10); //deg. Plato + est_mash_sg = Round(plato_to_sg(s), 5); + $('#est_mash_sg').val(est_mash_sg); + } + + // Estimate total recipe OG. + dataRecord.est_og = estimate_sg(sugarsf + addedS, parseFloat(dataRecord.batch_size)); + $('#est_og').val(dataRecord.est_og); + $('#est_og2').val(dataRecord.est_og); + org = dataRecord.est_og; + + // Estimate SG in kettle after boil + aboil_sg = estimate_sg(sugarsf, parseFloat(dataRecord.batch_size)); + $('#est_og3').val(aboil_sg); + + // Estimate SG in kettle before boil + preboil_sg = estimate_sg(sugarsm, parseFloat(dataRecord.boil_size)); + $('#est_pre_sg').val(preboil_sg); + + // Recalculate volumes. + aboil_volume = parseFloat(dataRecord.batch_size); + if (dataRecord.brew_aboil_volume > 0) + aboil_volume = dataRecord.brew_aboil_volume / 1.04; // volume @ 20 degrees + if (dataRecord.brew_fermenter_tcloss == 0) { + dataRecord.brew_fermenter_tcloss = dataRecord.eq_trub_chiller_loss; + $("#brew_fermenter_tcloss").val(dataRecord.brew_fermenter_tcloss); + } + dataRecord.brew_fermenter_volume = aboil_volume - dataRecord.brew_fermenter_tcloss + dataRecord.brew_fermenter_extrawater; + $("#brew_fermenter_volume").val(dataRecord.brew_fermenter_volume); + // Estimated needed sparge water corrected for the temperature. + spoelw = (dataRecord.boil_size - mash_infuse + (mashkg * my_grain_absorbtion) + dataRecord.eq_lauter_deadspace) * 1.03; + $("#brew_sparge_est").val(spoelw); + // Calculate SG in fermenter + ogx = dataRecord.brew_aboil_sg; + if (ogx < 1.002) + ogx = aboil_sg; + topw = dataRecord.brew_fermenter_extrawater; + + if (dataRecord.brew_fermenter_volume > 0) { + sug = sg_to_plato(ogx) * dataRecord.brew_fermenter_volume * ogx / 100; //kg of sugar in + sug += addedS; //kg + + if ((dataRecord.brew_fermenter_volume * ogx + addedmass) > 0) { + pt = 100 * sug / (dataRecord.brew_fermenter_volume * ogx + addedmass + topw); + dataRecord.brew_fermenter_sg = Round(plato_to_sg(pt),4); + $("#brew_fermenter_sg").val(dataRecord.brew_fermenter_sg); + // color + if (dataRecord.color_method == 4) { + dataRecord.brew_fermenter_color = Math.round(((pt / 8.6) * colorn) + (dataRecord.boil_time / 60)); + } else if (dataRecord.color_method == 3) { + dataRecord.brew_fermenter_color = Math.round((4.46 * bv * sr) / (aboil_volume + topw) * colorh); + } else { + cw = colort / (aboil_volume + topw) * 8.34436; + dataRecord.brew_fermenter_color = kw_to_ebc(dataRecord.color_method, cw); + } + $("#brew_fermenter_color").val(dataRecord.brew_fermenter_color); + scolor = ebc_to_color(dataRecord.brew_fermenter_color); + $("#bcolorf").show(); + document.getElementById("bcolorf").style.background = scolor; + } + } else { + // Negative volume + dataRecord.brew_fermenter_sg = dataRecord.brew_fermenter_color = 0; + $("#brew_fermenter_sg").val(0); + $("#brew_fermenter_color").val(0); + $("#bcolorf").hide(); + } + + // Color of the wort + if (dataRecord.color_method == 4) { + color = Math.round(((sg_to_plato(dataRecord.est_og) / 8.6) * colorn) + (dataRecord.boil_time / 60)); + } else if (dataRecord.color_method == 3) { // Hans Halberstadt + color = Math.round((4.46 * bv * sr) / parseFloat(dataRecord.batch_size) * colorh); + } else { + cw = colort / parseFloat(dataRecord.batch_size) * 8.34436; + color = kw_to_ebc(dataRecord.color_method, cw); + } + dataRecord.est_color = color; + $('#est_color').val(color); + $('#est_color2').val(color); + scolor = ebc_to_color(color); + document.getElementById("bcolor").style.background= scolor; + document.getElementById("bcolor2").style.background= scolor; + + // Progress bars + pmalts = mashkg / dataRecord.eq_mash_max * 100; + $("#perc_malts").jqxProgressBar('val', pmalts); + $("#perc_sugars").jqxProgressBar('val', psugar); + $("#perc_cara").jqxProgressBar('val', pcara); + calcStage(); + + // Calculate estimated svg. + svg = 0; // default. + initcells = 0; + rows = $('#yeastGrid').jqxGrid('getrows'); + for (i = 0; i < rows.length; i++) { + row = rows[i]; + if (row.y_use == 0) { // Primary + if (parseFloat(row.y_attenuation) > svg) + svg = parseFloat(row.y_attenuation); // Take the highest if multiple yeasts. + if (row.y_form == 0) + initcells += (parseFloat(row.y_cells) / 1000000000) * parseFloat(row.y_amount) * (dataRecord.starter_viability / 100); + else + initcells += (parseFloat(row.y_cells) / 1000000) * parseFloat(row.y_amount); + } + // TODO: brett in secondary ?? + if ((((dataRecord.inventory_reduced <= 3) && (row.y_use == 0)) || // Primary + ((dataRecord.inventory_reduced <= 4) && (row.y_use == 1)) || // Secondary + ((dataRecord.inventory_reduced <= 5) && (row.y_use == 2)) || // Tertiary + ((dataRecord.inventory_reduced <= 6) && (row.y_use == 3))) && // Bottle + (row.y_inventory < row.y_amount)) { + ok_yeasts = 0; + } + } + calcSupplies(); + if (svg == 0) + svg = 77; + + if ((mashkg > 0) && (mash_infuse > 0) && (mashtime > 0) && (mashtemp > 0)) { + dataRecord.est_fg = estimate_fg(psugar, pcara, mash_infuse / mashkg, mashtime, mashtemp, svg, dataRecord.est_og); + } else { + dataRecord.est_fg = estimate_fg(psugar, pcara, 0, 0, 0, svg, dataRecord.est_og); + } + $('#est_fg').val(dataRecord.est_fg); + $('#est_fg2').val(dataRecord.est_fg); + $('#est_fg3').val(dataRecord.est_fg); + fig = dataRecord.est_fg; + + dataRecord.est_abv = abvol(dataRecord.est_og, dataRecord.est_fg); + $("#est_abv").val(dataRecord.est_abv); + $("#est_abv2").val(dataRecord.est_abv); + + // Calculate the final svg if available use the real value. + if ((dataRecord.stage >= 6) && (dataRecord.fg > 0.990) && (dataRecord.fg < dataRecord.brew_fermenter_sg)) { + svg = 100 * (dataRecord.brew_fermenter_sg - dataRecord.fg) / (dataRecord.brew_fermenter_sg - 1); + org = dataRecord.brew_fermenter_sg; + fig = dataRecord.fg; + } + + $("#yeast_cells").val(initcells); + $("#need_cells").val(getNeededYeastCells()); + + // Calculate the calories in kcal/l (from brouwhulp) + alc = 1881.22 * fig * (org - fig) / (1.775 - org); + sug = 3550 * fig * (0.1808 * org + 0.8192 * fig - 1.0004); + $("#kcal").val(Math.round((alc + sug) / (12 * 0.0295735296))); + }; + + function calcMash() { + + var infused = 0, i, row; + + if (!(rows = $('#mashGrid').jqxGrid('getrows'))) + return; + if (mashkg == 0) + return; + + for (i = 0; i < rows.length; i++) { + row = $("#mashGrid").jqxGrid('getrowdata', i); + if (row.step_type == 0) // Infusion + infused += row.step_infuse_amount; + $("#mashGrid").jqxGrid('setcellvalue', i, "step_thickness", infused / mashkg); + } + } + + /* + * Change OG of recipe but keep the water volumes. + */ + function calcFermentablesFromOG(OG) { + + console.log("calcFermentablesFromOG("+OG+")"); + var amount, row, d, i, sug, tot = 0, totmass = 0, rowscount, efficiency = parseFloat($("#efficiency").jqxNumberInput('decimal')); + sug = sg_to_plato(OG) * parseFloat($("#batch_size").jqxNumberInput('decimal')) * OG / 100; //total amount of sugars in kg + rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + + for (i = 0; i < rowscount; i++) { + row = $("#fermentableGrid").jqxGrid('getrowdata', i); + if (row.f_added < 4) { + d = row.f_percentage / 100 * (row.f_yield / 100) * (1 - row.f_moisture / 100); + if (row.f_added == 0) // Mash + d = efficiency / 100 * d; + tot += d; + } + } + if (tot) + totmass = Round(sug / tot,3); + + if (totmass) { + for (i = 0; i < rowscount; i++) { + row = $("#fermentableGrid").jqxGrid('getrowdata', i); + if (row.f_added < 4) { + amount = Math.round(row.f_percentage * 10 * totmass) / 1000; + $("#fermentableGrid").jqxGrid('setcellvalue', i, "f_amount", amount); + } + } + } + }; + + function getNeededYeastCells() { + + var plato, volume, sg = dataRecord.brew_fermenter_sg; + if (sg <= 1.0001 && dataRecord.fg > 1.000) + sg = dataRecord.fg; + else if (sg <= 1.0001) + sg = dataRecord.est_og; + plato = sg_to_plato(sg); + + volume = dataRecord.brew_fermenter_volume; + if (volume <= 0) + volume = dataRecord.batch_size - dataRecord.eq_trub_chiller_loss; + + return pitchrate * volume * plato; + } + + function hopFlavourContribution(bt, vol, use, amount) { + var result; + + if (use == 1) { // 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 + } + return (result * amount * 1000) / vol; + } + + function hopAromaContribution(bt, vol, use, amount) { + var result = 0; + + if (use == 5) { // Dry hop + result = 1.33; + } else 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 == 2) { // Boil + result = 1; + } else if (use == 3) { // Aroma + result = 1.2; + } else if (use == 4) { // Whirlpool + result = 1.2; + } + return (result * amount * 1000) / vol; + } + + function calcIBUs() { + var total_ibus = 0, ferm_ibus = 0, rows = {}, i, row; + hop_aroma = hop_flavour = 0; + if (!(rows = $('#hopGrid').jqxGrid('getrows'))) { + return; + } + ok_hops = 1; + for (i = 0; i < rows.length; i++) { + 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); + ferm_ibus += toIBU(row.h_useat, row.h_form, preboil_sg, + parseFloat(dataRecord.brew_fermenter_volume) + parseFloat(dataRecord.brew_fermenter_tcloss), + 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)); + if ((((dataRecord.inventory_reduced <= 2) && (row.h_useat <= 4)) || // Mash, FW, Boil, Aroma, Whirlpool + ((dataRecord.inventory_reduced <= 6) && (row.h_useat == 5))) && // Dry-hop + (row.h_inventory < row.h_amount)) + ok_hops = 0; + } + total_ibus = Math.round(total_ibus * 10) / 10; + ferm_ibus = Math.round(ferm_ibus * 10) / 10; + hop_flavour = Math.round(hop_flavour * 1000 / 5) / 10; + hop_aroma = Math.round(hop_aroma * 1000 / 6) / 10; + if (hop_flavour > 100) + hop_flavour = 100; + if (hop_aroma > 100) + hop_aroma = 100; + console.log("calcIBUs(): " + total_ibus + " flavour: " + hop_flavour + " aroma: " + hop_aroma+" fermenter:"+ferm_ibus+" supplies:"+ok_hops); + dataRecord.est_ibu = total_ibus; + $('#est_ibu').val(total_ibus); + $('#est_ibu2').val(total_ibus); + $("#hop_flavour").jqxProgressBar('val', hop_flavour); + $("#hop_aroma").jqxProgressBar('val', hop_aroma); + $("#brew_fermenter_ibu").val(ferm_ibus); + calcStage(); + calcSupplies(); + }; + + /* + * http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/ + * + * stype: 0=stirred, 1=shaken, 2=simple + * totcells: initial cells + * egrams: gram extract + */ + function getGrowthRate(stype, totcells, egrams){ + + /* Cells per grams extract (B/g) */ + var cpe = totcells / egrams; + + if (cpe > 3.5) + return 0; // no growth + if (stype == 2) + return 0.4; // simple starter + if (stype == 1) + return 0.62; // shaken starter + if (cpe <= 1.4) // stirred starter + return 1.4; + return 2.33 - (.67 * cpe ); + }; + + function calcStep(svol, stype, start) { + + var gperpoint = 2.72715, //number of grams of extract per point of starter gravity per liter + prate = start/svol * 1000, + irate = Round(prate,1), + egrams = (dataRecord.starter_sg - 1) * svol * gperpoint; + grate = getGrowthRate(stype, start, egrams), + ncells = Round(egrams * grate, 1), + totcells = parseFloat(ncells) + start; + + console.log("svol:"+svol+" start:"+start+" irate:"+irate+" egrams:"+egrams+" grate:"+grate+" ncells:"+ncells); + return { + svol: svol, + irate: irate, + prate: Round(prate,1), + ncells: ncells, + totcells: totcells, + growf: Round(ncells/start, 2) + }; + } + + /* + * Calculate all starter steps. + * stype: final starter type: 0 = stirred, 1 = shaked, 2 = simple. + * start: initial cells in billions + * needed: needed cells in billions + * + * result: all values updated. + */ + function calcSteps(stype, start, needed) { + + var uvols = [ 20, 40, 60, 80, 100, 150, 200, 250, 375, 500, 625, 750, 875, 1000, 1250, 1500, 2000, 2500, 3000, 4000, 5000 ], + mvols = uvols.length, svol = 0, lasti = 0, result = {}, i; + + /* + * If no values are set, auto calculate the starter. + */ + if ((parseFloat($("#prop1_volume").jqxNumberInput('decimal')) + parseFloat($("#prop2_volume").jqxNumberInput('decimal')) + + parseFloat($("#prop3_volume").jqxNumberInput('decimal')) + parseFloat($("#prop4_volume").jqxNumberInput('decimal'))) == 0) { + // clear by default + for (i = 1; i < 5; i++) { + $("#prop"+i+"_type").hide(); + $("#r"+i+"_pmpt").show(); + $("#prop"+i+"_type").val(stype); + $("#prop"+i+"_volume").hide(); + $("#prop"+i+"_volume").val(0); + $("#prop"+i+"_irate").hide(); + $("#prop"+i+"_ncells").hide(); + $("#prop"+i+"_tcells").hide(); + $("#prop"+i+"_growf").hide(); + } + if (start > needed) { + return; // no starter needed + } + $("#prop1_type").show(); + $("#r1_pmpt").hide(); + $("#prop1_volume").show(); + $("#prop1_irate").show(); + $("#prop1_ncells").show(); + $("#prop1_tcells").show(); + $("#prop1_growf").show(); + for (i = lasti; i <= mvols; i++) { + lasti = i; + svol = uvols[lasti]; + result = calcStep(svol, stype, start); + if (result.irate < 25) { + // inocculation rate too low, backup one step and break out. + lasti = i - 1; + svol = uvols[lasti]; + result = calcStep(svol, stype, start); + break; + } + if (result.totcells > needed || i == mvols) { // hit the target or loops done + break; + } + } + $("#prop1_volume").val(result.svol / 1000); // to liters + $("#prop1_irate").val(result.prate); + $("#prop1_ncells").val(result.ncells); + $("#prop1_tcells").val(result.totcells); + $("#prop1_growf").val(result.growf); + if (result.totcells > needed) + return; // hit the target + + // second stage + $("#r2_pmpt").hide(); + $("#prop2_type").val(stype); + $("#prop2_type").show(); + $("#prop2_volume").show(); + $("#prop2_irate").show(); + $("#prop2_ncells").show(); + $("#prop2_tcells").show(); + $("#prop2_growf").show(); + for (i = lasti; i <= mvols; i++) { + lasti = i; + svol = uvols[lasti]; + result = calcStep(svol, stype, $("#prop1_tcells").val()); + if (result.irate < 25) { + lasti = i - 1; + svol = uvols[lasti]; + result = calcStep(svol, stype, $("#prop1_tcells").val()); + break; + } + if (result.totcells > needed || i == mvols) { // hit the target or loops done + break; + } + } + $("#prop2_volume").val(result.svol / 1000); // to liters + $("#prop2_irate").val(result.prate); + $("#prop2_ncells").val(result.ncells); + $("#prop2_tcells").val(result.totcells); + $("#prop2_growf").val(result.growf); + if (result.totcells > needed) + return; // hit the target + + // third stage + $("#r3_pmpt").hide(); + $("#prop3_type").val(stype); + $("#prop3_type").show(); + $("#prop3_volume").show(); + $("#prop3_irate").show(); + $("#prop3_ncells").show(); + $("#prop3_tcells").show(); + $("#prop3_growf").show(); + for (i = lasti; i <= mvols; i++) { + lasti = i; + svol = uvols[lasti]; + result = calcStep(svol, stype, $("#prop2_tcells").val()); + if (result.irate < 25) { + lasti = i - 1; + svol = uvols[lasti]; + result = calcStep(svol, stype, $("#prop2_tcells").val()); + break; + } + if (result.totcells > needed || i == mvols) { // hit the target or loops done + break; + } + } + $("#prop3_volume").val(result.svol / 1000); // to liters + $("#prop3_irate").val(result.prate); + $("#prop3_ncells").val(result.ncells); + $("#prop3_tcells").val(result.totcells); + $("#prop3_growf").val(result.growf); + if (result.totcells > needed) + return; // hit the target + + // fourth stage + $("#r4_pmpt").hide(); + $("#prop4_type").val(stype); + $("#prop4_type").show(); + $("#prop4_volume").show(); + $("#prop4_irate").show(); + $("#prop4_ncells").show(); + $("#prop4_tcells").show(); + $("#prop4_growf").show(); + for (i = lasti; i <= mvols; i++) { + lasti = i; + svol = uvols[lasti]; + result = calcStep(svol, stype, $("#prop3_tcells").val()); + if (result.totcells > needed || i == mvols) { // hit the target or loops done + $("#prop4_volume").val(result.svol / 1000); // to liters + $("#prop4_irate").val(result.prate); + $("#prop4_ncells").val(result.ncells); + $("#prop4_tcells").val(result.totcells); + $("#prop4_growf").val(result.growf); + return; + } + } + } else { + // recalculate + if (dataRecord.prop1_volume > 0) { + $("#r1_pmpt").hide(); + $("#prop1_type").show(); + $("#prop1_volume").show(); + $("#prop1_irate").show(); + $("#prop1_ncells").show(); + $("#prop1_tcells").show(); + $("#prop1_growf").show(); + result = calcStep($("#prop1_volume").val() * 1000, dataRecord.prop1_type, start); + $("#prop1_irate").val(result.prate); + $("#prop1_ncells").val(result.ncells); + $("#prop1_tcells").val(result.totcells); + $("#prop1_growf").val(result.growf); + } + if (dataRecord.prop2_volume > 0) { + $("#r2_pmpt").hide(); + $("#prop2_type").show(); + $("#prop2_volume").show(); + $("#prop2_irate").show(); + $("#prop2_ncells").show(); + $("#prop2_tcells").show(); + $("#prop2_growf").show(); + result = calcStep($("#prop2_volume").val() * 1000, dataRecord.prop2_type, $("#prop1_tcells").val()); + $("#prop2_irate").val(result.prate); + $("#prop2_ncells").val(result.ncells); + $("#prop2_tcells").val(result.totcells); + $("#prop2_growf").val(result.growf); + } + if (dataRecord.prop3_volume > 0) { + $("#r3_pmpt").hide(); + $("#prop3_type").show(); + $("#prop3_volume").show(); + $("#prop3_irate").show(); + $("#prop3_ncells").show(); + $("#prop3_tcells").show(); + $("#prop3_growf").show(); + result = calcStep($("#prop3_volume").val() * 1000, dataRecord.prop3_type, $("#prop2_tcells").val()); + $("#prop3_irate").val(result.prate); + $("#prop3_ncells").val(result.ncells); + $("#prop3_tcells").val(result.totcells); + $("#prop3_growf").val(result.growf); + } + if (dataRecord.prop4_volume > 0) { + $("#r4_pmpt").hide(); + $("#prop4_type").show(); + $("#prop4_volume").show(); + $("#prop4_irate").show(); + $("#prop4_ncells").show(); + $("#prop4_tcells").show(); + $("#prop4_growf").show(); + result = calcStep($("#prop4_volume").val() * 1000, dataRecord.prop4_type, $("#prop3_tcells").val()); + $("#prop4_irate").val(result.prate); + $("#prop4_ncells").val(result.ncells); + $("#prop4_tcells").val(result.totcells); + $("#prop4_growf").val(result.growf); + } + + } + } + + function calcYeast() { + + // Calculate needed cells. + var plato, volume, rows, rowscount, row, i, needed, use_cells, + sg = dataRecord.brew_fermenter_sg; + if (sg <= 1.0001 && dataRecord.fg > 1.000) + sg = dataRecord.fg; + else if (sg <= 1.0001) + sg = dataRecord.est_og; + plato = sg_to_plato(sg); + + volume = dataRecord.brew_fermenter_volume; + if (volume > 0) { + if (dataRecord.brew_fermenter_extrawater > 0) + volume += dataRecord.brew_fermenter_extrawater; + } else { + volume = dataRecord.batch_size - dataRecord.eq_trub_chiller_loss; + } + + // Also in calcFermentables() + $("#yeast_cells").val(initcells); + + if (!(rows = $('#yeastGrid').jqxGrid('getrows'))) { + return; // grid not yet loaded. + } + rowscount = $("#yeastGrid").jqxGrid('getdatainformation').rowscount; + if (rowscount == 0) + return; // no yeast in recipe + + for (i = 0; i < rowscount; i++) { + row = $("#yeastGrid").jqxGrid('getrowdata', i); + if (row.y_use == 0) { // primary + // pitchrate see https://www.brewersfriend.com/yeast-pitch-rate-and-starter-calculator/ + // and http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/ + pitchrate = 0.75; + if (dataRecord.est_og > 1.060) + pitchrate = 1.0; +// if (dataRecord.est_og > 1.076) +// pitchrate = 1.25; // Wyeast labs. http://www.wyeastlab.com/hb_pitchrates.cfm + if (row.y_type == 0) // lager yeast + pitchrate *= 2; + + if (row.y_form == 1) { // dry yeast + } else { // possible starter needed + } + } + } + needed = pitchrate * volume * plato; + console.log("calcYeast() pitchrate:"+pitchrate+" start:"+initcells+" needed:"+needed+" volume:"+volume); + $("#need_cells").val(needed); + use_cells = initcells; + + if (dataRecord.starter_enable) { + calcSteps(dataRecord.starter_type, initcells, needed); + + for (i = 1; i < 5; i++) { + $("#r"+i+"_irate").html(""); + $("#r"+i+"_growf").html(""); + $("#r"+i+"_tcells").html(""); + if (parseFloat($("#prop"+i+"_volume").val()) > 0) { + if ((parseFloat($("#prop"+i+"_irate").val()) < 25) || (parseFloat($("#prop"+i+"_irate").val()) > 100)) { + $("#r"+i+"_irate").html(""); + } else { + $("#r"+i+"_irate").html(""); + } + if (parseFloat($("#prop"+i+"_growf").val()) < 1) + $("#r"+i+"_growf").html(""); + if (($("#prop"+i+"_type").val() > 0) && (parseFloat($("#prop"+i+"_growf").val()) > 3)) + $("#r"+i+"_growf").html(""); + if (parseFloat($("#prop"+i+"_tcells").val()) > needed) + $("#r"+i+"_tcells").html(""); + use_cells = parseFloat($("#prop"+i+"_tcells").val()); + } else { + $("#r"+i+"_irate").html(""); + } + } + } + $("#plato_cells").val(parseFloat(use_cells / (volume * plato) )); + }; + + function adjustHops(factor) { + + console.log("adjustHops("+factor+")"); + var row, i, amount, rowscount = $("#hopGrid").jqxGrid('getdatainformation').rowscount; + if (rowscount == 0) + return; + for (i = 0; i < rowscount; i++) { + row = $("#hopGrid").jqxGrid('getrowdata', i); + amount = row.h_amount * factor; + $("#hopGrid").jqxGrid('setcellvalue', i, "h_amount", amount); + } + }; + + function calcMiscs() { + + ok_miscs = 1; + var row, i, rowscount = $("#miscGrid").jqxGrid('getdatainformation').rowscount; + if (rowscount == 0) + return; + for (i = 0; i < rowscount; i++) { + row = $("#miscGrid").jqxGrid('getrowdata', i); + if ((((dataRecord.inventory_reduced <= 2) && (row.m_use_use <= 2)) || // Starter, Mash, Boil + ((dataRecord.inventory_reduced <= 3) && (row.m_use_use == 3)) || // Primary + ((dataRecord.inventory_reduced <= 5) && (row.m_use_use == 4)) || // Secondary, Teriary + ((dataRecord.inventory_reduced <= 6) && (row.m_use_use == 5))) && // Bottle + (row.m_inventory < row.m_amount)) { + ok_miscs = 0; + } + } + calcSupplies(); + }; + + function adjustMiscs(factor) { + + console.log("adjustMiscs("+factor+")"); + var row, i, amount, rowscount = $("#miscGrid").jqxGrid('getdatainformation').rowscount; + if (rowscount == 0) + return; + for (i = 0; i < rowscount; i++) { + row = $("#miscGrid").jqxGrid('getrowdata', i); + amount = row.m_amount * factor; + $("#miscGrid").jqxGrid('setcellvalue', i, "m_amount", amount); + switch (row.m_name) { + case 'CaCl2': $("#wa_cacl2").val(row.m_amount * 1000); + break; + case 'CaSO4': $("#wa_caso4").val(row.m_amount * 1000); + break; + case 'MgSO4': $("#wa_mgso4").val(row.m_amount * 1000); + break; + case 'NaCl': $("#wa_nacl").val(row.m_amount * 1000); + break; + case 'Melkzuur': + case 'Zoutzuur': + case 'Fosforzuur': + case 'Zwavelzuur': $("#wa_acid").val(row.m_amount * 1000); + break; + case 'NaHCO3': + case 'Na2CO3': + case 'CaCO3': + case 'Ca(OH)2': $("#wa_base").val(row.m_amount * 1000); + break; + } + } + }; + + function adjustYeasts(factor) { + + console.log("adjustYeasts("+factor+")"); + var row, i, amount, rowscount = $("#yeastGrid").jqxGrid('getdatainformation').rowscount; + if (rowscount == 0) + return; + for (i = 0; i < rowscount; i++) { + row = $("#yeastGrid").jqxGrid('getrowdata', i); + if (row.y_form == 1) { // Only adjust dry yeast + amount = row.y_amount * factor; + $("#yeastGrid").jqxGrid('setcellvalue', i, "y_amount", amount); + } + } + calcYeast(); + }; + + function adjustWaters(factor) { + + console.log("adjustWaters("+factor+")"); + var amount, row, i, rowscount = $("#mashGrid").jqxGrid('getdatainformation').rowscount; + if (rowscount == 0) + return; + mash_infuse = 0; + for (i = 0; i < rowscount; i++) { + row = $("#mashGrid").jqxGrid('getrowdata', i); + if (row.step_type == 0) { // Infusion + amount = Round(row.step_infuse_amount * factor, 1); + $("#mashGrid").jqxGrid('setcellvalue', i, "step_infuse_amount", amount); + mash_infuse += amount; + } + } + if (dataRecord.w2_amount == 0) { + dataRecord.w1_amount = mash_infuse; + $("#w1_amount").val(mash_infuse); + } else { + dataRecord.w1_amount = (dataRecord.w1_amount / (dataRecord.w1_amount + dataRecord.w2_amount)) * mash_infuse; + dataRecord.w2_amount = (dataRecord.w2_amount / (dataRecord.w1_amount + dataRecord.w2_amount)) * mash_infuse; + $("#w1_amount").val(dataRecord.w1_amount); + $("#w2_amount").val(dataRecord.w2_amount); + } + $('#wg_amount').val(mash_infuse); + }; + + function calcMashEfficiency() { + var c, m; + if (parseFloat($("#brew_mash_sg").jqxNumberInput('decimal')) < 1.002) + return; + c = sg_to_plato(est_mash_sg); + m = sg_to_plato(parseFloat($("#brew_mash_sg").jqxNumberInput('decimal'))); + if (c > 0.5) + $("#brew_mash_efficiency").val(100 * m / c); + else + $("#brew_mash_efficiency").val(0); + }; + + function calcEfficiencyBeforeBoil() { + var m = 0, rows = {}, i, row, tot, result = 0; + if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) { + return; // grid not yet loaded. + } + for (i = 0; i < rows.length; i++) { + row = rows[i]; + if (row.f_added == 0) { // Mash + m += row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100); + } + } + tot = sg_to_plato(dataRecord.brew_preboil_sg) * (dataRecord.brew_preboil_volume / 1.04) * dataRecord.brew_preboil_sg * 10 / 1000; + if (m > 0) + result = Round((tot / m * 100), 1); + if (result < 0) + result = 0; + $("#brew_preboil_efficiency").val(result); + } + + function calcEfficiencyAfterBoil() { + var m = 0, // Sugars added at mash + b = 0, // Sugars added at boil + rows = {}, i, row, tot, result = 0; + if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) { + return; // grid not yet loaded. + } + for (i = 0; i < rows.length; i++) { + row = rows[i]; + if (row.f_added == 0) { // Mash + m += row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100); + } else if (row.f_added == 1) { // Boil + b += row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100); + } + } + tot = sg_to_plato(dataRecord.brew_aboil_sg) * (dataRecord.brew_aboil_volume / 1.04) * dataRecord.brew_aboil_sg * 10 / 1000; + tot -= b; // total sugars in wort minus added sugars. + if (m > 0) + result = Round((tot / m * 100), 1); + if (result < 0) + result = 0; + dataRecord.brew_aboil_efficiency = result; + $("#brew_aboil_efficiency").val(result); + + } + + function GetBUGU() { + var gu = (dataRecord.est_og - 1) * 1000; + if (gu > 0) + return dataRecord.est_ibu / gu; + else + return 0.5; + } + + function GetOptClSO4ratio() { + var BUGU = GetBUGU(); + return (-1.2 * BUGU + 1.4); + } + + function setWaterAgent(name, amount) { + var row, i, id, found = false, miscs, rows = $('#miscGrid').jqxGrid('getrows'); + if (amount == 0) { + for (i = 0; i < rows.length; i++) { + row = rows[i]; + if (row.m_name == name) { + id = $("#miscGrid").jqxGrid('getrowid', i); + $("#miscGrid").jqxGrid('deleterow', id); + } + } + } else { + for (i = 0; i < rows.length; i++) { + row = rows[i]; + if (row.m_name == name) { + found = true; + $("#miscGrid").jqxGrid('setcellvalue', i, 'm_amount', amount / 1000); + break; + } + } + if (! found) { + miscs = new $.jqx.dataAdapter(miscInvSource, { + loadComplete: function () { + var record, i, row = {}, records = miscs.records; + for (i = 0; i < records.length; i++) { + record = records[i]; + if (record.name == name) { + row["m_name"] = record.name; + row["m_amount"] = amount / 1000; + row["m_cost"] = record.cost; + row["m_type"] = record.type; + row["m_use_use"] = record.use_use; + row["m_time"] = 0; + row["m_amount_is_weight"] = record.amount_is_weight; + row["m_inventory"] = record.inventory; + row["m_avail"] = 1; + $("#miscGrid").jqxGrid('addrow', null, row); + } + } + } + }); + miscs.dataBind(); + return; + } + } + } + + function setRangeIndicator(ion, rangeCode) { + if ((rangeCode == "laag") || (rangeCode == "hoog")) + $("#wr_"+ion).html(""+rangeCode + ""); + else + $("#wr_"+ion).html(""); + } + + function mix(v1, v2, c1, c2) { + if ((v1 + v2) > 0) { + return ((v1 * c1) + (v2 * c2)) / (v1 + v2); + } + return 0; + } + + // mg/l as CaCO3 + function ResidualAlkalinity(total_alkalinity, calcium, magnesium) { + return total_alkalinity - (calcium / 1.4 + magnesium / 1.7); + } + + function PartCO3(pH) { + var H = Math.pow(10, -pH); + return 100 * Ka1 * Ka2 / (H*H + H * Ka1 + Ka1 * Ka2); + } + + function PartHCO3(pH) { + var H = Math.pow(10, -pH); + return 100 * Ka1 * H / (H*H + H * Ka1 + Ka1 * Ka2); + } + + function Charge(pH) { + return (-2 * PartCO3(pH) - PartHCO3(pH)); + } + + //Z alkalinity is the amount of acid (in mEq/l) needed to bring water to the target pH (Z pH) + function ZAlkalinity(pHZ) { + var C43 = Charge(4.3), + Cw = Charge(parseFloat($("#wg_ph").jqxNumberInput('decimal'))), + Cz = Charge(pHZ), + DeltaCNaught = -C43+Cw, + CT = parseFloat($("#wg_total_alkalinity").jqxNumberInput('decimal')) / 50 / DeltaCNaught, + DeltaCZ = -Cz+Cw; + return CT * DeltaCZ; + } + + //Z Residual alkalinity is the amount of acid (in mEq/l) needed to bring the water in the mash to the target pH (Z pH) + function ZRA(pHZ) { + + var Magn, Z, Calc = parseFloat($("#wg_calcium").jqxNumberInput('decimal')) / (MMCa / 2); + Magn = parseFloat($("#wg_magnesium").jqxNumberInput('decimal')) / (MMMg / 2); + Z = ZAlkalinity(pHZ); + return Z - (Calc / 3.5 + Magn / 7); + } + + function ProtonDeficit(pHZ) { + + var rows, i, C1, ebc, x, Result = ZRA(pHZ) * parseFloat($("#wg_amount").jqxNumberInput('decimal')); + // proton deficit for the grist + rows = $('#fermentableGrid').jqxGrid('getrows'); + for (i = 0; i < rows.length; i++) { + row = rows[i]; + if (row.f_added == 0 && row.f_graintype != 6) { // Added == Mash && graintype != No Malt + // Check if acid is required + C1 = 0; + if ((row.f_di_ph != 5.7) && ((row.f_acid_to_ph_57 < - 0.1) || (row.f_acid_to_ph_57 > 0.1))) { + C1 = row.f_acid_to_ph_57 / (row.f_di_ph - 5.7); + } else { + // If the acid_to_ph_5.7 is unknown from the maltster, guess the required acid. + ebc = row.f_color; + switch (row.f_graintype) { + case 0: // Base, Special, Kilned + case 3: + case 5: C1 = 0.014 * ebc - 34.192; + break; + case 2: C1 = -0.0597 * ebc - 32.457; // Crystal + break; + case 1: C1 = 0.0107 * ebc - 54.768; // Roast + break; + case 4: C1 = -149; // Sour malt + break; + } + } + x = C1 * (pHZ - row.f_di_ph); // AcidRequired(ZpH) + Result += x * row.f_amount; + } + } + return Result; + } + + function MashpH() { + var n = 0, pH = 5.4, deltapH = 0.001, deltapd = 0.1, pd = ProtonDeficit(pH); + while (((pd < -deltapd) || (pd > deltapd)) && (n < 2000)) { + n++; + if (pd < -deltapd) + pH -= deltapH; + else if (pd > deltapd) + pH += deltapH; + pd = ProtonDeficit(pH); + } + console.log("MashpH() n: "+n+" pH: "+pH); + return pH; + } + + function GetAcidSpecs(AT) { + switch(AT) { + case 0: return { // Melkzuur + pK1: 3.86, + pK2: 20, + pK3: 20, + MolWt: 90.08, + AcidSG: 1214, // 1214 1209 + AcidPrc: 0.88 // 0.88 0.80 + }; + case 1: return { // Zoutzuur + pK1: -7, + pK2: 20, + pK3: 20, + MolWt: 36.46, + AcidSG: 1142, + AcidPrc: 0.28 + }; + case 2: return { // Fosforzuur + pK1: 2.12, + pK2: 7.20, + pK3: 12.44, + MolWt: 98.00, + AcidSG: 1170, + AcidPrc: 0.25 + }; + case 3: return { // Zwavelzuur + pK1: -1, + pK2: 1.92, + pK3: 20, + MolWt: 98.07, + AcidSG: 1700, + AcidPrc: 0.93 + }; + } + } + + function calcWater() { + + console.log("calcWater()"); + var liters = 0, + calcium = 0, + magnesium = 0, + sodium = 0, + total_alkalinity = 0, + bicarbonate = 0, + chloride = 0, + sulfate = 0, + ph = 0, + RA = 0, + frac = 0, + TpH = 0, + protonDeficit = 0, + AT, BT, result, pK1, pK2, pK3, MolWt, AcidSG, AcidPrc, + r1d, r2d, f1d, f2d, f3d, + deltapH, deltapd, pd, n, + piCLSO4_low, piCLSO4_high, Res, + wg_calcium, wg_sodium, wg_total_alkalinity, wg_chloride, wg_sulfate, wg_bicarbonate; + + if (dataRecord.w1_name == "") { + return; + } + + // If there is a dillute water source, mix the waters. + if (dataRecord.w2_name != "") { + liters = dataRecord.w1_amount + dataRecord.w2_amount; + calcium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_calcium, dataRecord.w2_calcium); + magnesium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_magnesium, dataRecord.w2_magnesium); + sodium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sodium, dataRecord.w2_sodium); + chloride = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_chloride, dataRecord.w2_chloride); + sulfate = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sulfate, dataRecord.w2_sulfate); + total_alkalinity = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_total_alkalinity, dataRecord.w2_total_alkalinity); + ph = -Math.log10(((Math.pow(10, -dataRecord.w1_ph) * dataRecord.w1_amount) + (Math.pow(10, -dataRecord.w2_ph) * dataRecord.w2_amount)) / liters); + } else { + liters = dataRecord.w1_amount; + calcium = dataRecord.w1_calcium; + magnesium = dataRecord.w1_magnesium; + sodium = dataRecord.w1_sodium; + chloride = dataRecord.w1_chloride; + sulfate = dataRecord.w1_sulfate; + total_alkalinity = dataRecord.w1_total_alkalinity; + ph = dataRecord.w1_ph; + } + $('#wg_amount').val(liters); + wg_calcium = calcium; + $('#wg_calcium').val(Math.round(calcium * 10) / 10); + //var wg_magnesium = magnesium; + $('#wg_magnesium').val(Math.round(magnesium * 10) / 10); + wg_sodium = sodium; + $('#wg_sodium').val(Math.round(sodium * 10) / 10); + wg_total_alkalinity = total_alkalinity; + $('#wg_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10); + wg_chloride = chloride; + $('#wg_chloride').val(Math.round(chloride * 10) / 10); + wg_sulfate = sulfate; + $('#wg_sulfate').val(Math.round(sulfate * 10) / 10); + // Note: brouwhulp has the malts included here in the result. + //var wg_ph = ph; + $('#wg_ph').val(Round(ph,1)); + $('#wb_ph').val(Round(MashpH(), 1)); + $('#est_mash_ph').val(Round(MashpH(), 1)); + bicarbonate = total_alkalinity * 1.22; + wg_bicarbonate = bicarbonate; + + // Noot: de volgende berekeningen geven bijna gelijke resultaten in Brun'water. + // Calculate Ca + RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + + parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4; + calcium += 1000 * RA / liters; + + // Calculate Mg + RA = parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMMg / MMMgSO4; + magnesium += 1000 * RA / liters; + + // Calculate Na + RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; + sodium += 1000 * RA / liters; + + // Calculate SO4 + RA = parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + + parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMSO4 / MMMgSO4; + sulfate += 1000 * RA / liters; + + // Calculate Cl + RA = 2 * parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCl / MMCaCl2 + + parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMCl / MMNaCl; + chloride += 1000 * RA / liters; + // Einde noot. + + if ($("#wa_acid_name").val() < 0 || $("#wa_acid_name").val() > 3) { + $("#wa_acid_name").val(0); + dataRecord.wa_acid_name = 0; + } + if (last_acid == '') + last_acid = AcidTypeData[$("#wa_acid_name").val()].nl; + + if ($("#wa_base_name").val() < 0 || $("#wa_base_name").val() > 3) { + $("#wa_base_name").val(0); + dataRecord.wa_base_name = 0; + } + if (last_base == '') + last_base = BaseTypeData[$("#wa_base_name").val()].nl; + + AT = dataRecord.wa_acid_name; + BT = dataRecord.wa_base_name; + + result = GetAcidSpecs(AT); + pK1 = result.pK1; + pK2 = result.pK2; + pK3 = result.pK3; + MolWt = result.MolWt; + AcidSG = result.AcidSG; + AcidPrc = result.AcidPrc; + + if (dataRecord.calc_acid) { + TpH = parseFloat(dataRecord.mash_ph); + protonDeficit = ProtonDeficit(TpH); + console.log("calc_acid tgt: "+TpH+" protonDeficit: "+protonDeficit); + if (protonDeficit > 0) { // Add acid + $("#wa_base").val(0); + setWaterAgent(last_base, 0); + frac = CalcFrac(TpH, pK1, pK2, pK3); + Acid = protonDeficit / frac; + Acid *= MolWt; // mg + Acidmg = Acid; + Acid = Acid / AcidSG; // ml + + if (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) == 0) + $("#wa_acid_perc").val(AcidPrc); + Acid = Acid * AcidPrc / (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) / 100); // ml + console.log("Final ml: "+Acid); + $("#wa_acid").val(Round(Acid, 2)); + setWaterAgent(AcidTypeData[AT].nl, Round(Acid, 2)); + + bicarbonate = bicarbonate - protonDeficit * frac / liters; + total_alkalinity = bicarbonate * 50 / 61; + } else if (protonDeficit < 0) { //Add base + $("#wa_acid").val(0); + setWaterAgent(last_acid, 0); + r1d = Math.pow(10, (TpH - 6.38)); + r2d = Math.pow(10, (TpH - 10.38)); + f1d = 1 / (1 + r1d + r1d * r2d); + f2d = f1d * r1d; + f3d = f2d * r2d; + switch (BT) { + case 0: RA = -protonDeficit / (f1d - f3d); // Sodiumbicarbonate, mmol totaal + RA = RA * MMNaHCO3/1000; //gram + $("#wa_base").val(Round(RA, 2)); + setWaterAgent('NaHCO3', Round(RA, 2)); + if (liters > 0) { + // Na + RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; + RA = 1000 * RA / liters; + sodium = wg_sodium + RA; + // HCO3 + RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3; + RA = 1000 * RA / liters; + bicarbonate = wg_bicarbonate + RA; + total_alkalinity = bicarbonate * 50 / 61; + RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); + } + break; + case 1: RA = -protonDeficit / (2 * f1d + f2d); // Sodiumcarbonate, mmol totaal + RA = RA * MMNa2CO3/1000; //gram + $("#wa_base").val(Round(RA, 2)); + setWaterAgent('Na2CO3', Round(RA, 2)); + if (liters > 0) { + RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + + parseFloat($("#wa_base").jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3; + RA = 1000 * RA / liters; + sodium = wg_sodium + RA; + // HCO3 + RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3; + RA = 1000 * RA / liters; + bicarbonate = wg_bicarbonate + RA; + total_alkalinity = bicarbonate * 50 / 61; + RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); + } + break; + case 2: RA = -protonDeficit * (f1d - f3d); // Calciumcarbonate, mmol totaal + RA = RA * MMCaCO3/1000; //gram + //but only 1/3 is effective, so add 3 times as much + RA = 3 * RA; + $("#wa_base").val(Round(RA, 2)); + setWaterAgent('CaCO3', Round(RA, 2)); + if (liters > 0) { + //Bicarbonate + RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3; + RA = 1000 * RA / liters; + bicarbonate = wg_bicarbonate + RA; + total_alkalinity = bicarbonate * 50 / 61; + //Ca precipitates out as Ca10(PO4)6(OH)2 + RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + + parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaCO3; + RA = 1000 * RA / liters; + calcium = wg_calcium + RA; + RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); + } + break; + case 3: RA = -protonDeficit / 19.3; // Calciumhydroxide + $("#wa_base").val(Round(RA, 2)); + setWaterAgent('Ca(OH)2', Round(RA, 2)); + if (liters > 0) { + // Bicarbonate + RA = -protonDeficit / liters; + total_alkalinity = wg_total_alkalinity + RA; + bicarbonate = total_alkalinity * 61 / 50; + // Calcium + RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + + parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaOH2; + RA = 1000 * RA / liters; + calcium = wg_calcium + RA; + RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); + } + break; + } + } + ph = TpH; + $('#wb_ph').val(Round(ph, 1)); + $('#est_mash_ph').val(Round(ph, 1)); + } else { // Manual + console.log("calc_acid no"); + // First add base salts + if (parseFloat($("#wa_base").jqxNumberInput('decimal')) > 0) { + if (liters > 0) { + switch (BT) { + case 0: // Sodiumbicarbonate, Na + RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; + RA = 1000 * RA / liters; + sodium = wg_sodium + RA; + // HCO3 + RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3; + RA = 1000 * RA / liters; + bicarbonate = wg_bicarbonate + RA; + total_alkalinity = bicarbonate * 50 / 61; + RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); + break; + case 1: // Sodiumcarbonate + RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + + parseFloat($("#wa_base").jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3; + RA = 1000 * RA / liters; + sodium = wg_sodium + RA; + // HCO3 + RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3; + RA = 1000 * RA / liters; + bicarbonate = wg_bicarbonate + RA; + total_alkalinity = bicarbonate * 50 / 61; + RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); + break; + case 2: // Calciumcarbonate: Bicarbonate + RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3; + RA = 1000 * RA / liters; + bicarbonate = wg_bicarbonate + RA; + total_alkalinity = bicarbonate * 50 / 61; + RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); + // Ca + RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + + parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaCO3; + RA = 1000 * RA / liters; + calcium = wg_calcium + RA; + break; + } + } + } + + TpH = parseFloat(dataRecord.mash_ph); + pHa = MashpH(); // This one is in demi water, should be in adjusted water??? + // Then calculate the new pH with added acids + if (parseFloat($("#wa_acid").jqxNumberInput('decimal')) > 0) { + console.log("TpH: "+TpH+" water: "+pHa); + Acid = parseFloat($("#wa_acid").jqxNumberInput('decimal')); + if (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) == 0) + $("#wa_acid_perc").val(AcidPrc); + Acid = Acid / AcidPrc * (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) / 100); // ml + Acid *= AcidSG; // ml + Acid /= MolWt; // mg + Acidmg = Acid; + + //find the pH where the protondeficit = protondeficit by the acid + frac = CalcFrac(pHa, pK1, pK2, pK3); + protonDeficit = Acid * frac; + + deltapH = 0.001; + deltapd = 0.1; + pd = ProtonDeficit(pHa); + n = 0; + while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 2000)) { + n++; + if (pd < (protonDeficit-deltapd)) + pHa -= deltapH; + else if (pd > (protonDeficit+deltapd)) + pHa += deltapH; + frac = CalcFrac(pHa, pK1, pK2, pK3); + protonDeficit = Acid * frac; + pd = ProtonDeficit(pHa); + } + console.log("n: "+n+" pd: "+pd+" protonDeficit: "+protonDeficit+" frac: "+frac+" pHa: "+pHa); + RA = wg_bicarbonate - protonDeficit * frac / liters; + bicarbonate = RA; + total_alkalinity = RA * 50 / 61; + ph = pHa; + $('#wb_ph').val(Round(ph, 1)); + $('#est_mash_ph').val(Round(ph, 1)); + } + } + + if ((AT == 3) && (liters > 0)) { // Sulfuctic / Zwavelzuur + RA = parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + + parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 + + Acidmg / 1000 * MMSO4 / (MMSO4 + 2); + RA = 1000 * RA / liters; + sulfate = wg_sulfate + RA; // Not add to sulfate?? + } else if ((AT == 1) && (liters > 0)) { // Hydrochloric, Zoutzuur + RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCl / MMCaCl2 + + parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMCl / MMNaCl + + Acidmg / 1000 * MMCl / (MMCl + 1); + RA = 1000 * RA / liters; + chloride = wg_chloride + RA; + } + + // 2:1 Sulfate to Chroride IPA's, Pale Ales. + // 1:1 Sulfate to Chloride Balanced + // 1:2 Sulfate to Chloride Malty + // Note, values below are the other way, cl to so4! + // So: 0.5 is IPA's, Pale Ales. + // 1 Balanced + // 2 Malty. + $('#tgt_bu').val(Round(GetBUGU(), 2)); + // From brouwhulp. + if (GetBUGU() < 0.32) + $('#wr_bu').html("Zeer moutig en zoet"); + else if (GetBUGU() < 0.43) + $('#wr_bu').html("Moutig, zoet"); + else if (GetBUGU() < 0.52) + $('#wr_bu').html("Evenwichtig"); + else if (GetBUGU() < 0.63) + $('#wr_bu').html("Licht hoppig, bitter"); + else + $('#wr_bu').html("Extra hoppig, zeer bitter"); + $('#tgt_cl_so4').val(Round(GetOptClSO4ratio(), 1)); + if (sulfate > 0) + RA = chloride / sulfate; + else + RA = 10; + $('#got_cl_so4').val(Round(RA, 1)); + piCLSO4_low = 0.8 * GetOptClSO4ratio(); + piCLSO4_high = 1.2 * GetOptClSO4ratio(); + Res = 'normaal'; + if (RA < piCLSO4_low) + Res = 'laag'; + else if (RA > piCLSO4_high) + Res = 'hoog'; + setRangeIndicator('cl_so4', Res); + + $('#wb_calcium').val(Round(calcium, 1)); + $('#wb_magnesium').val(Round(magnesium, 1)); + $('#wb_sodium').val(Round(sodium, 1)); + $('#wb_sulfate').val(Round(sulfate, 1)); + $('#wb_chloride').val(Round(chloride, 1)); + $('#wb_total_alkalinity').val(Round(total_alkalinity, 1)); + + if (calcium < 40) { + setRangeIndicator("calcium", "laag"); + } else if (calcium > 150) { + setRangeIndicator("calcium", "hoog"); + } else { + setRangeIndicator("calcium", "normaal"); + } + if (magnesium >= 0 && magnesium <= 30) { + setRangeIndicator("magnesium", "normaal"); + } else { + setRangeIndicator("magnesium", "hoog"); + } + if (sodium <= 150) { + setRangeIndicator("sodium", "normaal"); + } else { + setRangeIndicator("sodium", "hoog"); + } + // Both chloride and sulfate should be above 50 according to + // John Palmer. So the Cl/SO4 ratio calculation will work. + if (chloride <= 50) { + setRangeIndicator("chloride", "laag"); + } else if (chloride <= 100) { + setRangeIndicator("chloride", "normaal"); + } else { + setRangeIndicator("chloride", "hoog"); + } + if (sulfate <= 50) { + setRangeIndicator("sulfate", "laag"); + } else if (sulfate <= 350) { + setRangeIndicator("sulfate", "normaal"); + } else { + setRangeIndicator("sulfate", "hoog"); + } + if (ph < 5.2) { + setRangeIndicator("ph", "laag"); + } else if (ph > 5.6) { + setRangeIndicator("ph", "hoog"); + } else { + setRangeIndicator("ph", "normaal"); + } + calcSparge(); + calcMiscs(); + calcSupplies(); + } + + function calcSparge() { + + var TargetpH, Source_pH, Source_alkalinity, r1, r2, d, f1, f3, + r143, r243, d43, f143, f343, alkalinity, Ct, r1g, r2g, dg, f1g, f3g, + Acid, AT, result, pK1, pK2, pK3, MolWt, AcidSG, AcidPrc, fract; + + // Code from BrewBuddy/Brouwhulp, who got it from http://www.brewery.org/brewery/library/Acidi0,00fWaterAJD0497.html + TargetpH = dataRecord.sparge_ph; + Source_pH = dataRecord.w1_ph; + Source_alkalinity = dataRecord.w1_total_alkalinity; + // Select watersource or fallback to the first source. + if (dataRecord.sparge_source == 1) { // Source 2 + if (dataRecord.w2_ph > 0.0) { + Source_pH = dataRecord.w2_ph; + Source_alkalinity = dataRecord.w2_total_alkalinity; + } else { + dataRecord.sparge_source = 0; // Source 1 + $("#sparge_source").val(0); + } + } else if (dataRecord.sparge_source == 2) { // Mixed + if (dataRecord.w2_ph > 0.0) { + Source_pH = parseFloat($("#wg_ph").jqxNumberInput('decimal')); + Source_alkalinity = parseFloat($("#wg_total_alkalinity").jqxNumberInput('decimal')); + } else { + dataRecord.sparge_source = 0; + $("#sparge_source").val(0); + } + } + + // Step 1: Compute the mole fractions of carbonic (f1o), bicarbonate (f2o) and carbonate(f3o) at the water pH + r1 = Math.pow(10, Source_pH - 6.38); + r2 = Math.pow(10, Source_pH - 10.373); + d = 1 + r1 + r1*r2; + f1 = 1/d; + f3 = r1 * r2 / d; + + //Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity) + r143 = Math.pow(10, 4.3 - 6.38); + r243 = Math.pow(10, 4.3 - 10.373); + d43 = 1 + r143 + r143*r243; + f143 = 1/d43; + f343 = r143 * r243 / d43; + + //Step 3. Convert the water alkalinity to milliequivalents/L + alkalinity = Source_alkalinity / 50; + + //Step 4. Solve + Ct = (alkalinity - 1000 * (Math.pow(10, -4.3) - Math.pow(10, -Source_pH))) / ((f143-f1)+(f3-f343)); + + //Step 5. Compute mole fractions at desired pH + r1g = Math.pow(10, TargetpH - 6.38); + r2g = Math.pow(10, TargetpH - 10.373); + dg = 1 + r1g + r1g*r2g; + f1g = 1/dg; + f3g = r1g * r2g / dg; + + //Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L) + Acid = Ct * ((f1g-f1)+(f3-f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH); //mEq/l + Acid += 0.01; // Add acid that would be required for distilled water. + if (dataRecord.sparge_acid_type < 0 || dataRecord.sparge_acid_type > 3) { + dataRecord.sparge_acid_type = 0; + $("#sparge_acid_type").val(0); + } + + //Step 8. Get the acid data. + AT = dataRecord.sparge_acid_type; + result = GetAcidSpecs(AT); + pK1 = result.pK1; + pK2 = result.pK2; + pK3 = result.pK3; + MolWt = result.MolWt; + AcidSG = result.AcidSG; + AcidPrc = result.AcidPrc; + fract = CalcFrac(TargetpH, pK1, pK2, pK3); + + //Step 9. Now divide the mEq required by the "fraction". This is the required number of moles of acid. + Acid /= fract; + + //Step 10. Multiply by molecular weight of the acid + Acid *= MolWt; //mg + + Acid = Acid / AcidSG; //ml ; 88% lactic solution + f1 = dataRecord.sparge_acid_perc; + if (f1 <= 0.1) + f1 = AcidPrc; + Acid = Acid * AcidPrc / (f1 / 100); + + Acid *= dataRecord.sparge_volume; //ml lactic acid total + Acid = Round(Acid, 2); + dataRecord.sparge_acid_amount = Acid / 1000; + $("#sparge_acid_amount").val(Acid); + } + + function calcFermentation(){ + + var primary_svg, secondary_svg, final_svg, ABV; + if (dataRecord.brew_fermenter_sg<1.020) + return; + + if ((dataRecord.primary_end_sg > 0.990) && (dataRecord.primary_end_sg < dataRecord.brew_fermenter_sg)) { + primary_svg = Round(100*(dataRecord.brew_fermenter_sg-dataRecord.primary_end_sg)/(dataRecord.brew_fermenter_sg-1),1); + $("#primary_svg").val(primary_svg); + if ((dataRecord.secondary_end_sg > 0.990) && (dataRecord.secondary_end_sg < dataRecord.brew_fermenter_sg)) { + secondary_svg = Round(100*(dataRecord.brew_fermenter_sg-dataRecord.secondary_end_sg)/(dataRecord.brew_fermenter_sg-1),1); + $("#secondary_svg").val(secondary_svg); + if ((dataRecord.fg > 0.990) && (dataRecord.fg < dataRecord.brew_fermenter_sg)) { + final_svg = Round(100*(dataRecord.brew_fermenter_sg-dataRecord.fg)/(dataRecord.brew_fermenter_sg-1),1); + $("#final_svg").val(final_svg); + ABV = Round(abvol(dataRecord.brew_fermenter_sg,dataRecord.fg),2); + $("#final_abv").val(ABV); + } + } + } + } + + function ResCO2(CO2,T){ + + var F=T*1.8+32; + return 3.0378-0.050062*F+0.00026555*F*F; + } + + function CarbCO2toS(CO2,T,SFactor){ + var sugar=SFactor*(CO2-ResCO2(CO2,T))/0.286; + if(sugar<0) + sugar=0; + return Round(sugar,3); + } + + function GetPressure(CO2, T1, T2) { + var P, V = CO2 - ResCO2(CO2, T1); + if (V < 0) + return 0; + P = -1.09145427669121 + 0.00800006989646477 * T2 + 0.000260276315484684 * T2 * T2 + 0.0215142075945119 * T2 * V + + 0.674996600795854 * V + -0.00471757220150754 * V * V; + //console.log("CO2: "+CO2+" "+V+" Temp: "+T1+" "+T2+" Pressure: "+P); + if (P < 0) + P = 0; + P = P * 1.01325; // atm to bar + return Round(P,1); + } + + function CarbCO2ToPressure(CO2, T) { + return (CO2-(-0.000005594056*Math.pow(T,4)+0.000144357886*Math.pow(T,3)+0.000362999168*T*T-0.064872987645*T+1.641145175049)) / + (0.00000498031*Math.pow(T,4)-0.00024358267*Math.pow(T,3)+0.00385867329*T*T-0.05671206825*T+1.53801423376); + } + + function calcCarbonation() { + + var TSec, ABV, bvol, balc, babv, mvol, malc, tvol, talc, + i, row, SFactor, pvol, pabv, Pressure, kabv; + + TSec=dataRecord.secondary_temp; + if(TSec<1) + TSec=dataRecord.primary_end_temp; + if(TSec<1) + TSec=18; + + if(dataRecord.fg==0.000) + ABV=abvol(dataRecord.brew_fermenter_sg,parseFloat($("#est_fg").jqxNumberInput('decimal'))); + else + ABV=abvol(dataRecord.brew_fermenter_sg,dataRecord.fg); + + /* Calculate new volume and alcohol. */ + bvol = dataRecord.package_volume-(ABV*dataRecord.package_volume)/100; + balc = dataRecord.package_volume-bvol; + mvol = dataRecord.package_infuse_amount-(dataRecord.package_infuse_abv*dataRecord.package_infuse_amount)/100; + malc = dataRecord.package_infuse_amount-mvol; + talc = balc+malc; + tvol = bvol+mvol; + ABV = Round(talc/(tvol+talc)*100,2); + dataRecord.package_abv=ABV; + $("#package_abv").val(ABV); + +// console.log("calcCarbonation() TSec:"+TSec+" ABV:"+ABV); + if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))){ + return; + } + + // Bottles + dataRecord.bottle_priming_amount=0; + dataRecord.bottle_priming_total=0; + for (i = 0; i < rows.length; i++) { + row = rows[i]; + if(row.f_added==4){ + SFactor=1/((row.f_yield/100)*(1-row.f_moisture/100)); + dataRecord.bottle_priming_amount=CarbCO2toS(dataRecord.bottle_carbonation,TSec,SFactor); + dataRecord.bottle_priming_total=Round(dataRecord.bottle_amount*dataRecord.bottle_priming_amount,2); + $("#fermentableGrid").jqxGrid('setcellvalue',i,'f_amount',dataRecord.bottle_priming_total/1000); + } + } + $("#bottle_priming_amount").val(Round(dataRecord.bottle_priming_amount,1)); + $("#bottle_priming_total").val(dataRecord.bottle_priming_total); + pabv=ABV+dataRecord.bottle_priming_amount*0.47/7.907; + pvol=dataRecord.bottle_amount-(pabv*dataRecord.bottle_amount)/100; + talc=dataRecord.bottle_amount-pvol; + tvol=pvol+dataRecord.bottle_priming_water; + babv = Round(talc/(tvol+talc)*100,2); + //console.log("bottle pabv:"+pabv+" pvol:"+pvol+" wvol:"+dataRecord.bottle_priming_water+" tvol:"+tvol+" talc:"+talc+" abv:"+babv); + $("#bottle_abv").val(babv); + $("#bottle_pressure").val(GetPressure(dataRecord.bottle_carbonation,TSec,dataRecord.bottle_carbonation_temp)); + + // Kegs + Pressure=CarbCO2ToPressure(dataRecord.keg_carbonation,dataRecord.keg_carbonation_temp); + if(Pressure<0)Pressure=0; + dataRecord.keg_pressure=Pressure; + $("#keg_pressure").val(Round(Pressure,1)); + + dataRecord.keg_priming_amount=0; + dataRecord.keg_priming_total=0; + if(!dataRecord.keg_forced_carb){ + for(i = 0; i < rows.length; i++){ + row=rows[i]; + if(row.f_added==5){ + SFactor=1/((row.f_yield/100)*(1-row.f_moisture/100)); + dataRecord.keg_priming_amount=CarbCO2toS(dataRecord.keg_carbonation,TSec,SFactor); + dataRecord.keg_priming_total=Round(dataRecord.keg_amount*dataRecord.keg_priming_amount,2); + $("#fermentableGrid").jqxGrid('setcellvalue',i,'f_amount',dataRecord.keg_priming_total/1000); + } + } + $("#keg_priming_amount").val(Round(dataRecord.keg_priming_amount,1)); + $("#keg_priming_total").val(dataRecord.keg_priming_total); + pabv=ABV+dataRecord.keg_priming_amount*0.47/7.907; + pvol=dataRecord.keg_amount-(pabv*dataRecord.keg_amount)/100; + talc=dataRecord.keg_amount-pvol; + tvol=pvol+dataRecord.keg_priming_water; + kabv=Round(talc/(tvol+talc)*100,2); + //console.log("kegs pabv:"+pabv+" pvol:"+pvol+" wvol:"+dataRecord.keg_priming_water+" tvol:"+tvol+" talc:"+talc+" abv:"+kabv); + $("#keg_abv").val(kabv); + } else { + $("#keg_priming_amount").val(0); + $("#keg_priming_total").val(0); + $("#keg_abv").val(ABV); + } + } + + function calcStage() { + + var newstage = dataRecord.stage, d, date1, date2, date1_unixtime, date2_unixtime, + timeDifference, timeDifferenceInDays; + + if (newstage == 0 && dataRecord.est_og > 1.005 && dataRecord.est_color > 3 && dataRecord.est_ibu > 3) + newstage = 1; + if (newstage == 1 && parseFloat($("#brew_date_start").val()) > 2000) + newstage = 2; // Brewday + if (newstage == 2 && ($("#brew_date_start").val() == '')) + newstage = 1; // No brewday + if (newstage == 2 && parseFloat($("#brew_date_end").val()) > 2000) + newstage = 3; // Primary + if (newstage == 3 && parseFloat($("#primary_end_date").val()) > 2000) + newstage = 4; // Secondary + if (newstage == 4 && parseFloat($("#secondary_end_date").val()) > 2000) + newstage = 5; // Tertiary + if (newstage == 5 && parseFloat($("#package_date").val()) > 2000) + newstage = 6; // Package + if (newstage >= 6 && newstage < 9) { + d = new Date(); + date2 = $("#package_date").val(); + date2 = date2.split('-'); + // Now we convert the array to a Date object + date1 = new Date(d.getFullYear(), d.getMonth(), d.getDate()); + date2 = new Date(date2[0], date2[1]-1, date2[2]); + // We use the getTime() method and get the unixtime + date1_unixtime = parseInt(date1.getTime() / 1000); + date2_unixtime = parseInt(date2.getTime() / 1000); + // This is the calculated difference in seconds + timeDifference = date1_unixtime - date2_unixtime; + timeDifferenceInDays = timeDifference / 60 / 60 / 24; + if (timeDifferenceInDays > 0) { // At least one day + if (timeDifferenceInDays >= 42) // 6 weeks + newstage = 9; // Ready to taste + else if (timeDifferenceInDays >= 14) // 14 days + newstage = 8; // Mature + else + newstage = 7; // Carbonation + } + } + if (newstage == 9 && parseFloat($("#taste_date").val()) > 2000) + newstage = 10; // Ready + + if (newstage != dataRecord.stage) { + console.log("calcStage() old: "+dataRecord.stage+" new: "+newstage); + dataRecord.stage = newstage; + } + + /* + * Set stage and enable or disable parts of the screens. + */ + $("#stage").val(StageData[dataRecord.stage].nl); + if (dataRecord.stage >= 10) { + $("#locked").jqxCheckBox({ disabled:false }); + } + + /* + * When the brew is in progress or done, block equipment select and delete. + */ + if (dataRecord.stage > 1) { + $("#equipmentSelect").jqxDropDownList({ disabled: true }); + $("#Delete").jqxButton({ disabled: true }); + } + + if (dataRecord.stage < 1) // Planning, no ingredients + $('#jqxTabs').jqxTabs('disableAt', 8); // Brewday tab + else + $('#jqxTabs').jqxTabs('enableAt', 8); + + if (dataRecord.stage < 3) { // Primary + $('#jqxTabs').jqxTabs('disableAt', 9); // Fermentation tab + } else { + $('#jqxTabs').jqxTabs('enableAt', 9); + $("#name").jqxInput({ disabled: true }); + $("#code").jqxInput({ disabled: true }); + $("#batch_size").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#boil_size").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#boil_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#efficiency").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#est_og").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#type").jqxDropDownList({ disabled: true }); + $("#styleSelect").jqxDropDownList({ disabled: true }); + $("#color_method").jqxDropDownList({ disabled: true }); + $("#ibu_method").jqxDropDownList({ disabled: true }); + $("#mash_select").jqxDropDownList({ disabled: true }); + $("#w1_name").jqxDropDownList({ disabled: true }); + $("#w2_name").jqxDropDownList({ disabled: true }); + $("#w2_amount").jqxNumberInput({ readOnly: true }); + $("#pr_name").jqxDropDownList({ disabled: true }); + $("#wa_cacl2").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#wa_caso4").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#wa_mgso4").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#wa_nacl").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#mash_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#calc_acid").jqxCheckBox({ disabled: true }); + $("#wa_base_name").jqxDropDownList({ disabled: true }); + $("#wa_base").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#wa_acid_name").jqxDropDownList({ disabled: true }); + $("#wa_acid").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#wa_acid_perc").jqxNumberInput({ spinButtons: false, readOnly: true, width: 70 }); + $("#sparge_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#sparge_volume").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#sparge_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#sparge_source").jqxDropDownList({ disabled: true }); + $("#sparge_acid_type").jqxDropDownList({ disabled: true }); + $("#sparge_acid_perc").jqxNumberInput({ spinButtons: false, readOnly: true, width: false }); + $("#starter_enable").jqxCheckBox({ disabled: true }); + $("#starter_type").jqxDropDownList({ disabled: true }); + $("#starter_try").jqxButton({ disabled: true }); + $("#starter_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#starter_viability").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + } + if (dataRecord.stage > 3) { // Primary fermentation done + $("#brew_date_start").jqxDateTimeInput({ disabled: true }); + $("#brew_date_end").jqxDateTimeInput({ disabled: true }); + $("#brew_mash_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_preboil_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_aboil_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_mash_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_preboil_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_aboil_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_preboil_volume").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_aboil_volume").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_whirlpool9").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_cooling_to").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_whirlpool7").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_cooling_method").jqxDropDownList({ disabled: true }); + $("#brew_whirlpool6").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_cooling_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_sparge_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_whirlpool2").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_aeration_type").jqxDropDownList({ disabled: true }); + $("#brew_fermenter_tcloss").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_aeration_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_fermenter_extrawater").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#brew_aeration_speed").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + } + if (dataRecord.stage == 5) // Lagering, allow packaging + $("#package_date").jqxDateTimeInput({ disabled: false }); + else + $("#package_date").jqxDateTimeInput({ disabled: true }); + if (dataRecord.stage >= 5) { // At least secondary + $("#primary_start_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#primary_max_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#primary_end_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#primary_end_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#primary_end_brix").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#primary_end_date").jqxDateTimeInput({ disabled: true }); + } + if (dataRecord.stage >= 6) { // Packaged + $("#secondary_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#secondary_end_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#secondary_end_date").jqxDateTimeInput({ disabled: true }); + $("#tertiary_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#fg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#final_brix").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#package_date").jqxDateTimeInput({ disabled: true }); + $("#package_volume").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#package_infuse_amount").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#package_infuse_abv").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#package_infuse_notes").jqxInput({ disabled: true }); + $("#package_ph").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#bottle_amount").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#bottle_priming_water").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#keg_priming_water").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#keg_amount").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#bottle_carbonation").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#keg_carbonation").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#bottle_priming_sugar").jqxDropDownList({ disabled: true }); + $("#keg_priming_sugar").jqxDropDownList({ disabled: true }); + $("#keg_forced_carb").jqxCheckBox({ disabled : true }); + $("#bottle_carbonation_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#keg_carbonation_temp").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + } + if (dataRecord.stage < 8) { // Taste when at least Mature. + $('#jqxTabs').jqxTabs('disableAt', 11); // Tasting tab + } else { + $('#jqxTabs').jqxTabs('enableAt', 11); + } + + if (dataRecord.stage == 11) { // Locked + $("#taste_date").jqxDateTimeInput({ disabled: true }); + $("#taste_rate").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#taste_color").jqxInput({ disabled: true }); + $("#taste_transparency").jqxInput({ disabled: true }); + $("#taste_head").jqxInput({ disabled: true }); + $("#taste_aroma").jqxInput({ disabled: true }); + $("#taste_taste").jqxInput({ disabled: true }); + $("#taste_aftertaste").jqxInput({ disabled: true }); + $("#taste_mouthfeel").jqxInput({ disabled: true }); + $("#taste_notes").jqxInput({ disabled: true }); + $("#notes").jqxInput({ disabled: true }); + } else { + $("#notes").jqxInput({ disabled: false }); + } + } + + function showStarter() { + + if (dataRecord.starter_enable) { + $("#propagator").show(); + $("#starter_type").jqxDropDownList( {disabled: false }); + $("#starter_try").jqxButton({ disabled: false }); + $("#starter_sg").jqxNumberInput({ spinButtons: true, readOnly: false, width: 110 }); + $("#starter_viability").jqxNumberInput({ spinButtons: true, readOnly: false, width: 110 }); + } else { + $("#propagator").hide(); + $("#starter_type").jqxDropDownList( {disabled: true }); + $("#starter_try").jqxButton({ disabled: true }); + $("#starter_sg").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + $("#starter_viability").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); + } + } + + function calcInit () { + console.log("calcInit()"); + + calcMashEfficiency(); + calcEfficiencyBeforeBoil(); + calcEfficiencyAfterBoil(); + + $("#starter_enable").on('checked', function (event) { + dataRecord.starter_enable = 1; + showStarter(); + calcYeast(); + }); + $("#starter_enable").on('unchecked', function (event) { + dataRecord.starter_enable = 0; + showStarter(); + calcYeast(); + }); + $("#starter_try").click(function () { + $("#prop1_volume").val(0); + $("#prop2_volume").val(0); + $("#prop3_volume").val(0); + $("#prop4_volume").val(0); + calcYeast(); + }); + $('#starter_type').on('change', function (event) { + if (event.args) { + var index = event.args.index; + dataRecord.starter_type = index; + calcYeast(); + } + }); + $('#starter_sg').on('change', function (event) { + if (event.args) { + dataRecord.starter_sg = event.args.value; + calcYeast(); + } + }); + $('#starter_viability').on('change', function (event) { + if (event.args) { + dataRecord.starter_viability = event.args.value; + calcFermentables(); + calcYeast(); + } + }); + $('#prop1_type').on('change', function (event) { + if (event.args) { + var index = event.args.index; + dataRecord.prop1_type = index; + calcYeast(); + } + }); + $('#prop1_volume').on('change', function (event) { + if (event.args) { + dataRecord.prop1_volume = event.args.value; + calcYeast(); + } + }); + $('#prop2_type').on('change', function (event) { + if (event.args) { + var index = event.args.index; + dataRecord.prop2_type = index; + calcYeast(); + } + }); + $('#prop2_volume').on('change', function (event) { + if (event.args) { + dataRecord.prop2_volume = event.args.value; + calcYeast(); + } + }); + $('#prop3_type').on('change', function (event) { + if (event.args) { + var index = event.args.index; + dataRecord.prop3_type = index; + calcYeast(); + } + }); + $('#prop3_volume').on('change', function (event) { + if (event.args) { + dataRecord.prop3_volume = event.args.value; + calcYeast(); + } + }); + $('#prop4_type').on('change', function (event) { + if (event.args) { + var index = event.args.index; + dataRecord.prop4_type = index; + calcYeast(); + } + }); + $('#prop4_volume').on('change', function (event) { + if (event.args) { + dataRecord.prop4_volume = event.args.value; + calcYeast(); + } + }); + + $("#calc_acid").on('checked', function (event) { + dataRecord.calc_acid = 1; + calcWater(); + }); + $("#calc_acid").on('unchecked', function (event) { + dataRecord.calc_acid = 0; + calcWater(); + }); + $("#w1_name").jqxDropDownList('selectItem', dataRecord.w1_name); + $("#w2_name").jqxDropDownList('selectItem', dataRecord.w2_name); + // Fix tap water if zero using mash infuse amount. + if (parseFloat($("#w1_amount").jqxNumberInput('decimal')) == 0 && mash_infuse > 0) { + $("#w1_amount").val(mash_infuse); + dataRecord.w1_amount = mash_infuse; + $("#wg_amount").val(mash_infuse); + $("#w2_amount").val(0); + dataRecord.w2_amount = 0; + } + calcWater(); + $("#w2_amount").on('change', function (event) { + var newval = parseFloat(event.args.value); + + if (newval > mash_infuse) { + $("#w2_amount").val(dataRecord.w2_amount); + return; + } + dataRecord.w1_amount = parseFloat($("#wg_amount").jqxNumberInput('decimal')) - newval; + $("#w1_amount").val(dataRecord.w1_amount); + dataRecord.w2_amount = newval; + console.log("new: "+event.args.value+" w1: "+dataRecord.w1_amount+" w2: "+dataRecord.w2_amount); + calcWater(); + }); + $('#wa_cacl2').on('change', function (event) { + if (event.args) { + setWaterAgent('CaCl2', 0); // This can prevent double entries. + setWaterAgent('CaCl2', event.args.value); + calcWater(); + } + }); + $('#wa_caso4').on('change', function (event) { + if (event.args) { + setWaterAgent('CaSO4', 0); + setWaterAgent('CaSO4', event.args.value); + calcWater(); + } + }); + $('#wa_mgso4').on('change', function (event) { + if (event.args) { + setWaterAgent('MgSO4', 0); + setWaterAgent('MgSO4', event.args.value); + calcWater(); + } + }); + $('#wa_nacl').on('change', function (event) { + if (event.args) { + setWaterAgent('NaCl', 0); + setWaterAgent('NaCl', event.args.value); + calcWater(); + } + }); + $('#wa_base_name').on('change', function (event) { + if (event.args) { + var index = event.args.index; + console.log("wa_base_name "+index); + setWaterAgent(last_base, 0); + last_base = BaseTypeData[index].nl; + setWaterAgent(last_base, parseFloat($("#wa_base").jqxNumberInput('decimal'))); + dataRecord.wa_base_name = index; + calcWater(); + } + }); + $('#wa_base').on('change', function (event) { + var name = BaseTypeData[$("#wa_base_name").val()].nl; + setWaterAgent(name, parseFloat(event.args.value)); + calcWater(); + }); + $('#wa_acid_name').on('change', function (event) { + if (event.args) { + var index = event.args.index; + console.log("wa_acid_name "+index); + setWaterAgent(last_acid, 0); + last_acid = AcidTypeData[index].nl; + setWaterAgent(last_acid, parseFloat($("#wa_acid").jqxNumberInput('decimal'))); + dataRecord.wa_acid_name = index; + calcWater(); + } + }); + $('#wa_acid').on('change', function (event) { + var name = AcidTypeData[$("#wa_acid_name").val()].nl; + setWaterAgent(name, parseFloat(event.args.value)); + calcWater(); + }); + $('#wa_acid_perc').on('change', function (event) { calcWater(); }); + + $('#color_method').on('change', function (event) { + dataRecord.color_method = event.args.index; + calcFermentables(); + }); + $('#ibu_method').on('change', function (event) { + dataRecord.ibu_method = event.args.index; + calcFermentables(); + calcIBUs(); + }); + + $('#batch_size').on('change', function (event) { + console.log("batch_size change:"+event.args.value+" old:"+dataRecord.batch_size); + $("#est_a_vol").val(event.args.value * 1.04); + var factor, new_boil = parseFloat(event.args.value) + dataRecord.boil_size - dataRecord.batch_size; + factor = parseFloat(event.args.value) / dataRecord.batch_size; + dataRecord.boil_size = new_boil; + $("#boil_size").val(Round(new_boil, 2)); + $("#est_pre_vol").val(Round(new_boil * 1.04, 2)); + dataRecord.sparge_volume *= factor; + $("#sparge_volume").val(dataRecord.sparge_volume); + $("#brew_sparge_volume").val(dataRecord.sparge_volume); + dataRecord.batch_size = parseFloat(event.args.value); + calcFermentablesFromOG(parseFloat($("#est_og").jqxNumberInput('decimal'))); // Keep the OG + adjustWaters(factor); + calcFermentables(); + adjustHops(factor); + adjustMiscs(factor); + adjustYeasts(factor); + calcIBUs(); + calcWater(); + calcSparge(); + calcMash(); + }); + $('#boil_time').on('change', function (event) { + console.log("boil_time change:"+parseFloat(event.args.value)+" old:"+dataRecord.boil_time); + var new_boil, new_evap, old_evap = parseFloat(dataRecord.boil_size) - parseFloat(dataRecord.batch_size); + new_evap = old_evap * (parseFloat(event.args.value) / dataRecord.boil_time); + new_boil = parseFloat(dataRecord.batch_size) + new_evap; + dataRecord.boil_time = parseFloat(event.args.value); + dataRecord.boil_size = new_boil; + $("#est_pre_vol").val(Round(new_boil * 1.04, 2)); + $("#boil_size").val(Round(new_boil, 2)); + calcFermentables(); + calcIBUs(); + calcYeast(); + }); + $('#efficiency').on('change', function (event) { + var estog = parseFloat($("#est_og").jqxNumberInput('decimal')); + dataRecord.efficiency = parseFloat(event.args.value); + console.log("efficiency change:"+dataRecord.efficiency+" est_og:"+estog); + calcFermentablesFromOG(estog); // Keep the OG + calcFermentables(); + calcIBUs(); + calcYeast(); + }); + $('#est_og').on('change', function (event) { + dataRecord.est_og = parseFloat(event.args.value); + console.log("est_og change:"+dataRecord.est_og); + $('#est_og2').val(dataRecord.est_og); + calcFermentablesFromOG(dataRecord.est_og); // Adjust fermentables amounts + calcFermentables(); // Update the recipe details + calcIBUs(); // and the IBU's. + calcMash(); + calcYeast(); + }); + $('#mash_ph').on('change', function (event) { + dataRecord.mash_ph = parseFloat(event.args.value); + calcWater(); + }); + + $('#sparge_ph').on('change', function (event) { + dataRecord.sparge_ph = parseFloat(event.args.value); + calcSparge(); + }); + $('#sparge_volume').on('change', function (event) { + dataRecord.sparge_volume = parseFloat(event.args.value); + $('#brew_sparge_volume').val(dataRecord.sparge_volume); + calcSparge(); + }); + $("#sparge_temp").on('change', function (event) { + dataRecord.sparge_temp = parseFloat(event.args.value); + $('#brew_sparge_temperature').val(dataRecord.sparge_temp); + }); + $('#sparge_source').on('change', function (event) { + if (event.args) { + var index = event.args.index; + dataRecord.sparge_source= index; + calcSparge(); + } + }); + $('#sparge_acid_type').on('change', function (event) { + if (event.args) { + var index = event.args.index; + dataRecord.sparge_acid_type = index; + console.log("new sparge_acid_type: "+dataRecord.sparge_acid_type); + calcSparge(); + } + }); + $('#sparge_acid_perc').on('change', function (event) { + dataRecord.sparge_acid_perc = parseFloat(event.args.value); + calcSparge(); + }); + + calcFermentation(); + calcCarbonation(); + $('#package_volume').on('change', function (event) { + var diff, tnew, told = dataRecord.package_volume + dataRecord.package_infuse_amount; + dataRecord.package_volume = parseFloat(event.args.value); + if (dataRecord.package_volume > dataRecord.brew_fermenter_volume) { + dataRecord.package_volume = dataRecord.brew_fermenter_volume; + $('#package_volume').val(dataRecord.package_volume); + } + tnew = dataRecord.package_volume + dataRecord.package_infuse_amount; + diff = tnew - told; + if (told > 0) { + dataRecord.bottle_amount += (dataRecord.bottle_amount / told) * diff; + dataRecord.keg_amount += (dataRecord.keg_amount / told) * diff; + } else { + dataRecord.bottle_amount = tnew; + dataRecord.keg_amount = 0; + } + console.log("diff:"+diff+" old:"+told+" bottle:"+dataRecord.bottle_amount+" keg:"+dataRecord.keg_amount); + $('#bottle_amount').val(parseFloat(dataRecord.bottle_amount * 1000) / 1000); + $('#keg_amount').val(parseFloat(dataRecord.keg_amount * 1000) / 1000); + calcCarbonation(); + }); + $('#package_infuse_amount').on('change', function (event) { + var diff, tnew, told = dataRecord.package_volume + dataRecord.package_infuse_amount; + dataRecord.package_infuse_amount = parseFloat(event.args.value); + tnew = dataRecord.package_volume + dataRecord.package_infuse_amount; + diff = tnew - told; + if (told > 0) { + dataRecord.bottle_amount += (dataRecord.bottle_amount / told) * diff; + dataRecord.keg_amount += (dataRecord.keg_amount / told) * diff; + } else { + dataRecord.bottle_amount = tnew; + dataRecord.keg_amount = 0; + } + console.log("diff:"+diff+" old:"+told+" bottle:"+dataRecord.bottle_amount+" keg:"+dataRecord.keg_amount); + $('#bottle_amount').val(parseFloat(dataRecord.bottle_amount * 1000) / 1000); + $('#keg_amount').val(parseFloat(dataRecord.keg_amount * 1000) / 1000); + calcCarbonation(); + }); + $('#package_infuse_abv').on('change', function (event) { + dataRecord.package_infuse_abv = parseFloat(event.args.value); + calcCarbonation(); + }); + $('#bottle_amount').on('change', function (event) { + var vtot, diff, vnew = parseFloat(event.args.value); + vtot = dataRecord.package_volume + dataRecord.package_infuse_amount; + if (vnew > vtot) + vnew = vtot; + diff = dataRecord.bottle_amount - vnew; + dataRecord.bottle_amount = Math.round((dataRecord.bottle_amount - diff) * 1000) / 1000; + dataRecord.keg_amount = Math.round((dataRecord.keg_amount + diff) * 1000) / 1000; + $('#bottle_amount').val(parseFloat(dataRecord.bottle_amount)); + $('#keg_amount').val(parseFloat(dataRecord.keg_amount)); + calcCarbonation(); + }); + $("#bottle_priming_water").on('change', function (event) { + dataRecord.bottle_priming_water = parseFloat(event.args.value); + calcCarbonation(); + }); + $('#keg_amount').on('change', function (event) { + var diff, vtot, vnew = parseFloat(event.args.value); + vtot = dataRecord.package_volume + dataRecord.package_infuse_amount; + if (vnew > vtot) + vnew = vtot; + diff = dataRecord.keg_amount - vnew; + dataRecord.bottle_amount = Math.round((dataRecord.bottle_amount + diff) * 1000) / 1000; + dataRecord.keg_amount = Math.round((dataRecord.keg_amount - diff) * 1000) / 1000; + $('#bottle_amount').val(parseFloat(dataRecord.bottle_amount)); + $('#keg_amount').val(parseFloat(dataRecord.keg_amount)); + calcCarbonation(); + }); + $("#keg_priming_water").on('change', function (event) { + dataRecord.keg_priming_water = parseFloat(event.args.value); + calcCarbonation(); + }); + $('#bottle_carbonation').on('change', function (event) { + dataRecord.bottle_carbonation = parseFloat(event.args.value); + calcCarbonation(); + }); + $('#bottle_carbonation_temp').on('change', function (event) { + dataRecord.bottle_carbonation_temp = parseFloat(event.args.value); + calcCarbonation(); + }); + $('#keg_carbonation').on('change', function (event) { + dataRecord.keg_carbonation = parseFloat(event.args.value); + calcCarbonation(); + }); + $("#keg_forced_carb").on('checked', function (event) { + dataRecord.keg_forced_carb = 1; + calcCarbonation(); + }); + $("#keg_forced_carb").on('unchecked', function (event) { + dataRecord.keg_forced_carb = 0; + calcCarbonation(); + }); + $('#keg_carbonation_temp').on('change', function (event) { + dataRecord.keg_carbonation_temp = parseFloat(event.args.value); + calcCarbonation(); + }); + + $("#brew_fermenter_extrawater").on('change',function (event){ + dataRecord.brew_fermenter_extrawater=parseFloat(event.args.value);calcFermentables();calcIBUs();calcYeast(); + }); + $("#brew_fermenter_tcloss").on('change',function (event){ + dataRecord.brew_fermenter_tcloss=parseFloat(event.args.value);calcFermentables();calcIBUs();calcYeast(); + }); + $("#primary_end_sg").on('change',function (event){dataRecord.primary_end_sg=parseFloat(event.args.value);calcFermentation();}); + $("#primary_end_brix").on('change', function (event) { + var OBrix, FBrix, FG; + if(dataRecord.brew_fermenter_sg>=1.020){ + OBrix = sg_to_brix(dataRecord.brew_fermenter_sg); + FBrix = parseFloat(event.args.value); + FG = Round(1.0031 - 0.002318474*OBrix - 0.000007775*(OBrix*OBrix) - 0.000000034*Math.pow(OBrix,3) + + 0.00574*(FBrix) + 0.00003344*(FBrix*FBrix) + 0.000000086*Math.pow(FBrix,3), 4); + //console.log("OBrix:"+OBrix+" FBrix:"+FBrix+" FG:"+FG); + if (FBrix > 0.05) { + $("#primary_end_sg").val(FG); + dataRecord.primary_end_sg=FG; + } + calcFermentation(); + } + }); + $("#secondary_end_sg").on('change',function (event){dataRecord.secondary_end_sg=parseFloat(event.args.value);calcFermentation();}); + $("#secondary_end_brix").on('change', function (event) { + var OBrix, FBrix, FG; + if(dataRecord.brew_fermenter_sg>=1.020){ + OBrix = sg_to_brix(dataRecord.brew_fermenter_sg); + FBrix = parseFloat(event.args.value); + FG = Round(1.0031 - 0.002318474*OBrix - 0.000007775*(OBrix*OBrix) - 0.000000034*Math.pow(OBrix,3) + + 0.00574*(FBrix) + 0.00003344*(FBrix*FBrix) + 0.000000086*Math.pow(FBrix,3), 4); + //console.log("OBrix:"+OBrix+" FBrix:"+FBrix+" FG:"+FG); + if (FBrix > 0.05) { + $("#secondary_end_sg").val(FG); + dataRecord.secondary_end_sg=FG; + } + calcFermentation(); + } + }); + $("#final_brix").on('change',function (event){ + var OBrix, FBrix, FG; + if(dataRecord.brew_fermenter_sg>=1.020){ + OBrix = sg_to_brix(dataRecord.brew_fermenter_sg); + FBrix = parseFloat(event.args.value); + FG = Round(1.0031 - 0.002318474*OBrix - 0.000007775*(OBrix*OBrix) - 0.000000034*Math.pow(OBrix,3) + + 0.00574*(FBrix) + 0.00003344*(FBrix*FBrix) + 0.000000086*Math.pow(FBrix,3), 4); + //console.log("OBrix:"+OBrix+" FBrix:"+FBrix+" FG:"+FG); + if (FBrix > 0.05) { + $("#fg").val(FG); + dataRecord.fg=FG; + } + calcFermentation(); + } + }); + $("#fg").on('change',function (event){dataRecord.fg=parseFloat(event.args.value);calcFermentation();}); + $("#BLog").jqxButton({disabled:(dataRecord.log_brew)?false:true}); + $("#FLog").jqxButton({disabled:(dataRecord.log_fermentation)?false:true}); + } + + $("#styleSelect").jqxDropDownList({ + placeHolder: "Kies bierstijl:", + theme: theme, + source: styleslist, + displayMember: "name", + width: 180, + height: 23, + dropDownVerticalAlignment: 'top', + dropDownWidth: 500, + dropDownHeight: 380, + renderer: function (index, label, value) { + var datarecord = styleslist.records[index]; + return datarecord.style_guide + " " + datarecord.style_letter+ " " + datarecord.name; + } + }); + $("#styleSelect").on('select', function (event) { + if (event.args) { + var datarecord, index = event.args.index; + datarecord = styleslist.records[index]; + $("#st_name").val(datarecord.name); + $("#st_category").val(datarecord.category); + $("#st_category_number").val(datarecord.category_number); + $("#st_letter").val(datarecord.style_letter); + $("#st_guide").val(datarecord.style_guide); + $("#st_type").val(StyleTypeData[datarecord.type].nl); + $("#st_og_min").val(datarecord.og_min); + $("#st_og_max").val(datarecord.og_max); + $("#st_fg_min").val(datarecord.fg_min); + $("#st_fg_max").val(datarecord.fg_max); + $("#st_ibu_min").val(datarecord.ibu_min); + $("#st_ibu_max").val(datarecord.ibu_max); + $("#st_color_min").val(datarecord.color_min); + $("#st_color_max").val(datarecord.color_max); + $("#st_carb_min").val(datarecord.carb_min); + $("#st_carb_min2").val(datarecord.carb_min); + $("#st_carb_max").val(datarecord.carb_max); + $("#st_carb_max2").val(datarecord.carb_max); + $("#st_abv_min").val(datarecord.abv_min); + $("#st_abv_max").val(datarecord.abv_max); + } + }); + + // Equipemnt dropdown list + $("#equipmentSelect").jqxDropDownList({ + placeHolder: "Kies apparatuur:", + theme: theme, + source: equipmentlist, + displayMember: "name", + width: 170, + height: 23, + dropDownWidth: 300, + renderer: function (index, label, value) { + var datarecord = equipmentlist.records[index]; + return datarecord.batch_size + " liter " + datarecord.name; + } + }); + $("#equipmentSelect").on('select', function (event) { + if (event.args) { + var datarecord, factor, index = event.args.index; + datarecord = equipmentlist.records[index]; + factor = datarecord.batch_size / dataRecord.batch_size; + $("#eq_name").val(datarecord.name); + $("#eq_boil_size").val(datarecord.boil_size); + dataRecord.boil_size = datarecord.boil_size; + $("#boil_size").val(datarecord.boil_size); + $("#eq_batch_size").val(datarecord.batch_size); + dataRecord.batch_size = datarecord.batch_size; + $("#batch_size").val(datarecord.batch_size); + $("#est_a_vol").val(datarecord.batch_size * 1.04); + $("#eq_tun_volume").val(datarecord.tun_volume); + dataRecord.eq_tun_weight = datarecord.tun_weight; + dataRecord.eq_tun_specific_heat = datarecord.tun_specific_heat; + dataRecord.eq_tun_material = datarecord.tun_material; + dataRecord.eq_tun_height = datarecord.tun_height / 100.0; + $("#eq_top_up_water").val(datarecord.top_up_water); + dataRecord.eq_trub_chiller_loss = datarecord.trub_chiller_loss; + $("#eq_trub_chiller_loss").val(datarecord.trub_chiller_loss); + $("#eq_evap_rate").val(datarecord.evap_rate); + $("#eq_boil_time").val(datarecord.boil_time); + dataRecord.eq_calc_boil_volume = datarecord.calc_boil_volume; + $("#eq_top_up_kettle").val(datarecord.top_up_kettle); + $("#eq_hop_utilization").val(datarecord.hop_utilization); + $("#eq_notes").val(datarecord.notes); + $("#eq_lauter_volume").val(datarecord.lauter_volume); + dataRecord.eq_lauter_height = datarecord.lauter_height / 100.0; + $("#eq_lauter_deadspace").val(datarecord.lauter_deadspace); + $("#eq_kettle_volume").val(datarecord.kettle_volume); + dataRecord.eq_kettle_height = datarecord.kettle_height / 100.0; + $("#eq_mash_volume").val(datarecord.mash_volume); + $("#eq_mash_max").val(datarecord.mash_max); + dataRecord.eq_mash_max = datarecord.mash_max; + $("#mash_max").val(datarecord.mash_max); + $("#eq_efficiency").val(datarecord.efficiency); + dataRecord.efficiency = datarecord.efficiency; + $("#efficiency").val(datarecord.efficiency); + + dataRecord.sparge_volume = Math.round(datarecord.boil_size * 5) / 10; + $("#sparge_volume").val(dataRecord.sparge_volume); + $("#brew_sparge_volume").val(dataRecord.sparge_volume); + $("#est_pre_vol").val(datarecord.boil_size * 1.04); + calcFermentablesFromOG(parseFloat($("#est_og").jqxNumberInput('decimal'))); // Keep the OG + adjustWaters(factor); + calcFermentables(); + adjustHops(factor); + adjustMiscs(factor); + adjustYeasts(factor); + calcIBUs(); + calcWater(); + calcSparge(); + } + }); + + function saveRecord() { + console.log("saveRecord()"); + var row = { + record: my_record, + uuid: dataRecord.uuid, + name: $("#name").val(), + code: $("#code").val(), + birth: $("#birth").val(), + stage: dataRecord.stage, + notes: $("#notes").val(), + log_brew: dataRecord.log_brew, + log_fermentation: dataRecord.log_fermentation, + inventory_reduced: dataRecord.inventory_reduced, + locked: dataRecord.locked, + eq_name: $("#eq_name").val(), + eq_boil_size: parseFloat($("#eq_boil_size").jqxNumberInput('decimal')), + eq_batch_size: parseFloat($("#eq_batch_size").jqxNumberInput('decimal')), + eq_tun_volume: parseFloat($("#eq_tun_volume").jqxNumberInput('decimal')), + eq_tun_weight: dataRecord.eq_tun_weight, + eq_tun_specific_heat: dataRecord.eq_tun_specific_heat, + eq_tun_material: dataRecord.eq_tun_material, + eq_tun_height: dataRecord.eq_tun_height, + eq_top_up_water: parseFloat($("#eq_top_up_water").jqxNumberInput('decimal')), + eq_trub_chiller_loss: parseFloat($("#eq_trub_chiller_loss").jqxNumberInput('decimal')), + eq_evap_rate: parseFloat($("#eq_evap_rate").jqxNumberInput('decimal')), + eq_boil_time: parseFloat($("#eq_boil_time").jqxNumberInput('decimal')), + eq_calc_boil_volume: dataRecord.eq_calc_boil_volume, + eq_top_up_kettle: parseFloat($("#eq_top_up_kettle").jqxNumberInput('decimal')), + eq_hop_utilization: parseFloat($("#eq_hop_utilization").jqxNumberInput('decimal')), + eq_notes: $("#eq_notes").val(), + eq_lauter_volume: parseFloat($("#eq_lauter_volume").jqxNumberInput('decimal')), + eq_lauter_height: dataRecord.eq_lauter_height, + eq_lauter_deadspace: parseFloat($("#eq_lauter_deadspace").jqxNumberInput('decimal')), + eq_kettle_volume: parseFloat($("#eq_kettle_volume").jqxNumberInput('decimal')), + 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')), + brew_date_start: $("#brew_date_start").val(), + brew_mash_ph: parseFloat($("#brew_mash_ph").jqxNumberInput('decimal')), + brew_mash_sg: parseFloat($("#brew_mash_sg").jqxNumberInput('decimal')), + brew_mash_efficiency: parseFloat($("#brew_mash_efficiency").jqxNumberInput('decimal')), + brew_sparge_est: parseFloat($("#brew_sparge_est").jqxNumberInput('decimal')), + brew_sparge_ph: parseFloat($("#brew_sparge_ph").jqxNumberInput('decimal')), + brew_preboil_volume: parseFloat($("#brew_preboil_volume").jqxNumberInput('decimal')), + brew_preboil_sg: parseFloat($("#brew_preboil_sg").jqxNumberInput('decimal')), + brew_preboil_ph: parseFloat($("#brew_preboil_ph").jqxNumberInput('decimal')), + brew_preboil_efficiency: parseFloat($("#brew_preboil_efficiency").jqxNumberInput('decimal')), + brew_aboil_volume: parseFloat($("#brew_aboil_volume").jqxNumberInput('decimal')), + brew_aboil_sg: parseFloat($("#brew_aboil_sg").jqxNumberInput('decimal')), + brew_aboil_ph: parseFloat($("#brew_aboil_ph").jqxNumberInput('decimal')), + brew_aboil_efficiency: parseFloat($("#brew_aboil_efficiency").jqxNumberInput('decimal')), + brew_cooling_method: $("#brew_cooling_method").val(), + brew_cooling_time: parseFloat($("#brew_cooling_time").jqxNumberInput('decimal')), + brew_cooling_to: parseFloat($("#brew_cooling_to").jqxNumberInput('decimal')), + brew_whirlpool9: parseFloat($("#brew_whirlpool9").jqxNumberInput('decimal')), + brew_whirlpool7: parseFloat($("#brew_whirlpool7").jqxNumberInput('decimal')), + brew_whirlpool6: parseFloat($("#brew_whirlpool6").jqxNumberInput('decimal')), + brew_whirlpool2: parseFloat($("#brew_whirlpool2").jqxNumberInput('decimal')), + brew_fermenter_volume: parseFloat($("#brew_fermenter_volume").jqxNumberInput('decimal')), + brew_fermenter_extrawater: parseFloat($("#brew_fermenter_extrawater").jqxNumberInput('decimal')), + brew_fermenter_tcloss: parseFloat($("#brew_fermenter_tcloss").jqxNumberInput('decimal')), + brew_aeration_time: parseFloat($("#brew_aeration_time").jqxNumberInput('decimal')), + brew_aeration_speed: parseFloat($("#brew_aeration_speed").jqxNumberInput('decimal')), + brew_aeration_type: $("#brew_aeration_type").val(), + brew_fermenter_sg: parseFloat($("#brew_fermenter_sg").jqxNumberInput('decimal')), + brew_fermenter_ibu: parseFloat($("#brew_fermenter_ibu").jqxNumberInput('decimal')), + brew_fermenter_color: parseFloat($("#brew_fermenter_color").jqxNumberInput('decimal')), + brew_date_end: $("#brew_date_end").val(), + og: dataRecord.og, + fg: parseFloat($("#fg").jqxNumberInput('decimal')), + primary_start_temp: parseFloat($("#primary_start_temp").jqxNumberInput('decimal')), + primary_max_temp: parseFloat($("#primary_max_temp").jqxNumberInput('decimal')), + primary_end_temp: parseFloat($("#primary_end_temp").jqxNumberInput('decimal')), + primary_end_sg: parseFloat($("#primary_end_sg").jqxNumberInput('decimal')), + primary_end_date: $("#primary_end_date").val(), + secondary_temp: parseFloat($("#secondary_temp").jqxNumberInput('decimal')), + secondary_end_sg: parseFloat($("#secondary_end_sg").jqxNumberInput('decimal')), + secondary_end_date: $("#secondary_end_date").val(), + tertiary_temp: parseFloat($("#tertiary_temp").jqxNumberInput('decimal')), + package_date: $("#package_date").val(), + package_volume: parseFloat($("#package_volume").jqxNumberInput('decimal')), + package_infuse_amount: parseFloat($("#package_infuse_amount").jqxNumberInput('decimal')), + package_infuse_abv: parseFloat($("#package_infuse_abv").jqxNumberInput('decimal')), + package_infuse_notes: $("#package_infuse_notes").val(), + package_abv: parseFloat($("#package_abv").jqxNumberInput('decimal')), + package_ph: parseFloat($("#package_ph").jqxNumberInput('decimal')), + bottle_amount: parseFloat($("#bottle_amount").jqxNumberInput('decimal')), + bottle_carbonation: parseFloat($("#bottle_carbonation").jqxNumberInput('decimal')), + bottle_priming_water: parseFloat($("#bottle_priming_water").jqxNumberInput('decimal')), + bottle_priming_amount: parseFloat($("#bottle_priming_amount").jqxNumberInput('decimal')), + bottle_carbonation_temp: parseFloat($("#bottle_carbonation_temp").jqxNumberInput('decimal')), + keg_amount: parseFloat($("#keg_amount").jqxNumberInput('decimal')), + keg_carbonation: parseFloat($("#keg_carbonation").jqxNumberInput('decimal')), + keg_priming_water: parseFloat($("#keg_priming_water").jqxNumberInput('decimal')), + keg_priming_amount: parseFloat($("#keg_priming_amount").jqxNumberInput('decimal')), + keg_carbonation_temp: parseFloat($("#keg_carbonation_temp").jqxNumberInput('decimal')), + keg_forced_carb: dataRecord.keg_forced_carb, + keg_pressure: parseFloat($("#keg_pressure").jqxNumberInput('decimal')), + taste_notes: $("#taste_notes").val(), + taste_rate: parseFloat($("#taste_rate").jqxNumberInput('decimal')), + taste_date: $("#taste_date").val(), + taste_color: $("#taste_color").val(), + taste_transparency: $("#taste_transparency").val(), + taste_head: $("#taste_head").val(), + taste_aroma: $("#taste_aroma").val(), + taste_taste: $("#taste_taste").val(), + taste_mouthfeel: $("#taste_mouthfeel").val(), + taste_aftertaste: $("#taste_aftertaste").val(), + st_name: $('#st_name').val(), + st_letter: $('#st_letter').val(), + st_guide: $('#st_guide').val(), + st_type: dataRecord.st_type, + 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_source: $("#sparge_source").val(), + sparge_acid_type: $("#sparge_acid_type").val(), + sparge_acid_perc: parseFloat($("#sparge_acid_perc").jqxNumberInput('decimal')), + sparge_acid_amount: dataRecord.sparge_acid_amount, + calc_acid: dataRecord.calc_acid, + 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, + wg_amount: parseFloat($("#wg_amount").jqxNumberInput('decimal')), + wg_calcium: parseFloat($("#wg_calcium").jqxNumberInput('decimal')), + wg_sulfate: parseFloat($("#wg_sulfate").jqxNumberInput('decimal')), + wg_chloride: parseFloat($("#wg_chloride").jqxNumberInput('decimal')), + wg_sodium: parseFloat($("#wg_sodium").jqxNumberInput('decimal')), + wg_magnesium: parseFloat($("#wg_magnesium").jqxNumberInput('decimal')), + wg_total_alkalinity: parseFloat($("#wg_total_alkalinity").jqxNumberInput('decimal')), + wg_ph: parseFloat($("#wg_ph").jqxNumberInput('decimal')), + wb_calcium: parseFloat($("#wb_calcium").jqxNumberInput('decimal')), + wb_sulfate: parseFloat($("#wb_sulfate").jqxNumberInput('decimal')), + wb_chloride: parseFloat($("#wb_chloride").jqxNumberInput('decimal')), + wb_sodium: parseFloat($("#wb_sodium").jqxNumberInput('decimal')), + wb_magnesium: parseFloat($("#wb_magnesium").jqxNumberInput('decimal')), + wb_total_alkalinity: parseFloat($("#wb_total_alkalinity").jqxNumberInput('decimal')), + wb_ph: parseFloat($("#wb_ph").jqxNumberInput('decimal')), + wa_acid_name: $("#wa_acid_name").val(), + wa_acid_perc: parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')), + wa_base_name: $("#wa_base_name").val(), + starter_enable: dataRecord.starter_enable, + starter_type: $("#starter_type").val(), + starter_sg: parseFloat($("#starter_sg").jqxNumberInput('decimal')), + starter_viability: parseFloat($("#starter_viability").jqxNumberInput('decimal')), + prop1_type: $("#prop1_type").val(), + prop1_volume: parseFloat($("#prop1_volume").jqxNumberInput('decimal')), + prop2_type: $("#prop2_type").val(), + prop2_volume: parseFloat($("#prop2_volume").jqxNumberInput('decimal')), + prop3_type: $("#prop3_type").val(), + prop3_volume: parseFloat($("#prop3_volume").jqxNumberInput('decimal')), + prop4_type: $("#prop4_type").val(), + prop4_volume: parseFloat($("#prop4_volume").jqxNumberInput('decimal')), + fermentables: $('#fermentableGrid').jqxGrid('getrows'), + hops: $('#hopGrid').jqxGrid('getrows'), + miscs: $('#miscGrid').jqxGrid('getrows'), + yeasts: $('#yeastGrid').jqxGrid('getrows'), + mashs: $('#mashGrid').jqxGrid('getrows') + }, + data = "update=true&" + $.param(row); + $.ajax({ + dataType: 'json', + url: url, + cache: false, + data: data, + async: false, + type: "POST", + success: function (data, status, xhr) { + console.log("saveRecord() success"); + }, + error: function(jqXHR, textStatus, errorThrown) { + console.log("saveRecord() error"); + } + }); + }; + // initialize the input fields. // Tab 1, Algemeen $("#name").jqxTooltip({ content: 'De naam voor dit product.' }); @@ -4629,9 +4618,9 @@ }); $("#FermentableReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#FermentableReady").click(function () { - var rowID = $("#fermentableGrid").jqxGrid('getrowid', fermentableRow); + var row, rowID = $("#fermentableGrid").jqxGrid('getrowid', fermentableRow); console.log("FermentableReady row:"+fermentableRow+" ID:"+rowID); - var row = { + row = { f_name: fermentableData.f_name, f_origin: fermentableData.f_origin, f_supplier: fermentableData.f_supplier, @@ -4686,8 +4675,8 @@ }); $("#wf_select").on('select', function (event) { if (event.args) { - var index = event.args.index; - var datarecord = fermentablelist.records[index]; + var datarecord, index = event.args.index; + datarecord = fermentablelist.records[index]; $("#wf_name").val(datarecord.name); fermentableData.f_name = datarecord.name; fermentableData.f_origin = datarecord.origin; @@ -4724,34 +4713,35 @@ }); $("#wf_percentage").jqxNumberInput( Perc1dec ); $("#wf_percentage").on('change', function (event) { - var oldvalue = Math.round(fermentableData.f_percentage * 10) / 10.0; - var newvalue = event.args.value; + var newvalue, rowscount, rowdata, diff, tw, damount, namount, nw, newperc, + oldvalue = Math.round(fermentableData.f_percentage * 10) / 10.0; + newvalue = event.args.value; console.log("percentage changed: "+newvalue+" old: "+oldvalue); fermentableData.f_percent = newvalue; - var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; if ((oldvalue != newvalue) && (rowscount > 1)) { - var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', fermentableRow); + rowdata = $("#fermentableGrid").jqxGrid('getrowdata', fermentableRow); if (rowdata.f_adjust_to_total_100) { $("#wf_percentage").val(oldvalue); } else { - var diff = newvalue - oldvalue; - var tw = 0; // total weight + diff = newvalue - oldvalue; + tw = 0; // total weight for (i = 0; i < rowscount; i++) { - var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_added < 4) tw += Math.round(rowdata.f_amount * 1000) / 1000; } tw = Math.round(tw * 1000) / 1000; if (to_100) { // Adjust this row and the 100% row. - var damount = Math.round(tw * diff *10) / 1000; - var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', fermentableRow); - var namount = Math.round((rowdata.f_amount + damount) * 1000) / 1000; + damount = Math.round(tw * diff *10) / 1000; + rowdata = $("#fermentableGrid").jqxGrid('getrowdata', fermentableRow); + namount = Math.round((rowdata.f_amount + damount) * 1000) / 1000; $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_amount', namount); $("#wf_amount").val(namount); $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_percentage', rowdata.f_percentage + diff); for (i = 0; i < rowscount; i++) { - var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_adjust_to_total_100) { namount = rowdata.f_amount - damount; $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_percentage', rowdata.f_percentage - diff); @@ -4763,18 +4753,18 @@ calcMash(); } else { // Adjust all the rows. - var nw = tw * diff / 100; + nw = tw * diff / 100; for (i = 0; i < rowscount; i++) { - var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); + rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_added < 4) { if (i == fermentableRow) { - var namount = Math.round((rowdata.f_amount + nw) * 1000) / 1000; + namount = Math.round((rowdata.f_amount + nw) * 1000) / 1000; $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_amount', namount); // $("#wf_amount").val(namount); // Will crash the script. $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_percentage', newvalue); } else { - var namount = Math.round((rowdata.f_amount - (nw / (rowscount - 1))) * 1000) / 1000; - var newperc = Math.round((namount / tw) * 1000) / 10.0; + namount = Math.round((rowdata.f_amount - (nw / (rowscount - 1))) * 1000) / 1000; + newperc = Math.round((namount / tw) * 1000) / 10.0; $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_amount', namount); $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_percentage', newperc); } @@ -4795,8 +4785,8 @@ if (fermentableData.f_adjust_to_total_100 == 0) { if (to_100) { // Reset other flag first. - var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; - for (var i = 0; i < rowscount; i++) { + var i, rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; + for (i = 0; i < rowscount; i++) { if (i != fermentableRow) { $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_adjust_to_total_100', 0); } @@ -4899,9 +4889,8 @@ }); $("#HopReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#HopReady").click(function () { - var rowID = $("#hopGrid").jqxGrid('getrowid', hopRow); - console.log("HopReady row:"+hopRow+" ID:"+rowID); - var row = { + var row, rowID = $("#hopGrid").jqxGrid('getrowid', hopRow); + row = { h_name: $("#wh_name").val(), h_origin: hopData.h_origin, h_amount: parseFloat($("#wh_amount").jqxNumberInput('decimal')) / 1000, @@ -4946,9 +4935,8 @@ }); $("#wh_select").on('select', function (event) { if (event.args) { - var index = event.args.index; - var datarecord = hoplist.records[index]; - // console.log("select another hop:"+index+" "+datarecord.name); + var datarecord, index = event.args.index; + datarecord = hoplist.records[index]; $("#wh_name").val(datarecord.name); hopData.h_name = datarecord.name; hopData.h_origin = datarecord.origin; @@ -4969,8 +4957,8 @@ $("#wh_amount").jqxNumberInput( Spin1dec ); $('#wh_amount').on('change', function (event) { console.log("amount changed: "+event.args.value+" time:"+hopData.h_time+" alpha:"+hopData.h_alpha); - var amount = parseFloat(event.args.value) / 1000; - var ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, + var ibu, amount = parseFloat(event.args.value) / 1000; + ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($("#batch_size").jqxNumberInput('decimal')), amount, parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $("#ibu_method").val() @@ -4981,7 +4969,7 @@ $("#wh_ibu").jqxNumberInput( Show1dec ); $("#wh_time").jqxNumberInput( PosInt ); $("#wh_time").on('change', function (event) { - var newtime = parseFloat(event.args.value); + var ibu, newtime = parseFloat(event.args.value); // Check limits and correct if (hopData.h_useat == 2) { // Boil if (newtime > parseFloat($("#boil_time").jqxNumberInput('decimal'))) { @@ -5002,7 +4990,7 @@ } hopData.h_time = newtime * 1440; } - var ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($("#batch_size").jqxNumberInput('decimal')), + ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($("#batch_size").jqxNumberInput('decimal')), parseFloat(hopData.h_amount), parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $("#ibu_method").val()); // console.log("time changed: "+newtime+" final:"+hopData.h_time+" ibu:"+ibu); $("#wh_ibu").val(ibu); @@ -5053,9 +5041,9 @@ }); $("#MiscReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#MiscReady").click(function () { - var rowID = $("#miscGrid").jqxGrid('getrowid', miscRow); + var row, rowID = $("#miscGrid").jqxGrid('getrowid', miscRow); console.log("MiscReady row:"+miscRow+" ID:"+rowID); - var row = { + row = { m_name: miscData.m_name, m_amount: miscData.m_amount, m_cost: miscData.m_cost, @@ -5087,8 +5075,8 @@ }); $("#wm_select").on('select', function (event) { if (event.args) { - var index = event.args.index; - var datarecord = misclist.records[index]; + var datarecord, index = event.args.index; + datarecord = misclist.records[index]; $("#wm_name").val(datarecord.name); miscData.m_name = datarecord.name; miscData.m_cost = datarecord.cost; @@ -5105,7 +5093,6 @@ }); $("#wm_time").jqxNumberInput( PosInt ); $("#wm_time").on('change', function (event) { - console.log("time changed: "+event.args.value); var newtime = parseFloat(event.args.value); if (miscData.m_use_use == 2) { // Boil @@ -5167,9 +5154,9 @@ }); $("#YeastReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#YeastReady").click(function () { - var rowID = $("#yeastGrid").jqxGrid('getrowid', yeastRow); + var row, rowID = $("#yeastGrid").jqxGrid('getrowid', yeastRow); console.log("YeastReady row:"+yeastRow+" ID:"+rowID); - var row = { + row = { y_name: yeastData.y_name, y_laboratory: yeastData.y_laboratory, y_product_id: yeastData.y_product_id, @@ -5215,8 +5202,8 @@ }); $("#wy_select").on('select', function (event) { if (event.args) { - var index = event.args.index; - var datarecord = yeastlist.records[index]; + var datarecord, index = event.args.index; + datarecord = yeastlist.records[index]; $("#wy_name").val(datarecord.name); $("#wy_laboratory").val(datarecord.laboratory); $("#wy_product_id").val(datarecord.product_id); @@ -5245,11 +5232,9 @@ }); $("#wy_amount").jqxNumberInput( Spin1dec ); $('#wy_amount').on('change', function (event) { - console.log("amount changed: "+event.args.value); - if (yeastData.y_form == 0) // Liquid - var amount = parseFloat(event.args.value); - else - var amount = parseFloat(event.args.value) / 1000; + var amount = parseFloat(event.args.value); + if (yeastData.y_form != 0) // not Liquid + amount = parseFloat(event.args.value) / 1000; yeastData.y_amount = amount; calcFermentables(); calcYeast(); @@ -5272,7 +5257,7 @@ calcYeast(); } }); - for (var i = 1; i < 5; i++) { + for (i = 1; i < 5; i++) { $("#prop"+i+"_type").jqxDropDownList({ theme: theme, source: StarterTypeAdapter, @@ -5324,21 +5309,20 @@ }); $("#mash_select").on('select', function (event) { if (event.args) { - var index = event.args.index; + var data, datarecord, rowIDs, rows, i, row = {}, index = event.args.index; // First delete all current steps - var rowIDs = new Array(); - var rows = $("#mashGrid").jqxGrid('getdisplayrows'); - for (var i = 0; i < rows.length; i++) { - var row = rows[i]; + rowIDs = new Array(); + rows = $("#mashGrid").jqxGrid('getdisplayrows'); + for (i = 0; i < rows.length; i++) { + row = rows[i]; rowIDs.push(row.uid); } $("#mashGrid").jqxGrid('deleterow', rowIDs); // Then add the new steps - var datarecord = mashlist.records[index]; + datarecord = mashlist.records[index]; $("#mash_name").val(datarecord.name); for (i = 0; i < datarecord.steps.length; i++) { - var data = datarecord.steps[i]; - var row = {}; + data = datarecord.steps[i]; row["step_name"] = data.step_name; row["step_type"] = data.step_type; // For now, but this must be smarter. @@ -5391,8 +5375,8 @@ }); $("#wstep_type").on('select', function (event) { if (event.args) { - var index = event.args.index; - var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); + var rowdata, i, rows, row, index = event.args.index; + rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.step_type = index; if (index == 0) { $("#wstep_infuse_amount").show(); @@ -5403,9 +5387,9 @@ $("#wstep_pmpt").hide(); } mash_infuse = 0; - var rows = $('#mashGrid').jqxGrid('getrows'); - for (var i = 0; i < rows.length; i++) { - var row = rows[i]; + rows = $('#mashGrid').jqxGrid('getrows'); + for (i = 0; i < rows.length; i++) { + row = rows[i]; if (row.step_type == 0) // Infusion mash_infuse += parseFloat(row.step_infuse_amount); } @@ -5433,12 +5417,12 @@ }); $("#wstep_infuse_amount").jqxNumberInput( Spin1dec ); $('#wstep_infuse_amount').on('change', function (event) { - var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); + var row, i, rows, rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.step_infuse_amount = parseFloat(event.args.value); mash_infuse = 0; - var rows = $('#mashGrid').jqxGrid('getrows'); - for (var i = 0; i < rows.length; i++) { - var row = rows[i]; + rows = $('#mashGrid').jqxGrid('getrows'); + for (i = 0; i < rows.length; i++) { + row = rows[i]; if (row.step_type == 0) // Infusion mash_infuse += parseFloat(row.step_infuse_amount); } @@ -5472,8 +5456,8 @@ }); $("#w1_name").on('select', function (event) { if (event.args) { - var index = event.args.index; - var datarecord = waterlist.records[index]; + var datarecord, index = event.args.index; + datarecord = waterlist.records[index]; dataRecord.w1_name = datarecord.name; $("#w1_calcium").val(datarecord.calcium); dataRecord.w1_calcium = datarecord.calcium; @@ -5515,8 +5499,8 @@ }); $("#w2_name").on('select', function (event) { if (event.args) { - var index = event.args.index; - var datarecord = waterlist.records[index]; + var datarecord, index = event.args.index; + datarecord = waterlist.records[index]; dataRecord.w2_name = datarecord.name; $("#w2_calcium").val(datarecord.calcium); dataRecord.w2_calcium = datarecord.calcium; @@ -5582,8 +5566,8 @@ }); $("#pr_name").on('select', function (event) { if (event.args) { - var index = event.args.index; - var datarecord = waterprofiles.records[index]; + var datarecord, index = event.args.index; + datarecord = waterprofiles.records[index]; $("#pr_calcium").val(datarecord.calcium); $("#pr_sulfate").val(datarecord.sulfate); $("#pr_chloride").val(datarecord.chloride); @@ -5774,8 +5758,7 @@ $("#BLog").jqxButton({ template: "info", width: '150px', theme: theme }); $("#BLog").click(function () { // Open log in a new tab. - var url="log_brew.php?code=" + dataRecord.code + "&name=" + dataRecord.name; - window.open(url); + window.open("log_brew.php?code=" + dataRecord.code + "&name=" + dataRecord.name); }); // Tab 10, Fermentation @@ -5865,16 +5848,15 @@ }); $("#bottle_priming_sugar").on('select', function (event) { if (event.args) { - var index = event.args.index; - var editrow = -1; - var datarecord = fermentablesugars.records[index]; - var rows = $('#fermentableGrid').jqxGrid('getrows'); - for (var i = 0; i < rows.length; i++) { + var rowID, index, editrow = -1, datarecord, rows, i, row = {}; + index = event.args.index; + datarecord = fermentablesugars.records[index]; + rows = $('#fermentableGrid').jqxGrid('getrows'); + for (i = 0; i < rows.length; i++) { if (rows[i].f_added == 4) { editrow = i; } } - var row = {}; row["f_name"] = datarecord.name; row["f_origin"] = datarecord.origin; row["f_supplier"] = datarecord.supplier; @@ -5899,7 +5881,7 @@ row["f_acid_to_ph_57"] = datarecord.acid_to_ph_57; row["f_inventory"] = datarecord.inventory; if (editrow >= 0) { - var rowID = $('#fermentableGrid').jqxGrid('getrowid', editrow); + rowID = $('#fermentableGrid').jqxGrid('getrowid', editrow); $('#fermentableGrid').jqxGrid('updaterow', rowID, row); } else { $("#fermentableGrid").jqxGrid('addrow', null, row); @@ -5919,16 +5901,15 @@ }); $("#keg_priming_sugar").on('select', function (event) { if (event.args) { - var index = event.args.index; - var editrow = -1; - var datarecord = fermentablesugars.records[index]; - var rows = $('#fermentableGrid').jqxGrid('getrows'); - for (var i = 0; i < rows.length; i++) { + var rowID, index, editrow = -1, datarecord, rows, i, row = {}; + index = event.args.index; + datarecord = fermentablesugars.records[index]; + rows = $('#fermentableGrid').jqxGrid('getrows'); + for (i = 0; i < rows.length; i++) { if (rows[i].f_added == 5) { editrow = i; } } - var row = {}; row["f_name"] = datarecord.name; row["f_origin"] = datarecord.origin; row["f_supplier"] = datarecord.supplier; @@ -5953,7 +5934,7 @@ row["f_acid_to_ph_57"] = datarecord.acid_to_ph_57; row["f_inventory"] = datarecord.inventory; if (editrow >= 0) { - var rowID = $('#fermentableGrid').jqxGrid('getrowid', editrow); + rowID = $('#fermentableGrid').jqxGrid('getrowid', editrow); $('#fermentableGrid').jqxGrid('updaterow', rowID, row); } else { $("#fermentableGrid").jqxGrid('addrow', null, row);