src/EditProductTab3.cpp

changeset 190
bb6c06910f0f
parent 187
91af2c697345
child 191
7446ee2fb427
--- a/src/EditProductTab3.cpp	Mon May 02 22:42:19 2022 +0200
+++ b/src/EditProductTab3.cpp	Tue May 03 20:05:04 2022 +0200
@@ -109,9 +109,11 @@
 
 	item = new QTableWidgetItem(QString("%1 Kg").arg(product->fermentables.at(i).f_inventory, 4, 'f', 3, '0'));
         item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
+	if (product->fermentables.at(i).f_inventory < product->fermentables.at(i).f_amount)
+	    item->setForeground(QBrush(QColor(Qt::red)));
         ui->fermentablesTable->setItem(i, 8, item);
 
-	if (product->fermentables.at(i).f_added < 4) {
+	if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
             item = new QTableWidgetItem(QString("%1%").arg(product->fermentables.at(i).f_percentage, 2, 'f', 1, '0'));
 	} else {
 	    item = new QTableWidgetItem(QString(""));	// Blank for bottling and kegging.
@@ -122,27 +124,36 @@
 	to100Fermentables(i);
 
 	/* Add the Delete row button */
-        pWidget = new QWidget();
-        QPushButton* btn_dele = new QPushButton();
-        btn_dele->setObjectName(QString("%1").arg(i));  /* Send row with the button */
-        btn_dele->setText(tr("Delete"));
-        connect(btn_dele, SIGNAL(clicked()), this, SLOT(deleteFermentRow_clicked()));
-        pLayout = new QHBoxLayout(pWidget);
-        pLayout->addWidget(btn_dele);
-        pLayout->setContentsMargins(5, 0, 5, 0);
-        pWidget->setLayout(pLayout);
-        ui->fermentablesTable->setCellWidget(i, 11, pWidget);
+	if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
+            pWidget = new QWidget();
+            QPushButton* btn_dele = new QPushButton();
+            btn_dele->setObjectName(QString("%1").arg(i));  /* Send row with the button */
+            btn_dele->setText(tr("Delete"));
+            connect(btn_dele, SIGNAL(clicked()), this, SLOT(deleteFermentRow_clicked()));
+            pLayout = new QHBoxLayout(pWidget);
+            pLayout->addWidget(btn_dele);
+            pLayout->setContentsMargins(5, 0, 5, 0);
+            pWidget->setLayout(pLayout);
+            ui->fermentablesTable->setCellWidget(i, 11, pWidget);
 
-	pWidget = new QWidget();
-	QPushButton* btn_edit = new QPushButton();
-	btn_edit->setObjectName(QString("%1").arg(i));  /* Send row with the button */
-	btn_edit->setText(tr("Edit"));
-	connect(btn_edit, SIGNAL(clicked()), this, SLOT(editFermentRow_clicked()));
-	pLayout = new QHBoxLayout(pWidget);
-        pLayout->addWidget(btn_edit);
-	pLayout->setContentsMargins(5, 0, 5, 0);
-        pWidget->setLayout(pLayout);
-        ui->fermentablesTable->setCellWidget(i, 12, pWidget);
+	    pWidget = new QWidget();
+	    QPushButton* btn_edit = new QPushButton();
+	    btn_edit->setObjectName(QString("%1").arg(i));  /* Send row with the button */
+	    btn_edit->setText(tr("Edit"));
+	    connect(btn_edit, SIGNAL(clicked()), this, SLOT(editFermentRow_clicked()));
+	    pLayout = new QHBoxLayout(pWidget);
+            pLayout->addWidget(btn_edit);
+	    pLayout->setContentsMargins(5, 0, 5, 0);
+            pWidget->setLayout(pLayout);
+            ui->fermentablesTable->setCellWidget(i, 12, pWidget);
+	} else {
+	    item = new QTableWidgetItem("");
+	    item->setToolTip(tr("Edit this from the package tab"));
+            ui->fermentablesTable->setItem(i, 11, item);
+	    item = new QTableWidgetItem("");
+            item->setToolTip(tr("Edit this from the package tab"));
+            ui->fermentablesTable->setItem(i, 12, item);
+	}
     }
 }
 
