Thu, 20 Jun 2019 13:55:12 +0200
Added packaging volume and add water or liquer to the beer after fermentation. Auto divide changing volumes between bottles and fusts. Upgrade the database in the crontask. Added these fields to the packaging tab screen.
/***************************************************************************** * Copyright (C) 2018-2019 * * Michiel Broek <mbroek at mbse dot eu> * * This file is part of BMS * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * BrewCloud is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ThermFerm; see the file COPYING. If not, write to the Free * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *****************************************************************************/ function createDelElements() { $('#eventWindow').jqxWindow({ theme: theme, position: { x: 490, y: 210 }, width: 300, height: 175, resizable: false, isModal: true, modalOpacity: 0.4, okButton: $('#delOk'), cancelButton: $('#delCancel'), initContent: function () { $('#delOk').jqxButton({ template: "danger", width: '65px', theme: theme }); $('#delCancel').jqxButton({ template: "success", width: '65px', theme: theme }); $('#delCancel').focus(); } }); $('#eventWindow').jqxWindow('hide'); } $(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 MMCO3 = 60.01684; var MMHCO3 = 61.01684; var MMCaSO4 = 172.171; var MMCaCl2 = 147.015; var MMCaCO3 = 100.087; var MMMgSO4 = 246.475; var MMNaHCO3 = 84.007; var MMNa2CO3 = 105.996; var MMNaCl = 58.443; var MMCaOH2 = 74.06268; var 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("<img src='images/dialog-ok-apply.png'>"); else $("#ok_supplies").html("<img src='images/dialog-error.png'>"); } 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; i < rows.length; i++) { var row = rows[i]; if (row.step_type == 0) // Infusion mvol += parseFloat(row.step_infuse_amount); if (row.step_temp <= 75) { // Ignore mashout mashtime += row.step_time; mashtemp += row.step_time * row.step_temp; } } mashtemp = mashtemp / mashtime; } 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 += 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); 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); // 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 = Math.round(plato_to_sg(pt) * 10000) / 10000; $("#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); 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); 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); } $("#yeast_cells").val(initcells); $("#need_cells").val(getNeededYeastCells()); }; 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 (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("<img src='images/dialog-error.png'>"); } else { $("#r"+i+"_irate").html("<img src='images/dialog-ok-apply.png'>"); } if (parseFloat($("#prop"+i+"_growf").val()) < 1) $("#r"+i+"_growf").html("<img src='images/dialog-error.png'>"); if (($("#prop"+i+"_type").val() > 0) && (parseFloat($("#prop"+i+"_growf").val()) > 3)) $("#r"+i+"_growf").html("<img src='images/dialog-error.png'>"); if (parseFloat($("#prop"+i+"_tcells").val()) > needed) $("#r"+i+"_tcells").html("<img src='images/dialog-ok-apply.png'>"); 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); var commit = $("#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; var commit = $("#miscGrid").jqxGrid('addrow', null, row); } } } }); miscs.dataBind(); return; } } } function setRangeIndicator(ion, rangeCode) { if ((rangeCode == "laag") || (rangeCode == "hoog")) $("#wr_"+ion).html("<img src='images/dialog-error.png'><span style='vertical-align: top; font-size: 10px; font-style: italic;'>"+rangeCode + "</span>"); else $("#wr_"+ion).html("<img src='images/dialog-ok-apply.png'>"); } 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("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer moutig en zoet</span>"); else if (GetBUGU() < 0.43) $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Moutig, zoet</span>"); else if (GetBUGU() < 0.52) $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Evenwichtig</span>"); else if (GetBUGU() < 0.63) $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Licht hoppig, bitter</span>"); else $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Extra hoppig, zeer bitter</span>"); $('#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); console.log("calcFermentation() og:"+dataRecord.brew_fermenter_sg+" brix:"+obrix); if ((dataRecord.primary_end_sg > 0.990) && (dataRecord.primary_end_sg < dataRecord.brew_fermenter_sg)) { var primary_svg = 100 * (dataRecord.brew_fermenter_sg - dataRecord.primary_end_sg) / (dataRecord.brew_fermenter_sg - 1); //console.log("primary svg: "+primary_svg); $("#primary_svg").val(primary_svg); if ((dataRecord.fg > 0.990) && (dataRecord.fg < dataRecord.brew_fermenter_sg)) { var final_svg = 100 * (dataRecord.brew_fermenter_sg - dataRecord.fg) / (dataRecord.brew_fermenter_sg - 1); $("#final_svg").val(final_svg); var ABV = abvol(dataRecord.brew_fermenter_sg, dataRecord.fg); $("#final_abv").val(ABV); } } } function ResCO2(CO2, T) { //var resco2 = 0.000849151 * T * T - 0.0587512 * T + 1.71137; // brouwhulp var F = T * 1.8 + 32; var resco2 = 3.0378 - 0.050062 * F + 0.00026555 * F * F; // most of the rest //console.log("CO2: "+resco2); return resco2; } function CarbCO2toS(CO2, T, SFactor) { var sugar = SFactor * (CO2 - ResCO2(CO2, T)) / 0.286; if (sugar < 0) sugar = 0; return Math.round(sugar * 1000) / 1000; } function GetPressure(CO2, T1, T2) { var F = T2 * 1.8 + 32; var V = CO2 - ResCO2(CO2, T1); if (V < 0) return 0; var 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 P = Math.round(P * 10) / 10; return P; } 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 = dataRecord.secondary_temp; // End fermentation temperature. if (TSec < 1) TSec = dataRecord.primary_end_temp; // Fallback if (TSec < 1) TSec = 18; // Fallback to room temperature. if (dataRecord.fg == 0.000) var ABV = abvol(dataRecord.brew_fermenter_sg, parseFloat($("#est_fg").jqxNumberInput('decimal'))); else var ABV = abvol(dataRecord.brew_fermenter_sg, dataRecord.fg); /* * Calculate new volume and alcohol. */ var bvol = dataRecord.package_volume - (ABV * dataRecord.package_volume) / 100; var balc = dataRecord.package_volume - bvol; var mvol = dataRecord.package_infuse_amount - (dataRecord.package_infuse_abv * dataRecord.package_infuse_amount) / 100; var malc = dataRecord.package_infuse_amount - mvol; var talc = balc + malc; var tvol = bvol + mvol; ABV = Math.round(talc / (tvol + talc) * 10000) / 100; //console.log("bvol:"+bvol+" balc:"+balc+" mvol:"+mvol+" malc:"+malc+" tvol:"+tvol+" talc:"+talc+" abv:"+ABV+" vol:"+(tvol + talc)); dataRecord.package_abv = ABV; $("#package_abv").val(ABV); console.log("calcCarbonation() TSec:"+TSec+" ABV:"+ABV); if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) { return; // grid not yet loaded. } // Bottles dataRecord.bottle_priming_amount = 0; dataRecord.bottle_priming_total = 0; for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.f_added == 4) { var 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 = Math.round(dataRecord.bottle_amount * dataRecord.bottle_priming_amount * 100) / 100; $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_amount', dataRecord.bottle_priming_total / 1000); } } $("#bottle_priming_amount").val(Math.round(dataRecord.bottle_priming_amount * 10) / 10); $("#bottle_priming_total").val(dataRecord.bottle_priming_total); $("#bottle_abv").val(Math.round((ABV + dataRecord.bottle_priming_amount * 0.47 / 7.907) * 10) / 10); $("#bottle_pressure").val(GetPressure(dataRecord.bottle_carbonation, TSec, dataRecord.bottle_carbonation_temp)); // Kegs var Pressure = CarbCO2ToPressure(dataRecord.keg_carbonation, dataRecord.keg_carbonation_temp); if (Pressure < 0) Pressure = 0; dataRecord.keg_pressure = Pressure; $("#keg_pressure").val(Math.round(Pressure * 10) / 10); dataRecord.keg_priming_amount = 0; dataRecord.keg_priming_total = 0; if (! dataRecord.keg_forced_carb) { for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.f_added == 5) { var 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 = Math.round(dataRecord.keg_amount * dataRecord.keg_priming_amount * 100) / 100; $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_amount', dataRecord.keg_priming_total / 1000); } } } $("#keg_priming_amount").val(Math.round(dataRecord.keg_priming_amount * 10) / 10); $("#keg_priming_total").val(dataRecord.keg_priming_total); $("#keg_abv").val(Math.round((ABV + dataRecord.keg_priming_amount * 0.47 / 7.907) * 10) / 10); } function calcStage() { var newstage = dataRecord.stage; /* parseFloat$("#brew_date_start").val()) returns the year if it is a valid mysql style date. */ 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) { 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 }); } 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_sparge_temperature").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_sparge_volume").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_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 }); $("#bottle_amount").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 }); } else { $("#propagator").hide(); $("#starter_type").jqxDropDownList( {disabled: true }); $("#starter_try").jqxButton({ disabled: true }); $("#starter_sg").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(); } }); $('#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); 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); calcSparge(); }); $('#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(); }); $('#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(); }); $('#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) { // Brix reading from refractometer RI if (dataRecord.brew_fermenter_sg >= 1.020) { OBrix = sg_to_brix(dataRecord.brew_fermenter_sg); FBrix = parseFloat(event.args.value) / my_brix_correction; // http://seanterrill.com/2011/04/07/refractometer-fg-results/ var FG = 1.0000 - 0.0044993 * OBrix + 0.0117741 * FBrix + 0.000275806 * (OBrix * OBrix) - 0.00127169 * (FBrix * FBrix) - 0.00000727999 * Math.pow(OBrix, 3) + 0.0000632929 * Math.pow(FBrix, 3); // var FG = 1.0000 - 0.00085683 * OBrix + 0.0034941 * FBrix; // Brouwhulp // 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 (FG > 1.00001) { $("#primary_end_sg").val(FG); dataRecord.primary_end_sg = FG; } calcFermentation(); } }); $("#final_brix").on('change', function (event) { // Brix reading from refractometer RI if (dataRecord.brew_fermenter_sg >= 1.020) { OBrix = sg_to_brix(dataRecord.brew_fermenter_sg); FBrix = parseFloat(event.args.value) / my_brix_correction; var FG = 1.0000 - 0.0044993 * OBrix + 0.0117741 * FBrix + 0.000275806 * (OBrix * OBrix) - 0.00127169 * (FBrix * FBrix) - 0.00000727999 * Math.pow(OBrix, 3) + 0.0000632929 * Math.pow(FBrix, 3); console.log("OBrix:"+OBrix+" FBrix:"+FBrix+" FG:"+FG); if (FG > 1.00001) { $("#fg").val(FG); dataRecord.fg = FG; } 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); $("#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_temperature: parseFloat($("#brew_sparge_temperature").jqxNumberInput('decimal')), brew_sparge_volume: parseFloat($("#brew_sparge_volume").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_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')), bottle_amount: parseFloat($("#bottle_amount").jqxNumberInput('decimal')), bottle_carbonation: parseFloat($("#bottle_carbonation").jqxNumberInput('decimal')), bottle_priming_water: $("#bottle_priming_water").val(), 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: $("#keg_priming_water").val(), 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')), 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"; // Prepare the data var source = { datatype: "json", cache: false, datafields: [ // From prod_main { name: 'record', type: 'number' }, { name: 'uuid', type: 'string' }, { name: 'name', type: 'string' }, { name: 'code', type: 'string' }, { name: 'birth', type: 'string' }, { name: 'stage', type: 'int' }, { name: 'notes', type: 'string' }, { name: 'log_brew', type: 'int' }, { name: 'log_fermentation', type: 'int' }, { name: 'inventory_reduced', type: 'int' }, { name: 'locked', type: 'int' }, { name: 'eq_name', type: 'string' }, { name: 'eq_boil_size', type: 'float' }, { name: 'eq_batch_size', type: 'float' }, { name: 'eq_tun_volume', type: 'float' }, { name: 'eq_tun_weight', type: 'float' }, { name: 'eq_tun_specific_heat', type: 'float' }, { name: 'eq_tun_material', type: 'int' }, { name: 'eq_tun_height', type: 'float' }, { name: 'eq_top_up_water', type: 'float' }, { name: 'eq_trub_chiller_loss', type: 'float' }, { name: 'eq_evap_rate', type: 'float' }, { name: 'eq_boil_time', type: 'float' }, { name: 'eq_calc_boil_volume', type: 'int' }, { name: 'eq_top_up_kettle', type: 'float' }, { name: 'eq_hop_utilization', type: 'float' }, { name: 'eq_notes', type: 'string' }, { name: 'eq_lauter_volume', type: 'float' }, { name: 'eq_lauter_height', type: 'float' }, { name: 'eq_lauter_deadspace', type: 'float' }, { name: 'eq_kettle_volume', type: 'float' }, { name: 'eq_kettle_height', type: 'float' }, { name: 'eq_mash_volume', type: 'float' }, { name: 'eq_mash_max', type: 'float' }, { name: 'eq_efficiency', type: 'float' }, { name: 'brew_date_start', type: 'string' }, { name: 'brew_mash_ph', type: 'float' }, { name: 'brew_mash_sg', type: 'float' }, { name: 'brew_mash_efficiency', type: 'float' }, { name: 'brew_sparge_temperature', type: 'float' }, { name: 'brew_sparge_volume', type: 'float' }, { name: 'brew_sparge_est', type: 'float' }, { name: 'brew_sparge_ph', type: 'float' }, { name: 'brew_preboil_volume', type: 'float' }, { name: 'brew_preboil_sg', type: 'float' }, { name: 'brew_preboil_ph', type: 'float' }, { name: 'brew_preboil_efficiency', type: 'float' }, { name: 'brew_aboil_volume', type: 'float' }, { name: 'brew_aboil_sg', type: 'float' }, { name: 'brew_aboil_ph', type: 'float' }, { name: 'brew_aboil_efficiency', type: 'float' }, { name: 'brew_cooling_method', type: 'int' }, { name: 'brew_cooling_time', type: 'float' }, { name: 'brew_cooling_to', type: 'float' }, { name: 'brew_whirlpool9', type: 'float' }, { name: 'brew_whirlpool7', type: 'float' }, { name: 'brew_whirlpool6', type: 'float' }, { name: 'brew_whirlpool2', type: 'float' }, { name: 'brew_fermenter_volume', type: 'float' }, { name: 'brew_fermenter_extrawater', type: 'float' }, { name: 'brew_fermenter_tcloss', type: 'float' }, { name: 'brew_aeration_time', type: 'float' }, { name: 'brew_aeration_speed', type: 'float' }, { name: 'brew_aeration_type', type: 'int' }, { name: 'brew_fermenter_sg', type: 'float' }, { name: 'brew_fermenter_ibu', type: 'float' }, { name: 'brew_fermenter_color', type: 'float' }, { name: 'brew_date_end', type: 'string' }, { name: 'og', type: 'float' }, { name: 'fg', type: 'float' }, { name: 'primary_start_temp', type: 'float' }, { name: 'primary_max_temp', type: 'float' }, { name: 'primary_end_temp', type: 'float' }, { name: 'primary_end_sg', type: 'float' }, { name: 'primary_end_date', type: 'string' }, { name: 'secondary_temp', type: 'float' }, { name: 'secondary_end_date', type: 'string' }, { name: 'tertiary_temp', type: 'float' }, { name: 'package_date', type: 'string' }, { name: 'package_volume', type: 'float' }, { name: 'package_infuse_amount', type: 'float' }, { name: 'package_infuse_abv', type: 'float' }, { name: 'package_infuse_notes', type: 'string' }, { name: 'package_abv', type: 'float' }, { name: 'bottle_amount', type: 'float' }, { name: 'bottle_carbonation', type: 'float' }, { name: 'bottle_priming_water', type: 'int' }, { name: 'bottle_priming_amount', type: 'float' }, { name: 'bottle_carbonation_temp', type: 'float' }, { name: 'keg_amount', type: 'float' }, { name: 'keg_carbonation', type: 'float' }, { name: 'keg_priming_water', type: 'int' }, { name: 'keg_priming_amount', type: 'float' }, { name: 'keg_carbonation_temp', type: 'float' }, { name: 'keg_forced_carb', type: 'int' }, { name: 'keg_pressure', type: 'float' }, { name: 'taste_notes', type: 'string' }, { name: 'taste_rate', type: 'float' }, { name: 'taste_date', type: 'string' }, { name: 'taste_color', type: 'string' }, { name: 'taste_transparency', type: 'string' }, { name: 'taste_head', type: 'string' }, { name: 'taste_aroma', type: 'string' }, { name: 'taste_taste', type: 'string' }, { name: 'taste_mouthfeel', type: 'string' }, { name: 'taste_aftertaste', type: 'string' }, { name: 'st_name', type: 'string' }, { name: 'st_letter', type: 'string' }, { name: 'st_guide', type: 'string' }, { name: 'st_category', type: 'string' }, { name: 'st_category_number', type: 'float' }, { name: 'st_type', type: 'int' }, { name: 'st_og_min', type: 'float' }, { name: 'st_og_max', type: 'float' }, { name: 'st_fg_min', type: 'float' }, { name: 'st_fg_max', type: 'float' }, { name: 'st_ibu_min', type: 'float' }, { name: 'st_ibu_max', type: 'float' }, { name: 'st_color_min', type: 'float' }, { name: 'st_color_max', type: 'float' }, { name: 'st_carb_min', type: 'float' }, { name: 'st_carb_max', type: 'float' }, { name: 'st_abv_min', type: 'float' }, { name: 'st_abv_max', type: 'float' }, { name: 'type', type: 'int' }, { name: 'batch_size', type: 'float' }, { name: 'boil_size', type: 'float' }, { name: 'boil_time', type: 'float' }, { name: 'efficiency', type: 'float' }, { name: 'est_og', type: 'float' }, { name: 'est_fg', type: 'float' }, { name: 'est_abv', type: 'float' }, { name: 'est_color', type: 'float' }, { name: 'color_method', type: 'int' }, { name: 'est_ibu', type: 'float' }, { name: 'ibu_method', type: 'int' }, { name: 'est_carb', type: 'float' }, { name: 'sparge_temp', type: 'float' }, { name: 'sparge_ph', type: 'float' }, { name: 'sparge_volume', type: 'float' }, { name: 'sparge_source', type: 'int' }, { name: 'sparge_acid_type', type: 'int' }, { name: 'sparge_acid_perc', type: 'float' }, { name: 'sparge_acid_amount', type: 'float' }, { name: 'mash_ph', type: 'float' }, { name: 'mash_name', type: 'string' }, { name: 'calc_acid', type: 'int' }, { name: 'w1_name', type: 'string' }, { name: 'w1_amount', type: 'float' }, { name: 'w1_calcium', type: 'float' }, { name: 'w1_sulfate', type: 'float' }, { name: 'w1_chloride', type: 'float' }, { name: 'w1_sodium', type: 'float' }, { name: 'w1_magnesium', type: 'float' }, { name: 'w1_total_alkalinity', type: 'float' }, { name: 'w1_ph', type: 'float' }, { name: 'w1_cost', type: 'float' }, { name: 'w2_name', type: 'string' }, { name: 'w2_amount', type: 'float' }, { name: 'w2_calcium', type: 'float' }, { name: 'w2_sulfate', type: 'float' }, { name: 'w2_chloride', type: 'float' }, { name: 'w2_sodium', type: 'float' }, { name: 'w2_magnesium', type: 'float' }, { name: 'w2_total_alkalinity', type: 'float' }, { name: 'w2_ph', type: 'float' }, { name: 'w2_cost', type: 'float' }, { name: 'wg_amount', type: 'float' }, { name: 'wg_calcium', type: 'float' }, { name: 'wg_sulfate', type: 'float' }, { name: 'wg_chloride', type: 'float' }, { name: 'wg_sodium', type: 'float' }, { name: 'wg_magnesium', type: 'float' }, { name: 'wg_total_alkalinity', type: 'float' }, { name: 'wg_ph', type: 'float' }, { name: 'wb_calcium', type: 'float' }, { name: 'wb_sulfate', type: 'float' }, { name: 'wb_chloride', type: 'float' }, { name: 'wb_sodium', type: 'float' }, { name: 'wb_magnesium', type: 'float' }, { name: 'wb_total_alkalinity', type: 'float' }, { name: 'wb_ph', type: 'float' }, { name: 'wa_acid_name', type: 'int' }, { name: 'wa_acid_perc', type: 'int' }, { name: 'wa_base_name', type: 'int' }, { name: 'starter_enable', type: 'int' }, { name: 'starter_type', type: 'int' }, { name: 'starter_sg', type: 'float' }, { name: 'prop1_type', type: 'int' }, { name: 'prop1_volume', type: 'float' }, { name: 'prop2_type', type: 'int' }, { name: 'prop2_volume', type: 'float' }, { name: 'prop3_type', type: 'int' }, { name: 'prop3_volume', type: 'float' }, { name: 'prop4_type', type: 'int' }, { name: 'prop4_volume', type: 'float' }, { name: 'fermentables', type: 'array' }, { name: 'hops', type: 'array' }, { name: 'miscs', type: 'array' }, { name: 'yeasts', type: 'array' }, { name: 'mashs', type: 'array' } ], id: 'record', url: url + '?record=' + my_record }; // Load data and select one record. var dataAdapter = new $.jqx.dataAdapter(source, { loadComplete: function () { var records = dataAdapter.records; dataRecord = records[0]; // Hidden record uuid $("#name").val(dataRecord.name); $("#code").val(dataRecord.code); $("#birth").val(dataRecord.birth); $("#stage").val(StageData[dataRecord.stage].nl); $("#notes").val(dataRecord.notes); $("#locked").val(dataRecord.locked); $("#eq_name").val(dataRecord.eq_name); $("#eq_notes").val(dataRecord.eq_notes); $("#eq_boil_size").val(dataRecord.eq_boil_size); $("#eq_batch_size").val(dataRecord.eq_batch_size); $("#eq_tun_volume").val(dataRecord.eq_tun_volume); $("#eq_top_up_water").val(dataRecord.eq_top_up_water); $("#eq_trub_chiller_loss").val(dataRecord.eq_trub_chiller_loss); $("#eq_evap_rate").val(dataRecord.eq_evap_rate); $("#eq_boil_time").val(dataRecord.eq_boil_time); $("#eq_top_up_kettle").val(dataRecord.eq_top_up_kettle); $("#eq_hop_utilization").val(dataRecord.eq_hop_utilization); $("#eq_lauter_volume").val(dataRecord.eq_lauter_volume); $("#eq_lauter_deadspace").val(dataRecord.eq_lauter_deadspace); $("#eq_kettle_volume").val(dataRecord.eq_kettle_volume); $("#eq_mash_volume").val(dataRecord.eq_mash_volume); $("#eq_mash_max").val(dataRecord.eq_mash_max); $("#eq_efficiency").val(dataRecord.eq_efficiency); // Brewdate $("#brew_date_start").val(dataRecord.brew_date_start); $("#brew_mash_ph").val(dataRecord.brew_mash_ph); $("#brew_mash_sg").val(dataRecord.brew_mash_sg); $("#brew_mash_efficiency").val(dataRecord.brew_mash_efficiency); // Header Spoelen en filteren $("#brew_sparge_temperature").val(dataRecord.brew_sparge_temperature); $("#brew_sparge_volume").val(dataRecord.brew_sparge_volume); $("#brew_sparge_est").val(dataRecord.brew_sparge_est); $("#brew_sparge_ph").val(dataRecord.brew_sparge_ph); // Header Beluchten $("#brew_aeration_type").val(dataRecord.brew_aeration_type); $("#brew_aeration_time").val(dataRecord.brew_aeration_time); $("#brew_aeration_speed").val(dataRecord.brew_aeration_speed); $("#brew_preboil_ph").val(dataRecord.brew_preboil_ph); $("#brew_preboil_sg").val(dataRecord.brew_preboil_sg); $("#brew_preboil_volume").val(dataRecord.brew_preboil_volume); $("#brew_preboil_efficiency").val(dataRecord.brew_preboil_efficiency); // Header Koelen en whirlpoolen $("#brew_whirlpool9").val(dataRecord.brew_whirlpool9); $("#brew_whirlpool7").val(dataRecord.brew_whirlpool7); $("#brew_whirlpool6").val(dataRecord.brew_whirlpool6); $("#brew_whirlpool2").val(dataRecord.brew_whirlpool2); // Header Naar gistvat $("#brew_fermenter_volume").val(dataRecord.brew_fermenter_volume); $("#brew_fermenter_sg").val(dataRecord.brew_fermenter_sg); $("#brew_fermenter_sg2").val(dataRecord.brew_fermenter_sg); $("#brew_fermenter_ibu").val(dataRecord.brew_fermenter_ibu); $("#brew_fermenter_color").val(dataRecord.brew_fermenter_color); $("#brew_fermenter_extrawater").val(dataRecord.brew_fermenter_extrawater); $("#brew_fermenter_tcloss").val(dataRecord.brew_fermenter_tcloss); $("#brew_aboil_ph").val(dataRecord.brew_aboil_ph); $("#brew_aboil_sg").val(dataRecord.brew_aboil_sg); $("#brew_aboil_volume").val(dataRecord.brew_aboil_volume); $("#brew_aboil_efficiency").val(dataRecord.brew_aboil_efficiency); // Header Koelen en whirlpoolen $("#brew_cooling_to").val(dataRecord.brew_cooling_to); $("#brew_cooling_method").val(dataRecord.brew_cooling_method); $("#brew_cooling_time").val(dataRecord.brew_cooling_time); // Niks $("#brew_date_end").val(dataRecord.brew_date_end); $("#og").val(dataRecord.og); $("#fg").val(dataRecord.fg); $("#primary_start_temp").val(dataRecord.primary_start_temp); $("#primary_max_temp").val(dataRecord.primary_max_temp); $("#primary_end_temp").val(dataRecord.primary_end_temp); $("#primary_end_sg").val(dataRecord.primary_end_sg); $("#primary_end_date").val(dataRecord.primary_end_date); $("#secondary_temp").val(dataRecord.secondary_temp); $("#secondary_end_date").val(dataRecord.secondary_end_date); $("#tertiary_temp").val(dataRecord.tertiary_temp); $("#package_date").val(dataRecord.package_date); $("#package_volume").val(dataRecord.package_volume); $("#package_infuse_amount").val(dataRecord.package_infuse_amount); $("#package_infuse_abv").val(dataRecord.package_infuse_abv); $("#package_infuse_notes").val(dataRecord.package_infuse_notes); $("#package_abv").val(dataRecord.package_abv); $("#bottle_amount").val(dataRecord.bottle_amount); $("#bottle_carbonation").val(dataRecord.bottle_carbonation); $("#bottle_priming_water").val(dataRecord.bottle_priming_water); $("#bottle_priming_amount").val(dataRecord.bottle_priming_amount); $("#bottle_carbonation_temp").val(dataRecord.bottle_carbonation_temp); $("#keg_amount").val(dataRecord.keg_amount); $("#keg_carbonation").val(dataRecord.keg_carbonation); $("#keg_priming_water").val(dataRecord.keg_priming_water); $("#keg_priming_amount").val(dataRecord.keg_priming_amount); $("#keg_carbonation_temp").val(dataRecord.keg_carbonation_temp); $("#keg_forced_carb").val(dataRecord.keg_forced_carb); $("#keg_pressure").val(dataRecord.keg_pressure); $("#taste_notes").val(dataRecord.taste_notes); $("#taste_rate").val(dataRecord.taste_rate); $("#taste_date").val(dataRecord.taste_date); $("#taste_color").val(dataRecord.taste_color); $("#taste_transparency").val(dataRecord.taste_transparency); $("#taste_head").val(dataRecord.taste_head); $("#taste_aroma").val(dataRecord.taste_aroma); $("#taste_taste").val(dataRecord.taste_taste); $("#taste_mouthfeel").val(dataRecord.taste_mouthfeel); $("#taste_aftertaste").val(dataRecord.taste_aftertaste); // Recipe $("#st_name").val(dataRecord.st_name); $("#st_letter").val(dataRecord.st_letter); $("#st_guide").val(dataRecord.st_guide); $("#st_category").val(dataRecord.st_category); $("#st_category_number").val(dataRecord.st_category_number); $("#st_type").val(StyleTypeData[dataRecord.st_type].nl); $("#st_og_min").val(dataRecord.st_og_min); $("#st_og_max").val(dataRecord.st_og_max); $("#st_fg_min").val(dataRecord.st_fg_min); $("#st_fg_max").val(dataRecord.st_fg_max); $("#st_abv_min").val(dataRecord.st_abv_min); $("#st_abv_max").val(dataRecord.st_abv_max); $("#st_color_min").val(dataRecord.st_color_min); $("#st_color_max").val(dataRecord.st_color_max); $("#st_ibu_min").val(dataRecord.st_ibu_min); $("#st_ibu_max").val(dataRecord.st_ibu_max); $("#st_carb_min").val(dataRecord.st_carb_min); $("#st_carb_min2").val(dataRecord.st_carb_min); $("#st_carb_max").val(dataRecord.st_carb_max); $("#st_carb_max2").val(dataRecord.st_carb_max); $("#type").val(dataRecord.type); $("#batch_size").val(dataRecord.batch_size); $("#est_a_vol").val(dataRecord.batch_size * 1.04); $("#boil_size").val(dataRecord.boil_size); $("#est_pre_vol").val(dataRecord.boil_size * 1.04); $("#boil_time").val(dataRecord.boil_time); $("#efficiency").val(dataRecord.efficiency); $("#est_og").val(dataRecord.est_og); $("#est_og2").val(dataRecord.est_og); $("#est_og3").val(0); $("#est_fg").val(dataRecord.est_fg); $("#est_fg2").val(dataRecord.est_fg); $("#est_fg3").val(dataRecord.est_fg); $("#est_color").val(dataRecord.est_color); $("#est_color2").val(dataRecord.est_color); $("#est_abv").val(dataRecord.est_abv); $("#color_method").val(dataRecord.color_method); $("#est_ibu").val(dataRecord.est_ibu); $("#est_ibu2").val(dataRecord.est_ibu); $("#ibu_method").val(dataRecord.ibu_method); $("#est_carb").val(dataRecord.est_carb); $("#mash_name").val(dataRecord.mash_name); $("#mash_ph").val(dataRecord.mash_ph); $("#sparge_temp").val(dataRecord.sparge_temp); $("#sparge_ph").val(dataRecord.sparge_ph); $("#sparge_volume").val(dataRecord.sparge_volume); $("#sparge_source").val(dataRecord.sparge_source); $("#sparge_acid_type").val(dataRecord.sparge_acid_type); $("#sparge_acid_perc").val(dataRecord.sparge_acid_perc); $("#sparge_acid_amount").val(dataRecord.sparge_acid_amount * 1000); $("#calc_acid").val(dataRecord.calc_acid); $("#w1_name").val(dataRecord.w1_name); $("#w1_amount").val(dataRecord.w1_amount); $("#w1_calcium").val(dataRecord.w1_calcium); $("#w1_sulfate").val(dataRecord.w1_sulfate); $("#w1_chloride").val(dataRecord.w1_chloride); $("#w1_sodium").val(dataRecord.w1_sodium); $("#w1_magnesium").val(dataRecord.w1_magnesium); $("#w1_total_alkalinity").val(dataRecord.w1_total_alkalinity); $("#w1_ph").val(dataRecord.w1_ph); $("#w1_cost").val(dataRecord.w1_cost); $("#w2_name").val(dataRecord.w2_name); $("#w2_amount").val(dataRecord.w2_amount); $("#w2_calcium").val(dataRecord.w2_calcium); $("#w2_sulfate").val(dataRecord.w2_sulfate); $("#w2_chloride").val(dataRecord.w2_chloride); $("#w2_sodium").val(dataRecord.w2_sodium); $("#w2_magnesium").val(dataRecord.w2_magnesium); $("#w2_total_alkalinity").val(dataRecord.w2_total_alkalinity); $("#w2_ph").val(dataRecord.w2_ph); $("#w2_cost").val(dataRecord.w2_cost); $("#wg_amount").val(dataRecord.wg_amount); $("#wg_calcium").val(dataRecord.wg_calcium); $("#wg_sulfate").val(dataRecord.wg_sulfate); $("#wg_chloride").val(dataRecord.wg_chloride); $("#wg_sodium").val(dataRecord.wg_sodium); $("#wg_magnesium").val(dataRecord.wg_magnesium); $("#wg_total_alkalinity").val(dataRecord.wg_total_alkalinity); $("#wg_ph").val(dataRecord.wg_ph); $("#wb_calcium").val(dataRecord.wb_calcium); $("#wb_sulfate").val(dataRecord.wb_sulfate); $("#wb_chloride").val(dataRecord.wb_chloride); $("#wb_sodium").val(dataRecord.wb_sodium); $("#wb_magnesium").val(dataRecord.wb_magnesium); $("#wb_total_alkalinity").val(dataRecord.wb_total_alkalinity); $("#wb_ph").val(dataRecord.wb_ph); $("#wa_acid_name").val(dataRecord.wa_acid_name); $("#wa_acid_perc").val(dataRecord.wa_acid_perc); $("#wa_base_name").val(dataRecord.wa_base_name); $("#starter_enable").val(dataRecord.starter_enable); $("#starter_type").val(dataRecord.starter_type); $("#starter_sg").val(dataRecord.starter_sg); $("#prop1_type").val(dataRecord.prop1_type); $("#prop1_volume").val(dataRecord.prop1_volume); $("#prop2_type").val(dataRecord.prop2_type); $("#prop2_volume").val(dataRecord.prop2_volume); $("#prop3_type").val(dataRecord.prop3_type); $("#prop3_volume").val(dataRecord.prop3_volume); $("#prop4_type").val(dataRecord.prop4_type); $("#prop4_volume").val(dataRecord.prop4_volume); editFermentable(dataRecord); editHop(dataRecord); editMisc(dataRecord); editYeast(dataRecord); editMash(dataRecord); calcStage(); $('#jqxTabs').jqxTabs('select', 2); }, loadError: function (jqXHR, status, error) { }, beforeLoadComplete: function (records) { $('#jqxLoader').jqxLoader('open'); } }); dataAdapter.dataBind(); // Inline fermentables editor var editFermentable = function (data) { var fermentableSource = { localdata: data.fermentables, datatype: "local", cache: false, async: false, datafields: [ { name: 'f_name', type: 'string' }, { name: 'f_origin', type: 'string' }, { name: 'f_supplier', type: 'string' }, { name: 'f_amount', type: 'float' }, { name: 'f_cost', type: 'float' }, { name: 'f_type', type: 'int' }, { name: 'f_yield', type: 'float' }, { name: 'f_color', type: 'float' }, { name: 'f_coarse_fine_diff', type: 'float' }, { name: 'f_moisture', type: 'float' }, { name: 'f_diastatic_power', type: 'float' }, { name: 'f_protein', type: 'float' }, { name: 'f_max_in_batch', type: 'float' }, { name: 'f_graintype', type: 'int' }, { name: 'f_added', type: 'int' }, { name: 'f_dissolved_protein', type: 'float' }, { name: 'f_recommend_mash', type: 'int' }, { name: 'f_add_after_boil', type: 'int' }, { name: 'f_adjust_to_total_100', type: 'int' }, { name: 'f_percentage', type: 'float' }, { name: 'f_di_ph', type: 'float' }, { name: 'f_acid_to_ph_57', type: 'float' }, { name: 'f_inventory', type: 'float' }, { name: 'f_avail', type: 'int' } ], addrow: function (rowid, rowdata, position, commit) { //console.log("fermentable addrow "+rowid); commit(true); }, deleterow: function (rowid, commit) { //console.log("fermentable deleterow "+rowid); commit(true); }, updaterow: function (rowid, rowdata, commit) { //console.log("fermentable updaterow "+rowid); commit(true); } }; var fermentableAdapter = new $.jqx.dataAdapter(fermentableSource); $("#fermentableGrid").jqxGrid({ width: 1240, height: 470, source: fermentableAdapter, theme: theme, selectionmode: 'singlerow', showtoolbar: true, rendertoolbar: function (toolbar) { var me = this; var container = $("<div style='overflow: hidden; position: relative; margin: 5px;'></div>"); toolbar.append(container); container.append('<div style="float: left; margin-left: 165px;" id="faddrowbutton"></div>'); container.append('<div style="float: left; margin-left: 10px; margin-top: 5px;">In voorraad:</div>'); container.append('<div style="float: left; margin-left: 10px;" id="finstockbutton"></div>'); container.append('<input style="float: left; margin-left: 400px;" id="fdeleterowbutton" type="button" value="Verwijder mout" />'); // add fermentable from dropdownlist. $("#faddrowbutton").jqxDropDownList({ placeHolder: "Kies mout:", theme: theme, template: "primary", source: fermentablelist, displayMember: "name", disabled: (dataRecord.stage > 3), width: 150, height: 27, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = fermentablelist.records[index]; return datarecord.supplier+ " / " + datarecord.name + " (" + datarecord.color + " EBC)"; } }); $("#faddrowbutton").on('select', function (event) { if (event.args) { var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; var index = event.args.index; var datarecord = fermentablelist.records[index]; var row = {}; row["f_name"] = datarecord.name; row["f_origin"] = datarecord.origin; row["f_supplier"] = datarecord.supplier; row["f_amount"] = 0; row["f_cost"] = datarecord.cost; row["f_type"] = datarecord.type; row["f_yield"] = datarecord.yield; row["f_color"] = datarecord.color; row["f_coarse_fine_diff"] = datarecord.coarse_fine_diff; row["f_moisture"] = datarecord.moisture; row["f_diastatic_power"] = datarecord.diastatic_power; row["f_protein"] = datarecord.protein; row["f_max_in_batch"] = datarecord.max_in_batch; row["f_graintype"] = datarecord.graintype; if (datarecord.add_after_boil) { row["f_added"] = 2; // Fermentation } else if ((datarecord.type == 1) || (datarecord.type == 4)) { // Sugar or Adjunct row["f_added"] = 1; // Boil } else { row["f_added"] = 0; // Mash } row["f_dissolved_protein"] = datarecord.dissolved_protein; row["f_recommend_mash"] = datarecord.recommend_mash; row["f_add_after_boil"] = datarecord.add_after_boil; if (rowscount == 0) { // The first fermentable row["f_adjust_to_total_100"] = 1; row["f_percentage"] = 100; } else { row["f_adjust_to_total_100"] = 0; row["f_percentage"] = 0; } row["f_di_ph"] = datarecord.di_ph; row["f_acid_to_ph_57"] = datarecord.acid_to_ph_57; row["f_inventory"] = datarecord.inventory; var commit = $("#fermentableGrid").jqxGrid('addrow', null, row); } }); $("#finstockbutton").jqxCheckBox({ theme: theme, height: 27, disabled: (dataRecord.stage > 3) }); $("#finstockbutton").on('change', function (event) { fermentableinstock = event.args.checked; fermentablelist.dataBind(); }); // 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; if (selectedrowindex >= 0 && selectedrowindex < rowscount) { var id = $("#fermentableGrid").jqxGrid('getrowid', selectedrowindex); var percent = $('#fermentableGrid').jqxGrid('getcellvalue', id, "f_percentage"); var amount = $('#fermentableGrid').jqxGrid('getcellvalue', id, "f_amount"); var commit = $("#fermentableGrid").jqxGrid('deleterow', id); } rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; if (rowscount > 1) { if (to_100) { for (var i = 0; i < rowscount; i++) { var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_adjust_to_total_100) { rowdata.f_percentage += percent; rowdata.f_amount += amount; } } } else { calcPercentages(); } } else { $("#fermentableGrid").jqxGrid('setcellvalue', 0, "f_percentage", 100); } calcFermentables(); calcIBUs(); }); }, ready: function() { calcFermentables(); $('#jqxTabs').jqxTabs('next'); }, columns: [ { text: 'Vergistbaar ingrediënt', datafield: 'f_name', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" + rowdata.f_supplier+" / "+rowdata.f_name+" ("+rowdata.f_color+" EBC)</span>"; } }, { text: 'Type', width: 100, datafield: 'f_type', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" + FermentableTypeData[value].nl + "</span>"; } }, { text: 'Moment', width: 110, datafield: 'f_added', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" + AddedData[value].nl + "</span>"; } }, { text:'Maxinbatch', datafield: 'f_max_in_batch', hidden: true }, { text: 'Opbrengst', datafield: 'f_yield', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'p1' }, { text: 'Gewicht Kg', datafield: 'f_amount', width: 120, align: 'right', cellsalign: 'right', cellsformat: 'f3' }, { text: 'Voorraad Kg', datafield: 'f_inventory', width: 120, align: 'right', cellsrenderer: function (row, columnfield, value, defaulthtml, columnproperties, rowdata) { var color = '#ffffff'; if (((dataRecord.inventory_reduced <= 2) && (rowdata.f_added <= 1)) || // Mash or boil ((dataRecord.inventory_reduced <= 3) && (rowdata.f_added == 2)) || // Primary ((dataRecord.inventory_reduced <= 5) && (rowdata.f_added == 3)) || // Secondary or Tertiary ((dataRecord.inventory_reduced <= 6) && (rowdata.f_added == 4)) || // Bottle ((dataRecord.inventory_reduced <= 6) && (rowdata.f_added == 5))) { // Kegs if (value < rowdata.f_amount) color = '#ff4040'; return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' +fermentableAdapter.formatNumber(value, "f3") + '</span>'; } else { return '<span></span>'; } } }, { text: 'Procent', datafield: 'f_percentage', width: 90, align: 'right', cellsrenderer: function (row, columnfield, value, defaulthtml, columnproperties, rowdata) { if (rowdata.f_added >= 4) return '<span></span>'; var color = '#ffffff'; if (value > rowdata.f_max_in_batch) color = '#ff4040'; return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' +fermentableAdapter.formatNumber(value, "p1") + '</span>'; } }, { text: '100%', datafield: 'f_adjust_to_total_100', width: 70, align: 'center', cellsalign: 'center', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { if (value == 0) return '<span></span>'; return '<span><img style="float:left; margin-left:25px; margin-top:4px;" src="images/dialog-ok-apply.png"></span>'; } }, { text: '', datafield: 'Edit', columntype: 'button', width: 100, align: 'center', cellsrenderer: function () { return "Wijzig"; }, buttonclick: function (row) { fermentableRow = row; fermentableData = $("#fermentableGrid").jqxGrid('getrowdata', fermentableRow); if (fermentableData.f_added >= 4) { alert("Wijzig dit in de Verpakken tab"); } else if (dataRecord.stage > 3) { alert("Ingredieënt is al verwerkt."); } else { $("#wf_name").val(fermentableData.f_name); $("#wf_amount").val(fermentableData.f_amount); $("#wf_percentage").val(fermentableData.f_percentage); $("#wf_max_in_batch").val(fermentableData.f_max_in_batch); $("#wf_adjust_to_total_100").val(fermentableData.f_adjust_to_total_100); $("#wf_added").val(fermentableData.f_added); // show the popup window. $("#popupFermentable").jqxWindow('open'); } } } ] }); }; // Inline hops editor var editHop = function (data) { var hopSource = { localdata: data.hops, datatype: "local", cache: false, async: false, datafields: [ { name: 'h_name', type: 'string' }, { name: 'h_origin', type: 'string' }, { name: 'h_amount', type: 'float' }, { name: 'h_cost', type: 'float' }, { name: 'h_type', type: 'int' }, { name: 'h_form', type: 'int' }, { name: 'h_useat', type: 'int' }, { name: 'h_time', type: 'float' }, { name: 'h_alpha', type: 'float' }, { name: 'h_beta', type: 'float' }, { name: 'h_hsi', type: 'float' }, { name: 'h_humulene', type: 'float' }, { name: 'h_caryophyllene', type: 'float' }, { name: 'h_cohumulone', type: 'float' }, { name: 'h_myrcene', type: 'float' }, { name: 'h_total_oil', type: 'float' }, { name: 'h_inventory', type: 'float' }, { name: 'h_avail', type: 'int' } ], addrow: function (rowid, rowdata, position, commit) { console.log("hop addrow "+rowid); commit(true); }, deleterow: function (rowid, commit) { console.log("hop deleterow "+rowid); commit(true); }, updaterow: function (rowid, rowdata, commit) { console.log("hop updaterow "+rowid); commit(true); } }; var hopAdapter = new $.jqx.dataAdapter(hopSource); $("#hopGrid").jqxGrid({ width: 1240, height: 560, source: hopAdapter, theme: theme, selectionmode: 'singlerow', showtoolbar: true, rendertoolbar: function (toolbar) { var me = this; var container = $("<div style='overflow: hidden; position: relative; margin: 5px;'></div>"); toolbar.append(container); container.append('<div style="float: left; margin-left: 165px;" id="haddrowbutton"></div>'); container.append('<div style="float: left; margin-left: 10px; margin-top: 5px;">In voorraad:</div>'); container.append('<div style="float: left; margin-left: 10px;" id="hinstockbutton"></div>'); container.append('<input style="float: left; margin-left: 400px;" id="hdeleterowbutton" type="button" value="Verwijder hop" />'); // add hop from dropdownlist. $("#haddrowbutton").jqxDropDownList({ placeHolder: "Kies hop:", theme: theme, template: "primary", source: hoplist, disabled: (dataRecord.stage > 3), displayMember: "name", width: 150, height: 27, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = hoplist.records[index]; return datarecord.origin+ " - " + datarecord.name + " / " + HopFormData[datarecord.form].nl + " (" + datarecord.alpha + "% α)"; } }); $("#haddrowbutton").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = hoplist.records[index]; var row = {}; row["h_name"] = datarecord.name; row["h_origin"] = datarecord.origin; row["h_amount"] = 0; row["h_cost"] = datarecord.cost; row["h_type"] = datarecord.type; row["h_form"] = datarecord.form; row["h_useat"] = 2; // Boil row["h_time"] = 0; row["h_alpha"] = datarecord.alpha; row["h_beta"] = datarecord.beta; row["h_hsi"] = datarecord.hsi; row["h_humulene"] = datarecord.humulene; row["h_caryophyllene"] = datarecord.caryophyllene; row["h_cohumulone"] = datarecord.cohumulone; row["h_myrcene"] = datarecord.myrcene; row["h_total_oil"] = datarecord.total_oil; row["h_inventory"] = datarecord.inventory; var commit = $("#hopGrid").jqxGrid('addrow', null, row); } $("#haddrowbutton").jqxDropDownList('clearSelection'); }); $("#hinstockbutton").jqxCheckBox({ theme: theme, height: 27, disabled: (dataRecord.stage > 3) }); $("#hinstockbutton").on('change', function (event) { hopinstock = event.args.checked; hoplist.dataBind(); }); // 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; if (selectedrowindex >= 0 && selectedrowindex < rowscount) { var id = $("#hopGrid").jqxGrid('getrowid', selectedrowindex); var commit = $("#hopGrid").jqxGrid('deleterow', id); } calcIBUs(); }); }, ready: function() { calcIBUs(); $('#jqxTabs').jqxTabs('next'); }, columns: [ { text: 'Hop', datafield: 'h_name', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" +rowdata.h_origin+" / "+rowdata.h_name+"</span>"; }, }, { text: 'Type', width: 90, datafield: 'h_type', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopTypeData[value].nl + '</span>'; } }, { text: 'Vorm', width: 90, datafield: 'h_form', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopFormData[value].nl + '</span>'; } }, { text: 'Alpha', datafield: 'h_alpha', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'p1' }, { text: 'Gebruik', width: 110, datafield: 'h_useat', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopUseData[value].nl + '</span>'; } }, { text: 'Tijdsduur', datafield: 'h_time', width: 90, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var duration = ''; if ((rowdata.h_useat == 2) || (rowdata.h_useat == 4)) // Boil, Whirlpool duration = dataAdapter.formatNumber(value, "f0")+" min."; else if (rowdata.h_useat == 5) // Dry hop duration = dataAdapter.formatNumber(value/1440, "f0")+" dagen"; return '<span style="margin: 4px; margin-top: 6px; float: right;">' + duration + '</span>'; } }, { text: 'IBU', datafield: 'ibu', width: 80, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var ibu = toIBU(rowdata.h_useat, rowdata.h_form, preboil_sg, parseFloat($("#batch_size").jqxNumberInput('decimal')), parseFloat(rowdata.h_amount), parseFloat(rowdata.h_time), parseFloat(rowdata.h_alpha), $("#ibu_method").val()); return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(ibu, "f1") + '</span>'; } }, { text: 'Gewicht', datafield: 'h_amount', width: 110, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var amount = dataAdapter.formatNumber(value, "f1") + ' kg'; if (value < 1) amount = dataAdapter.formatNumber(value * 1000, "f1") + ' gr'; return '<span style="margin: 4px; margin-top: 6px; float: right;">' + amount + '</span>'; } }, { text: 'Voorraad', datafield: 'h_inventory', width: 110, align: 'right', 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'; if (value < rowdata.h_amount) color = '#ff4040'; var amount = dataAdapter.formatNumber(value, "f1") + ' kg'; if (value < 1) amount = dataAdapter.formatNumber(value * 1000, "f1") + ' gr'; return '<span style="margin: 4px; margin-top: 6px; float: right; color: '+color+';">'+amount+'</span>'; } else { return '<span></span>'; } } }, { text: '', datafield: 'Edit', columntype: 'button', width: 100, align: 'center', cellsrenderer: function () { return "Wijzig"; }, buttonclick: function (row) { if (dataRecord.stage > 3) { alert("Ingredieënt is al verwerkt."); } else { console.log("edit button row "+row); hopRow = row; hopData = $("#hopGrid").jqxGrid('getrowdata', hopRow); $("#wh_name").val(hopData.h_name); $("#wh_amount").val(hopData.h_amount * 1000); var 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() ); $("#wh_ibu").val(ibu); if (hopData.h_useat == 5) // Dry hop $("#wh_time").val(hopData.h_time / 1440); else $("#wh_time").val(hopData.h_time); $("#wh_useat").val(hopData.h_useat); // show the popup window. $("#popupHop").jqxWindow('open'); } } } ] }); }; // Inline miscs editor var editMisc = function (data) { var miscSource = { localdata: data.miscs, datatype: "local", cache: false, async: false, datafields: [ { name: 'm_name', type: 'string' }, { name: 'm_amount', type: 'float' }, { name: 'm_cost', type: 'float' }, { name: 'm_type', type: 'int' }, { name: 'm_use_use', type: 'int' }, { name: 'm_time', type: 'float' }, { name: 'm_amount_is_weight', type: 'int' }, { name: 'm_inventory', type: 'float' }, { name: 'm_avail', type: 'int' } ], addrow: function (rowid, rowdata, position, commit) { console.log("misc addrow "+rowid); commit(true); }, deleterow: function (rowid, commit) { console.log("misc deleterow "+rowid); commit(true); }, updaterow: function (rowid, rowdata, commit) { console.log("misc updaterow "+rowid); commit(true); } }; var miscAdapter = new $.jqx.dataAdapter(miscSource, { beforeLoadComplete: function (records) { var data = new Array(); for (var i = 0; i < records.length; i++) { var row = records[i]; data.push(row); // Initial set water agent values. 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': $("#wa_acid_name").val(0); $("#wa_acid").val(row.m_amount * 1000); $("#wa_acid_perc").val(80); last_acid = 'Melkzuur'; break; case 'Zoutzuur': $("#wa_acid_name").val(1); $("#wa_acid").val(row.m_amount * 1000); $("#wa_acid_perc").val(80); last_acid = 'Zoutzuur'; break; case 'Fosforzuur': $("#wa_acid_name").val(2); $("#wa_acid").val(row.m_amount * 1000); $("#wa_acid_perc").val(80); last_acid = 'Fosforzuur'; break; case 'Zwavelzuur': $("#wa_acid_name").val(3); $("#wa_acid").val(row.m_amount * 1000); $("#wa_acid_perc").val(80); last_acid = 'Zwavelzuur'; break; case 'NaHCO3': $("#wa_base_name").val(0); $("#wa_base").val(row.m_amount * 1000); last_base = 'NaHCO3'; break; case 'Na2CO3': $("#wa_base_name").val(1); $("#wa_base").val(row.m_amount * 1000); last_base = 'Na2CO3'; break; case 'CaCO3': $("#wa_base_name").val(2); $("#wa_base").val(row.m_amount * 1000); last_base = 'CaCO3'; break; case 'Ca(OH)2': $("#wa_base_name").val(3); $("#wa_base").val(row.m_amount * 1000); last_base = 'Ca(OH)2'; break; } } return data; }, loadError: function(jqXHR, status, error) { $('#err').text(status + ' ' + error); }, }); $("#miscGrid").jqxGrid({ width: 1240, height: 575, source: miscAdapter, theme: theme, selectionmode: 'singlerow', showtoolbar: true, rendertoolbar: function (toolbar) { var me = this; var container = $("<div style='overflow: hidden; position: relative; margin: 5px;'></div>"); toolbar.append(container); container.append('<div style="float: left; margin-left: 165px;" id="maddrowbutton"></div>'); container.append('<div style="float: left; margin-left: 10px; margin-top: 5px;">In voorraad:</div>'); container.append('<div style="float: left; margin-left: 10px;" id="minstockbutton"></div>'); container.append('<input style="float: left; margin-left: 400px;" id="mdeleterowbutton" type="button" value="Verwijder ingredient" />'); // add misc from dropdownlist. $("#maddrowbutton").jqxDropDownList({ placeHolder: "Kies ingrediënt:", theme: theme, template: "primary", source: misclist, disabled: (dataRecord.stage > 3), displayMember: "name", width: 150, height: 27, dropDownWidth: 500, dropDownHeight: 500 }); $("#maddrowbutton").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = misclist.records[index]; var row = {}; row["m_name"] = datarecord.name; row["m_amount"] = 0; row["m_cost"] = datarecord.cost; row["m_type"] = datarecord.type; row["m_use_use"] = datarecord.use_use; row["m_time"] = 0; row["m_amount_is_weight"] = datarecord.amount_is_weight; row["m_inventory"] = datarecord.inventory; var commit = $("#miscGrid").jqxGrid('addrow', null, row); } }); $("#minstockbutton").jqxCheckBox({ theme: theme, height: 27, disabled: (dataRecord.stage > 3) }); $("#minstockbutton").on('change', function (event) { miscinstock = event.args.checked; misclist.dataBind(); }); // 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"); if (selectedrowindex >= 0 && selectedrowindex < rowscount && type != 4) { // Water agent var id = $("#miscGrid").jqxGrid('getrowid', selectedrowindex); var commit = $("#miscGrid").jqxGrid('deleterow', id); } }); }, ready: function() { calcMiscs(); $('#jqxTabs').jqxTabs('next'); }, columns: [ { text: 'Ingredient', datafield: 'm_name' }, { text: 'Type', width: 140, datafield: 'm_type', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" + MiscTypeData[value].nl + "</span>"; } }, { text: 'Gebruik', width: 140, datafield: 'm_use_use', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" + MiscUseData[value].nl + "</span>"; } }, { text: 'Tijd', datafield: 'm_time', width: 90, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var duration = ''; if (rowdata.m_use_use == 2) // Boil duration = dataAdapter.formatNumber(value, "f0")+" min."; else if ((rowdata.m_use_use == 3) || (rowdata.m_use_use == 4)) // Primary or Secondary duration = dataAdapter.formatNumber(value/1440, "f0")+" dagen"; return '<span style="margin: 4px; margin-top: 6px; float: right;">' + duration + '</span>'; }, }, { text: 'Hoeveel', datafield: 'm_amount', width: 110, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var vstr = rowdata.m_amount_is_weight ? "gr":"ml"; return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(value * 1000,"f2")+" "+vstr + '</span>'; } }, { text: 'Voorraad', datafield: 'm_inventory', width: 110, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { 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'; if (value < rowdata.m_amount) color = '#ff4040'; var amount = dataAdapter.formatNumber(value * 1000,"f2")+" "+vstr; return '<span style="margin: 4px; margin-top: 6px; float: right; color: '+color+';">'+amount+'</span>'; } else { return '<span></span>'; } } }, { text: '', datafield: 'Edit', columntype: 'button', width: 100, align: 'center', cellsrenderer: function () { return "Wijzig"; }, buttonclick: function (row) { miscRow = row; miscData = $("#miscGrid").jqxGrid('getrowdata', miscRow); if (dataRecord.stage > 3) { alert("Ingredieënt is al verwerkt."); } else if (miscData.m_type == 4) { alert("Brouwzouten wijzigen in de water tab."); } else { console.log("edit button row "+row); if (miscData.m_amount_is_weight) $("#wm_pmpt_amount").html("Gewicht gram:"); else $("#wm_pmpt_amount").html("Volume ml:"); $("#wm_name").val(miscData.m_name); $("#wm_amount").val(miscData.m_amount * 1000); if ((miscData.m_use_use == 3) || (miscData.m_use_use == 4)) // Primary or Secondary $("#wm_time").val(miscData.m_time / 1440); else $("#wm_time").val(miscData.m_time); $("#wm_use_use").val(miscData.m_use_use); // show the popup window. $("#popupMisc").jqxWindow('open'); } } } ] }); }; // Inline yeasts editor var editYeast = function (data) { var yeastSource = { localdata: data.yeasts, datatype: "local", cache: false, async: false, datafields: [ { name: 'y_name', type: 'string' }, { name: 'y_laboratory', type: 'string' }, { name: 'y_product_id', type: 'string' }, { name: 'y_amount', type: 'float' }, { name: 'y_cost', type: 'float' }, { name: 'y_type', type: 'int' }, { name: 'y_form', type: 'int' }, { name: 'y_flocculation', type: 'int' }, { name: 'y_min_temperature', type: 'float' }, { name: 'y_max_temperature', type: 'float' }, { name: 'y_attenuation', type: 'float' }, { name: 'y_use', type: 'int' }, { name: 'y_cells', type: 'float' }, { name: 'y_tolerance', type: 'float' }, { name: 'y_inventory', type: 'float' }, { name: 'y_avail', type: 'int' } ], addrow: function (rowid, rowdata, position, commit) { console.log("yeast addrow "+rowid); commit(true); }, deleterow: function (rowid, commit) { console.log("yeast deleterow "+rowid); commit(true); }, updaterow: function (rowid, rowdata, commit) { console.log("yeast updaterow "+rowid); commit(true); } }; var yeastAdapter = new $.jqx.dataAdapter(yeastSource); $("#yeastGrid").jqxGrid({ width: 1240, height: 350, source: yeastAdapter, theme: theme, selectionmode: 'singlerow', showtoolbar: true, rendertoolbar: function (toolbar) { var me = this; var container = $("<div style='overflow: hidden; position: relative; margin: 5px;'></div>"); toolbar.append(container); container.append('<div style="float: left; margin-left: 165px;" id="yaddrowbutton"></div>'); container.append('<div style="float: left; margin-left: 10px; margin-top: 5px;">In voorraad:</div>'); container.append('<div style="float: left; margin-left: 10px;" id="yinstockbutton"></div>'); container.append('<input style="float: left; margin-left: 400px;" id="ydeleterowbutton" type="button" value="Verwijder gist" />'); // add yeast from dropdownlist. $("#yaddrowbutton").jqxDropDownList({ placeHolder: "Kies gist:", theme: theme, source: yeastlist, disabled: (dataRecord.stage > 3), template: "primary", displayMember: "name", width: 150, height: 27, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = yeastlist.records[index]; return datarecord.laboratory+" "+datarecord.product_id+" "+datarecord.name; } }); $("#yaddrowbutton").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = yeastlist.records[index]; var row = {}; row["y_name"] = datarecord.name; row["y_laboratory"] = datarecord.laboratory; row["y_product_id"] = datarecord.product_id; row["y_type"] = datarecord.type; row["y_form"] = datarecord.form; row["y_amount"] = 0; row["y_cost"] = datarecord.cost; row["y_use"] = 0; row["y_min_temperature"] = datarecord.min_temperature; row["y_max_temperature"] = datarecord.max_temperature; row["y_attenuation"] = datarecord.attenuation; row["y_flocculation"] = datarecord.flocculation; row["y_cells"] = datarecord.cells; row["y_tolerance"] = datarecord.tolerance; row["y_inventory"] = datarecord.inventory; var commit = $("#yeastGrid").jqxGrid('addrow', null, row); } calcYeast(); $("#yaddrowbutton").jqxDropDownList('clearSelection'); }); $("#yinstockbutton").jqxCheckBox({ theme: theme, height: 27, disabled: (dataRecord.stage > 3) }); $("#yinstockbutton").on('change', function (event) { yeastinstock = event.args.checked; yeastlist.dataBind(); }); // 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; if (selectedrowindex >= 0 && selectedrowindex < rowscount) { var id = $("#yeastGrid").jqxGrid('getrowid', selectedrowindex); var commit = $("#yeastGrid").jqxGrid('deleterow', id); calcYeast(); } }); }, ready: function() { calcFermentables(); showStarter(); calcYeast(); $('#jqxTabs').jqxTabs('next'); }, columns: [ { text: 'Gist', datafield: 'y_name' }, { text: 'Laboratorium', width: 150, datafield: 'y_laboratory' }, { text: 'Code', width: 90, datafield: 'y_product_id' }, { text: 'Soort', width: 100, datafield: 'y_form', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return '<span style="margin: 4px; margin-top: 6px; float: left;">' + YeastFormData[value].nl + '</span>'; } }, { text: 'Min. °C', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_min_temperature' }, { 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 = ""; if (value > 0) { amount = dataAdapter.formatNumber(value, "f1"); if (dataRecord.est_abv > value) color = '#ff4040'; } return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>'; } }, { text: 'Attn. %', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_attenuation', cellsformat: 'f1' }, { text: 'Voor', width: 120, datafield: 'y_use', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return '<span style="margin: 4px; margin-top: 6px; float: left;">' + YeastUseData[value].nl + '</span>'; } }, { text: 'Hoeveel', datafield: 'y_amount', width: 90, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var 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 amount = dataAdapter.formatNumber(value*1000, "f1")+" gr"; return '<span style="margin: 4px; margin-top: 6px; float: right;">' + amount + '</span>'; } }, { text: 'Voorraad', datafield: 'y_inventory', width: 90, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { 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'; if (value < rowdata.y_amount) color = '#ff4040'; var 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 amount = dataAdapter.formatNumber(value*1000, "f1")+" gr"; return '<span style="margin: 4px; margin-top: 6px; float: right; color: '+color+';">'+amount+'</span>'; } else { return '<span></span>'; } } }, { text: '', datafield: 'Edit', columntype: 'button', width: 90, align: 'center', cellsrenderer: function () { return "Wijzig"; }, buttonclick: function (row) { if (dataRecord.stage > 3) { alert("Ingredieënt is al verwerkt."); } else { yeastRow = row; yeastData = $("#yeastGrid").jqxGrid('getrowdata', yeastRow); if (yeastData.y_form == 0) { $("#wy_pmpt_amount").html("Pak(ken):"); $("#wy_amount").val(yeastData.y_amount); $("#wy_amount").jqxNumberInput({ decimalDigits: 0 }); } else if (yeastData.y_form == 1) { $("#wy_pmpt_amount").html("Gewicht gram:"); $("#wy_amount").val(yeastData.y_amount * 1000); $("#wy_amount").jqxNumberInput({ decimalDigits: 1 }); } else { $("#wy_pmpt_amount").html("Volume ml:"); $("#wy_amount").val(yeastData.y_amount * 1000); $("#wy_amount").jqxNumberInput({ decimalDigits: 0 }); } $("#wy_name").val(yeastData.y_name); $("#wy_laboratory").val(yeastData.y_laboratory); $("#wy_product_id").val(yeastData.y_product_id); $("#wy_use").val(yeastData.y_use); // show the popup window. $("#popupYeast").jqxWindow('open'); } } } ] }); }; // inline mash editor var editMash = function (data) { var mashSource = { localdata: data.mashs, datatype: "local", cache: false, async: false, datafields: [ { name: 'step_name', type: 'string' }, { name: 'step_type', type: 'int' }, { name: 'step_infuse_amount', type: 'float' }, { name: 'step_temp', type: 'float' }, { name: 'step_time', type: 'float' }, { name: 'step_thickness', type: 'float' }, { name: 'ramp_time', type: 'float' }, { name: 'end_temp', type: 'float' } ], addrow: function (rowid, rowdata, position, commit) { commit(true); }, deleterow: function (rowid, commit) { commit(true); } }; var mashAdapter = new $.jqx.dataAdapter(mashSource, { beforeLoadComplete: function (records) { mash_infuse = 0; var data = new Array(); for (var i = 0; i < records.length; i++) { var row = records[i]; if (row.step_type == 0) // Infusion mash_infuse += parseFloat(row.step_infuse_amount); row.step_thickness = 0; // Init this field. data.push(row); } }, }); $("#mashGrid").jqxGrid({ width: 1240, height: 400, source: mashAdapter, theme: theme, selectionmode: 'singlerow', showtoolbar: true, rendertoolbar: function (toolbar) { var me = this; var container = $("<div style='overflow: hidden; position: relative; margin: 5px;'></div>"); toolbar.append(container); container.append('<input style="float: left; margin-left: 165px;" id="saddrowbutton" type="button" value="Nieuwe stap" />'); container.append('<input style="float: left; margin-left: 565px;" id="sdeleterowbutton" type="button" value="Verwijder stap" />'); $("#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 = {}; row["step_name"] = "Stap " + (rowscount + 1); if (rowscount > 0) { row["step_type"] = 1; } else { row["step_type"] = 0; row["step_infuse_amount"] = 15; } row["step_temp"] = 62.0; row['step_time'] = 20.0; row['step_thickness'] = 0; row['ramp_time'] = 1.0; row['end_temp'] = 62.0; var commit = $("#mashGrid").jqxGrid('addrow', null, row); }); // 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; if (selectedrowindex >= 0 && selectedrowindex < rowscount) { var id = $("#mashGrid").jqxGrid('getrowid', selectedrowindex); var commit = $("#mashGrid").jqxGrid('deleterow', id); } }); }, ready: function() { calcInit(); calcMash(); $('#jqxLoader').jqxLoader('close'); $('#jqxTabs').jqxTabs('first'); }, columns: [ { text: 'Stap naam', datafield: 'step_name' }, { text: 'Stap type', datafield: 'step_type', width: 175, cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return '<span style="margin: 4px; margin-top: 6px; float: left;">' + MashStepTypeData[value].nl + '</span>'; } }, { text: 'Start °C', datafield: 'step_temp', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, { text: 'Eind °C', datafield: 'end_temp', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, { text: 'Rust min.', datafield: 'step_time', width: 90, align: 'right', cellsalign: 'right' }, { text: 'Stap min.', datafield: 'ramp_time', width: 90, align: 'right', cellsalign: 'right' }, { text: 'Infuse L.', datafield: 'step_infuse_amount', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, { text: 'L/Kg.', datafield: 'step_thickness', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'f2' }, { text: '', datafield: 'Edit', columntype: 'button', width: 100, align: 'center', cellsrenderer: function () { return "Wijzig"; }, buttonclick: function (row) { if (dataRecord.stage > 3) { alert("Het maichen is al gedaan."); } else { mashRow = row; mashData = $("#mashGrid").jqxGrid('getrowdata', mashRow); $("#wstep_name").val(mashData.step_name); $("#wstep_type").val(mashData.step_type); $("#wstep_infuse_amount").val(mashData.step_infuse_amount); $("#wstep_temp").val(mashData.step_temp); $("#wend_temp").val(mashData.end_temp); $("#wstep_time").val(mashData.step_time); $("#wramp_time").val(mashData.ramp_time); if (mashData.step_type == 0) { $("#wstep_infuse_amount").show(); $("#wstep_pmpt").show(); } else { $("#wstep_infuse_amount").hide(); $("#wstep_pmpt").hide(); } // show the popup window. $("#popupMash").jqxWindow('open'); } } } ] }); }; // initialize the input fields. // Tab 1, Algemeen $("#name").jqxTooltip({ content: 'De naam voor dit product.' }); $("#name").jqxInput({ theme: theme, width: 640, height: 23 }); $("#code").jqxTooltip({ content: 'Product code nummer.' }); $("#code").jqxInput({ theme: theme, width: 100, height: 23 }); $("#birth").jqxTooltip({ content: 'De ontwerp datum van dit product.' }); $("#birth").jqxInput({ theme: theme, width: 120, height: 23 }); $("#stage").jqxTooltip({ content: 'De productie fase van dit product.' }); $("#stage").jqxInput({ theme: theme, width: 100, height: 23 }); $("#locked").jqxCheckBox({ theme: theme, width: 120, height: 23, disabled : true }); $('#locked').on('checked', function (event) { if (dataRecord.stage >= 10) { dataRecord.locked = 1; dataRecord.stage = 11; calcStage(); } }); $('#locked').on('unchecked', function (event) { if (dataRecord.stage >= 10) { dataRecord.locked = 0; dataRecord.stage = 10; calcStage(); } }); $("#notes").jqxTooltip({ content: 'De uitgebreide opmerkingen over dit product.' }); $("#notes").jqxInput({ theme: theme, width: 960, height: 100 }); $("#type").jqxTooltip({ content: 'Het brouw type van dit recept.' }); $("#type").jqxDropDownList({ theme: theme, source: RecipeTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true }); $("#efficiency").jqxTooltip({ content: 'Het rendement van maischen en koken.' }); $("#efficiency").jqxNumberInput( Perc1dec ); $("#batch_size").jqxTooltip({ content: 'Het volume van het gekoelde wort na het koken.' }); $("#batch_size").jqxNumberInput( Spin1dec ); $("#batch_size").jqxNumberInput({ min: 4 }); $("#boil_time").jqxTooltip({ content: 'De kooktijd in minuten.' }); $("#boil_time").jqxNumberInput( PosInt ); $("#boil_time").jqxNumberInput({ min: 4, max: 360 }); $("#boil_size").jqxTooltip({ content: 'Het volume van het wort voor het koken.' }); $("#boil_size").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 90, height: 23, decimalDigits: 2, readOnly: true }); $("#st_guide").jqxTooltip({ content: 'De bierstijl gids voor dit recept.'}); $("#st_guide").jqxInput({ theme: theme, width: 250, height: 23 }); $("#st_name").jqxTooltip({ content: 'De bierstijl naam voor dit recept.'}); $("#st_name").jqxInput({ theme: theme, width: 250, height: 23 }); $("#st_letter").jqxTooltip({ content: 'De bierstijl letter voor dit recept.'}); $("#st_letter").jqxInput({ theme: theme, width: 100, height: 23 }); $("#st_type").jqxTooltip({ content: 'Het bierstijl type.'}); $("#st_type").jqxInput({ theme: theme, width: 250, height: 23 }); $("#st_category").jqxTooltip({ content: 'De Amerikaanse bierstijl categorie.'}); $("#st_category").jqxInput({ theme: theme, width: 250, height: 23 }); $("#st_category_number").jqxTooltip({ content: 'De Amerikaanse bierstijl categorie sub nummer.'}); $("#st_category_number").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#est_og").jqxTooltip({ content: 'Het begin SG wat je wilt bereiken. De moutstort wordt automatisch herberekend.' }); $("#est_og").jqxNumberInput( SGopts ); $("#st_og_min").jqxTooltip({ content: 'Het minimum begin SG voor deze bierstijl.'}); $("#st_og_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); $("#st_og_max").jqxTooltip({ content: 'Het maximum begin SG voor deze bierstijl.'}); $("#st_og_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); $("#est_fg").jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' }); $("#est_fg").jqxNumberInput( Show3dec ); $("#st_fg_min").jqxTooltip({ content: 'Het minimum eind SG voor deze bierstijl.'}); $("#st_fg_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); $("#st_fg_max").jqxTooltip({ content: 'Het maximum eind SG voor deze bierstijl.'}); $("#st_fg_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); $("#est_abv").jqxTooltip({ content: 'Alcohol volume %. Dit wordt automatisch berekend.' }); $("#est_abv").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#st_abv_min").jqxTooltip({ content: 'Het minimum alcohol volume % voor deze bierstijl.'}); $("#st_abv_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#st_abv_max").jqxTooltip({ content: 'Het maximum alcohol volume % voor deze bierstijl.'}); $("#st_abv_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#est_color").jqxTooltip({ content: 'De kleur in EBC. Dit wordt automatisch berekend.' }); $("#est_color").jqxNumberInput( Show0dec ); $("#st_color_min").jqxTooltip({ content: 'De minimum kleur voor deze bierstijl.'}); $("#st_color_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#st_color_max").jqxTooltip({ content: 'De maximum kleur voor deze bierstijl.'}); $("#st_color_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#color_method").jqxDropDownList({ theme: theme, source: ColorMethodAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true }); $("#est_ibu").jqxTooltip({ content: 'De bitterheid in IBU. Dit wordt automatisch berekend.' }); $("#est_ibu").jqxNumberInput( Show0dec ); $("#st_ibu_min").jqxTooltip({ content: 'De minimum bitterheid voor deze bierstijl.'}); $("#st_ibu_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#st_ibu_max").jqxTooltip({ content: 'De maximum bitterheid voor deze bierstijl.'}); $("#st_ibu_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#ibu_method").jqxDropDownList({ theme: theme, source: IBUmethodAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true, dropDownVerticalAlignment: 'top' }); $("#est_carb").jqxTooltip({ content: 'Koolzuur volume. Dit wordt automatisch berekend.' }); $("#est_carb").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#st_carb_min").jqxTooltip({ content: 'Het minimum koolzuur volume voor deze bierstijl.'}); $("#st_carb_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#st_carb_max").jqxTooltip({ content: 'Het maximum koolzuur volume voor deze bierstijl.'}); $("#st_carb_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); // Tab 2, Equipment $("#eq_name").jqxTooltip({ content: 'De naam van deze brouw apparatuur.' }); $("#eq_name").jqxInput({ theme: theme, width: 250, height: 23 }); $("#eq_boil_size").jqxTooltip({ content: 'Normaal kook volume in liters' }); $("#eq_boil_size").jqxNumberInput( Show1dec ); $("#eq_batch_size").jqxTooltip({ content: 'Berekende batch grootte in liters aan het eind van de kook.' }); $("#eq_batch_size").jqxNumberInput( Show1dec ); $("#eq_tun_volume").jqxTooltip({ content: 'Maisch ketel volume.' }); $("#eq_tun_volume").jqxNumberInput( Show1dec ); $("#eq_top_up_water").jqxTooltip({ content: 'Extra water in het gistvat.' }); $("#eq_top_up_water").jqxNumberInput( Show1dec ); $("#eq_trub_chiller_loss").jqxTooltip({ content: 'Standaard verlies bij het overbrengen naar het gistvat.' }); $("#eq_trub_chiller_loss").jqxNumberInput( Show1dec ); $("#eq_evap_rate").jqxTooltip({ content: 'Verdamping in liters per uur.' }); $("#eq_evap_rate").jqxNumberInput( Show2dec ); $("#eq_boil_time").jqxTooltip({ content: 'Normale kooktijd in minuten.' }); $("#eq_boil_time").jqxNumberInput( Show0dec ); $("#eq_top_up_kettle").jqxTooltip({ content: 'Extra water toevoegen tijdens de kook.' }); $("#eq_top_up_kettle").jqxNumberInput( Show1dec ); $("#eq_hop_utilization").jqxTooltip({ content: '100% voor kleine installaties, hoger voor grote brouwerijen.' }); $("#eq_hop_utilization").jqxNumberInput( Show0dec ); $("#eq_notes").jqxTooltip({ content: 'Opmerkingen over deze apparatuur.' }); $("#eq_notes").jqxInput({ theme: theme, width: 960, height: 200 }); $("#eq_lauter_volume").jqxTooltip({ content: 'Filterkuip volume.' }); $("#eq_lauter_volume").jqxNumberInput( Show1dec ); $("#eq_lauter_deadspace").jqxTooltip({ content: 'Filterkuip verlies in liters.' }); $("#eq_lauter_deadspace").jqxNumberInput( Show1dec ); $("#eq_kettle_volume").jqxTooltip({ content: 'Kook ketel volume in liters.' }); $("#eq_kettle_volume").jqxNumberInput( Show1dec ); $("#eq_mash_volume").jqxTooltip({ content: 'Maisch water voor de eerste stap.' }); $("#eq_mash_volume").jqxNumberInput( Show1dec ); $("#eq_mash_max").jqxTooltip({ content: 'De maximale moutstort in Kg.' }); $("#eq_mash_max").jqxNumberInput( Show1dec ); $("#eq_efficiency").jqxTooltip({ content: 'Gemiddeld brouwzaal rendement.' }); $("#eq_efficiency").jqxNumberInput( Show1dec ); // Tab 3, Fermentables $("#est_color2").jqxTooltip({ content: 'De kleur in EBC. Dit wordt automatisch berekend.' }); $("#est_color2").jqxNumberInput( Show0dec ); $("#est_og2").jqxTooltip({ content: 'Het geschatte begin SG van dit product.' }); $("#est_og2").jqxNumberInput( Show3dec ); $("#mash_kg").jqxTooltip({ content: 'Het gewicht van alle mouten in de maisch.' }); $("#mash_kg").jqxNumberInput( Show3dec ); $("#perc_malts").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, max: 120, animationDuration: 0, colorRanges: [ { stop: 90, color: '#008C00' }, { stop: 100, color: '#EB7331' }, { stop: 120, color: '#FF0000' } ], renderText: function (text) { return (Math.round(parseInt(text) * 1.2)) + '%'; } }); $("#perc_sugars").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, max: 50, animationDuration: 0, colorRanges: [ { stop: 20, color: '#008C00' }, { stop: 50, color: '#FF0000' } ], renderText: function (text) { return (Math.round(parseInt(text) * 5) / 10) + '%'; } }); $("#perc_cara").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, max: 50, animationDuration: 0, colorRanges: [ { stop: 25, color: '#008C00' }, { stop: 50, color: '#FF0000' } ], renderText: function (text) { return (Math.round(parseInt(text) * 5) / 10) + '%'; } }); $("#ferm_lintner").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, max: 200, animationDuration: 0, colorRanges: [ { stop: 30, color: '#FF0000' }, { stop: 40, color: '#EB7331' }, { stop: 200, color: '#008C00' } ], renderText: function (text) { return (parseInt(text) * 2) + ' lintner'; } }); $("#popupFermentable").jqxWindow({ width: 800, height: 300, position: { x: 230, y: 100 }, resizable: false, theme: theme, isModal: true, autoOpen: false, cancelButton: $("#FermentableReady"), modalOpacity: 0.40 }); $("#FermentableReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#FermentableReady").click(function () { var rowID = $("#fermentableGrid").jqxGrid('getrowid', fermentableRow); console.log("FermentableReady row:"+fermentableRow+" ID:"+rowID); var row = { f_name: fermentableData.f_name, f_origin: fermentableData.f_origin, f_supplier: fermentableData.f_supplier, f_amount: fermentableData.f_amount, f_cost: fermentableData.f_cost, f_type: fermentableData.f_type, f_yield: fermentableData.f_yield, f_color: fermentableData.f_color, f_coarse_fine_diff: fermentableData.f_coarse_fine_diff, f_moisture: fermentableData.f_moisture, f_diastatic_power: fermentableData.f_diastatic_power, f_protein: fermentableData.f_protein, f_max_in_batch: fermentableData.f_max_in_batch, f_graintype: fermentableData.f_graintype, f_added: fermentableData.f_added, f_dissolved_protein: fermentableData.f_dissolved_protein, f_recommend_mash: fermentableData.f_recommend_mash, f_add_after_boil: fermentableData.f_add_after_boil, f_adjust_to_total_100: fermentableData.f_adjust_to_total_100, f_percentage: fermentableData.f_percentage, f_di_ph: fermentableData.f_di_ph, f_acid_to_ph_57: fermentableData.f_acid_to_ph_57, f_inventory: fermentableData.f_inventory, f_avail: fermentableData.f_avail }; $("#fermentableGrid").jqxGrid('updaterow', rowID, row); calcPercentages(); calcFermentables(); calcIBUs(); calcMash(); // Waters: yes there is impact. }); $("#wf_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wf_instock").jqxCheckBox({ theme: theme, height: 23 }); $("#wf_instock").on('change', function (event) { fermentableinstock = event.args.checked; fermentablelist.dataBind(); }); $("#wf_select").jqxDropDownList({ placeHolder: "Kies mout:", theme: theme, source: fermentablelist, displayMember: "name", width: 150, height: 23, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = fermentablelist.records[index]; return datarecord.supplier+ " / " + datarecord.name + " (" + datarecord.color + " EBC)"; } }); $("#wf_select").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = fermentablelist.records[index]; $("#wf_name").val(datarecord.name); fermentableData.f_name = datarecord.name; fermentableData.f_origin = datarecord.origin; fermentableData.f_supplier = datarecord.supplier; fermentableData.f_type = datarecord.type; fermentableData.f_cost = datarecord.cost; fermentableData.f_yield = datarecord.yield; fermentableData.f_color = datarecord.color; fermentableData.f_coarse_fine_diff = datarecord.coarse_fine_diff; fermentableData.f_moisture = datarecord.moisture; fermentableData.f_diastatic_power = datarecord.diastatic_power; fermentableData.f_protein = datarecord.protein; fermentableData.f_max_in_batch = datarecord.max_in_batch; fermentableData.f_graintype = datarecord.graintype; fermentableData.f_dissolved_protein = datarecord.dissolved_protein; fermentableData.f_recommend_mash = datarecord.recommend_mash; fermentableData.f_add_after_boil = datarecord.add_after_boil; fermentableData.f_di_ph = datarecord.di_ph; fermentableData.f_acid_to_ph_57 = datarecord.acid_to_ph_57; fermentableData.f_inventory = datarecord.inventory; } }); $("#wf_amount").jqxNumberInput( Spin3dec ); $('#wf_amount').on('change', function (event) { console.log("amount changed: "+event.args.value); $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_amount', event.args.value); fermentableData.f_amount = event.args.value; if (! to_100) { calcPercentages(); calcFermentables(); calcIBUs(); calcMash(); }; }); $("#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; console.log("percentage changed: "+newvalue+" old: "+oldvalue); fermentableData.f_percent = newvalue; var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; if ((oldvalue != newvalue) && (rowscount > 1)) { var 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 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; 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; $("#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); if (rowdata.f_adjust_to_total_100) { namount = rowdata.f_amount - damount; $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_percentage', rowdata.f_percentage - diff); $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_amount', namount); } } calcFermentables(); calcIBUs(); calcMash(); } else { // Adjust all the rows. var nw = tw * diff / 100; for (i = 0; i < rowscount; i++) { var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_added < 4) { if (i == fermentableRow) { var 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; $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_amount', namount); $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_percentage', newperc); } } else { $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_percentage', 0); } } calcFermentables(); calcIBUs(); calcMash(); } } } }); $("#wf_max_in_batch").jqxNumberInput( Show1dec ); $("#wf_adjust_to_total_100").jqxCheckBox({ theme: theme, width: 120, height: 23 }); $("#wf_adjust_to_total_100").on('checked', function (event) { 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++) { if (i != fermentableRow) { $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_adjust_to_total_100', 0); } } } $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_adjust_to_total_100', 1); calcFermentables(); } }); $("#wf_adjust_to_total_100").on('unchecked', function (event) { if (fermentableData.f_adjust_to_total_100 != 0) { $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_adjust_to_total_100', 0); calcFermentables(); } }); $("#wf_added").jqxDropDownList({ theme: theme, source: AddedAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true, dropDownVerticalAlignment: 'top' }); $("#wf_added").on('select', function (event) { if (event.args) { var index = event.args.index; $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_added', index); calcFermentables(); calcIBUs(); calcMash(); } }); // Tab 4, Hops $("#est_ibu2").jqxTooltip({ content: 'De bitterheid in IBU. Dit wordt automatisch berekend.' }); $("#est_ibu2").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#hop_flavour").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, animationDuration: 0, colorRanges: [ { stop: 20, color: '#004D00' }, { stop: 40, color: '#008C00' }, { stop: 60, color: '#00BF00' }, { stop: 80, color: '#00FF00' }, { stop: 100, color: '#80FF80' } ], renderText: function (text) { var val = parseInt(text); if (val < 20) return 'Weinig'; else if (val < 40) return 'Matig'; else if (val < 60) return 'Redelijk'; else if (val < 80) return 'Veel'; else return 'Zeer veel'; } }); $("#hop_aroma").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, animationDuration: 0, colorRanges: [ { stop: 20, color: '#004D00' }, { stop: 40, color: '#008C00' }, { stop: 60, color: '#00BF00' }, { stop: 80, color: '#00FF00' }, { stop: 100, color: '#80FF80' } ], renderText: function (text) { var val = parseInt(text); if (val < 20) return 'Weinig'; else if (val < 40) return 'Matig'; else if (val < 60) return 'Redelijk'; else if (val < 80) return 'Veel'; else return 'Zeer veel'; } }); $("#popupHop").jqxWindow({ width: 800, height: 300, position: { x: 230, y: 100 }, resizable: false, theme: theme, isModal: true, autoOpen: false, cancelButton: $("#HopReady"), modalOpacity: 0.40 }); $("#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 = { h_name: $("#wh_name").val(), h_origin: hopData.h_origin, h_amount: parseFloat($("#wh_amount").jqxNumberInput('decimal')) / 1000, h_cost: hopData.h_cost, h_type: hopData.h_type, h_form: hopData.h_form, h_useat: $("#wh_useat").val(), h_time: hopData.h_time, h_alpha: hopData.h_alpha, h_beta: hopData.h_beta, h_hsi: hopData.h_hsi, h_humulene: hopData.h_humulene, h_caryophyllene: hopData.h_caryophyllene, h_cohumulone: hopData.h_cohumulone, h_myrcene: hopData.h_myrcene, h_total_oil: hopData.h_total_oil, h_inventory: hopData.h_inventory, h_avail: hopData.h_avail }; $("#hopGrid").jqxGrid('updaterow', rowID, row); calcIBUs(); }); $("#wh_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wh_instock").jqxCheckBox({ theme: theme, height: 23 }); $("#wh_instock").on('change', function (event) { hopinstock = event.args.checked; hoplist.dataBind(); }); $("#wh_select").jqxDropDownList({ placeHolder: "Kies hop:", theme: theme, source: hoplist, displayMember: "name", width: 150, height: 23, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = hoplist.records[index]; return datarecord.origin+ " - " + datarecord.name + " / " + HopFormData[datarecord.form].nl + " (" + datarecord.alpha + " % α)"; } }); $("#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); $("#wh_name").val(datarecord.name); hopData.h_name = datarecord.name; hopData.h_origin = datarecord.origin; hopData.h_cost = datarecord.cost; hopData.h_type = datarecord.type; hopData.h_form = datarecord.form; hopData.h_alpha = datarecord.alpha; hopData.h_beta = datarecord.beta; hopData.h_hsi = datarecord.hsi; hopData.h_humulene = datarecord.humulene; hopData.h_caryophyllene = datarecord.caryophyllene; hopData.h_cohumulone = datarecord.cohumulone; hopData.h_myrcene = datarecord.myrcene; hopData.h_total_oil = datarecord.total_oil; hopData.h_inventory = datarecord.inventory; } }); $("#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, parseFloat($("#batch_size").jqxNumberInput('decimal')), amount, parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $("#ibu_method").val() ); hopData.h_amount = amount; $("#wh_ibu").val(ibu); }); $("#wh_ibu").jqxNumberInput( Show1dec ); $("#wh_time").jqxNumberInput( PosInt ); $("#wh_time").on('change', function (event) { var newtime = parseFloat(event.args.value); // Check limits and correct if (hopData.h_useat == 2) { // Boil if (newtime > parseFloat($("#boil_time").jqxNumberInput('decimal'))) { newtime = parseFloat($("#boil_time").jqxNumberInput('decimal')); $("#wh_time").val(newtime); } hopData.h_time = newtime; } else if (hopData.h_useat == 4) { // Whirlpool if (newtime > 120) { newtime = 120; $("#wh_time").val(newtime); } hopData.h_time = newtime; } else if (hopData.h_useat == 5) { // Dry hop if (newtime > 21) { newtime = 21; $("#wh_time").val(newtime); } hopData.h_time = newtime * 1440; } var 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); }); $("#wh_useat").jqxDropDownList({ theme: theme, source: HopUseAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true, dropDownVerticalAlignment: 'top' }); $("#wh_useat").on('select', function (event) { if (event.args) { var index = event.args.index; hopData.h_useat = index; if ((index == 0) || (index == 1)) { // Mashhop or First wort hop hopData.h_time = parseFloat(dataRecord.boil_time); $("#wh_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); $("#wh_time").val(hopData.h_time); } else if (index == 3) { // Aroma hopData.h_time = 0; $("#wh_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); $("#wh_time").val(0); } else { // Boil, Whirlpool or Dry hop $("#wh_time").jqxNumberInput({ spinButtons: true, readOnly: false, width: 110 }); } if (index == 5) // Dry hop $("#wh_pmpt_time").html("Tijd in dagen"); else $("#wh_pmpt_time").html("Tijd in minuten"); } }); // Tab 5, Miscs $("#popupMisc").jqxWindow({ width: 800, height: 275, position: { x: 230, y: 100 }, resizable: false, theme: theme, isModal: true, autoOpen: false, cancelButton: $("#MiscReady"), modalOpacity: 0.40 }); $("#MiscReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#MiscReady").click(function () { var rowID = $("#miscGrid").jqxGrid('getrowid', miscRow); console.log("MiscReady row:"+miscRow+" ID:"+rowID); var row = { m_name: miscData.m_name, m_amount: miscData.m_amount, m_cost: miscData.m_cost, m_type: miscData.m_type, m_use_use: miscData.m_use_use, m_time: miscData.m_time, m_amount_is_weight: miscData.m_amount_is_weight, m_inventory: miscData.m_inventory, m_avail: miscData.m_avail }; $("#miscGrid").jqxGrid('updaterow', rowID, row); calcMiscs(); }); $("#wm_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wm_instock").jqxCheckBox({ theme: theme, height: 23 }); $("#wm_instock").on('change', function (event) { miscinstock = event.args.checked; misclist.dataBind(); }); $("#wm_select").jqxDropDownList({ placeHolder: "Kies ingrediënt:", theme: theme, source: misclist, displayMember: "name", width: 150, height: 23, dropDownWidth: 500, dropDownHeight: 500 }); $("#wm_select").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = misclist.records[index]; $("#wm_name").val(datarecord.name); miscData.m_name = datarecord.name; miscData.m_cost = datarecord.cost; miscData.m_type = datarecord.type; miscData.m_use_use = datarecord.use_use; miscData.m_amount_is_weight = datarecord.amount_is_weight; miscData.m_inventory = datarecord.inventory; } }); $("#wm_amount").jqxNumberInput( Spin1dec ); $('#wm_amount').on('change', function (event) { console.log("amount changed: "+event.args.value); miscData.m_amount = parseFloat(event.args.value) / 1000; }); $("#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 if (newtime > parseFloat($("#boil_time").jqxNumberInput('decimal'))) { newtime = parseFloat($("#boil_time").jqxNumberInput('decimal')); $("#wm_time").val(newtime); } miscData.m_time = newtime; } else if ((miscData.m_use_use == 3) || (miscData.m_use_use == 4)) { // Primary or Secondary if (newtime > 21) { newtime = 21; $("#wm_time").val(newtime); } miscData.m_time = newtime * 1440; } }); $("#wm_use_use").jqxDropDownList({ theme: theme, source: MiscUseAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true, dropDownVerticalAlignment: 'top' }); $("#wm_use_use").on('select', function (event) { if (event.args) { var index = event.args.index; miscData.m_use_use = index; if ((index == 2) || (index == 3) || (index == 4)) { // Boil, Primary or Secondary $("#wm_time").jqxNumberInput({ spinButtons: true, readOnly: false, width: 110 }); } else { $("#wm_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); $("#wm_time").val(0); miscData.m_time = 0; } } }); // Tab 6, Yeasts $("#est_fg2").jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' }); $("#est_fg2").jqxNumberInput( Show3dec ); $("#est_abv2").jqxTooltip({ content: 'Alcohol volume %. Dit wordt automatisch berekend.' }); $("#est_abv2").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#yeast_cells").jqxNumberInput( Show1dec ); $("#need_cells").jqxNumberInput( Show1dec ); $("#plato_cells").jqxNumberInput( Show2dec ); $("#popupYeast").jqxWindow({ width: 800, height: 300, position: { x: 230, y: 100 }, resizable: false, theme: theme, isModal: true, autoOpen: false, cancelButton: $("#YeastReady"), modalOpacity: 0.40 }); $("#YeastReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#YeastReady").click(function () { var rowID = $("#yeastGrid").jqxGrid('getrowid', yeastRow); console.log("YeastReady row:"+yeastRow+" ID:"+rowID); var row = { y_name: yeastData.y_name, y_laboratory: yeastData.y_laboratory, y_product_id: yeastData.y_product_id, y_amount: yeastData.y_amount, y_cost: yeastData.y_cost, y_type: yeastData.y_type, y_form: yeastData.y_form, y_flocculation: yeastData.y_flocculation, y_min_temperature: yeastData.y_min_temperature, y_max_temperature: yeastData.y_max_temperature, y_attenuation: yeastData.y_attenuation, y_use: yeastData.y_use, y_cells: yeastData.y_cells, y_tolerance: yeastData.y_tolerance, y_inventory: yeastData.y_inventory, y_avail: yeastData.y_avail }; $("#yeastGrid").jqxGrid('updaterow', rowID, row); calcFermentables(); calcYeast(); }); $("#wy_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wy_laboratory").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wy_product_id").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wy_instock").jqxCheckBox({ theme: theme, height: 23 }); $("#wy_instock").on('change', function (event) { yeastinstock = event.args.checked; yeastlist.dataBind(); }); $("#wy_select").jqxDropDownList({ placeHolder: "Kies gist:", theme: theme, source: yeastlist, displayMember: "name", width: 150, height: 23, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = yeastlist.records[index]; return datarecord.laboratory+" "+datarecord.product_id+" "+datarecord.name; } }); $("#wy_select").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = yeastlist.records[index]; $("#wy_name").val(datarecord.name); $("#wy_laboratory").val(datarecord.laboratory); $("#wy_product_id").val(datarecord.product_id); yeastData.y_name = datarecord.name; yeastData.y_cost = datarecord.cost; yeastData.y_type = datarecord.type; yeastData.y_form = datarecord.form; yeastData.y_laboratory = datarecord.laboratory; yeastData.y_product_id = datarecord.product_id; yeastData.y_min_temperature = datarecord.min_temperature; yeastData.y_max_temperature = datarecord.max_temperature; yeastData.y_flocculation = datarecord.flocculation; yeastData.y_attenuation = datarecord.attenuation; yeastData.y_cells = datarecord.cells; yeastData.y_inventory = datarecord.inventory; if (yeastData.y_form == 0) { $("#wy_pmpt_amount").html("Pak(ken):"); } else if (yeastData.y_form == 1) { $("#wy_pmpt_amount").html("Gewicht gram:"); } else { $("#wy_pmpt_amount").html("Volume ml:"); } calcFermentables(); calcYeast(); } }); $("#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; yeastData.y_amount = amount; calcFermentables(); calcYeast(); }); $("#wy_use").jqxDropDownList({ theme: theme, source: YeastUseAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true, dropDownVerticalAlignment: 'top' }); $("#wy_use").on('select', function (event) { if (event.args) { var index = event.args.index; yeastData.y_use = index; calcFermentables(); calcYeast(); } }); for (var i = 1; i < 5; i++) { $("#prop"+i+"_type").jqxDropDownList({ theme: theme, source: StarterTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 120, height: 23, autoDropDownHeight: true }); $("#prop"+i+"_type").hide(); $("#prop"+i+"_volume").jqxNumberInput( Spin3dec ); $("#prop"+i+"_volume").hide(); $("#prop"+i+"_irate").jqxNumberInput( Show1dec ); $("#prop"+i+"_irate").hide(); $("#prop"+i+"_ncells").jqxNumberInput( Show1dec ); $("#prop"+i+"_ncells").hide(); $("#prop"+i+"_tcells").jqxNumberInput( Show1dec ); $("#prop"+i+"_tcells").hide(); $("#prop"+i+"_growf").jqxNumberInput( Show2dec ); $("#prop"+i+"_growf").hide(); } $("#starter_enable").jqxCheckBox({ theme: theme, height: 23 }); $("#starter_type").jqxDropDownList({ theme: theme, source: StarterTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 120, height: 23, autoDropDownHeight: true }); $("#starter_sg").jqxNumberInput( SGopts ); $("#starter_try").jqxButton({ template: "primary", width: '100px', height: 23, theme: theme }); // Tab 7, Mashing $("#mash_name").jqxTooltip({ content: 'De omschrijving van dit maisch profiel.' }); $("#mash_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#mash_select").jqxDropDownList({ placeHolder: "Kies schema:", theme: theme, source: mashlist, displayMember: "name", width: 250, height: 23, dropDownWidth: 500, dropDownHeight: 500, dropDownHorizontalAlignment: 'right' }); $("#mash_select").on('select', function (event) { if (event.args) { var 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.push(row.uid); } $("#mashGrid").jqxGrid('deleterow', rowIDs); // Then add the new steps var datarecord = mashlist.records[index]; $("#mash_name").val(datarecord.name); for (var i = 0; i < datarecord.steps.length; i++) { var data = datarecord.steps[i]; var row = {}; row["step_name"] = data.step_name; row["step_type"] = data.step_type; // For now, but this must be smarter. if (mash_infuse == 0 && dataRecord.w1_amount > 0) mash_infuse = dataRecord.w1_amount; if (i == 0) row["step_infuse_amount"] = mash_infuse; else row["step_infuse_amount"] = 0; if (mashkg > 0) row['step_thickness'] = parseFloat(mash_infuse / mashkg); else row['step_thickness'] = 0; row["step_temp"] = data.step_temp; row["end_temp"] = data.end_temp; row["step_time"] = data.step_time; row["ramp_time"] = data.ramp_time; var commit = $("#mashGrid").jqxGrid('addrow', null, row); } } }); $("#popupMash").jqxWindow({ width: 800, height: 350, position: { x: 230, y: 100 }, resizable: false, theme: theme, isModal: true, autoOpen: false, cancelButton: $("#MashReady"), modalOpacity: 0.40 }); $("#MashReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#MashReady").click(function () { calcMash(); }); $("#wstep_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wstep_name").on('change', function (event) { var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.step_name = event.args.value; }); $("#wstep_type").jqxDropDownList({ theme: theme, source: MashStepTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true }); $("#wstep_type").on('select', function (event) { if (event.args) { var index = event.args.index; var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.step_type = index; if (index == 0) { $("#wstep_infuse_amount").show(); $("#wstep_pmpt").show(); } else { rowdata.step_infuse_amount = 0; $("#wstep_infuse_amount").hide(); $("#wstep_pmpt").hide(); } mash_infuse = 0; var rows = $('#mashGrid').jqxGrid('getrows'); for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.step_type == 0) // Infusion mash_infuse += parseFloat(row.step_infuse_amount); } } }); $("#wstep_temp").jqxNumberInput( Spin1dec ); $('#wstep_temp').on('change', function (event) { var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.step_temp = parseFloat(event.args.value); }); $("#wend_temp").jqxNumberInput( Spin1dec ); $('#wend_temp').on('change', function (event) { var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.end_temp = parseFloat(event.args.value); }); $("#wstep_time").jqxNumberInput( PosInt ); $('#wstep_time').on('change', function (event) { var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.step_time = parseFloat(event.args.value); }); $("#wramp_time").jqxNumberInput( PosInt ); $('#wramp_time').on('change', function (event) { var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.ramp_time = parseFloat(event.args.value); }); $("#wstep_infuse_amount").jqxNumberInput( Spin1dec ); $('#wstep_infuse_amount').on('change', function (event) { var 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]; if (row.step_type == 0) // Infusion mash_infuse += parseFloat(row.step_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); }); // Tab 8, Water $("#tgt_bu").jqxNumberInput( Show2wat ); $("#tgt_cl_so4").jqxNumberInput( Show1wat ); $("#got_cl_so4").jqxNumberInput( Show1wat ); // Water source 1 $("#w1_name").jqxDropDownList({ placeHolder: "Kies hoofd water:", theme: theme, source: waterlist, displayMember: "name", width: 250, height: 27, dropDownWidth: 400, dropDownHeight: 400 }); $("#w1_name").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = waterlist.records[index]; dataRecord.w1_name = datarecord.name; $("#w1_calcium").val(datarecord.calcium); dataRecord.w1_calcium = datarecord.calcium; $("#w1_sulfate").val(datarecord.sulfate); dataRecord.w1_sulfate = datarecord.sulfate; $("#w1_chloride").val(datarecord.chloride); dataRecord.w1_chloride = datarecord.chloride; $("#w1_sodium").val(datarecord.sodium); dataRecord.w1_sodium = datarecord.sodium; $("#w1_magnesium").val(datarecord.magnesium); dataRecord.w1_magnesium = datarecord.magnesium; $("#w1_total_alkalinity").val(datarecord.total_alkalinity); dataRecord.w1_total_alkalinity = datarecord.total_alkalinity; $("#w1_ph").val(datarecord.ph); dataRecord.w1_ph = datarecord.ph; $("#w1_cost").val(datarecord.cost); dataRecord.w1_cost = datarecord.cost; calcWater(); } }); $("#w1_amount").jqxNumberInput( Show1wat ); $("#w1_calcium").jqxNumberInput( Show1wat ); $("#w1_magnesium").jqxNumberInput( Show1wat ); $("#w1_sodium").jqxNumberInput( Show1wat ); $("#w1_total_alkalinity").jqxNumberInput( Show1wat ); $("#w1_chloride").jqxNumberInput( Show1wat ); $("#w1_sulfate").jqxNumberInput( Show1wat ); $("#w1_ph").jqxNumberInput( Show1wat ); // Water source 2 $("#w2_name").jqxDropDownList({ placeHolder: "Kies meng water:", theme: theme, source: waterlist, displayMember: "name", width: 250, height: 27, dropDownWidth: 400, dropDownHeight: 400 }); $("#w2_name").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = waterlist.records[index]; dataRecord.w2_name = datarecord.name; $("#w2_calcium").val(datarecord.calcium); dataRecord.w2_calcium = datarecord.calcium; $("#w2_sulfate").val(datarecord.sulfate); dataRecord.w2_sulfate = datarecord.sulfate; $("#w2_chloride").val(datarecord.chloride); dataRecord.w2_chloride = datarecord.chloride; $("#w2_sodium").val(datarecord.sodium); dataRecord.w2_sodium = datarecord.sodium; $("#w2_magnesium").val(datarecord.magnesium); dataRecord.w2_magnesium = datarecord.magnesium; $("#w2_total_alkalinity").val(datarecord.total_alkalinity); dataRecord.w2_total_alkalinity = datarecord.total_alkalinity; $("#w2_ph").val(datarecord.ph); dataRecord.w2_ph = datarecord.ph; $("#w2_cost").val(datarecord.cost); dataRecord.w2_cost = datarecord.cost; $("#w2_amount").jqxNumberInput({ max: 100000, readOnly: false }); // Set high max to enable the spinbuttons. calcWater(); } }); $("#w2_amount").jqxTooltip({ content: 'De verdeling van het hoofd en meng water. Het totale maisch water volume blijft gelijk.'}); $("#w2_amount").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 94, height: 23, min: 0, max: 0, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.5, readOnly: true }); $("#w2_calcium").jqxNumberInput( Show1wat ); $("#w2_magnesium").jqxNumberInput( Show1wat ); $("#w2_sodium").jqxNumberInput( Show1wat ); $("#w2_total_alkalinity").jqxNumberInput( Show1wat ); $("#w2_chloride").jqxNumberInput( Show1wat ); $("#w2_sulfate").jqxNumberInput( Show1wat ); $("#w2_ph").jqxNumberInput( Show1wat ); // Water mixed $("#wg_amount").jqxNumberInput( Show1wat ); $("#wg_calcium").jqxNumberInput( Show1wat ); $("#wg_magnesium").jqxNumberInput( Show1wat ); $("#wg_sodium").jqxNumberInput( Show1wat ); $("#wg_total_alkalinity").jqxNumberInput( Show1wat ); $("#wg_chloride").jqxNumberInput( Show1wat ); $("#wg_sulfate").jqxNumberInput( Show1wat ); $("#wg_ph").jqxNumberInput( Show1wat ); // Water treated $("#wb_calcium").jqxTooltip({ content: 'De ideale hoeveelheid Calcium is tussen 40 en 150.'}); $("#wb_calcium").jqxNumberInput( Show1wat ); $("#wb_magnesium").jqxTooltip({ content: 'De ideale hoeveelheid Magnesium is lager dan 30.'}); $("#wb_magnesium").jqxNumberInput( Show1wat ); $("#wb_sodium").jqxTooltip({ content: 'De ideale hoeveelheid Natrium is lager dan 150.'}); $("#wb_sodium").jqxNumberInput( Show1wat ); $("#wb_total_alkalinity").jqxNumberInput( Show1wat ); $("#wb_chloride").jqxTooltip({ content: 'De ideale hoeveelheid Chloride is tussen 50 en 100.'}); $("#wb_chloride").jqxNumberInput( Show1wat ); $("#wb_sulfate").jqxTooltip({ content: 'De ideale hoeveelheid Sulfaat is tussen 50 en 350.'}); $("#wb_sulfate").jqxNumberInput( Show1wat ); $("#wb_ph").jqxNumberInput( Show1wat ); // Water target profile $("#pr_name").jqxDropDownList({ placeHolder: "Kies doel profiel:", theme: theme, source: waterprofiles, displayMember: "name", width: 250, height: 27, dropDownWidth: 400, dropDownHeight: 300 }); $("#pr_name").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = waterprofiles.records[index]; $("#pr_calcium").val(datarecord.calcium); $("#pr_sulfate").val(datarecord.sulfate); $("#pr_chloride").val(datarecord.chloride); $("#pr_sodium").val(datarecord.sodium); $("#pr_magnesium").val(datarecord.magnesium); $("#pr_total_alkalinity").val(datarecord.total_alkalinity); } }); $("#pr_calcium").jqxNumberInput( Show1wat ); $("#pr_magnesium").jqxNumberInput( Show1wat ); $("#pr_sodium").jqxNumberInput( Show1wat ); $("#pr_total_alkalinity").jqxNumberInput( Show1wat ); $("#pr_chloride").jqxNumberInput( Show1wat ); $("#pr_sulfate").jqxNumberInput( Show1wat ); // Water agents $("#wa_cacl2").jqxTooltip({ content: 'Voor het maken van een ander waterprofiel. Voegt calcium en chloride toe. Voor het verbeteren van zoetere bieren.' }); $("#wa_cacl2").jqxNumberInput( Spin1dec ); $("#wa_caso4").jqxTooltip({ content: 'Gips. Voor het maken van een ander waterprofiel. Voegt calcium en sulfaat toe. Voor het verbeteren van bittere bieren.' }); $("#wa_caso4").jqxNumberInput( Spin1dec ); $("#wa_mgso4").jqxTooltip({ content: 'Epsom zout. Voor het maken van een ander waterprofiel. Voegt magnesium en sulfaat toe. Gebruik spaarzaam!' }); $("#wa_mgso4").jqxNumberInput( Spin1dec ); $("#wa_nacl").jqxTooltip({ content: 'Keukenzout. Voor het maken van een ander waterprofiel. Voegt natrium en chloride toe. Voor het accentueren van zoetheid. Bij hoge dosering wordt het bier ziltig.' }); $("#wa_nacl").jqxNumberInput( Spin1dec ); $("#mash_ph").jqxTooltip({ content: 'Maisch pH tussen 5.2 en 5.6. Gebruik 5.2 voor lichte en 5.5 voor donkere bieren.'}); $("#mash_ph").jqxNumberInput( SpinpH ); $("#calc_acid").jqxCheckBox({ theme: theme, width: 120, height: 23 }); $("#wa_base_name").jqxDropDownList({ theme: theme, source: BaseTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 170, height: 23, autoDropDownHeight: true }); $("#wa_base").jqxNumberInput( Spin2dec ); $("#wa_base").jqxNumberInput({ symbol: ' gr', symbolPosition: 'right' }); $("#wa_acid_name").jqxDropDownList({ theme: theme, source: AcidTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 170, height: 23, autoDropDownHeight: true }) $("#wa_acid").jqxNumberInput( Spin2dec ); $("#wa_acid").jqxNumberInput({ symbol: ' ml', symbolPosition: 'right' }); $("#wa_acid_perc").jqxNumberInput( Perc0 ); $("#wa_acid_perc").jqxNumberInput({ width: 70, symbol: '%', symbolPosition: 'right' }); // Sparge water $("#sparge_temp").jqxNumberInput( Spin1dec ); $("#sparge_volume").jqxNumberInput( Spin1dec ); $("#sparge_ph").jqxNumberInput( SpinpH ); $("#sparge_source").jqxDropDownList({ theme: theme, source: SpargeSourceAdapter, valueMember: 'id', displayMember: 'nl', width: 110, height: 23, autoDropDownHeight: true }); $("#sparge_acid_amount").jqxNumberInput( Spin2dec ); $("#sparge_acid_amount").jqxNumberInput({ spinButtons: false, readOnly: true, symbol: ' ml', symbolPosition: 'right' }); $("#sparge_acid_type").jqxDropDownList({ theme: theme, source: AcidTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 110, height: 23, autoDropDownHeight: true }); $("#sparge_acid_perc").jqxNumberInput( Perc0 ); $("#sparge_acid_perc").jqxNumberInput({ symbol: '%', symbolPosition: 'right' }); // Tab 9, Brewday $("#brew_date_start").jqxTooltip({ content: 'Brouw datum en tijd. Voor planning laat de tijd op 00:00:00 staan.' }); $("#brew_date_start").jqxDateTimeInput( DateTimeopts ); $('#brew_date_start').on('close', function (event) { calcStage(); }); $("#brew_date_end").jqxTooltip({ content: 'End datum en tijd van de brouw. Leeg laten als er nog niet gebrouwen is.' }); $("#brew_date_end").jqxDateTimeInput( DateTimeopts ); $('#brew_date_end').on('close', function (event) { calcStage(); }); $("#brew_mash_ph").jqxTooltip({ content: 'De gemeten pH tijdens het maischen eventueel na correctie.' }); $("#brew_mash_ph").jqxNumberInput( SpinpH ); $("#est_mash_ph").jqxTooltip({ content: 'De gewenste pH tijdens het maischen.' }); $("#est_mash_ph").jqxNumberInput( Show1wat ); $("#brew_preboil_ph").jqxTooltip({ content: 'De gemeten pH in de kookketel na het spoelen en voor de kook.' }); $("#brew_preboil_ph").jqxNumberInput( SpinpH ); // est_preboil_ph $("#brew_aboil_ph").jqxTooltip({ content: 'De gemeten pH na het koken.' }); $("#brew_aboil_ph").jqxNumberInput( SpinpH ); // est_aboil_ph $("#brew_mash_sg").jqxTooltip({ content: 'Het bereikte SG na het maischen.' }); $("#brew_mash_sg").jqxNumberInput( SGopts ); $("#brew_mash_sg").on('valueChanged', function () { calcMashEfficiency(); }); $("#est_mash_sg").jqxTooltip({ content: 'Het berekende verwachte SG na het maischen.' }); $("#est_mash_sg").jqxNumberInput( Show3wat ); $("#brew_preboil_sg").jqxTooltip({ content: 'Het gemeten SG in de kookketel na het spoelen en voor het koken.' }); $("#brew_preboil_sg").jqxNumberInput( SGopts ); $("#brew_preboil_sg").on('valueChanged', function (event) { dataRecord.brew_preboil_sg = event.args.value; calcEfficiencyBeforeBoil(); }); $("#est_pre_sg").jqxTooltip({ content: 'Het berekende SG in de kookketel na het spoelen en voor het koken.' }); $("#est_pre_sg").jqxNumberInput( Show3wat ); $("#brew_aboil_sg").jqxTooltip({ content: 'Het gemeten SG in de kookketel na het koken.' }); $("#brew_aboil_sg").jqxNumberInput( SGopts ); $("#brew_aboil_sg").on('valueChanged', function (event) { dataRecord.brew_aboil_sg = event.args.value; calcEfficiencyAfterBoil(); calcFermentables(); calcIBUs(); }); $("#est_og3").jqxTooltip({ content: 'Het gewenste SG in de kookketel na het koken.' }); $("#est_og3").jqxNumberInput( Show3wat ); $("#brew_mash_efficiency").jqxTooltip({ content: 'Het behaalde maisch rendement.' }); $("#brew_mash_efficiency").jqxNumberInput( Show1dec ); $("#brew_preboil_volume").jqxTooltip({ content: 'Het gemeten volume van het wort voor het koken.' }); $("#brew_preboil_volume").jqxNumberInput( Spin1dec ); $("#brew_preboil_volume").on('valueChanged', function (event) { dataRecord.brew_preboil_volume = event.args.value; calcEfficiencyBeforeBoil(); }); $("#est_pre_vol").jqxTooltip({ content: 'Het berekende volume van het wort voor het koken.' }); $("#est_pre_vol").jqxNumberInput( Show1wat ); $("#brew_aboil_volume").jqxTooltip({ content: 'Het gemeten volume van het wort na het koken.' }); $("#brew_aboil_volume").jqxNumberInput( Spin1dec ); $("#brew_aboil_volume").on('valueChanged', function (event) { dataRecord.brew_aboil_volume = event.args.value; calcEfficiencyAfterBoil(); calcFermentables(); calcIBUs(); }); $("#est_a_vol").jqxTooltip({ content: 'Het gewenste volume na het koken.' }); $("#est_a_vol").jqxNumberInput( Show1wat ); $("#brew_preboil_efficiency").jqxTooltip({ content: 'Het berekende rendement voor het koken.' }); $("#brew_preboil_efficiency").jqxNumberInput( Show1dec ); $("#brew_aboil_efficiency").jqxTooltip({ content: 'Het bereikte rendement na het koken.' }); $("#brew_aboil_efficiency").jqxNumberInput( Show1dec ); $("#brew_sparge_temperature").jqxNumberInput( Spin1dec ); $("#brew_sparge_volume").jqxNumberInput( Spin1dec ); $("#brew_sparge_est").jqxNumberInput( Show1dec ); $("#brew_whirlpool9").jqxNumberInput( PosInt ); $("#brew_whirlpool9").jqxNumberInput({ max: 120 }); $("#brew_cooling_to").jqxNumberInput( Spin1dec ); $("#brew_sparge_ph").jqxNumberInput( SpinpH ); $("#brew_whirlpool7").jqxNumberInput( PosInt ); $("#brew_whirlpool7").jqxNumberInput({ max: 120 }); $("#brew_cooling_method").jqxDropDownList({ theme: theme, source: CoolingTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true }); $("#brew_whirlpool6").jqxNumberInput( PosInt ); $("#brew_whirlpool6").jqxNumberInput({ max: 120 }); $("#brew_cooling_time").jqxNumberInput( PosInt ); $("#brew_cooling_time").jqxNumberInput({ max: 1440 }); $("#brew_whirlpool2").jqxNumberInput( PosInt ); $("#brew_whirlpool2").jqxNumberInput({ max: 120 }); $("#brew_aeration_type").jqxDropDownList({ theme: theme, source: AerationTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true }); $("#brew_aeration_time").jqxNumberInput( PosInt ); $("#brew_aeration_time").jqxNumberInput({ max: 1440 }); $("#brew_aeration_speed").jqxNumberInput( PosInt ); $("#brew_aeration_speed").jqxNumberInput({ max: 1440 }); $("#brew_fermenter_volume").jqxNumberInput( Show1dec ); $("#brew_fermenter_extrawater").jqxNumberInput( Spin1dec ); $("#brew_fermenter_sg").jqxNumberInput( Show3dec ); $("#brew_fermenter_tcloss").jqxNumberInput( Spin1dec ); $("#brew_fermenter_ibu").jqxNumberInput( Show0dec ); $("#brew_fermenter_color").jqxNumberInput( Show0dec ); $("#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); }); // Tab 10, Fermentation // Note, fermentation temps changes must do calcCarbonation() $("#brew_fermenter_sg2").jqxTooltip({ content: 'Het behaalde SG in het gistvat, overgenomen van de brouwdag.' }); $("#brew_fermenter_sg2").jqxNumberInput( Show3dec ); $("#primary_start_temp").jqxTooltip({ content: 'De begintemperatuur van de hoofdvergisting.' }); $("#primary_start_temp").jqxNumberInput( YeastT ); $("#primary_max_temp").jqxTooltip({ content: 'De hoogst bereikte piek temperatuur tijdens de hoofgvergisting.' }); $("#primary_max_temp").jqxNumberInput( YeastT ); $("#primary_end_temp").jqxTooltip({ content: 'De eind temperatuur van de hoofdvergisting.' }); $("#primary_end_temp").jqxNumberInput( YeastT ); $("#primary_end_sg").jqxTooltip({ content: 'Het gemeten SG aan het eind van de hoofdvergisting.' }); $("#primary_end_sg").jqxNumberInput( SGopts ); $("#primary_end_brix").jqxTooltip({ content: 'Hulpfinctie: de afgelezen °Brix RI waarde met een refractometer.' }); $("#primary_end_brix").jqxNumberInput( Spin1dec ); $("#primary_svg").jqxTooltip({ content: 'De schijnbare vergisting graad behaald na de hoofdgisting.' }); $("#primary_svg").jqxNumberInput( Show1dec ); $("#primary_end_date").jqxTooltip({ content: 'De eind datum van de hoofdvergisting en eventueel overhevelen.' }); $("#primary_end_date").jqxDateTimeInput( Dateopts ); $('#primary_end_date').on('close', function (event) { calcStage(); }); $("#secondary_temp").jqxNumberInput( YeastT ); $("#secondary_end_date").jqxTooltip({ content: 'De eind datum van de navergisting en het begin van het lageren.' }); $("#secondary_end_date").jqxDateTimeInput( Dateopts ); $('#secondary_end_date').on('close', function (event) { calcStage(); }); $("#tertiary_temp").jqxNumberInput( YeastT ); $("#fg").jqxNumberInput( Spin3dec ); $("#est_fg3").jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' }); $("#est_fg3").jqxNumberInput( Show3dec ); $("#final_brix").jqxTooltip({ content: 'Hulpfinctie: de afgelezen °Brix RI waarde met een refractometer.' }); $("#final_brix").jqxNumberInput( Spin1dec ); $("#final_abv").jqxNumberInput( Show1dec ); $("#final_svg").jqxNumberInput( Show1dec ); $("#FLog").jqxButton({ template: "info", width: '150px', theme: theme }); $("#FLog").click(function () { // Open log in a new tab. var url="log_fermentation.php?code=" + dataRecord.code + "&name=" + dataRecord.name; window.open(url); }); // Tab 11, Packaging // TODO: high gravity packaging, extra water and recalc abv, color and ibu. $("#package_date").jqxTooltip({ content: 'De verpakkings datum van dit bier.' }); $("#package_date").jqxDateTimeInput( Dateopts ); $('#package_date').on('close', function (event) { calcStage(); }); $('#package_volume').jqxTooltip({ content: 'Het beschikbare volume om te bottelen of op fust te zetten.' }); $('#package_volume').jqxNumberInput( Spin1dec ); $('#package_infuse_amount').jqxTooltip({ content: 'De hoeveelheid water of drank extra toe te voegen.' }); $('#package_infuse_amount').jqxNumberInput( Spin3dec ); $('#package_infuse_abv').jqxTooltip({ content: 'De hoeveelheid alcohol in de drank, of 0.0 als het water is.' }); $('#package_infuse_abv').jqxNumberInput( Spin1dec ); $('#package_infuse_notes').jqxTooltip({ content: 'Omschrijving van de extra toevoeging.' }); $('#package_infuse_notes').jqxInput({ theme: theme, width: 640, height: 23 }); $('#package_abv').jqxTooltip({ content: 'De uiteindelijke hoeveelheid alcohol volume %.' }); $('#package_abv').jqxNumberInput( Show1dec ); $("#st_carb_min2").jqxTooltip({ content: 'Het minimum aanbevolen koolzuur volume voor deze bierstijl.'}); $("#st_carb_min2").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#st_carb_max2").jqxTooltip({ content: 'Het maximum aamnevolen koolzuur volume voor deze bierstijl.'}); $("#st_carb_max2").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#bottle_amount").jqxTooltip({ content: 'De totale hoeveelheid te bottelen bier.' }); $("#bottle_amount").jqxNumberInput( Spin1dec ); $("#keg_amount").jqxTooltip({ content: 'De totale hoeveelheid op fust te zetten bier.' }); $("#keg_amount").jqxNumberInput( Spin1dec ); $("#bottle_carbonation").jqxTooltip({ content: 'Het gewenste CO2 volume in de flessen.' }); $("#bottle_carbonation").jqxNumberInput( Spin2dec ); $("#bottle_carbonation").jqxNumberInput({ max: 5 }); $("#keg_carbonation").jqxTooltip({ content: 'Het gewenste CO2 volume door de suiker in de fusten.' }); $("#keg_carbonation").jqxNumberInput( Spin2dec ); $("#keg_carbonation").jqxNumberInput({ max: 5 }); $("#bottle_priming_sugar").jqxDropDownList({ placeHolder: "Kies suiker:", theme: theme, source: fermentablesugars, displayMember: 'name', width: 200, height: 23, dropDownWidth: 300, dropDownHeight: 400 }); $("#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++) { 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; row["f_amount"] = parseFloat($("#bottle_priming_total").jqxNumberInput('decimal')) / 1000; row["f_cost"] = datarecord.cost; row["f_type"] = datarecord.type; row["f_yield"] = datarecord.yield; row["f_color"] = datarecord.color; row["f_coarse_fine_diff"] = datarecord.coarse_fine_diff; row["f_moisture"] = datarecord.moisture; row["f_diastatic_power"] = datarecord.diastatic_power; row["f_protein"] = datarecord.protein; row["f_max_in_batch"] = datarecord.max_in_batch; row["f_graintype"] = datarecord.graintype; row["f_added"] = 4; row["f_dissolved_protein"] = datarecord.dissolved_protein; row["f_recommend_mash"] = datarecord.recommend_mash; row["f_add_after_boil"] = 1; row["f_adjust_to_total_100"] = 0; row["f_percentage"] = 0; row["f_di_ph"] = datarecord.di_ph; 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); $('#fermentableGrid').jqxGrid('updaterow', rowID, row); } else { $("#fermentableGrid").jqxGrid('addrow', null, row); } calcCarbonation(); } }); $("#keg_priming_sugar").jqxDropDownList({ placeHolder: "Kies suiker:", theme: theme, source: fermentablesugars, displayMember: 'name', width: 200, height: 23, dropDownWidth: 300, dropDownHeight: 400 }); $("#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++) { 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; row["f_amount"] = parseFloat($("#keg_priming_total").jqxNumberInput('decimal')) / 1000; row["f_cost"] = datarecord.cost; row["f_type"] = datarecord.type; row["f_yield"] = datarecord.yield; row["f_color"] = datarecord.color; row["f_coarse_fine_diff"] = datarecord.coarse_fine_diff; row["f_moisture"] = datarecord.moisture; row["f_diastatic_power"] = datarecord.diastatic_power; row["f_protein"] = datarecord.protein; row["f_max_in_batch"] = datarecord.max_in_batch; row["f_graintype"] = datarecord.graintype; row["f_added"] = 5; row["f_dissolved_protein"] = datarecord.dissolved_protein; row["f_recommend_mash"] = datarecord.recommend_mash; row["f_add_after_boil"] = 1; row["f_adjust_to_total_100"] = 0; row["f_percentage"] = 0; row["f_di_ph"] = datarecord.di_ph; 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); $('#fermentableGrid').jqxGrid('updaterow', rowID, row); } else { $("#fermentableGrid").jqxGrid('addrow', null, row); } calcCarbonation(); } }); $("#bottle_priming_amount").jqxNumberInput( Show1dec ); $("#bottle_priming_water").jqxTooltip({ content: 'De hoeveelheid water om de suiker op te lossen.' }); $("#bottle_priming_water").jqxNumberInput( Spin3dec ); $("#keg_priming_amount").jqxNumberInput( Show1dec ); $("#keg_priming_water").jqxTooltip({ content: 'De hoeveelheid water om de suiker op te lossen.' }); $("#keg_priming_water").jqxNumberInput( Spin3dec ); $("#bottle_priming_total").jqxNumberInput( Show1dec ); $("#bottle_pressure").jqxTooltip({ content: 'De maximaal te verwachten druk tijdens het hergisten.' }); $("#bottle_pressure").jqxNumberInput( Show1dec ); $("#keg_priming_total").jqxNumberInput( Show1dec ); $("#keg_forced_carb").jqxCheckBox({ theme: theme, width: 120, height: 23 }); $("#keg_pressure").jqxNumberInput( Show1dec ); $("#bottle_abv").jqxNumberInput( Show1dec ); $("#keg_abv").jqxNumberInput( Show1dec ); $("#bottle_carbonation_temp").jqxNumberInput( YeastT ); $("#keg_carbonation_temp").jqxNumberInput( YeastT ); // Tab 12, Tasting $("#taste_date").jqxTooltip({ content: 'De proef datum van dit bier.' }); $("#taste_date").jqxDateTimeInput( Dateopts ); $('#taste_date').on('close', function (event) { calcStage(); }); $("#taste_rate").jqxTooltip({ content: 'Het cijfer voor dit bier van 1 tot 10.' }); $("#taste_rate").jqxNumberInput( Spin1dec ); $("#taste_rate").jqxNumberInput({ max: 10 }); $("#taste_color").jqxTooltip({ content: 'De kleur van het bier.' }); $("#taste_color").jqxInput({ theme: theme, width: 320, height: 23 }); $("#taste_transparency").jqxTooltip({ content: 'De helderheid van het bier.' }); $("#taste_transparency").jqxInput({ theme: theme, width: 320, height: 23 }); $("#taste_head").jqxTooltip({ content: 'Het schuim op het bier.' }); $("#taste_head").jqxInput({ theme: theme, width: 320, height: 23 }); $("#taste_aroma").jqxTooltip({ content: 'Het aroma van het bier.' }); $("#taste_aroma").jqxInput({ theme: theme, width: 960, height: 23 }); $("#taste_taste").jqxTooltip({ content: 'De smaak van het bier.' }); $("#taste_taste").jqxInput({ theme: theme, width: 960, height: 23 }); $("#taste_aftertaste").jqxTooltip({ content: 'De nasmaak van het bier.' }); $("#taste_aftertaste").jqxInput({ theme: theme, width: 960, height: 23 }); $("#taste_mouthfeel").jqxTooltip({ content: 'Het mondgevoelvan het bier.' }); $("#taste_mouthfeel").jqxInput({ theme: theme, width: 960, height: 23 }); $("#taste_notes").jqxTooltip({ content: 'Het oordeel en opmerkingen over dit bier.' }); $("#taste_notes").jqxInput({ theme: theme, width: 960, height: 100 }); $('#jqxTabs').jqxTabs({ theme: theme, width: 1280, height: 660, autoHeight: false, position: 'top' }); // Buttons below $("#Export").jqxButton({ template: "info", width: '80px', theme: theme }); $("#Export").bind('click', function () { saveRecord(); var url="prod_export.php?record=" + my_record + "&return=" + my_return + "&select=" + my_select + "&code=" + dataRecord.code + "&name=" + dataRecord.name; window.location.href = url; }); $("#Delete").jqxButton({ template: "danger", width: '80px', theme: theme }); $("#Delete").bind('click', function () { // Open a popup to confirm this action. $('#eventWindow').jqxWindow('open'); $("#delOk").click(function () { var data = "delete=true&" + $.param({ uuid: dataRecord.uuid }); $.ajax({ dataType: 'json', url: url, cache: false, data: data, type: "POST", success: function (data, status, xhr) { // delete command is executed. window.location.href = my_return; }, error: function (jqXHR, textStatus, errorThrown) { } }); }); }); $("#Cancel").jqxButton({ template: "primary", width: '80px', theme: theme }); $("#Cancel").bind('click', function () { window.location.href = my_return; }); $("#Save").jqxButton({ template: "success", width: '80px', theme: theme }); $("#Save").bind('click', function () { saveRecord(); window.location.href = my_return; }); createDelElements(); });