www/js/global.js

Sun, 02 Jun 2019 12:48:54 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Sun, 02 Jun 2019 12:48:54 +0200
changeset 392
544d7d0183b2
parent 376
1de1623e1760
child 406
0ad967f2d6ee
permissions
-rw-r--r--

Added 15 fields to the recipes table. Added 18 fields to the products table. These are calculated values that are now stored in the database so export programs can use these values without calculating them again. Product and recipe print have water and mash schedule added. Product print has brewday results added if the brewday is over. The ingredients layout changed in the product and recipe prints.

/*****************************************************************************
 * Copyright (C) 2014-2019
 *
 * Michiel Broek <mbroek at mbse dot eu>
 *
 * This file is part of BrewCloud
 *
 * 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.
 *****************************************************************************/


// dropdownlists arrays

var StageData = [
	{ id: 0,  en: "Plan",        nl: "Plan" },
	{ id: 1,  en: "Wait",        nl: "Wacht" },
	{ id: 2,  en: "Brew",        nl: "Brouwen" },
	{ id: 3,  en: "Primary",     nl: "Hoofdgisting" },
	{ id: 4,  en: "Secondary",   nl: "Nagisting" },
	{ id: 5,  en: "Tertiary",    nl: "Lagering" },
	{ id: 6,  en: "Package",     nl: "Afvullen" },
	{ id: 7,  en: "Carbonation", nl: "Hergisten" },
	{ id: 8,  en: "Mature",      nl: "Rijpen" },
	{ id: 9,  en: "Taste",       nl: "Proeven" },
	{ id: 10, en: "Ready",       nl: "Gereed" },
	{ id: 11, en: "Closed",      nl: "Afgesloten" }
];
var StageSource = {
	localdata: StageData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var StageAdapter = new $.jqx.dataAdapter(StageSource);

var MaterialData = [
	{ id: 0,  en: "Stainless Steel", nl: "RVS",       sh: 0.11 },
	{ id: 1,  en: "Aluminium",       nl: "Aluminium", sh: 0.22 },
	{ id: 2,  en: "Plastics",        nl: "Kunststof", sh: 0.46 },
	{ id: 3,  en: "Copper",          nl: "Koper",     sh: 0.092 }
];
var MaterialSource = {
	localdata: MaterialData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }, { name: 'sh' }]
};
var MaterialAdapter = new $.jqx.dataAdapter(MaterialSource);

var FermentableTypeData = [
	{ id: 0, en: 'Grain',       nl: 'Mout' },
	{ id: 1, en: 'Sugar',       nl: 'Suiker' },
	{ id: 2, en: 'Extract',     nl: 'Vloeibaar extract' },
	{ id: 3, en: 'Dry extract', nl: 'Droog extract' },
	{ id: 4, en: 'Adjunct',     nl: 'Ongemout graan' }
];
var FermentableTypeSource = {
	localdata: FermentableTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var FermentableTypeAdapter = new $.jqx.dataAdapter(FermentableTypeSource);

var GrainTypeData = [
	{ id: 0, en: 'Base',      nl: 'Basismout' },
	{ id: 1, en: 'Roast',     nl: 'Geroosterde mout' },
	{ id: 2, en: 'Crystal',   nl: 'Cara- of crystalmout' },
	{ id: 3, en: 'Kilned',    nl: 'Geƫeste mout'},
	{ id: 4, en: 'Sour malt', nl: 'Zuurmout' },
	{ id: 5, en: 'Special',   nl: 'Speciale mout' },
	{ id: 6, en: 'No malt',   nl: 'Geen mout' }
];
var GrainTypeSource = {
	localdata: GrainTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var GrainTypeAdapter = new $.jqx.dataAdapter(GrainTypeSource);

var AddedData = [
	{ id: 0, en: 'Mash', nl: 'Maischen' },
	{ id: 1, en: 'Boil', nl: 'Koken' },
	{ id: 2, en: 'Fermentation', nl: 'Vergisten' },
	{ id: 3, en: 'Lagering', nl: 'Nagisten/lageren' },
	{ id: 4, en: 'Bottle', nl: 'Bottelen' }
];
var AddedSource = {
	localdata: AddedData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var AddedAdapter = new $.jqx.dataAdapter(AddedSource);

var HopTypeData = [
	{ id: 0, en: 'Bittering', nl: 'Bitterhop' },
	{ id: 1, en: 'Aroma',     nl: 'Aromahop' },
	{ id: 2, en: 'Both',      nl: 'Beide' }
];
var HopTypeSource = {
	localdata: HopTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var HopTypeAdapter = new $.jqx.dataAdapter(HopTypeSource);

var HopFormData = [
	{ id: 0, en: 'Pellet',   nl: 'Pellets' },
	{ id: 1, en: 'Plug',     nl: 'Plugs' },
	{ id: 2, en: 'Leaf',     nl: 'Bloemen' },
	{ id: 3, en: 'Leaf wet', nl: 'Hop nat' }
];
var HopFormSource = {
	localdata: HopFormData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }] 
};
var HopFormAdapter = new $.jqx.dataAdapter(HopFormSource);

var HopUseData = [
	{ id: 0, en: 'Mash',       nl: 'Maischhop' },
	{ id: 1, en: 'First wort', nl: 'First wort hop' },
	{ id: 2, en: 'Boil',       nl: 'Koken' },
	{ id: 3, en: 'Aroma',      nl: 'Vlamuit' },
	{ id: 4, en: 'Whirlpool',  nl: 'Whirlpool' },
	{ id: 5, en: 'Dry hop',    nl: 'Koudhop' }
];
var HopUseSource = {
	localdata: HopUseData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var HopUseAdapter = new $.jqx.dataAdapter(HopUseSource);

var YeastTypeData = [
	{ id: 0, en: 'Lager',     nl: 'Ondergist' },
	{ id: 1, en: 'Ale',       nl: 'Bovengist' },
	{ id: 2, en: 'Wheat',     nl: 'Tarwegist' },
	{ id: 3, en: 'Wine',      nl: 'Wijngist' },
	{ id: 4, en: 'Champagne', nl: 'Champagnegist' }
];
var YeastTypeSource = {
	localdata: YeastTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var YeastTypeAdapter = new $.jqx.dataAdapter(YeastTypeSource);

var YeastFormData = [
	{ id: 0, en: 'Liquid',  nl: 'Vloeibaar',    cells: 100000000000 },
	{ id: 1, en: 'Dry',     nl: 'Korrel',       cells: 15000000000 },
	{ id: 2, en: 'Slant',   nl: 'Schuine buis', cells: 1700000000 },
	{ id: 3, en: 'Culture', nl: 'Slurry',       cells: 1700000000 },
	{ id: 4, en: 'Frozen',  nl: 'Ingevroren',   cells: 1700000000 },
	{ id: 5, en: 'Bottle',  nl: 'Depot',        cells: 1700000000 }
];
var YeastFormSource = {
	localdata: YeastFormData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }, { name: 'cells' }]
};
var YeastFormAdapter = new $.jqx.dataAdapter(YeastFormSource);

var YeastUseData = [
	{ id: 0, en: 'Primary',   nl: 'Hoofdgisting' },
	{ id: 1, en: 'Secondary', nl: 'Nagisting' },
	{ id: 2, en: 'Tertiary',  nl: 'Lagering' },
	{ id: 3, en: 'Bottle',    nl: 'Bottelen' }
];
var YeastUseSource = {
	localdata: YeastUseData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }, { name: 'cells' }]
};
var YeastUseAdapter = new $.jqx.dataAdapter(YeastUseSource);