@@ -150,7 +161,7 @@
 void EditProduct::calcFermentables()
 {
     int		i;
-    double	psugar = 0, pcara = 0, d, s = 0, x, color;
+    double	psugar = 0, pcara = 0, d, s = 0, x, cw, color;
     double	vol = 0;		// Volume sugars after boil
     double	addedS = 0;		// Added sugars after boil
     double	addedmass = 0;		// Added mass after boil
@@ -165,6 +176,8 @@
     double	colort = 0;		// Colors srm * vol totals
     double	colorh = 0;		// Colors ebc * vol * kt
     double	colorn = 0;		// Colors ebc * pt * pct
+    double	bv = 0.925;		// Beer loss efficiency
+    double	sr = 0.95;		// Mash and sparge efficiency
 
     qDebug() << "calcFermentables()";
 
@@ -177,10 +190,14 @@
 	    if (product->mashs.at(i).step_type == 0)		// Infusion
 		mashinfuse += product->mashs.at(i).step_infuse_amount;
 	    if (product->mashs.at(i).step_temp < 75) {		// Ignore mashout
-		mashtime += product->mashs.at(i).step_time;
-		mashtemp += product->mashs.at(i).step_time * product->mashs.at(i).step_temp;
+		double timem = product->mashs.at(i).step_time;
+		if (i > 0)
+		    timem += product->mashs.at(i).ramp_time;
+		mashtime += timem;
+		mashtemp += timem * product->mashs.at(i).step_temp;
 	    }
 	}
+	mashtime += 5;	// Correction for missing last ramp_time.
 	mashtemp = mashtemp / mashtime;
 	mvol = mashinfuse;
 	qDebug() << "  mash time" << mashtime << "temp" << mashtemp << "infuse" << mashinfuse;
@@ -223,15 +240,16 @@
     }
     qDebug() << "  adjust to 100" << product->fermentables_use100;
 
+    product->fermentables_ok = true;
     product->mashs_kg = 0;
     for (i = 0; i < product->fermentables.size(); i++) {
-	if (product->fermentables.at(i).f_type == 1 && product->fermentables.at(i).f_added < 4)		// Sugars
+	if (product->fermentables.at(i).f_type == FERMENTABLE_TYPE_SUGAR && product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)
 	    psugar += product->fermentables.at(i).f_percentage;
-	if (product->fermentables.at(i).f_graintype == 2 && product->fermentables.at(i).f_added < 4)	// Crystal/Cara
+	if (product->fermentables.at(i).f_graintype == FERMENTABLE_GRAINTYPE_CRYSTAL && product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)
 	    pcara += product->fermentables.at(i).f_percentage;
 	d = product->fermentables.at(i).f_amount * (product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100);
-	if (product->fermentables.at(i).f_added == 0) {					// Mash
-	    if (mvol > 0) {							// If mash volume is known
+	if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_MASH) {
+	    if (mvol > 0) {	// If mash volume is known
 		mvol += product->fermentables.at(i).f_amount * product->fermentables.at(i).f_moisture / 100;
 		s += d;
 	    }
@@ -239,32 +257,42 @@
 	    sugarsm += d;
 	    product->mashs_kg += product->fermentables.at(i).f_amount;
 	}
-	if (product->fermentables.at(i).f_added == 0 || product->fermentables.at(i).f_added == 1)		// Mash or boil
+	if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_MASH || product->fermentables.at(i).f_added == FERMENTABLE_ADDED_BOIL)
 	    sugarsf += d;
-	if (product->fermentables.at(i).f_added == 2 || product->fermentables.at(i).f_added == 3) {		// Fermentation or lagering
+	if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_FERMENTATION || product->fermentables.at(i).f_added == FERMENTABLE_ADDED_LAGERING) {
 	    x = (product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100);
 	    addedS += product->fermentables.at(i).f_amount * x;
 	    addedmass += product->fermentables.at(i).f_amount;
 	    vol += (x * sugardensity + (1 - x) * 1) * product->fermentables.at(i).f_amount;
 	}
-	if (product->fermentables.at(i).f_added == 0 &&
-	    (product->fermentables.at(i).f_type == 0 || product->fermentables.at(i).f_type == 4) &&
+	if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_MASH &&
+	    (product->fermentables.at(i).f_type == FERMENTABLE_TYPE_GRAIN || product->fermentables.at(i).f_type == FERMENTABLE_TYPE_ADJUCT) &&
 	    product->fermentables.at(i).f_color < 50) {
 	    lintner += product->fermentables.at(i).f_diastatic_power * product->fermentables.at(i).f_amount;
 	}
-	if (product->fermentables.at(i).f_added < 4) {
+	if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
 	    colort += product->fermentables.at(i).f_amount * Utils::ebc_to_srm(product->fermentables.at(i).f_color);
 	    colorh += product->fermentables.at(i).f_amount * product->fermentables.at(i).f_color * Utils::get_kt(product->fermentables.at(i).f_color);
 	    colorn += (product->fermentables.at(i).f_percentage / 100) * product->fermentables.at(i).f_color;	// For 8.6 Pt wort.
 	}
-	if (product->fermentables.at(i).f_added == 4) {	// Bottle priming
+	if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_BOTTLE) {	// Bottle priming
 	    ui->bottle_sug_weightShow->setValue(product->fermentables.at(i).f_amount * 1000);
 	    // product->fermentables.at(i).f_name  select in dropdown
 	}
-	if (product->fermentables.at(i).f_added == 5) {	// Keg priming
+	if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_KEGS) {	// Keg priming
 
 	}
+	/* Check supplies */
+	if ((((product->inventory_reduced <= PROD_STAGE_BREW)     && (product->fermentables.at(i).f_added <= FERMENTABLE_ADDED_BOIL)) ||
+	     ((product->inventory_reduced <= PROD_STAGE_PRIMARY)  && (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_FERMENTATION)) ||
+	     ((product->inventory_reduced <= PROD_STAGE_TERTIARY) && (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_LAGERING)) ||
+	     ((product->inventory_reduced <= PROD_STAGE_PACKAGE)  && (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_BOTTLE)) ||
+	     ((product->inventory_reduced <= PROD_STAGE_PACKAGE)  && (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_KEGS))) &&
+	       product->fermentables.at(i).f_inventory < product->fermentables.at(i).f_amount) {
+	    product->fermentables_ok = false;
+	}
     }