var FlocculationData = [
	{ id: 0, en: 'Low',       nl: 'Laag' },
	{ id: 1, en: 'Medium',    nl: 'Medium' },
	{ id: 2, en: 'High',      nl: 'Hoog' },
	{ id: 3, en: 'Very high', nl: 'Zeer hoog' }
];
var FlocculationSource = {
	localdata: FlocculationData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }] 
};
var FlocculationAdapter = new $.jqx.dataAdapter(FlocculationSource);

var StarterTypeData = [
	{ id: 0, en: 'Stirred', nl: 'Geroerd' },
	{ id: 1, en: 'Shaken',  nl: 'Geschud' },
	{ id: 2, en: 'Simple',  nl: 'Simpel' }
];
var StarterTypeSource = {
	localdata: StarterTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var StarterTypeAdapter = new $.jqx.dataAdapter(StarterTypeSource);

var MiscTypeData = [
	{ id: 0, en: 'Spice',          nl: 'Specerij' },
	{ id: 1, en: 'Herb',           nl: 'Kruid' },
	{ id: 2, en: 'Flavor',         nl: 'Smaakstof' },
	{ id: 3, en: 'Fining',         nl: 'Klaringsmiddel' },
	{ id: 4, en: 'Water agent',    nl: 'Brouwzout' },
	{ id: 5, en: 'Yeast nutrient', nl: 'Gistvoeding' },
	{ id: 6, en: 'Other',          nl: 'Overig' }
];
var MiscTypeSource = {
	localdata: MiscTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var MiscTypeAdapter = new $.jqx.dataAdapter(MiscTypeSource);

var MiscUseData = [
	{ id: 0, en: 'Starter',   nl: 'Starter' },
	{ id: 1, en: 'Mash',      nl: 'Maischen' },
	{ id: 2, en: 'Boil',      nl: 'Koken' },
	{ id: 3, en: 'Primary',   nl: 'Hoofdvergisting' },
	{ id: 4, en: 'Secondary', nl: 'Nagisting/lagering' },
	{ id: 5, en: 'Bottling',  nl: 'Bottelen' }
];
var MiscUseSource = {
	localdata: MiscUseData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var MiscUseAdapter = new $.jqx.dataAdapter(MiscUseSource);

var StyleTypeData = [
	{ id: 0, en: 'Lager', nl: 'Ondergistend bier' },
	{ id: 1, en: 'Ale',   nl: 'Bovengistend bier' },
	{ id: 2, en: 'Mead',  nl: 'Mede' },
	{ id: 3, en: 'Wheat', nl: 'Tarwebier' },
	{ id: 4, en: 'Mixed', nl: 'Gemengd' },
	{ id: 5, en: 'Cider', nl: 'Cider' }
];
var StyleTypeSource = {
	localdata: StyleTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var StyleTypeAdapter = new $.jqx.dataAdapter(StyleTypeSource);

var MashStepTypeData = [
	{ id: 0, en: 'Infusion',    nl: 'Infusie' },
	{ id: 1, en: 'Temperature', nl: 'Verwarming' },
	{ id: 2, en: 'Decoction',   nl: 'Decoctie' }
];
var MashStepTypeSource = {
	localdata: MashStepTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var MashStepTypeAdapter = new $.jqx.dataAdapter(MashStepTypeSource);

var RecipeTypeData = [
	{ id: 0, en: 'Extract',      nl: 'Extract' },
	{ id: 1, en: 'Partial Mash', nl: 'Deelmaisch' },
	{ id: 2, en: 'All Grain',    nl: 'Mout' }
];
var RecipeTypeSource = {
	localdata: RecipeTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var RecipeTypeAdapter = new $.jqx.dataAdapter(RecipeTypeSource);

var IBUmethodData = [
	{ id: 0, en: 'Tinseth', nl: 'Tinseth' },
	{ id: 1, en: 'Rager',   nl: 'Rager' },
	{ id: 2, en: 'Daniels', nl: 'Daniels' }
//	{ id: 3, en: 'Garetz',  nl: 'Garetz' },	// Not yet supported.
//	{ id: 4, en: 'Mosher',  nl: 'Mosher' },
//	{ id: 5, en: 'Noonan',  nl: 'Noonan' }
];
var IBUmethodSource = {
	localdata: IBUmethodData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var IBUmethodAdapter = new $.jqx.dataAdapter(IBUmethodSource);

var ColorMethodData = [
	{ id: 0, en: 'Morey',       nl: 'Morey' },
	{ id: 1, en: 'Mosher',      nl: 'Mosher' },
	{ id: 2, en: 'Daniels',     nl: 'Daniels' },
	{ id: 3, en: 'Halberstadt', nl: 'Halberstadt' },
	{ id: 4, en: 'Naudts',      nl: 'Naudts' }
];
var ColorMethodSource = {
	localdata: ColorMethodData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var ColorMethodAdapter = new $.jqx.dataAdapter(ColorMethodSource);

var CoolingTypeData = [
	{ id: 0, en: '-',                   nl: '-' },
	{ id: 1, en: 'Emersion chiller',    nl: 'Dompelkoeler' },
	{ id: 2, en: 'Counterflow chiller', nl: 'Tegenstroomkoeler' },
	{ id: 3, en: 'Au bain marie',       nl: 'Au bain marie' },
	{ id: 4, en: 'Natural',             nl: 'Laten afkoelen' }
];
var CoolingTypeSource = {
	localdata: CoolingTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var CoolingTypeAdapter = new $.jqx.dataAdapter(CoolingTypeSource);

var AerationTypeData = [
	{ id: 0, en: 'None',   nl: 'Geen' },
	{ id: 1, en: 'Air',    nl: 'Lucht' },
	{ id: 2, en: 'Oxygen', nl: 'Zuurstof' }
];
var AerationTypeSource = {
	localdata: AerationTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }] 
};
var AerationTypeAdapter = new $.jqx.dataAdapter(AerationTypeSource);

var PrimingSugarData = [
	{ id: 0, en: 'Saccharose',          nl: 'Kristalsuiker',    factor: 1 },
	{ id: 1, en: 'Glucose or dextrose', nl: 'Glucose/dextrose', factor: 1.16 },
	{ id: 2, en: 'Honey',               nl: 'Honing',           factor: 1.28 },
	{ id: 3, en: 'DME',                 nl: 'Moutextract',      factor: 1.74 },
	{ id: 4, en: 'Molassis',            nl: 'Melasse',          factor: 3.83 }
];
var PrimingSugarSource = {
	localdata: PrimingSugarData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }, { name: 'factor' }] 
};
var PrimingSugarAdapter = new $.jqx.dataAdapter(PrimingSugarSource);

var AcidTypeData = [
	{ id: 0, en: 'Lactic',       nl: 'Melkzuur' },
	{ id: 1, en: 'Hydrochloric', nl: 'Zoutzuur' },
	{ id: 2, en: 'Phosphoric',   nl: 'Fosforzuur' },
	{ id: 3, en: 'Sulfuric',     nl: 'Zwavelzuur' }
];
var AcidTypeSource = {
	localdata: AcidTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var AcidTypeAdapter = new $.jqx.dataAdapter(AcidTypeSource);

var BaseTypeData = [
	{ id: 0, en: 'Sodiumbicarbonate', nl: 'NaHCO3' },
	{ id: 1, en: 'Sodiumcarbonate',   nl: 'Na2CO3' },
	{ id: 2, en: 'Calciumcarbonate',  nl: 'CaCO3' },
	{ id: 3, en: 'Calciumhydroxide',  nl: 'Ca(OH)2' }
];
var BaseTypeSource = {
	localdata: BaseTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var BaseTypeAdapter = new $.jqx.dataAdapter(BaseTypeSource);

var SpargeSourceData = [
	{ id: 0, en: 'Source 1', nl: 'Bron 1' },
	{ id: 1, en: 'Source 2', nl: 'Bron 2' },
	{ id: 2, en: 'Mixed',    nl: 'Gemengd' }
];
var SpargeSourceSource = {
	localdata: SpargeSourceData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var SpargeSourceAdapter = new $.jqx.dataAdapter(SpargeSourceSource);


// options for editors

var Show1wat = { inputMode: 'simple', theme: theme, width:  74, height: 23, decimalDigits: 1, readOnly: true };
var Show2wat = { inputMode: 'simple', theme: theme, width:  74, height: 23, decimalDigits: 2, readOnly: true };
var Show3wat = { inputMode: 'simple', theme: theme, width:  74, height: 23, decimalDigits: 3, readOnly: true };
var Show0dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 0 };
var Show1dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 1 };
var Show2dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 2 };
var Show3dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 3 };
var SGopts   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0.990, max: 1.199, decimalDigits: 3, spinButtons: true };
var Spin1dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 1, spinButtons: true };
var Spin2dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 2, spinButtons: true };
var Spin3dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 3, spinButtons: true };
var SpinpH   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 1, max: 14, decimalDigits: 1, spinButtons: true };
var Spin2pH  = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 1, max: 14, decimalDigits: 2, spinButtons: true };
var YeastT   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, max: 40, decimalDigits: 1, spinButtons: true };
var PosInt   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 0, spinButtons: true };
var Perc1dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, max: 100, decimalDigits: 1, spinButtons: true };
var Perc0    = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, max: 100, decimalDigits: 0, spinButtons: true };
var Dateopts = {
	theme: theme, width: 150, height: 23, allowNullDate: true, todayString: 'Vandaag', clearString: 'Wissen', showFooter: true,
	formatString: 'yyyy-MM-dd', enableBrowserBoundsDetection: true
};
var DateTimeopts = {
	theme: theme, width: 230, height: 23, allowNullDate: true, todayString: 'Vandaag', clearString: 'Wissen', showFooter: true,
	formatString: 'yyyy-MM-dd HH:mm:ss', enableBrowserBoundsDetection: true, showTimeButton: true
};


var	sugardensity = 1.611; //kg/l in solution

// Styles dropdown list
var stylesUrl = "includes/db_profile_styles.php";
var stylesSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'category', type: 'string' },
		{ name: 'category_number', type: 'number' },
		{ name: 'style_letter', type: 'string' },
		{ name: 'style_guide', type: 'string' },
		{ name: 'type', type: 'int' },
		{ name: 'og_min', type: 'float' },
		{ name: 'og_max', type: 'float' },
		{ name: 'fg_min', type: 'float' },
		{ name: 'fg_max', type: 'float' },
		{ name: 'ibu_min', type: 'float' },
		{ name: 'ibu_max', type: 'float' },
		{ name: 'color_min', type: 'float' },
		{ name: 'color_max', type: 'float' },
		{ name: 'carb_min', type: 'float' },
		{ name: 'carb_max', type: 'float' },
		{ name: 'abv_min', type: 'float' },
		{ name: 'abv_max', type: 'float' },
		{ name: 'notes', type: 'string' },
		{ name: 'profile', type: 'string' },
		{ name: 'ingredients', type: 'string' },
		{ name: 'examples', type: 'string' }
	],
	url: stylesUrl
};
var styleslist = new $.jqx.dataAdapter(stylesSource);

// Equipemnt dropdown list
var equipmentUrl = "includes/db_inventory_equipments.php";
var equipmentSource = {
	datatype: "json",
	datafields: [
		{ name: 'name', type: 'string' },
		{ name: 'boil_size', type: 'float' },
		{ name: 'batch_size', type: 'float' },
		{ name: 'tun_volume', type: 'float' },
		{ name: 'tun_weight', type: 'float' },
		{ name: 'tun_specific_heat', type: 'float' },
		{ name: 'tun_material', type: 'int' },
		{ name: 'tun_height', type: 'float' },
		{ name: 'top_up_water', type: 'float' },
		{ name: 'trub_chiller_loss', type: 'float' },
		{ name: 'evap_rate', type: 'float' },
		{ name: 'boil_time', type: 'float' },
		{ name: 'calc_boil_volume', type: 'int' },
		{ name: 'top_up_kettle', type: 'float' },
		{ name: 'hop_utilization', type: 'float' },
		{ name: 'notes', type: 'string' },
		{ name: 'lauter_volume', type: 'float' },
		{ name: 'lauter_height', type: 'float' },
		{ name: 'lauter_deadspace', type: 'float' },
		{ name: 'kettle_volume', type: 'float' },
		{ name: 'kettle_height', type: 'float' },
		{ name: 'mash_volume', type: 'float' },
		{ name: 'mash_max', type: 'float' },
		{ name: 'efficiency', type: 'float' }
	],
	url: equipmentUrl
};
var equipmentlist = new $.jqx.dataAdapter(equipmentSource);