+    qDebug() << "  supplies" << product->fermentables_ok;
     qDebug() << "  colort" << colort << "colorh" << colorh << "colorn" << colorn;
     qDebug() << "  psugar" << psugar << "pcara" << pcara << "mvol" << mvol;
     qDebug() << "  sugarsf" << sugarsf << "sugarsm" << sugarsm;
@@ -274,32 +302,78 @@
     product->est_mash_sg = Utils::plato_to_sg(s);
     ui->brew_mashsgShow->setValue(product->est_mash_sg);
 
-    double og = Utils::estimate_sg(sugarsf + addedS, product->batch_size);
-    qDebug() << "  OG" << ui->est_ogEdit->value() << og;
-    product->est_og = og;
-    ui->est_ogEdit->setValue(og);
-    ui->est_og2Edit->setValue(og);
-    ui->est_og4Edit->setValue(og);
-    ui->est_ogShow->setValue(og);
+    /* Estimate total recipe OG */
+    product->est_og = Utils::estimate_sg(sugarsf + addedS, product->batch_size);
+    qDebug() << "  OG" << ui->est_ogEdit->value() << product->est_og;
+    ui->est_ogEdit->setValue(product->est_og);
+    ui->est_og2Edit->setValue(product->est_og);
+    ui->est_og4Edit->setValue(product->est_og);
+    ui->est_ogShow->setValue(product->est_og);
 
+    /* Estimate SG in kettle after boil */
     product->est_og3 = Utils::estimate_sg(sugarsf, product->batch_size);
     ui->brew_aboilsgShow->setValue(product->est_og3);
 
+    /* Estimate SG in kettle before boil */
     product->preboil_sg = Utils::estimate_sg(sugarsm, product->boil_size);
     ui->brew_preboilsgShow->setValue(product->preboil_sg);
     qDebug() << "  preboil SG" << product->preboil_sg;
 
     /*
+     * Recalculate volumes
+     */
+    double aboil_volume = product->batch_size;
+    if (product->brew_aboil_volume > 0)
+	aboil_volume = product->brew_aboil_volume / 1.04;	// Volume @ 20 degrees.
+    if (product->brew_fermenter_tcloss == 0) {
+	product->brew_fermenter_tcloss = product->eq_trub_chiller_loss;
+	ui->brew_trublossEdit->setValue(product->brew_fermenter_tcloss);
+    }
+    product->brew_fermenter_volume = aboil_volume - product->brew_fermenter_tcloss + product->brew_fermenter_extrawater;
+    ui->brew_tofermentEdit->setValue(product->brew_fermenter_volume);
+    /* Calculate SG in fermenter */
+    double ogx = product->brew_aboil_sg;
+    if (ogx < 1.002)
+	ogx = product->est_og3;
+    double topw = product->brew_fermenter_extrawater;
+
+    if (product->brew_fermenter_volume > 0) {
+	double sug = Utils::sg_to_plato(ogx) * product->brew_fermenter_volume * ogx / 100;  //kg of sugar in
+   	sug += addedS; //kg
+
+	if ((product->brew_fermenter_volume * ogx + addedmass) > 0) {
+	    double pt = 100 * sug / (product->brew_fermenter_volume * ogx + addedmass + topw);
+	    product->og = product->brew_fermenter_sg = round(Utils::plato_to_sg(pt) * 10000) / 10000.0;
+	    ui->brew_fermentsgShow->setValue(product->brew_fermenter_sg);
+	    // color
+	    if (product->color_method == 4) {		// Naudts
+		product->brew_fermenter_color = round(((pt / 8.6) * colorn) + (product->boil_time / 60));
+	    } else if (product->color_method == 3) {	// Hans Halberstadt
+		product->brew_fermenter_color = round((4.46 * bv * sr) / (aboil_volume + topw) * colorh);
+	    } else {
+		cw = colort / (aboil_volume + topw) * 8.34436;
+		product->brew_fermenter_color = Utils::kw_to_ebc(product->color_method, cw);
+	    }
+	    ui->brew_fermentcolorShow->setValue(product->brew_fermenter_color);
+	    ui->brew_fermentcolorShow->setStyleSheet(Utils::ebc_to_style(product->brew_fermenter_color));
+	}
+    } else {
+	// Negative volume
+	product->brew_fermenter_sg = product->brew_fermenter_color = 0;
+	ui->brew_fermentsgShow->setValue(0);
+	ui->brew_fermentcolorShow->setStyleSheet(0);
+	ui->brew_fermentcolorShow->setValue(0);
+    }
+
+    /*
      * Color of the wort
      */
     if (product->color_method == 4) {				// Naudts
-	color = round(((Utils::sg_to_plato(og) / 8.6) * colorn) + (product->boil_time / 60));
+	color = round(((Utils::sg_to_plato(product->est_og) / 8.6) * colorn) + (product->boil_time / 60));
     } else if (product->color_method == 3) {			// Hans Halberstadt
-	double bv = 0.925;					// Beer loss efficiency
-	double sr = 0.95;					// Mash and sparge efficiency
 	color = round((4.46 * bv * sr) / product->batch_size * colorh);
     } else {
-	double cw = colort / product->batch_size * 8.34436;
+	cw = colort / product->batch_size * 8.34436;
 	color = Utils::kw_to_ebc(product->color_method, cw);
 	//qDebug() << "  oud EBC" << color << "new EBC" << Utils::kw_to_newebc(product->color_method, cw) << "SRM" << Utils::kw_to_srm(product->color_method, cw);
     }
@@ -327,50 +401,68 @@
      * Calculate the apparant attenuation.
      */
     double svg = 0;