// dropdownlist datasource from inventory_fermentables
var fermentableInvSource = {
	datatype: "json",
        datafields: [
                { name: 'record', type: 'number' },
                { name: 'name', type: 'string' },
                { name: 'type', type: 'int' },
                { name: 'yield', type: 'float' },
                { name: 'color', type: 'float' },
                { name: 'add_after_boil', type: 'int' },
                { name: 'origin', type: 'string' },
                { name: 'supplier', type: 'string' },
                { name: 'coarse_fine_diff', type: 'float' },
                { name: 'moisture', type: 'float' },
                { name: 'diastatic_power', type: 'float' },
                { name: 'protein', type: 'float' },
		{ name: 'dissolved_protein', type: 'float' },
                { name: 'max_in_batch', type: 'float' },
                { name: 'recommend_mash', type: 'int' },
                { name: 'graintype', type: 'int' },
                { name: 'di_ph', type: 'float' },
		{ name: 'acid_to_ph_57', type: 'float' },
                { name: 'inventory', type: 'float' },
        	{ name: 'cost', type: 'float' }
        ],
        url: "getfermentablesources.php"
};
var fermentableinstock = false;
var fermentablelist = new $.jqx.dataAdapter(fermentableInvSource, {
	beforeLoadComplete: function (records) {
		var data = new Array();
		for (var i = 0; i < records.length; i++) {
			var row = records[i];
			if (row.inventory || ! fermentableinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		$('#err').text(status + ' ' + error);
	},
});

// dropdownlist datasource from inventory_hops
var hopInvSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'origin', type: 'string' },
		{ name: 'type', type: 'int' },
		{ name: 'alpha', type: 'float' },
		{ name: 'beta', type: 'float' },
		{ name: 'humulene', type: 'float' },
		{ name: 'caryophyllene', type: 'float' },
		{ name: 'cohumulone', type: 'float' },
		{ name: 'myrcene', type: 'float' },
		{ name: 'hsi', type: 'float' },
		{ name: 'useat', type: 'int' },
		{ name: 'form', type: 'int' },
		{ name: 'total_oil', type: 'float' },
		{ name: 'inventory', type: 'float' },
		{ name: 'cost', type: 'float' }
	],
	url: "gethopsources.php"
};
var hopinstock = false;
var hoplist = new $.jqx.dataAdapter(hopInvSource, {
	beforeLoadComplete: function (records) {
		var data = new Array();
		for (var i = 0; i < records.length; i++) {
			var row = records[i];
			if (row.inventory || ! hopinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		$('#err').text(status + ' ' + error);
	},
});

// dropdownlist datasource from inventory_miscs
var miscInvSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'type', type: 'int' },
		{ name: 'use_use', type: 'int' },
		{ name: 'amount_is_weight', type: 'int' },
		{ name: 'time', type: 'float' },
		{ name: 'inventory', type: 'float' },
		{ name: 'cost', type: 'float' }
	],
	url: "getmiscsources.php"
};
var miscinstock = false;
var misclist = new $.jqx.dataAdapter(miscInvSource, {
	beforeLoadComplete: function (records) {
		var data = new Array();
		for (var i = 0; i < records.length; i++) {
		var row = records[i];
			if (row.inventory || ! miscinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		$('#err').text(status + ' ' + error);
	},
});

// dropdownlist datasource from inventory_yeasts
var yeastInvSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'type', type: 'int' },
		{ name: 'form', type: 'int' },
		{ name: 'laboratory', type: 'string' },
		{ name: 'product_id', type: 'string' },
		{ name: 'min_temperature', type: 'float' },
		{ name: 'max_temperature', type: 'float' },
		{ name: 'flocculation', type: 'int' },
		{ name: 'attenuation', type: 'float' },
		{ name: 'cells', type: 'float' },
		{ name: 'inventory', type: 'float' },
		{ name: 'cost', type: 'float' },
		{ name: 'tolerance', type: 'float' }
	],
	url: "getyeastsources.php"
};
var yeastinstock = false;
var yeastlist = new $.jqx.dataAdapter(yeastInvSource, {
	beforeLoadComplete: function (records) {
		var data = new Array();
		for (var i = 0; i < records.length; i++) {
			var row = records[i];
			if (row.inventory || ! yeastinstock)
				data.push(row);
		}
		return data;
	},
	loadError: function(jqXHR, status, error) {
		$('#err').text(status + ' ' + error);
	},
});

// dropdownlist datasource from inventory_waters
var waterInvSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'unlimited_stock', type: 'int' },
		{ name: 'calcium', type: 'float' },
		{ name: 'sulfate', type: 'float' },
		{ name: 'chloride', type: 'float' },
		{ name: 'sodium', type: 'float' },
		{ name: 'magnesium', type: 'float' },
		{ name: 'ph', type: 'float' },
		{ name: 'total_alkalinity', type: 'float' },
		{ name: 'inventory', type: 'float' },
		{ name: 'cost', type: 'float' },
	],
	url: "getwatersources.php"
};
var waterinstock = false;
var waterlist = new $.jqx.dataAdapter(waterInvSource, {
	beforeLoadComplete: function (records) {
		var data = new Array();
		for (var i = 0; i < records.length; i++) {
			var row = records[i];
			if (row.inventory || row.unlimited_stock || ! waterinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		$('#err').text(status + ' ' + error);
	},
});

// dropdownlist datasource from profile_water
var waterProfileSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'calcium', type: 'float' },
		{ name: 'bicarbonate', type: 'float' },
		{ name: 'sulfate', type: 'float' },
		{ name: 'chloride', type: 'float' },
		{ name: 'sodium', type: 'float' },
		{ name: 'magnesium', type: 'float' },
		{ name: 'ph', type: 'float' },
		{ name: 'total_alkalinity', type: 'float' },
	],
	url: "includes/db_profile_water.php"
};
var waterprofiles = new $.jqx.dataAdapter(waterProfileSource);