+    double initcells = 0;
     if (product->yeasts.size() > 0) {
         for (i = 0; i < product->yeasts.size(); i++) {
 	    if (product->yeasts.at(i).y_use == 0) {		// Used in primary
 		if (product->yeasts.at(i).y_attenuation > svg)
 		    svg = product->yeasts.at(i).y_attenuation;	// Take the highest if multiple yeasts.
 	    }
+	    if (product->yeasts.at(i).y_form == 0)
+		initcells += (product->yeasts.at(i).y_cells / 1000000000) * product->yeasts.at(i).y_amount * (product->starter_viability / 100);
+	    else
+		initcells += (product->yeasts.at(i).y_cells / 1000000) * product->yeasts.at(i).y_amount * (product->starter_viability / 100);
 	    // TODO: brett or others in secondary.
+	    product->yeasts_ok = true;
+	    if ((((product->inventory_reduced <= PROD_STAGE_PRIMARY)   && (product->yeasts.at(i).y_use == 0)) ||  // Primary
+        	 ((product->inventory_reduced <= PROD_STAGE_SECONDARY) && (product->yeasts.at(i).y_use == 1)) ||  // Secondary
+        	 ((product->inventory_reduced <= PROD_STAGE_TERTIARY)  && (product->yeasts.at(i).y_use == 2)) ||  // Tertiary
+        	 ((product->inventory_reduced <= PROD_STAGE_PACKAGE)   && (product->yeasts.at(i).y_use == 3))) && // Bottle
+        	  (product->yeasts.at(i).y_inventory < product->yeasts.at(i).y_amount)) {
+		product->yeasts_ok = false;
+	    }
 	}
 	qDebug() << "  SVG" << svg;
     }
+    calcSupplies();
     if (svg == 0)
 	svg = 77.0;
     ui->est_svgEdit->setValue(svg);
 
-    double fg;
     if (product->mashs_kg > 0 && mashinfuse > 0 && mashtime > 0 && mashtemp > 0)
-	fg = Utils::estimate_fg(psugar, pcara, mashinfuse / product->mashs_kg, mashtime, mashtemp, svg, og);
+	product->est_fg = Utils::estimate_fg(psugar, pcara, mashinfuse / product->mashs_kg, mashtime, mashtemp, svg, product->est_og);
     else
-	fg = Utils::estimate_fg(psugar, pcara, 0, 0, 0, svg, og);
-    qDebug() << "  FG" << ui->est_fgEdit->value() << fg;
-    product->est_fg = fg;
-    ui->est_fgEdit->setValue(fg);
-    ui->est_fg3Edit->setValue(fg);
-    ui->est_fgShow->setValue(fg);
+	product->est_fg = Utils::estimate_fg(psugar, pcara, 0, 0, 0, svg, product->est_og);
+    qDebug() << "  FG" << ui->est_fgEdit->value() << product->est_fg;
+    ui->est_fgEdit->setValue(product->est_fg);
+    ui->est_fg3Edit->setValue(product->est_fg);
+    ui->est_fgShow->setValue(product->est_fg);
 
-    double abv = Utils::abvol(og, fg);
-    qDebug() << "  ABV" << ui->est_abvEdit->value() << abv;
-    ui->est_abvEdit->setValue(abv);
-    ui->est_abv2Edit->setValue(abv);
-    ui->est_abvShow->setValue(abv);
-    product->est_abv = abv;
+    /*
+     * Calculate the final values if available.
+     */
+    if ((product->stage >= 6) && (product->fg > 0.990) && (product->fg < product->brew_fermenter_sg)) {
+
+    }
+
+    product->est_abv = Utils::abvol(product->est_og, product->est_fg);
+    qDebug() << "  ABV" << ui->est_abvEdit->value() << product->est_abv;
+    ui->est_abvEdit->setValue(product->est_abv);
+    ui->est_abv2Edit->setValue(product->est_abv);
+    ui->est_abvShow->setValue(product->est_abv);
 
     /*
      * Calculate kilocalories/liter. Formula from brouwhulp.
      * Take the alcohol and sugar parts and then combine.
      */