// dropdownlist datasource from profile_mash
var mashProfileSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'steps', type: 'array' }
	],
	url: "includes/db_profile_mash.php"
};
var mashlist = new $.jqx.dataAdapter(mashProfileSource);




$(document).ready(function () {

	$("#jqxMenu").jqxMenu({
		width: 1280,
		height: '30px',
		autoOpen: false,
		clickToOpen: true,
		theme: theme
	});
	$("#jqxWidget").css('visibility', 'visible');
});



function ebc_to_srm(ebc) {
	var srm = -1.32303E-12 * Math.pow(ebc, 4) - 0.00000000291515 * Math.pow(ebc, 3) + 0.00000818515 * Math.pow(ebc, 2) + 0.372038 * ebc + 0.596351;
	if ((ebc < 0) || (srm < 0))
		console.log("ebc_to_srm("+ebc+") = "+srm);
	return srm
}



function srm_to_ebc(srm)
{
	var ebc = Math.round(0.000000000176506 * Math.pow(srm, 4) + 0.000000154529 * Math.pow(srm, 3) - 0.000159428 * Math.pow(srm, 2) + 2.68837 * srm - 1.6004);
	if ((ebc < 0) || (srm < 0))
		console.log("srm_to_ebc("+srm+") = "+ebc);
	return ebc;
}



/*
 * Return incremented color by the boil and yeast.
 * https://www.hobbybrouwen.nl/forum/index.php/topic,19020.msg281132.html#msg281132
 */
function get_kt(ebc) {

	var kt = 1;
	if (ebc < 3)
		kt = 3.5;
	else if (ebc < 6)
		kt = 3;
	else if (ebc < 8)
		kt = 2.75;
	else if (ebc < 10)
		kt = 2.5;
	else if (ebc < 20)
		kt = 1.8;
	else if (ebc < 30)
		kt = 1.6;
	else if (ebc < 60)
		kt = 1.3;
	else if (ebc < 100)
		kt = 1.2;
	else if (ebc < 300)
		kt = 1.1;
	return kt;
}



/*
 * Alcohol By Volume
 */
function abvol(og, fg) {

	if (((og - fg) < 0) || (fg < 0.9))
		return 0;

	/*
	 * Formule van Hans Halberstadt. De constante factor is afhankelijk van de
	 * zwaarte van het wort.
	 */
	var factor = og * 3157 * Math.pow(10, -5) + 9.716 * Math.pow(10, -2);
	var result = (og * 1000 - fg * 1000) * factor;

	console.log("HH abvol("+ og * 1000 + ", "+ fg * 1000 + ") factor:" + factor + " abv:" + result);
	return result;

	/*
	 * Dit lijkt goed en wordt in veel moderne software gebruikt, maar...
	 * dit klopt niet. Busted door Hans Halberstadt. 
	 * return (76.08 * (og-fg) / (1.775-og)) * (fg / 0.794); // Daniels
	 */

	/*
	 * Brouwhulp, houdt geen rekening met zwaardere bieren.
	 * if ((4.749804 - fg) != 0)
	 *	return 486.8693 * (og - fg) / (4.749804 - fg);
	 */
}



/*
 * Kleurwerking naar SRM. Niet voor Halberstadt, Naudts
 */
function kw_to_srm(colormethod, c) {

	if (colormethod == 0)	// Morey
		return 1.4922 * Math.pow(c, 0.6859);
	if (colormethod == 1)	// Mosher
		return 0.3 * c + 4.7;
	if (colormethod == 2)	// Daniels
		return 0.2 * c + 8.4;
	if (colormethod == 3)	// Halberstadt
		return 0;
	if (colormethod == 4)
		return 0;
}



function kw_to_ebc(colormethod, c) {
	return srm_to_ebc(kw_to_srm(colormethod, c));
}



/*
 * Berekeningen uit https://www.hobbybrouwen.nl/forum/index.php/topic,6079.msg69464.html#msg69464
 */
function toIBU(Use, Form, SG, Volume, Amount, Boiltime, Alpha, Method)
{
	var gravity = parseFloat(SG);
	var liters  = parseFloat(Volume);
	var alpha   = parseFloat(Alpha)/100;
	var mass    = parseFloat(Amount) * 1000;
	var time    = parseFloat(Boiltime);
	var fmoment = 1.0;
	var pfactor = 1.0;
	var ibu     = 0;

	if ((Use == 3) || (Use == 4) || (Use == 5)) {	// Aroma, Whirlpool or Dry hop.
		fmoment = 0.0;
	} else if (Use == 0) {				// Mash
		fmoment += my_factor_mashhop / 100;	// Brouwhulp
	} else if (Use == 1) {				// First wort
		fmoment += my_factor_fwh  / 100;	// Brouwhulp, Louis, Ozzie
	}

	if (Form == 0) {	// Pellet
		pfactor += my_factor_pellet / 100;
	}
	if (Form == 1 ) {	// Plug
		pfactor += my_factor_plug / 100;
	}
	if (Form == 3) {	// Wet leaf
		pfactor += my_factor_wethop / 100;	// From https://github.com/chrisgilmerproj/brewday/blob/master/brew/constants.py
	}

	if (Method == 0) {	// Tinseth
		/* http://realbeer.com/hops/research.html */
		var AddedAlphaAcids = (alpha * mass * 1000) / liters;
		var Bigness_factor = 1.65 * Math.pow( 0.000125, gravity - 1);
		var BoilTime_factor = ((1 - Math.exp(-0.04 * time)) / 4.15);
		var utiisation = Bigness_factor * BoilTime_factor;
		ibu = Math.round(utiisation * AddedAlphaAcids * fmoment * pfactor * 10) / 10.0;
	}
	if (Method == 2) {	// Daniels
		var boilfactor;
		var sgfactor;
		if (Form == 2)	// Leaf
			boilfactor = -(0.0041*time*time)+(0.6162*time)+1.5779;
		else
			boilfactor = -(0.0051*time*time)+(0.7835*time)+1.9348;
		if (gravity < 1050)
			sgfactor = 0;
		else
			sgfactor = (gravity - 1050) / 200;
		ibu = Math.round(fmoment * ((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor))) * 10) / 10;
	}
	if (Method == 1) {	// Rager
		var boilfactor;
		var sgfactor;
		boilfactor = fmoment * 18.11 + 13.86 * Math.tanh((time * 31.32) / 18.27);
		if (gravity < 1050)
			sgfactor = 0;
		else
			sgfactor = (gravity - 1050) / 200;
		ibu = Math.round((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor)) * 10) / 10;
	}