-    double alc = 1881.22 * fg * (og - fg) / (1.775 - og);
-    double sug = 3550 * fg * (0.1808 * og + 0.8192 * fg - 1.0004);
+    double alc = 1881.22 * product->est_fg * (product->est_og - product->est_fg) / (1.775 - product->est_og);
+    double sug = 3550 * product->est_fg * (0.1808 * product->est_og + 0.8192 * product->est_fg - 1.0004);
     ui->calEdit->setValue(round((alc + sug) / (12 * 0.0295735296)));
 
     // Bottle priming
     double priming_total = 0;
     for (i = 0; i < product->fermentables.size(); i++) {
-	if (product->fermentables.at(i).f_added == 4) {
+	if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_BOTTLE) {
 	    priming_total += ((product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100)) *
 		    		product->fermentables.at(i).f_amount;
 	    qDebug() << "  priming" << product->fermentables.at(i).f_amount << "total" << priming_total;
@@ -400,11 +492,11 @@
     double sug = Utils::sg_to_plato(og) * product->batch_size * og / 100.0;	// total amount of sugars in kg.
 
     for (i = 0; i < product->fermentables.size(); i++) {
-	if (product->fermentables.at(i).f_added < 4) {
+	if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
 	    d = product->fermentables.at(i).f_percentage / 100.0 *
 		    (product->fermentables.at(i).f_yield / 100.0) *
 		    (1 - product->fermentables.at(i).f_moisture / 100.0);
-	    if (product->fermentables.at(i).f_added == 0)  // Mash
+	    if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_MASH)
 		d = efficiency / 100.0 * d;
 	    tot += d;
 	}
@@ -477,7 +569,7 @@
     newf.f_supplier = "";
     newf.f_amount = 0;
     newf.f_cost = 0;
-    newf.f_type = 0;
+    newf.f_type = FERMENTABLE_TYPE_GRAIN;
     newf.f_yield = 0;
     newf.f_color = 0;
     newf.f_coarse_fine_diff = 0;
@@ -486,8 +578,8 @@
     newf.f_protein = 0;
     newf.f_dissolved_protein = 0;
     newf.f_max_in_batch = 100;
-    newf.f_graintype = 0;
-    newf.f_added = 0;
+    newf.f_graintype = FERMENTABLE_GRAINTYPE_BASE;
+    newf.f_added = FERMENTABLE_ADDED_MASH;
     newf.f_recommend_mash = true;
     newf.f_add_after_boil = false;
     newf.f_adjust_to_total_100 = false;
@@ -524,10 +616,10 @@
      */
     double total = 0;
     for (int i = 0; i < product->fermentables.size(); i++)
-        if (product->fermentables.at(i).f_added < 4)             // Only before bottle/kegging
+        if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)	// Only before bottle/kegging
             total += product->fermentables.at(i).f_amount;
     for (int i = 0; i < product->fermentables.size(); i++)
-        if (product->fermentables.at(i).f_added < 4)
+        if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)
             product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100;
 
     is_changed();
@@ -540,7 +632,7 @@
     QTableWidgetItem *item;
     double	total = 0, perc;
 
-    if (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4)
+    if (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < FERMENTABLE_ADDED_BOTTLE)
 	return;
 
     qDebug() << "ferment_amount_changed()" << product->fermentables_row << val;
@@ -551,13 +643,13 @@
     ui->fermentablesTable->setItem(product->fermentables_row, 7, item);
 
     for (int i = 0; i < product->fermentables.size(); i++)