//	console.log("toIBU("+Use+","+Form+","+SG+","+Volume+","+Amount+","+Boiltime+","+Alpha+","+Method+"):"+ibu+" fm:"+fmoment+" pf:"+pfactor);
	return ibu;
}



function ebc_to_color(ebc) {
	return srm_to_color(ebc_to_srm(ebc));
}



function srm_to_color(srm) {

	var i = Math.round(srm * 10);
        if (i < 0) {
		i = 0;
	}
	if (i > 299) {
		i = 299;
	}

	/* Table copied from Brouwhulp/BrewBuddy */
	var R = [ 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, // 0
		  250, 250, 250, 250, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, // 2
		  234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, // 4
		  214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 200, 199, 199, 198, 198, // 6
		  197, 197, 196, 196, 195, 195, 194, 194, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 8
		  192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 10
		  192, 192, 192, 192, 192, 192, 192, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, // 12
		  179, 178, 177, 175, 174, 172, 171, 169, 168, 167, 195, 164, 162, 161, 159, 158, 157, 155, 154, 152, // 14
		  151, 149, 148, 147, 145, 144, 142, 141, 139, 138, 137, 135, 134, 132, 131, 129, 128, 127, 125, 124, // 16
		  122, 121, 119, 118, 117, 115, 114, 112, 111, 109, 108, 107, 105, 104, 102, 101,  99,  98,  97,  95, // 18
		   94,  92,  91,  89,  88,  87,  85,  84,  82,  81,  79,  78,  77,  75,  74,  72,  71,  69,  68,  67, // 20
		   65,  64,  62,  61,  59,  58,  57,  55,  54,  52,  51,  49,  48,  47,  45,  44,  43,  41,  39,  38, // 22
		   37,  37,  36,  36,  35,  35,  34,  34,  33,  33,  32,  32,  31,  31,  30,  30,  29,  29,  28,  28, // 24
		   27,  27,  26,  26,  25,  25,  24,  24,  23,  23,  22,  22,  21,  21,  20,  20,  19,  19,  18,  18, // 26
		   17,  17,  16,  16,  15,  15,  14,  14,  13,  13,  12,  12,  11,  11,  10,  10,   9,   9,   8,   8 ];

	var G = [ 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
		  250, 250, 250, 250, 250, 250, 249, 248, 247, 246, 245, 244, 242, 240, 238, 236, 234, 232, 230, 228,
		  226, 224, 222, 220, 218, 216, 214, 212, 210, 208, 206, 204, 202, 200, 198, 196, 194, 192, 190, 188,
		  186, 184, 182, 180, 178, 176, 174, 172, 170, 168, 166, 164, 162, 160, 158, 156, 154, 152, 150, 148,
		  146, 144, 142, 141, 140, 139, 139, 138, 137, 136, 136, 135, 134, 133, 133, 132, 131, 130, 130, 129,
		  128, 127, 127, 126, 125, 124, 124, 123, 122, 121, 121, 120, 119, 118, 118, 117, 116, 115, 115, 114,
		  113, 112, 112, 111, 110, 109, 109, 108, 107, 106, 106, 105, 104, 103, 103, 102, 101, 100, 100,  99,
		   98,  97,  97,  96,  95,  94,  94,  93,  92,  91,  91,  90,  89,  88,  88,  87,  86,  85,  85,  84,
		   83,  82,  82,  81,  80,  79,  78,  77,  76,  75,  75,  74,  73,  72,  72,  71,  70,  69,  69,  68,
		   67,  66,  66,  65,  64,  63,  63,  62,  61,  60,  60,  59,  58,  57,  57,  56,  55,  54,  54,  53,
		   52,  51,  51,  50,  49,  48,  48,  47,  46,  45,  45,  44,  43,  42,  42,  41,  40,  39,  39,  38,
		   37,  36,  36,  35,  34,  33,  33,  32,  31,  30,  30,  29,  28,  27,  27,  26,  25,  24,  24,  23,
		   22,  22,  22,  21,  21,  21,  20,  20,  20,  19,  19,  19,  18,  18,  18,  17,  17,  17,  16,  16,
		   16,  15,  15,  15,  14,  14,  14,  13,  13,  13,  12,  12,  12,  11,  11,  11,  10,  10,  10,   9,
		    9,   9,   8,   8,   8,   7,   7,   7,   6,   6,   6,   5,   5,   5,   4,   4,   4,   3,   3,   3 ];

	var B = [ 210, 204, 199, 193, 188, 182, 177, 171, 166, 160, 155, 149, 144, 138, 133, 127, 122, 116, 111, 105,
		  100,  94,  89,  83,  78,  72,  67,  61,  56,  50,  45,  45,  45,  46,  46,  46,  46,  47,  47,  47,
		   47,  48,  48,  48,  48,  49,  49,  49,  49,  50,  50,  50,  50,  51,  51,  51,  51,  52,  52,  52,
		   52,  53,  53,  53,  53,  54,  54,  54,  54,  55,  55,  55,  55,  56,  56,  56,  56,  56,  56,  56,
		   56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,
		   56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,
		   56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,
		   56,  56,  56,  55,  55,  55,  55,  54,  54,  54,  54,  53,  53,  53,  53,  52,  52,  52,  52,  51,
		   51,  51,  51,  50,  50,  50,  50,  49,  49,  48,  47,  47,  46,  45,  45,  44,  43,  43,  42,  41,
		   41,  40,  39,  39,  38,  37,  37,  36,  35,  34,  33,  32,  31,  29,  28,  27,  26,  25,  24,  23,
		   21,  20,  19,  18,  17,  16,  15,  13,  12,  11,  10,   9,   8,   9,   9,  10,  10,  11,  11,  12,
		   12,  13,  13,  14,  14,  15,  15,  16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,  22,
		   21,  21,  21,  20,  20,  20,  19,  19,  19,  18,  18,  18,  17,  17,  17,  17,  16,  16,  15,  15,
		   15,  14,  14,  14,  13,  13,  13,  12,  12,  12,  11,  11,  11,  10,  10,  10,   9,   9,   9,   8,
		    8,   8,   7,   7,   7,   6,   6,   6,   5,   5,   5,   4,   4,   4,   3,   3,   3,   2,   2,   2 ];

	var color = R[i] * 65536 + G[i] * 256 + B[i];
	var result = color.toString(16).toUpperCase();
	if (result.length < 6) {
		result = '0' + result;
	}
	result = '#' + result;
	return result;
}