-	if (product->fermentables.at(i).f_added < 4)		// Only before bottle/kegging
+	if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)	// Only before bottle/kegging
 	    total += product->fermentables.at(i).f_amount;
     /*
      * Recalculate the percentages
      */
     for (int i = 0; i < product->fermentables.size(); i++) {
-	if (product->fermentables.at(i).f_added < 4) {
+	if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
 	    perc = product->fermentables.at(i).f_amount / total * 100;
 	    product->fermentables[i].f_percentage = perc;
 	    item = new QTableWidgetItem(QString("%1%").arg(perc, 2, 'f', 1, '0'));
@@ -585,7 +677,7 @@
      * this is not the entry to be adjusted to 100.
      */
     for (int i = 0; i < product->fermentables.size(); i++) {
-        if (product->fermentables.at(i).f_added < 4)             // Only before bottle/kegging
+        if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)	// Only before bottle/kegging
             total += product->fermentables.at(i).f_amount;
 	if (product->fermentables.at(i).f_adjust_to_total_100)
 	    row100 = i;
@@ -625,7 +717,7 @@
 {
     qDebug() << "ferment_to100_changed()" << product->fermentables_row << val << product->fermentables_use100;
 
-    if (product->fermentables.at(product->fermentables_row).f_added >= 4) {
+    if (product->fermentables.at(product->fermentables_row).f_added >= FERMENTABLE_ADDED_BOTTLE) {
 	const QSignalBlocker blocker1(to100Edit);
 	product->fermentables[product->fermentables_row].f_adjust_to_total_100 = false;
 	to100Edit->setChecked(false);
@@ -684,7 +776,7 @@
      * Search the fermentable pointed by the index and instock flag.
      */
     QString sql = "SELECT name,origin,supplier,cost,type,yield,color,coarse_fine_diff,moisture,diastatic_power,protein,dissolved_protein,max_in_batch,"
-	  	  "graintype,recommend_mash,add_after_boil,di_ph,acid_to_ph_57 FROM inventory_fermentables ";
+	  	  "graintype,recommend_mash,add_after_boil,di_ph,acid_to_ph_57,inventory FROM inventory_fermentables ";
     if (instock)
 	sql.append("WHERE inventory > 0 ");
     sql.append("ORDER BY supplier,name");
@@ -694,7 +786,6 @@
     for (int i = 0; i < (val - 1); i++) {
 	query.next();
     }
-    qDebug() << "found" << query.value(2).toString() << query.value(0).toString();
 
     /*
      * Replace the fermentable record contents
@@ -717,6 +808,7 @@
     product->fermentables[product->fermentables_row].f_add_after_boil = query.value(15).toInt() ? true:false;
     product->fermentables[product->fermentables_row].f_di_ph = query.value(16).toDouble();
     product->fermentables[product->fermentables_row].f_acid_to_ph_57 = query.value(17).toDouble();
+    product->fermentables[product->fermentables_row].f_inventory = query.value(18).toDouble();
 
     /*
      * Update the visible fields
@@ -745,6 +837,12 @@
     item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
     ui->fermentablesTable->setItem(product->fermentables_row, 6, item);
 
+    item = new QTableWidgetItem(QString("%1 Kg").arg(product->fermentables.at(product->fermentables_row).f_inventory, 4, 'f', 3, '0'));
+    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
+    if (product->fermentables.at(product->fermentables_row).f_inventory < product->fermentables.at(product->fermentables_row).f_amount)
+	item->setForeground(QBrush(QColor(Qt::red)));
+    ui->fermentablesTable->setItem(product->fermentables_row, 8, item);
+
     calcFermentables();
     is_changed();
 }
@@ -783,15 +881,15 @@
     item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
     ui->fermentablesTable->setItem(product->fermentables_row, 5, item);
 
-    famountEdit->setReadOnly(product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4);
-    pctEdit->setReadOnly(! (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4));
+    famountEdit->setReadOnly(product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < FERMENTABLE_ADDED_BOTTLE);
+    pctEdit->setReadOnly(! (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < FERMENTABLE_ADDED_BOTTLE));
 
     double total = 0;
     for (int i = 0; i < product->fermentables.size(); i++)
-        if (product->fermentables.at(i).f_added < 4)             // Only before bottle/kegging
+        if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)	// Only before bottle/kegging
             total += product->fermentables.at(i).f_amount;
     for (int i = 0; i < product->fermentables.size(); i++)
-        if (product->fermentables.at(i).f_added < 4)
+        if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)
             product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100;
 
     is_changed();
@@ -897,7 +995,7 @@
     pctEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
     pctEdit->setAccelerated(true);
     pctEdit->setDecimals(1);
-    if (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4) {
+    if (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < FERMENTABLE_ADDED_BOTTLE) {
     	if (product->fermentables.at(product->fermentables_row).f_adjust_to_total_100)
 	    pctEdit->setReadOnly(true);
     	else
@@ -916,8 +1014,6 @@
     faddedEdit->addItem(tr("Boil"));
     faddedEdit->addItem(tr("Fermentation"));
     faddedEdit->addItem(tr("Lagering"));
-    faddedEdit->addItem(tr("Bottle"));
-    faddedEdit->addItem(tr("Kegs"));
     faddedEdit->setCurrentIndex(product->fermentables.at(product->fermentables_row).f_added);
 
     to100Edit = new QCheckBox(dialog);
@@ -960,13 +1056,13 @@
 	 */
 	double total = 0;
 	for (int i = 0; i < product->fermentables.size(); i++)
-	    if (product->fermentables.at(i).f_added < 4)             // Only before bottle/kegging
+	    if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)	// Only before bottle/kegging
 		total += product->fermentables.at(i).f_amount;
 	product->fermentables_use100 = false;
 	for (int i = 0; i < product->fermentables.size(); i++) {
 	    if (product->fermentables.at(i).f_adjust_to_total_100)
 	    	product->fermentables_use100 = true;
-	    if (product->fermentables.at(i).f_added < 4) {
+	    if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
 		product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100;
 	    }
 	}

mercurial