function sg_to_plato(sg) {
	// http://www.brewersfriend.com/2012/10/31/on-the-relationship-between-plato-and-specific-gravity/
	return ((135.997 * sg - 630.272) * sg + 1111.14) * sg - 616.868;
}



function plato_to_sg(plato) {
	return 1 + (plato / (258.6 - ((plato / 258.2) * 227.1)));
}



function brix_to_sg(brix) {
	return plato_to_sg(brix / my_brix_correction);
}



function sg_to_brix(sg) {
	return sg_to_plato(sg) * my_brix_correction;
}



function estimate_sg(sugars, batch_size) {
	var plato = 100 * sugars / batch_size;

	var sg = plato_to_sg(plato);
	for (var i = 0; i < 20; i++) {
		if (sg > 0)
			plato = 100 * sugars / (batch_size * sg);
		sg = plato_to_sg(plato);
	}
//	console.log("estimate_sg(" + sugars + "," + batch_size + ") : " + sg);
	return sg;
}



function estimate_fg(percSugar, percCara, WGratio, TotTme, Temp, attenuation, og) {

	var	BD;

	if (percSugar > 40)
		percSugar = 0;
	if (percCara > 50)
		percCara = 0;
	if ((WGratio > 0) && (TotTme > 0)) {
		BD = WGratio;
		if (BD < 2)
			BD = 2;
		if (BD > 5.5)
			BD = 5.5;
		if (Temp < 60)
			Temp = 60;
		if (Temp > 72)
			Temp = 72;
	} else {
		BD = 3.5;
		Temp = 67;
		TotTme = 75;
	}
	if (attenuation < 30)
		attenuation = 77;

	var AttBeer = 0.00825 * attenuation + 0.00817 * BD - 0.00684 * Temp + 0.00026 * TotTme - 0.00356 * percCara + 0.00553 * percSugar + 0.547;
	var fg = Math.round((1 + (1 - AttBeer) * (og - 1)) * 10000) / 10000;

	//console.log("estimate_fg("+percSugar+","+percCara+","+BD+","+TotTme+","+Temp+","+attenuation+","+og+") :"+fg);
	return fg;
}



function CalcFrac(TpH, pK1, pK2, pK3) {

	var r1d = Math.pow(10, TpH - pK1);
	var r2d = Math.pow(10, TpH - pK2);
	var r3d = Math.pow(10, TpH - pK3);
	var dd = 1/(1 + r1d + r1d*r2d + r1d*r2d*r3d);
	var f1d = dd;
	var f2d = r1d*dd;
	var f3d = r1d*r2d*dd;
	var f4d = r1d*r2d*r3d*dd;
	return f2d + 2*f3d + 3*f4d;
}


function lintner_to_kolbach(lintner) {

	return (3.5 * lintner) - 16;
}


function kolbach_to_lintner(kolbach) {

	return (kolbach + 16) / 3.5;
}

mercurial